2 /*---------------------------------------------------------------------\
4 | |__ / \ / / . \ . \ |
9 \---------------------------------------------------------------------*/
10 /** \file zypp/media/MediaHandler.h
13 #ifndef ZYPP_MEDIA_MEDIAHANDLERL_H
14 #define ZYPP_MEDIA_MEDIAHANDLERL_H
20 #include "zypp/Pathname.h"
21 #include "zypp/PathInfo.h"
22 #include "zypp/base/PtrTypes.h"
26 #include "zypp/media/MediaSource.h"
27 #include "zypp/media/MediaException.h"
28 #include "zypp/APIConfig.h"
34 ///////////////////////////////////////////////////////////////////
36 // CLASS NAME : MediaHandler
38 * @short Abstract base class for 'physical' MediaHandler like MediaCD, etc.
40 * Handles the requests forwarded by @ref MediaAccess. The public interface
41 * contains nonvirtual methods, which should do common sanitychecks and
42 * logging. For the real action they call virtual methods overloaded by the
46 friend std::ostream & operator<<( std::ostream & str, const MediaHandler & obj );
49 typedef shared_ptr<MediaHandler> Ptr;
50 typedef shared_ptr<const MediaHandler> constPtr;
52 static bool setAttachPrefix(const Pathname &attach_prefix);
54 static std::string getRealPath(const std::string &path);
55 static Pathname getRealPath(const Pathname &path);
59 * User defined default attach point prefix.
61 static Pathname _attachPrefix;
64 * The attached media source description reference.
67 MediaSourceRef _mediaSource;
70 * This is where the media will be actually attached ("mounted").
71 * All files are provided bellow this + _relativeRoot directory.
73 AttachPointRef _attachPoint;
76 * The user provided attach preferred point. It may contain
79 * "", true => create temporary attach point bellow of
80 * _attachPrefix or a built-in default and
81 * remove it if not needed any more.
83 * dir, false => user specified attach point (not removed)
85 AttachPoint _AttachPointHint;
88 * The relative root directory of the data on the media.
89 * See also localRoot() and urlpath_below_attachpoint_r
90 * constructor argument.
92 Pathname _relativeRoot;
95 * True if concrete handler downloads files to the local
96 * filesystem. If true releaseFile/Dir will delete them.
100 /** timestamp of the the last attach verification */
101 mutable time_t _attach_mtime;
103 /** file usable for delta downloads */
104 mutable Pathname _deltafile;
113 * Access Id of media handler we depend on.
115 MediaAccessId _parentId;
118 * MediaAccess (MediaManager) needs access to the attachedMedia()
119 * function to deliver a shared media source and its attach point
120 * to the media manager and then to other media handler instances.
121 * Further, is needs to be able to forward the dependsOnParent()
122 * and resetParentId() functions to the media manager.
124 friend class MediaAccess;
127 * Check if the current media handler depends on an
128 * another handler specified by media access id.
129 * \param parentId The id of the parent handler to check against.
130 * \return true if it depends, false if not.
132 bool dependsOnParent(MediaAccessId parentId,
134 bool dependsOnParent();
137 * Called in case, where the media manager takes over the
138 * destruction of the parent id (e.g. while destruction
139 * of the media manager).
141 void resetParentId();
144 * Return the currently used attach point.
146 Pathname attachPoint() const;
149 * Set a new attach point.
150 * \param path The attach point directory path.
151 * \param temp If to remove the attach point while cleanup.
153 void setAttachPoint(const Pathname &path, bool temp);
156 * Set a (shared) attach point.
157 * \param ref New attach point reference.
159 void setAttachPoint(const AttachPointRef &ref);
162 * Get the actual attach point hint.
164 AttachPoint attachPointHint() const;
167 * Set the attach point hint as specified by the user.
168 * \param path The attach point directory path.
169 * \param temp If to remove the attach point while cleanup.
171 void attachPointHint(const Pathname &path, bool temp);
174 * Try to create a default / temporary attach point.
175 * It trys to create it in attachPrefix if avaliable,
176 * then in built-in directories.
177 * \return The name of the new attach point or empty path name.
179 Pathname createAttachPoint() const;
181 * Try to create a temporary attach point in specified root.
182 * \param attach_root The attach root dir where to create the
184 * \return The name of the new attach point or empty path name.
186 Pathname createAttachPoint(const Pathname &attach_root) const;
189 * Remove unused attach point. If the attach point is temporary,
190 * the attach point directory and all it content will be removed.
192 void removeAttachPoint();
195 * Verify if the specified directory as attach point (root)
196 * as requires by the particular media handler implementation.
197 * \param apoint The directory to check.
198 * \return True, if the directory checks succeeded.
200 virtual bool checkAttachPoint(const Pathname &apoint) const;
203 * Verify if the specified directory as attach point (root)
204 * using requested checks.
205 * \param apoint The directory to check.
206 * \param empty_dir Check if the directory is empty.
207 * \param writeable Check if the directory is writeable.
208 * \return True, if the directory checks succeeded.
210 static bool checkAttachPoint(const Pathname &apoint,
215 * Ask media manager, if the specified path is already used
216 * as attach point or if there are another attach points
218 * \param path The attach point path to check.
219 * \param mtab Whether to check against the mtab, too.
220 * \return True, if the path can be used as attach point.
222 bool isUseableAttachPoint(const Pathname &path,
223 bool mtab=true) const;
226 * Get the media source name or an empty string.
227 * \return media source name or empty string.
229 std::string mediaSourceName() const
231 return _mediaSource ? _mediaSource->name : "";
235 * Set new media source reference.
236 * \param ref The new reference.
238 void setMediaSource(const MediaSourceRef &ref);
241 * Ask the media manager if specified media source
242 * is already attached.
245 findAttachedMedia(const MediaSourceRef &media) const;
248 * Returns the attached media. Used by MediaManager
249 * to find other handlers using the same source.
250 * \note This function increments reference counters
251 * on the mediaSource and attachPoint references
252 * it contains, for the life time of the returned
253 * object. That is, it enables a (temporary) sharing
255 * \return The AttachedMedia struct containing (shared)
256 * references to media source and attach point.
258 AttachedMedia attachedMedia() const;
261 * Returns a hint if the media is shared or not.
262 * \return true, if media is shared.
264 bool isSharedMedia() const;
267 * Check actual mediaSource attachment against the current
268 * mount table of the system. Used to implement isAttached().
269 * \param matchMountFs If to use the filesystem type from the
270 * mount table (nfs, smb and cifs) or from mediaSource
271 * while compare of a mount entry with mediaSource.
272 * \return true, if the media appears in the mount table.
274 bool checkAttached(bool matchMountFs) const;
277 * Call to this function will try to release all media matching
278 * the currenlty attached media source, that it is able to find
279 * in the mount table. This means also foreign (user) mounts!
280 * \param matchMountFs If to use the filesystem type from the
281 * mount table (nfs, smb and cifs) or from mediaSource
282 * while compare of a mount entry with mediaSource.
284 void forceRelaseAllMedia(bool matchMountFs);
285 void forceRelaseAllMedia(const MediaSourceRef &ref,
290 ///////////////////////////////////////////////////////////////////
292 // Real action interface to be overloaded by concrete handler.
294 ///////////////////////////////////////////////////////////////////
297 * Call concrete handler to attach the media.
299 * Asserted that not already attached, and attachPoint is a directory.
301 * @param next try next available device in turn until end of device
302 * list is reached (for media which are accessible through multiple
303 * devices like cdroms).
305 * \throws MediaException
308 virtual void attachTo(bool next = false) = 0;
311 * Call concrete handler to disconnect media.
313 * Asserted that media is attached.
315 * This is useful for media which e.g. holds open a connection to a
316 * server like FTP. After calling disconnect() the media object still is
317 * valid and files are present.
319 * After calling disconnect() it's not possible to call provideFile() or
320 * provideDir() anymore.
322 * \throws MediaException
325 virtual void disconnectFrom() { return; }
328 * Call concrete handler to release the media.
330 * If eject is true, and the media is used in one handler
331 * instance only, physically eject the media (i.e. CD-ROM).
333 * Asserted that media is attached.
334 * \param ejectDev Device to eject. None if empty.
336 * \throws MediaException
339 virtual void releaseFrom( const std::string & ejectDev = "" ) = 0;
342 * Call concrete handler to physically eject the media (i.e. CD-ROM)
343 * in case the media is not attached..
345 * Asserted that media is not attached.
347 virtual void forceEject( const std::string & device ) {}
350 * Call concrete handler to provide file below attach point.
352 * Default implementation provided, that returns whether a file
353 * is located at 'localRoot + filename'.
355 * Asserted that media is attached.
357 * \throws MediaException
360 virtual void getFile( const Pathname & filename, const ByteCount &expectedFileSize_r ) const;
363 * Call concrete handler to provide a file under a different place
364 * in the file system (usually not under attach point) as a copy.
365 * Media must be attached before by callee.
367 * Default implementation provided that calls getFile(srcFilename)
368 * and copies the result around.
370 * \throws MediaException
373 virtual void getFileCopy( const Pathname & srcFilename, const Pathname & targetFilename, const ByteCount &expectedFileSize_r ) const;
377 * Call concrete handler to provide directory content (not recursive!)
378 * below attach point.
380 * Return E_not_supported_by_media if media does not support retrieval of
383 * Default implementation provided, that returns whether a directory
384 * is located at 'localRoot + dirname'.
386 * Asserted that media is attached.
388 * \throws MediaException
391 virtual void getDir( const Pathname & dirname, bool recurse_r ) const = 0;
394 * Call concrete handler to provide a content list of directory on media
395 * via retlist. If dots is false entries starting with '.' are not reported.
397 * Return E_not_supported_by_media if media does not support retrieval of
400 * Default implementation provided, that returns the content of a
401 * directory at 'localRoot + dirnname' retrieved via 'readdir'.
403 * Asserted that media is attached and retlist is empty.
405 * \throws MediaException
408 virtual void getDirInfo( std::list<std::string> & retlist,
409 const Pathname & dirname, bool dots = true ) const = 0;
412 * Basically the same as getDirInfo above. The content list is returned as
413 * filesystem::DirContent, which includes name and filetype of each directory
414 * entry. Retrieving the filetype usg. requires an additional ::stat call for
415 * each entry, thus it's more expensive than a simple readdir.
417 * Asserted that media is attached and retlist is empty.
419 * \throws MediaException
422 virtual void getDirInfo( filesystem::DirContent & retlist,
423 const Pathname & dirname, bool dots = true ) const = 0;
426 * check if a file exists
428 * Asserted that url is a file and not a dir.
430 * \throws MediaException
433 virtual bool getDoesFileExist( const Pathname & filename ) const = 0;
438 * Retrieve and if available scan dirname/directory.yast.
440 * Asserted that media is attached.
442 * \throws MediaException
445 void getDirectoryYast( std::list<std::string> & retlist,
446 const Pathname & dirname, bool dots = true ) const;
449 * Retrieve and if available scan dirname/directory.yast.
451 * Asserted that media is attached.
453 * \throws MediaException
456 void getDirectoryYast( filesystem::DirContent & retlist,
457 const Pathname & dirname, bool dots = true ) const;
462 * If the concrete media handler provides a nonempty
463 * attach_point, it must be an existing directory.
465 * On an empty attach_point, MediaHandler will create
466 * a temporay directory, which will be erased from
469 * On any error, the attach_point is set to an empty Pathname,
470 * which should lead to E_bad_attachpoint.
472 MediaHandler ( const Url& url_r,
473 const Pathname & attach_point_r,
474 const Pathname & urlpath_below_attachpoint_r,
475 const bool does_download_r );
478 * Contolling MediaAccess takes care, that attached media is released
479 * prior to deleting this.
481 virtual ~MediaHandler();
486 ///////////////////////////////////////////////////////////////////
488 // MediaAccess interface. Does common checks and logging.
489 // Invokes real action if necessary.
491 ///////////////////////////////////////////////////////////////////
494 * Hint if files are downloaded or not.
496 bool downloads() const { return _does_download; }
499 * Protocol hint for MediaAccess.
501 std::string protocol() const { return _url.getScheme(); }
506 Url url() const { return _url; }
509 * Use concrete handler to attach the media.
511 * @param next try next available device in turn until end of device
512 * list is reached (for media which are accessible through multiple
513 * devices like cdroms).
515 * \throws MediaException
518 void attach(bool next);
521 * True if media is attached.
523 virtual bool isAttached() const { return _mediaSource != nullptr; }
526 * Return the local directory that corresponds to medias url,
527 * no matter if media isAttached or not. Files requested will
528 * be available at 'localRoot() + filename' or better
529 * 'localPath( filename )'.
531 * Returns empty pathname if E_bad_attachpoint
533 Pathname localRoot() const;
536 * Files provided will be available at 'localPath(filename)'.
538 * Returns empty pathname if E_bad_attachpoint
540 Pathname localPath( const Pathname & pathname ) const;
543 * Use concrete handler to isconnect media.
545 * This is useful for media which e.g. holds open a connection to a
546 * server like FTP. After calling disconnect() the media object still is
547 * valid and files are present.
549 * After calling disconnect() it's not possible to call provideFile() or
550 * provideDir() anymore.
552 * \throws MediaException
558 * Use concrete handler to release the media.
559 * @param eject Device to physically eject. None if empty.
561 * \throws MediaException
563 void release( const std::string & ejectDev = "" );
566 * Use concrete handler to provide file denoted by path below
567 * 'localRoot'. Filename is interpreted relative to the
568 * attached url and a path prefix is preserved.
570 * \throws MediaException
573 void provideFile( Pathname filename, const ByteCount &expectedFileSize_r ) const;
576 * Call concrete handler to provide a copy of a file under a different place
577 * in the file system (usually not under attach point) as a copy.
578 * Media must be attached before by callee.
580 * @param srcFilename Filename of source file on the media
581 * @param targetFilename Filename for the target in the file system
583 * \throws MediaException
586 void provideFileCopy( Pathname srcFilename, Pathname targetFilename, const ByteCount &expectedFileSize_r ) const;
589 * Use concrete handler to provide directory denoted
590 * by path below 'localRoot' (not recursive!).
591 * dirname is interpreted relative to the
592 * attached url and a path prefix is preserved.
594 * \throws MediaException
597 void provideDir( Pathname dirname ) const;
600 * Use concrete handler to provide directory tree denoted
601 * by path below 'localRoot' (recursive!!).
602 * dirname is interpreted relative to the
603 * attached url and a path prefix is preserved.
605 * \throws MediaException
608 void provideDirTree( Pathname dirname ) const;
611 * Remove filename below localRoot IFF handler downloads files
612 * to the local filesystem. Never remove anything from media.
614 * \throws MediaException
617 void releaseFile( const Pathname & filename ) const { return releasePath( filename ); }
620 * Remove directory tree below localRoot IFF handler downloads files
621 * to the local filesystem. Never remove anything from media.
623 * \throws MediaException
626 void releaseDir( const Pathname & dirname ) const { return releasePath( dirname ); }
629 * Remove pathname below localRoot IFF handler downloads files
630 * to the local filesystem. Never remove anything from media.
632 * If pathname denotes a directory it is recursively removed.
633 * If pathname is empty or '/' everything below the localRoot
634 * is recursively removed.
635 * If pathname denotes a file it is unlinked.
637 * \throws MediaException
640 void releasePath( Pathname pathname ) const;
643 * set a deltafile to be used in the next download
645 void setDeltafile( const Pathname &filename = Pathname()) const;
648 * return the deltafile set with setDeltafile()
650 Pathname deltafile () const;
655 * Return content of directory on media via retlist. If dots is false
656 * entries starting with '.' are not reported.
658 * The request is forwarded to the concrete handler,
659 * which may atempt to retieve the content e.g. via 'readdir'
661 * <B>Caution:</B> This is not supported by all media types.
662 * Be prepared to handle E_not_supported_by_media.
664 * \throws MediaException
667 void dirInfo( std::list<std::string> & retlist,
668 const Pathname & dirname, bool dots = true ) const;
671 * Basically the same as dirInfo above. The content is returned as
672 * filesystem::DirContent, which includes name and filetype of each directory
673 * entry. Retrieving the filetype usg. requires an additional ::stat call for
674 * each entry, thus it's more expensive than a simple readdir.
676 * <B>Caution:</B> This is not supported by all media types.
677 * Be prepared to handle E_not_supported_by_media.
679 * \throws MediaException
682 void dirInfo( filesystem::DirContent & retlist,
683 const Pathname & dirname, bool dots = true ) const;
686 * check if a file exists
688 * Asserted that url is a file and not a dir.
690 * \throws MediaException
693 bool doesFileExist( const Pathname & filename ) const;
696 * Check if the media has one more device available for attach(true).
698 virtual bool hasMoreDevices();
701 * Fill in a vector of detected ejectable devices and the index of the
702 * currently attached device within the vector. The contents of the vector
703 * are the device names (/dev/cdrom and such).
705 * \param devices vector to load with the device names
706 * \param index index of the currently used device in the devices vector
709 getDetectedDevices(std::vector<std::string> & devices,
710 unsigned int & index) const;
713 ///////////////////////////////////////////////////////////////////
719 #endif // ZYPP_MEDIA_MEDIAHANDLERL_H