1 /*---------------------------------------------------------------------\
3 | |__ / \ / / . \ . \ |
8 \---------------------------------------------------------------------*/
9 /** \file zypp/media/MediaHandler.h
12 #ifndef ZYPP_MEDIA_MEDIAHANDLERL_H
13 #define ZYPP_MEDIA_MEDIAHANDLERL_H
19 #include "zypp/Pathname.h"
20 #include "zypp/PathInfo.h"
21 #include "zypp/base/PtrTypes.h"
25 #include "zypp/media/MediaSource.h"
26 #include "zypp/media/MediaException.h"
32 ///////////////////////////////////////////////////////////////////
34 // CLASS NAME : MediaHandler
36 * @short Abstract base class for 'physical' MediaHandler like MediaCD, etc.
38 * Handles the requests forwarded by @ref MediaAccess. The public interface
39 * contains nonvirtual methods, which should do common sanitychecks and
40 * logging. For the real action they call virtual methods overloaded by the
44 friend std::ostream & operator<<( std::ostream & str, const MediaHandler & obj );
47 typedef shared_ptr<MediaHandler> Ptr;
48 typedef shared_ptr<const MediaHandler> constPtr;
50 static bool setAttachPrefix(const Pathname &attach_prefix);
54 * User defined default attach point prefix.
56 static Pathname _attachPrefix;
59 * The attached media source description reference.
62 MediaSourceRef _mediaSource;
65 * This is where the media will be actually attached ("mounted").
66 * All files are provided bellow this + _relativeRoot directory.
68 AttachPointRef _attachPoint;
71 * The user provided attach preferred point. It may contain
74 * "", true => create temporary attach point bellow of
75 * _attachPrefix or a built-in default and
76 * remove it if not needed any more.
78 * dir, false => user specified attach point (not removed)
80 AttachPoint _AttachPointHint;
83 * The relative root directory of the data on the media.
84 * See also localRoot() and urlpath_below_attachpoint_r
85 * constructor argument.
87 Pathname _relativeRoot;
90 * True if concrete handler downloads files to the local
91 * filesystem. If true releaseFile/Dir will delete them.
95 /** timestamp of the the last attach verification */
96 mutable time_t _attach_mtime;
105 * Access Id of media handler we depend on.
107 MediaAccessId _parentId;
110 * MediaAccess (MediaManager) needs access to the attachedMedia()
111 * function to deliver a shared media source and its attach point
112 * to the media manager and then to other media handler instances.
113 * Further, is needs to be able to forward the dependsOnParent()
114 * and resetParentId() functions to the media manager.
116 friend class MediaAccess;
119 * Check if the current media handler depends on an
120 * another handler specified by media access id.
121 * \param parentId The id of the parent handler to check against.
122 * \return true if it depends, false if not.
124 bool dependsOnParent(MediaAccessId parentId,
126 bool dependsOnParent();
129 * Called in case, where the media manager takes over the
130 * destruction of the parent id (e.g. while destruction
131 * of the media manager).
133 void resetParentId();
136 * Return the currently used attach point.
138 Pathname attachPoint() const;
141 * Set a new attach point.
142 * \param path The attach point directory path.
143 * \param temp If to remove the attach point while cleanup.
145 void setAttachPoint(const Pathname &path, bool temp);
148 * Set a (shared) attach point.
149 * \param ref New attach point reference.
151 void setAttachPoint(const AttachPointRef &ref);
154 * Get the actual attach point hint.
156 AttachPoint attachPointHint() const;
159 * Set the attach point hint as specified by the user.
160 * \param path The attach point directory path.
161 * \param temp If to remove the attach point while cleanup.
163 void attachPointHint(const Pathname &path, bool temp);
166 * Try to create a default / temporary attach point.
167 * It trys to create it in attachPrefix if avaliable,
168 * then in built-in directories.
169 * \return The name of the new attach point or empty path name.
171 Pathname createAttachPoint() const;
173 * Try to create a temporary attach point in specified root.
174 * \param attach_root The attach root dir where to create the
176 * \return The name of the new attach point or empty path name.
178 Pathname createAttachPoint(const Pathname &attach_root) const;
181 * Remove unused attach point. If the attach point is temporary,
182 * the attach point directory and all it content will be removed.
184 void removeAttachPoint();
187 * Verify if the specified directory as attach point (root)
188 * as requires by the particular media handler implementation.
189 * \param apoint The directory to check.
190 * \return True, if the directory checks succeeded.
192 virtual bool checkAttachPoint(const Pathname &apoint) const;
195 * Verify if the specified directory as attach point (root)
196 * using requested checks.
197 * \param apoint The directory to check.
198 * \param empty_dir Check if the directory is empty.
199 * \param writeable Check if the directory is writeable.
200 * \return True, if the directory checks succeeded.
202 static bool checkAttachPoint(const Pathname &apoint,
207 * Ask media manager, if the specified path is already used
208 * as attach point or if there are another attach points
210 * \param path The attach point path to check.
211 * \return True, if the path can be used as attach point.
213 bool isUseableAttachPoint(const Pathname &path) const;
216 * Get the media source name or an empty string.
217 * \return media source name or empty string.
219 std::string mediaSourceName() const
221 return _mediaSource ? _mediaSource->name : "";
225 * Set new media source reference.
226 * \param ref The new reference.
228 void setMediaSource(const MediaSourceRef &ref);
231 * Ask the media manager if specified media source
232 * is already attached.
235 findAttachedMedia(const MediaSourceRef &media) const;
238 * Returns the attached media. Used by MediaManager
239 * to find other handlers using the same source.
240 * \note This function increments reference counters
241 * on the mediaSource and attachPoint references
242 * it contains, for the life time of the returned
243 * object. That is, it enables a (temporary) sharing
245 * \return The AttachedMedia struct containing (shared)
246 * references to media source and attach point.
248 AttachedMedia attachedMedia() const;
251 * Returns a hint if the media is shared or not.
252 * \return true, if media is shared.
254 bool isSharedMedia() const;
257 * Check actual mediaSource attachment against the current
258 * mount table of the system. Used to implement isAttached().
259 * \param matchMountFs If to use the filesystem type from the
260 * mount table (nfs, smb and cifs) or from mediaSource
261 * while compare of a mount entry with mediaSource.
262 * \return true, if the media appears in the mount table.
264 bool checkAttached(bool matchMountFs) const;
267 * Call to this function will try to release all media matching
268 * the currenlty attached media source, that it is able to find
269 * in the mount table. This means also foreign (user) mounts!
270 * \param matchMountFs If to use the filesystem type from the
271 * mount table (nfs, smb and cifs) or from mediaSource
272 * while compare of a mount entry with mediaSource.
274 void forceRelaseAllMedia(bool matchMountFs);
278 ///////////////////////////////////////////////////////////////////
280 // Real action interface to be overloaded by concrete handler.
282 ///////////////////////////////////////////////////////////////////
285 * Call concrete handler to attach the media.
287 * Asserted that not already attached, and attachPoint is a directory.
289 * @param next try next available device in turn until end of device
290 * list is reached (for media which are accessible through multiple
291 * devices like cdroms).
293 * \throws MediaException
296 virtual void attachTo(bool next = false) = 0;
299 * Call concrete handler to disconnect media.
301 * Asserted that media is attached.
303 * This is useful for media which e.g. holds open a connection to a
304 * server like FTP. After calling disconnect() the media object still is
305 * valid and files are present.
307 * After calling disconnect() it's not possible to call provideFile() or
308 * provideDir() anymore.
310 * \throws MediaException
313 virtual void disconnectFrom() { return; }
316 * Call concrete handler to release the media.
318 * If eject is true, and the media is used in one handler
319 * instance only, physically eject the media (i.e. CD-ROM).
321 * Asserted that media is attached.
323 * \throws MediaException
326 virtual void releaseFrom( bool eject ) = 0;
329 * Call concrete handler to physically eject the media (i.e. CD-ROM)
330 * in case the media is not attached..
332 * Asserted that media is not attached.
334 virtual void forceEject() {}
337 * Call concrete handler to provide file below attach point.
339 * Default implementation provided, that returns whether a file
340 * is located at 'localRoot + filename'.
342 * Asserted that media is attached.
344 * \throws MediaException
347 virtual void getFile( const Pathname & filename ) const = 0;
350 * Call concrete handler to provide a file under a different place
351 * in the file system (usually not under attach point) as a copy.
352 * Media must be attached before by callee.
354 * Default implementation provided that calls getFile(srcFilename)
355 * and copies the result around.
357 * \throws MediaException
360 virtual void getFileCopy( const Pathname & srcFilename, const Pathname & targetFilename ) const;
364 * Call concrete handler to provide directory content (not recursive!)
365 * below attach point.
367 * Return E_not_supported_by_media if media does not support retrieval of
370 * Default implementation provided, that returns whether a directory
371 * is located at 'localRoot + dirname'.
373 * Asserted that media is attached.
375 * \throws MediaException
378 virtual void getDir( const Pathname & dirname, bool recurse_r ) const = 0;
381 * Call concrete handler to provide a content list of directory on media
382 * via retlist. If dots is false entries starting with '.' are not reported.
384 * Return E_not_supported_by_media if media does not support retrieval of
387 * Default implementation provided, that returns the content of a
388 * directory at 'localRoot + dirnname' retrieved via 'readdir'.
390 * Asserted that media is attached and retlist is empty.
392 * \throws MediaException
395 virtual void getDirInfo( std::list<std::string> & retlist,
396 const Pathname & dirname, bool dots = true ) const = 0;
399 * Basically the same as getDirInfo above. The content list is returned as
400 * filesystem::DirContent, which includes name and filetype of each directory
401 * entry. Retrieving the filetype usg. requires an additional ::stat call for
402 * each entry, thus it's more expensive than a simple readdir.
404 * Asserted that media is attached and retlist is empty.
406 * \throws MediaException
409 virtual void getDirInfo( filesystem::DirContent & retlist,
410 const Pathname & dirname, bool dots = true ) const = 0;
415 * Retrieve and if available scan dirname/directory.yast.
417 * Asserted that media is attached.
419 * \throws MediaException
422 void getDirectoryYast( std::list<std::string> & retlist,
423 const Pathname & dirname, bool dots = true ) const;
426 * Retrieve and if available scan dirname/directory.yast.
428 * Asserted that media is attached.
430 * \throws MediaException
433 void getDirectoryYast( filesystem::DirContent & retlist,
434 const Pathname & dirname, bool dots = true ) const;
439 * If the concrete media handler provides a nonempty
440 * attach_point, it must be an existing directory.
442 * On an empty attach_point, MediaHandler will create
443 * a temporay directory, which will be erased from
446 * On any error, the attach_point is set to an empty Pathname,
447 * which should lead to E_bad_attachpoint.
449 MediaHandler ( const Url& url_r,
450 const Pathname & attach_point_r,
451 const Pathname & urlpath_below_attachpoint_r,
452 const bool does_download_r );
455 * Contolling MediaAccess takes care, that attached media is released
456 * prior to deleting this.
458 virtual ~MediaHandler();
463 ///////////////////////////////////////////////////////////////////
465 // MediaAccess interface. Does common checks and logging.
466 // Invokes real action if necessary.
468 ///////////////////////////////////////////////////////////////////
471 * Hint if files are downloaded or not.
473 bool downloads() const { return _does_download; }
476 * Protocol hint for MediaAccess.
478 std::string protocol() const { return _url.getScheme(); }
483 Url url() const { return _url; }
486 * Use concrete handler to attach the media.
488 * @param next try next available device in turn until end of device
489 * list is reached (for media which are accessible through multiple
490 * devices like cdroms).
492 * \throws MediaException
495 void attach(bool next);
498 * True if media is attached.
500 virtual bool isAttached() const { return _mediaSource; }
503 * Return the local directory that corresponds to medias url,
504 * no matter if media isAttached or not. Files requested will
505 * be available at 'localRoot() + filename' or better
506 * 'localPath( filename )'.
508 * Returns empty pathname if E_bad_attachpoint
510 Pathname localRoot() const;
513 * Files provided will be available at 'localPath(filename)'.
515 * Returns empty pathname if E_bad_attachpoint
517 Pathname localPath( const Pathname & pathname ) const;
520 * Use concrete handler to isconnect media.
522 * This is useful for media which e.g. holds open a connection to a
523 * server like FTP. After calling disconnect() the media object still is
524 * valid and files are present.
526 * After calling disconnect() it's not possible to call provideFile() or
527 * provideDir() anymore.
529 * \throws MediaException
535 * Use concrete handler to release the media.
536 * @param eject if true, physically eject the media * (i.e. CD-ROM)
538 * \throws MediaException
541 void release( bool eject = false );
544 * Use concrete handler to provide file denoted by path below
545 * 'localRoot'. Filename is interpreted relative to the
546 * attached url and a path prefix is preserved.
548 * \throws MediaException
551 void provideFile( Pathname filename ) const;
554 * Call concrete handler to provide a copy of a file under a different place
555 * in the file system (usually not under attach point) as a copy.
556 * Media must be attached before by callee.
558 * @param srcFilename Filename of source file on the media
559 * @param targetFilename Filename for the target in the file system
561 * \throws MediaException
564 void provideFileCopy( Pathname srcFilename, Pathname targetFilename) const;
567 * Use concrete handler to provide directory denoted
568 * by path below 'localRoot' (not recursive!).
569 * dirname is interpreted relative to the
570 * attached url and a path prefix is preserved.
572 * \throws MediaException
575 void provideDir( Pathname dirname ) const;
578 * Use concrete handler to provide directory tree denoted
579 * by path below 'localRoot' (recursive!!).
580 * dirname is interpreted relative to the
581 * attached url and a path prefix is preserved.
583 * \throws MediaException
586 void provideDirTree( Pathname dirname ) const;
589 * Remove filename below localRoot IFF handler downloads files
590 * to the local filesystem. Never remove anything from media.
592 * \throws MediaException
595 void releaseFile( const Pathname & filename ) const { return releasePath( filename ); }
598 * Remove directory tree below localRoot IFF handler downloads files
599 * to the local filesystem. Never remove anything from media.
601 * \throws MediaException
604 void releaseDir( const Pathname & dirname ) const { return releasePath( dirname ); }
607 * Remove pathname below localRoot IFF handler downloads files
608 * to the local filesystem. Never remove anything from media.
610 * If pathname denotes a directory it is recursively removed.
611 * If pathname is empty or '/' everything below the localRoot
612 * is recursively removed.
613 * If pathname denotes a file it is unlinked.
615 * \throws MediaException
618 void releasePath( Pathname pathname ) const;
623 * Return content of directory on media via retlist. If dots is false
624 * entries starting with '.' are not reported.
626 * The request is forwarded to the concrete handler,
627 * which may atempt to retieve the content e.g. via 'readdir'
629 * <B>Caution:</B> This is not supported by all media types.
630 * Be prepared to handle E_not_supported_by_media.
632 * \throws MediaException
635 void dirInfo( std::list<std::string> & retlist,
636 const Pathname & dirname, bool dots = true ) const;
639 * Basically the same as dirInfo above. The content is returned as
640 * filesystem::DirContent, which includes name and filetype of each directory
641 * entry. Retrieving the filetype usg. requires an additional ::stat call for
642 * each entry, thus it's more expensive than a simple readdir.
644 * <B>Caution:</B> This is not supported by all media types.
645 * Be prepared to handle E_not_supported_by_media.
647 * \throws MediaException
650 void dirInfo( filesystem::DirContent & retlist,
651 const Pathname & dirname, bool dots = true ) const;
654 ///////////////////////////////////////////////////////////////////
656 #define MEDIA_HANDLER_API \
658 virtual void attachTo (bool next = false); \
659 virtual void releaseFrom( bool eject ); \
660 virtual void getFile( const Pathname & filename ) const; \
661 virtual void getDir( const Pathname & dirname, bool recurse_r ) const; \
662 virtual void getDirInfo( std::list<std::string> & retlist, \
663 const Pathname & dirname, bool dots = true ) const; \
664 virtual void getDirInfo( filesystem::DirContent & retlist, \
665 const Pathname & dirname, bool dots = true ) const;
671 #endif // ZYPP_MEDIA_MEDIAHANDLERL_H