Imported Upstream version 16.3.2
[platform/upstream/libzypp.git] / zypp / media / MediaHandler.h
index 3b812de..9fd8782 100644 (file)
@@ -1,3 +1,4 @@
+
 /*---------------------------------------------------------------------\
 |                          ____ _   __ __ ___                          |
 |                         |__  / \ / / . \ . \                         |
@@ -24,6 +25,7 @@
 
 #include "zypp/media/MediaSource.h"
 #include "zypp/media/MediaException.h"
+#include "zypp/APIConfig.h"
 
 namespace zypp {
   namespace media {
@@ -47,65 +49,96 @@ class MediaHandler {
        typedef shared_ptr<MediaHandler> Ptr;
        typedef shared_ptr<const MediaHandler> constPtr;
 
+       static bool setAttachPrefix(const Pathname &attach_prefix);
+
+       static std::string getRealPath(const std::string &path);
+       static Pathname    getRealPath(const Pathname    &path);
+
     private:
         /**
-        * MediaAccess (MediaManager) needs access to the
-        * attachedMedia() function to deliver a shared
-        * media source and its attach point to other
-        * media handler instances.
+        * User defined default attach point prefix.
         */
-       friend class MediaAccess;
+       static Pathname _attachPrefix;
 
        /**
-        * Returns the attached media. Used by MediaManager
-        * to find other handlers using the same source.
+        * The attached media source description reference.
         */
-       AttachedMedia        attachedMedia() const;
+       mutable
+       MediaSourceRef  _mediaSource;
 
        /**
-        * this is where the media will be actually "mounted"
-        * all files are provided 'below' this directory.
+        * This is where the media will be actually attached ("mounted").
+        * All files are provided bellow this + _relativeRoot directory.
         **/
-       AttachPointRef _attachPoint;
+       AttachPointRef  _attachPoint;
 
        /**
-        * The relative root directory of the data on the media.
-        * See also _localRoot and urlpath_below_attachpoint_r
-        * constructor argument.
+        * The user provided attach preferred point. It may contain
+        * following values:
+        *
+        *      "",  true  => create temporary attach point bellow of
+        *                    _attachPrefix or a built-in default and
+        *                    remove it if not needed any more.
+        *
+        *      dir, false => user specified attach point (not removed)
         */
-       Pathname _relativeRoot;
+       AttachPoint     _attachPointHint;
 
        /**
-        * The local directory that corresponds to the media url.
-        * With NFS it's the '_attachPoint', as the directory on the
-        * server is mounted. With CD/DVD it's 'attach point+_relativeRoot'
-        * because the CDs root directory is mounted. And with CIFS
-        * it's '_url.path() without the shares name'.
-        **/
-       Pathname _localRoot;
+        * The relative root directory of the data on the media.
+        * See also localRoot() and urlpath_below_attachpoint_r
+        * constructor argument.
+        */
+       Pathname        _relativeRoot;
 
        /**
         * True if concrete handler downloads files to the local
         * filesystem. If true releaseFile/Dir will delete them.
         **/
-       bool _does_download;
+       bool            _does_download;
+
+        /** timestamp of the the last attach verification */
+        mutable time_t  _attach_mtime;
 
+       /** file usable for delta downloads */
+       mutable Pathname _deltafile;
+
+    protected:
         /**
-        * True, if media is attached.
+        * Url to handle
         **/
-       bool _isAttached;
+       const Url        _url;
 
-    protected:
-       // FIXME: private...?
        /**
-        * The attached media source.
+        * Access Id of media handler we depend on.
         */
-        MediaSourceRef _mediaSource;
+       MediaAccessId    _parentId;
 
         /**
-        * Url to handle
-        **/
-       const Url _url;
+        * MediaAccess (MediaManager) needs access to the attachedMedia()
+        * function to deliver a shared media source and its attach point
+        * to the media manager and then to other media handler instances.
+        * Further, is needs to be able to forward the dependsOnParent()
+        * and resetParentId() functions to the media manager.
+        */
+       friend class MediaAccess;
+
+       /**
+        * Check if the current media handler depends on an
+        * another handler specified by media access id.
+        * \param parentId The id of the parent handler to check against.
+        * \return true if it depends, false if not.
+        */
+       bool             dependsOnParent(MediaAccessId parentId,
+                                        bool exactIdMatch);
+       bool             dependsOnParent();
+
+       /**
+        * Called in case, where the media manager takes over the
+        * destruction of the parent id (e.g. while destruction
+        * of the media manager).
+        */
+       void             resetParentId();
 
         /**
         * Return the currently used attach point.
@@ -113,26 +146,98 @@ class MediaHandler {
        Pathname         attachPoint() const;
 
        /**
-        * Set a new attach point and update localRoot.
+        * Set a new attach point.
+        * \param path  The attach point directory path.
+        * \param temp  If to remove the attach point while cleanup.
         */
-       void             setAttachPoint(const Pathname &path, bool _temporary);
+       void             setAttachPoint(const Pathname &path, bool temp);
 
        /**
-        * Set a (shared) attach point and update localRoot.
+        * Set a (shared) attach point.
+        * \param ref New attach point reference.
         */
        void             setAttachPoint(const AttachPointRef &ref);
 
        /**
+        * Get the actual attach point hint.
+        */
+       AttachPoint      attachPointHint() const;
+
+       /**
+        * Set the attach point hint as specified by the user.
+        * \param path  The attach point directory path.
+        * \param temp  If to remove the attach point while cleanup.
+        */
+       void             attachPointHint(const Pathname &path, bool temp);
+
+       /**
         * Try to create a default / temporary attach point.
-        * \return The name of the new attach point or empty path name.
+        * It tries to create it in attachPrefix if avaliable,
+        * then in built-in directories.
+        * \throws MediaBadAttachPointException if no attach point can be created
+        * \return The name of the new attach point
         */
        Pathname         createAttachPoint() const;
+       /**
+        * Try to create a temporary attach point in specified root.
+        * \param attach_root The attach root dir where to create the
+        *                    attach point in.
+        * \return The name of the new attach point or empty path name.
+        */
+        Pathname         createAttachPoint(const Pathname &attach_root) const;
 
        /**
-        * Remove unused attach point.
+        * Remove unused attach point. If the attach point is temporary,
+        * the attach point directory and all it content will be removed.
         */
        void             removeAttachPoint();
 
+        /**
+        * Verify if the specified directory as attach point (root)
+        * as requires by the particular media handler implementation.
+        * \param apoint The directory to check.
+        * \return True, if the directory checks succeeded.
+        */
+       virtual bool     checkAttachPoint(const Pathname &apoint) const;
+
+       /**
+        * Verify if the specified directory as attach point (root)
+        * using requested checks.
+        * \param apoint The directory to check.
+        * \param empty_dir Check if the directory is empty.
+        * \param writeable Check if the directory is writeable.
+        * \return True, if the directory checks succeeded.
+        */
+       static bool      checkAttachPoint(const Pathname &apoint,
+                                         bool            empty_dir,
+                                         bool            writeable);
+
+       /**
+        * Ask media manager, if the specified path is already used
+        * as attach point or if there are another attach points
+        * bellow of it.
+        * \param path The attach point path to check.
+        * \param mtab Whether to check against the mtab, too.
+        * \return True, if the path can be used as attach point.
+        */
+        bool             isUseableAttachPoint(const Pathname &path,
+                                             bool            mtab=true) const;
+
+       /**
+        * Get the media source name or an empty string.
+        * \return media source name or empty string.
+        */
+       std::string      mediaSourceName() const
+       {
+         return _mediaSource ? _mediaSource->name : "";
+       }
+
+       /**
+        * Set new media source reference.
+        * \param ref The new reference.
+        */
+       void             setMediaSource(const MediaSourceRef &ref);
+
        /**
         * Ask the media manager if specified media source
         * is already attached.
@@ -140,6 +245,47 @@ class MediaHandler {
        AttachedMedia
        findAttachedMedia(const MediaSourceRef &media) const;
 
+       /**
+        * Returns the attached media. Used by MediaManager
+        * to find other handlers using the same source.
+        * \note This function increments reference counters
+        *       on the mediaSource and attachPoint references
+        *       it contains, for the life time of the returned
+        *       object. That is, it enables a (temporary) sharing
+        *       of them.
+        * \return The AttachedMedia struct containing (shared)
+        *         references to media source and attach point.
+        */
+       AttachedMedia    attachedMedia() const;
+
+       /**
+        * Returns a hint if the media is shared or not.
+        * \return true, if media is shared.
+        */
+       bool             isSharedMedia() const;
+
+       /**
+        * Check actual mediaSource attachment against the current
+        * mount table of the system. Used to implement isAttached().
+        * \param matchMountFs If to use the filesystem type from the
+        *        mount table (nfs, smb and cifs) or from mediaSource
+        *        while compare of a mount entry with mediaSource.
+        * \return true, if the media appears in the mount table.
+        */
+       bool             checkAttached(bool matchMountFs) const;
+
+       /**
+        * Call to this function will try to release all media matching
+        * the currenlty attached media source, that it is able to find
+        * in the mount table. This means also foreign (user) mounts!
+        * \param matchMountFs If to use the filesystem type from the
+        *        mount table (nfs, smb and cifs) or from mediaSource
+        *        while compare of a mount entry with mediaSource.
+        */
+       void             forceRelaseAllMedia(bool matchMountFs);
+       void             forceRelaseAllMedia(const MediaSourceRef &ref,
+                                            bool matchMountFs);
+
     protected:
 
         ///////////////////////////////////////////////////////////////////
@@ -186,11 +332,12 @@ class MediaHandler {
         * instance only, physically eject the media (i.e. CD-ROM).
         *
         * Asserted that media is attached.
+        * \param ejectDev Device to eject. None if empty.
         *
         * \throws MediaException
         *
         **/
-       virtual void releaseFrom( bool eject ) = 0;
+       virtual void releaseFrom( const std::string & ejectDev = "" ) = 0;
 
        /**
         * Call concrete handler to physically eject the media (i.e. CD-ROM)
@@ -198,13 +345,13 @@ class MediaHandler {
         *
         * Asserted that media is not attached.
         **/
-       virtual void forceEject() {}
+       virtual void forceEject( const std::string & device ) {}
 
        /**
         * Call concrete handler to provide file below attach point.
         *
         * Default implementation provided, that returns whether a file
-        * is located at '_localRoot + filename'.
+        * is located at 'localRoot + filename'.
         *
         * Asserted that media is attached.
         *
@@ -235,7 +382,7 @@ class MediaHandler {
         * directory content.
         *
         * Default implementation provided, that returns whether a directory
-        * is located at '_localRoot + dirname'.
+        * is located at 'localRoot + dirname'.
         *
         * Asserted that media is attached.
         *
@@ -252,7 +399,7 @@ class MediaHandler {
         * directory content.
         *
         * Default implementation provided, that returns the content of a
-        * directory at '_localRoot + dirnname' retrieved via 'readdir'.
+        * directory at 'localRoot + dirnname' retrieved via 'readdir'.
         *
         * Asserted that media is attached and retlist is empty.
         *
@@ -276,6 +423,16 @@ class MediaHandler {
         virtual void getDirInfo( filesystem::DirContent & retlist,
                                  const Pathname & dirname, bool dots = true ) const = 0;
 
+        /**
+         * check if a file exists
+         *
+         * Asserted that url is a file and not a dir.
+         *
+         * \throws MediaException
+         *
+         **/
+        virtual bool getDoesFileExist( const Pathname & filename ) const = 0;
+
   protected:
 
         /**
@@ -334,6 +491,11 @@ class MediaHandler {
         //
         ///////////////////////////////////////////////////////////////////
 
+       /**
+        * Hint if files are downloaded or not.
+        */
+       bool        downloads() const { return _does_download; }
+
         /**
         * Protocol hint for MediaAccess.
         **/
@@ -359,7 +521,7 @@ class MediaHandler {
        /**
         * True if media is attached.
         **/
-       bool isAttached() const { return _isAttached; }
+       virtual bool isAttached() const { return _mediaSource != nullptr; }
 
        /**
         * Return the local directory that corresponds to medias url,
@@ -369,7 +531,7 @@ class MediaHandler {
         *
         * Returns empty pathname if E_bad_attachpoint
         **/
-       const Pathname & localRoot() const { return _localRoot; }
+       Pathname localRoot() const;
 
        /**
         * Files provided will be available at 'localPath(filename)'.
@@ -395,12 +557,11 @@ class MediaHandler {
 
        /**
         * Use concrete handler to release the media.
-        * @param eject if true, physically eject the media * (i.e. CD-ROM)
+        * @param eject Device to physically eject. None if empty.
         *
         * \throws MediaException
-        *
         **/
-       void release( bool eject = false );
+       void release( const std::string & ejectDev = "" );
 
        /**
         * Use concrete handler to provide file denoted by path below
@@ -479,6 +640,16 @@ class MediaHandler {
         **/
        void releasePath( Pathname pathname ) const;
 
+        /*
+         * set a deltafile to be used in the next download
+         */
+       void setDeltafile( const Pathname &filename = Pathname()) const;
+
+       /*
+        * return the deltafile set with setDeltafile()
+        */
+       Pathname deltafile () const;
+
     public:
 
        /**
@@ -511,21 +682,37 @@ class MediaHandler {
         **/
        void dirInfo( filesystem::DirContent & retlist,
                       const Pathname & dirname, bool dots = true ) const;
+
+        /**
+         * check if a file exists
+         *
+         * Asserted that url is a file and not a dir.
+         *
+         * \throws MediaException
+         *
+         **/
+        bool doesFileExist( const Pathname & filename ) const;
+
+        /**
+         * Check if the media has one more device available for attach(true).
+         */
+        virtual bool hasMoreDevices();
+
+        /**
+         * Fill in a vector of detected ejectable devices and the index of the
+         * currently attached device within the vector. The contents of the vector
+         * are the device names (/dev/cdrom and such).
+         *
+         * \param devices  vector to load with the device names
+         * \param index    index of the currently used device in the devices vector
+         */
+        virtual void
+        getDetectedDevices(std::vector<std::string> & devices,
+                           unsigned int & index) const;
 };
 
 ///////////////////////////////////////////////////////////////////
 
-#define        MEDIA_HANDLER_API                                               \
-    protected:                                                         \
-       virtual void attachTo (bool next = false);                      \
-       virtual void releaseFrom( bool eject );                 \
-       virtual void getFile( const Pathname & filename ) const;        \
-       virtual void getDir( const Pathname & dirname, bool recurse_r ) const;  \
-        virtual void getDirInfo( std::list<std::string> & retlist,     \
-                                   const Pathname & dirname, bool dots = true ) const; \
-        virtual void getDirInfo( filesystem::DirContent & retlist,     \
-                                   const Pathname & dirname, bool dots = true ) const;
-
   } // namespace media
 } // namespace zypp