added media-specific backends, some of them still need some updates...
authorJiri Srain <jsrain@suse.cz>
Tue, 13 Dec 2005 16:20:01 +0000 (16:20 +0000)
committerJiri Srain <jsrain@suse.cz>
Tue, 13 Dec 2005 16:20:01 +0000 (16:20 +0000)
23 files changed:
zypp/KVMap.h [new file with mode: 0644]
zypp/Makefile.am
zypp/media/Makefile.am
zypp/media/MediaAccess.cc
zypp/media/MediaCD.cc [new file with mode: 0644]
zypp/media/MediaCD.h [new file with mode: 0644]
zypp/media/MediaCIFS.cc [new file with mode: 0644]
zypp/media/MediaCIFS.h [new file with mode: 0644]
zypp/media/MediaCallbacks.cc [new file with mode: 0644]
zypp/media/MediaCallbacks.h [new file with mode: 0644]
zypp/media/MediaCurl.cc
zypp/media/MediaDIR.cc [new file with mode: 0644]
zypp/media/MediaDIR.h [new file with mode: 0644]
zypp/media/MediaDISK.cc [new file with mode: 0644]
zypp/media/MediaDISK.h [new file with mode: 0644]
zypp/media/MediaException.cc
zypp/media/MediaException.h
zypp/media/MediaNFS.cc [new file with mode: 0644]
zypp/media/MediaNFS.h [new file with mode: 0644]
zypp/media/MediaSMB.cc [new file with mode: 0644]
zypp/media/MediaSMB.h [new file with mode: 0644]
zypp/media/Mount.cc
zypp/media/Mount.h

diff --git a/zypp/KVMap.h b/zypp/KVMap.h
new file mode 100644 (file)
index 0000000..f464228
--- /dev/null
@@ -0,0 +1,209 @@
+/*---------------------------------------------------------------------\
+|                                                                      |
+|                      __   __    ____ _____ ____                      |
+|                      \ \ / /_ _/ ___|_   _|___ \                     |
+|                       \ V / _` \___ \ | |   __) |                    |
+|                        | | (_| |___) || |  / __/                     |
+|                        |_|\__,_|____/ |_| |_____|                    |
+|                                                                      |
+|                               core system                            |
+|                                                    (C) SuSE Linux AG |
+\----------------------------------------------------------------------/
+
+  File:       KVMap.h
+
+  Author:     Michael Andres <ma@suse.de>
+  Maintainer: Michael Andres <ma@suse.de>
+
+  Purpose: Convenience stuff for handling (key,value) pairs
+
+/-*/
+#ifndef KVMap_h
+#define KVMap_h
+
+#include <iosfwd>
+#include <map>
+
+#include "zypp/base/String.h"
+
+namespace zypp {
+  namespace kvmap {
+
+    ///////////////////////////////////////////////////////////////////
+    //
+    // CLASS NAME : KVMapBase::KVMapPolicy
+    /**
+     * @short KVMapPolicy for conversion of KVMaps to/from string.
+     *
+     * <b>_kvsplit</b>: The string separating key from value
+     *
+     * <b>_fsplit</b>:  (key,value) pairs are separated by any nonempty
+     * sequence of characers occurring in _fsplit
+     *
+     * <b>_kvjoin</b>: The string used to join key and value.
+     *
+     * <b>_fjoin</b>: The string used to separate (key,value) pairs.
+     *
+     * TODO: Maybe options for exact _fsplit handling and timming of values.
+     *
+     **/
+    struct KVMapPolicy {
+      std::string _kvsplit;
+      std::string _fsplit;
+      std::string _kvjoin;
+      std::string _fjoin;
+      KVMapPolicy( const std::string & kvsplit_r, const std::string & fsplit_r )
+        : _kvsplit( kvsplit_r )
+        , _fsplit ( fsplit_r )
+        , _kvjoin ( _kvsplit )
+        , _fjoin  ( _fsplit )
+      {}
+      KVMapPolicy( const std::string & kvsplit_r, const std::string & fsplit_r,
+            const std::string & kvjoin_r )
+        : _kvsplit( kvsplit_r )
+        , _fsplit ( fsplit_r )
+        , _kvjoin ( kvjoin_r )
+        , _fjoin  ( _fsplit )
+      {}
+      KVMapPolicy( const std::string & kvsplit_r, const std::string & fsplit_r,
+            const std::string & kvjoin_r, const std::string & fjoin_r )
+        : _kvsplit( kvsplit_r )
+        , _fsplit ( fsplit_r )
+        , _kvjoin ( kvjoin_r )
+        , _fjoin  ( fjoin_r )
+      {}
+    };
+
+    ///////////////////////////////////////////////////////////////////
+    //
+    // CLASS NAME : KVMapBase
+    /**
+     * @short Base class for KVMaps, (key,value) pairs
+     **/
+    struct KVMapBase : public std::map<std::string,std::string> {
+    
+      /**
+       * (key,value) map type
+       **/
+      typedef std::map<std::string,std::string> map_type;
+    
+      KVMapBase()
+      {}
+      KVMapBase( const map_type & kvmap_r )
+        : std::map<std::string,std::string>( kvmap_r )
+      {}
+    
+      /**
+       * Test whether key is set.
+       **/
+      bool has( const std::string & key_r ) const {
+        return( find( key_r ) != end() );
+      }
+    
+      /**
+       * @short KVMapPolicy for KVMaps using a single char as separator (e.g. mount options).
+       **/
+      template<char kv, char f>
+      struct CharSep : public KVMapPolicy { CharSep() : KVMapPolicy( std::string(1,kv), std::string(1,f) ) {} };
+    
+      ///////////////////////////////////////////////////////////////////
+    
+      /**
+       * Split str_r into (key,value) map, using the separators defined
+       * by opts_r.
+       **/
+      static map_type split( const std::string & str_r,
+                        const KVMapPolicy & opts_r ) {
+        map_type ret;
+        std::vector<std::string> fields;
+#warning uncomment when split is ported
+#if 0
+        str::split( str_r, fields, opts_r._fsplit );
+#endif
+    
+        for ( unsigned i = 0; i < fields.size(); ++i ) {
+          std::string::size_type pos = fields[i].find( opts_r._kvsplit );
+          if ( pos == std::string::npos ) {
+       ret[fields[i]] = "";
+          } else {
+       ret[fields[i].substr( 0, pos )] = fields[i].substr( pos+1 );
+          }
+        }
+    
+        return ret;
+      }
+    
+      /**
+       * Join (key,value) map into string, using the separators defined
+       * by opts_r.
+       **/
+      static std::string join( const map_type & kvmap_r,
+                          const KVMapPolicy & opts_r ) {
+        std::string ret;
+    
+        for ( map_type::const_iterator it = kvmap_r.begin(); it != kvmap_r.end(); ++it ) {
+          if ( ! ret.empty() ) {
+       ret += opts_r._fjoin;
+          }
+          ret += it->first;
+          if ( !it->second.empty() ) {
+       ret += opts_r._kvjoin + it->second;
+          }
+        }
+    
+        return ret;
+      }
+    
+    };
+
+
+
+  } // namespace kvmap
+
+  ///////////////////////////////////////////////////////////////////
+
+  ///////////////////////////////////////////////////////////////////
+  //
+  //   CLASS NAME : KVMap<KVMapOpts>
+  /**
+   * @short A map of (key,value) strings.
+   *
+   * The template argument defines the @ref kvmap::Options for
+   * split and join.
+   *
+   * E.g. mount options (a comma separated list of key[=value] pairs)
+   * could be handled by KVMap<kvmap::KVMapBase::Comma>.
+   **/
+  template<typename KVMapOpts>
+  struct KVMap : public kvmap::KVMapBase {
+  
+    KVMap()
+    {}
+    KVMap( const char * str_r )
+      : kvmap::KVMapBase( split( (str_r?str_r:""), KVMapOpts() ) )
+    {}
+    KVMap( const std::string & str_r )
+      : kvmap::KVMapBase( split( str_r, KVMapOpts() ) )
+    {}
+    KVMap( const map_type & map_r )
+      : kvmap::KVMapBase( map_r )
+    {}
+  
+    ~KVMap() {}
+  
+    std::string asString() const {
+      return join( *this, KVMapOpts() );
+    }
+  
+  };
+
+  ///////////////////////////////////////////////////////////////////
+
+  template<typename KVMapOpts>
+  std::ostream & operator<<( std::ostream & str, const KVMap<KVMapOpts> & obj )
+  { return str << obj.asString(); }
+
+///////////////////////////////////////////////////////////////////
+} // namespace zypp
+
+#endif // KVMap_h
index b4a937b..30c7ee1 100644 (file)
@@ -28,7 +28,10 @@ include_HEADERS = NeedAType.h \
        Pathname.h      \
        PathInfo.h      \
        Digest.h        \
-       Url.h
+       Url.h           \
+       TmpPath.h       \
+       KVMap.h         \
+       Callback.h      
 
 ## ##################################################
 
@@ -58,7 +61,8 @@ lib@PACKAGE@_la_SOURCES = \
        ExternalProgram.cc\
        PathInfo.cc     \
        Digest.cc       \
-       Url.cc
+       Url.cc          \
+       TmpPath.cc
 
 lib@PACKAGE@_la_LDFLAGS =      @LIB_VERSION_INFO@
 
index a4e02bd..ea1575a 100644 (file)
@@ -12,9 +12,14 @@ include_HEADERS =            \
        MediaAccess.h           \
        MediaHandler.h          \
        Mount.h                 \
+       MediaNFS.h              \
+       MediaCD.h               \
+       MediaDIR.h              \
+       MediaDISK.h             \
+       MediaSMB.h              \
+       MediaCIFS.h             \
        MediaCurl.h
 
-#      MediaNFS.h              
 
 noinst_LTLIBRARIES =   lib@PACKAGE@_media.la
 
@@ -25,9 +30,14 @@ lib@PACKAGE@_media_la_SOURCES = \
        MediaAccess.cc          \
        MediaHandler.cc         \
        Mount.cc                \
+       MediaNFS.cc             \
+       MediaCD.cc              \
+       MediaDIR.cc             \
+       MediaDISK.cc            \
+       MediaSMB.cc             \
+       MediaCIFS.cc            \
        MediaCurl.cc
 
-#      MediaNFS.cc             
 
 lib@PACKAGE@_media_la_LIBADD = -lcurl
 
index 2957c40..1b386fd 100644 (file)
 #include "zypp/media/MediaAccess.h"
 #include "zypp/media/MediaHandler.h"
 
-/*
+#include "zypp/media/MediaNFS.h"
 #include "zypp/media/MediaCD.h"
 #include "zypp/media/MediaDIR.h"
 #include "zypp/media/MediaDISK.h"
 #include "zypp/media/MediaSMB.h"
 #include "zypp/media/MediaCIFS.h"
-#include "zypp/media/MediaNFS.h"
-*/
 #include "zypp/media/MediaCurl.h"
 
 using namespace std;
@@ -67,47 +65,36 @@ MediaAccess::open (const Url& url, const Pathname & preferred_attach_point)
 
     close();
 
-#warning FIXME uncomment once media backends get ready
-#if 0
-    switch ( url.protocol() ) {
-      case Url::cd:
-      case Url::dvd:
+    std::string scheme = url.getScheme();
+    if (scheme == "cd" || scheme == "dvd")
         _handler = new MediaCD (url,preferred_attach_point);
-        break;
-      case Url::nfs:
+    else if (scheme == "nfs")
         _handler = new MediaNFS (url,preferred_attach_point);
-        break;
-      case Url::file:
-      case Url::dir:
+//    else if (scheme == "iso")
+//        _handler = new MediaISO (url,preferred_attach_point);
+    else if (scheme == "file" || scheme == "dir")
         _handler = new MediaDIR (url,preferred_attach_point);
-        break;
-      case Url::hd:
+    else if (scheme == "hd")
         _handler = new MediaDISK (url,preferred_attach_point);
-        break;
-      case Url::smb:
-      case Url::cifs:
+    else if (scheme == "smb")
+       _handler = new MediaSMB (url,preferred_attach_point);
+    else if (scheme == "cifs")
         _handler = new MediaCIFS (url,preferred_attach_point);
-        break;
-      case Url::ftp:
-      case Url::http:
-      case Url::https:
+    else if (scheme == "ftp" || scheme == "http" || scheme == "https")
         _handler = new MediaCurl (url,preferred_attach_point);
-        break;
-      case Url::unknown:
-       ERR << Error::E_bad_media_type << " opening " << url << endl;
-       return Error::E_bad_media_type;
-       break;
+    else
+    {
+       ERR << "Error::E_bad_media_type opening " << url << endl;
+       ZYPP_THROW(MediaUnsupportedUrlSchemeException(url));
     }
 
     // check created handler
     if ( !_handler ){
       ERR << "Failed to create media handler" << endl;
-      return Error::E_system;
+      ZYPP_THROW(MediaSystemException(url, "Failed to create media handler"));
     }
 
     MIL << "Opened: " << *this << endl;
-    return Error::E_ok;
-#endif
 }
 
 // Type of media if open, otherwise NONE.
diff --git a/zypp/media/MediaCD.cc b/zypp/media/MediaCD.cc
new file mode 100644 (file)
index 0000000..9490eb5
--- /dev/null
@@ -0,0 +1,326 @@
+/*---------------------------------------------------------------------\
+|                          ____ _   __ __ ___                          |
+|                         |__  / \ / / . \ . \                         |
+|                           / / \ V /|  _/  _/                         |
+|                          / /__ | | | | | |                           |
+|                         /_____||_| |_| |_|                           |
+|                                                                      |
+\---------------------------------------------------------------------*/
+/** \file zypp/media/MediaCD.cc
+ *
+*/
+
+#include <iostream>
+
+#include "zypp/base/Logger.h"
+#include "zypp/ExternalProgram.h"
+#include "zypp/media/Mount.h"
+#include "zypp/media/MediaCD.h"
+
+#include <cstring> // strerror
+
+#include <errno.h>
+#include <dirent.h>
+
+#include <sys/ioctl.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+#include <linux/cdrom.h>
+
+
+using namespace std;
+
+namespace zypp {
+  namespace media {
+
+///////////////////////////////////////////////////////////////////
+//
+//     CLASS NAME : MediaCD
+//
+///////////////////////////////////////////////////////////////////
+
+    ///////////////////////////////////////////////////////////////////
+    //
+    //
+    // METHOD NAME : MediaCD::MediaCD
+    // METHOD TYPE : Constructor
+    //
+    // DESCRIPTION :
+    //
+    MediaCD::MediaCD( const Url &      url_r,
+                 const Pathname & attach_point_hint_r )
+      : MediaHandler( url_r, attach_point_hint_r,
+                   url_r.getPathName(), // urlpath below attachpoint
+                   false ), // does_download
+      _lastdev(-1)
+    {
+      string devices = _url.getQueryParam("devices");
+      if (!devices.empty())
+      {
+       string::size_type pos;
+       DBG << "parse " << devices << endl;
+       while(!devices.empty())
+       {
+           pos = devices.find(',');
+           string device = devices.substr(0,pos);
+           if (!device.empty())
+           {
+               _devices.push_back(device);
+               DBG << "use device " << device << endl;
+           }
+           if (pos!=string::npos)
+               devices=devices.substr(pos+1);
+           else
+               devices.erase();
+       }
+      }
+      else
+      {
+       //default is /dev/cdrom; for dvd: /dev/dvd if it exists
+       //TODO: make configurable
+          string device( "/dev/cdrom" );
+       if ( _url.getScheme() == "dvd" && PathInfo( "/dev/dvd" ).isBlk() ) {
+         device = "/dev/dvd";
+       }
+       DBG << "use default device " << device << endl;
+       _devices.push_back(device);
+      }
+    }
+
+    ///////////////////////////////////////////////////////////////////
+    //
+    //
+    // METHOD NAME : MediaCD::openTray
+    // METHOD TYPE : bool
+    //
+    bool MediaCD::openTray( const string & device_r )
+    {
+      int fd = ::open( device_r.c_str(), O_RDONLY|O_NONBLOCK );
+      if ( fd == -1 ) {
+        WAR << "Unable to open '" << device_r << "' (" << ::strerror( errno ) << ")" << endl;
+        return false;
+      }
+      int res = ::ioctl( fd, CDROMEJECT );
+      ::close( fd );
+      if ( res ) {
+        WAR << "Eject " << device_r << " failed (" << ::strerror( errno ) << ")" << endl;
+        return false;
+      }
+      MIL << "Eject " << device_r << endl;
+      return true;
+    }
+
+    ///////////////////////////////////////////////////////////////////
+    //
+    //
+    // METHOD NAME : MediaCD::closeTray
+    // METHOD TYPE : bool
+    //
+    bool MediaCD::closeTray( const string & device_r )
+    {
+      int fd = ::open( device_r.c_str(), O_RDONLY|O_NONBLOCK );
+      if ( fd == -1 ) {
+        WAR << "Unable to open '" << device_r << "' (" << ::strerror( errno ) << ")" << endl;
+        return false;
+      }
+      int res = ::ioctl( fd, CDROMCLOSETRAY );
+      ::close( fd );
+      if ( res ) {
+        WAR << "Close tray " << device_r << " failed (" << ::strerror( errno ) << ")" << endl;
+        return false;
+      }
+      DBG << "Close tray " << device_r << endl;
+      return true;
+    }
+
+    ///////////////////////////////////////////////////////////////////
+    //
+    //
+    // METHOD NAME : MediaCD::attachTo
+    // METHOD TYPE : PMError
+    //
+    // DESCRIPTION : Asserted that not already attached, and attachPoint is a directory.
+    //
+    void MediaCD::attachTo(bool next)
+    {
+      Mount mount;
+      const char *mountpoint = attachPoint().asString().c_str();
+      bool mountsucceeded = false;
+      int count = 0;
+    
+      DBG << "next " << next << " last " << _lastdev << " lastdevice " << _mounteddevice << endl;
+    
+      if (next && _lastdev == -1)
+       ZYPP_THROW(MediaNotSupportedException(url()));
+    
+      string options = _url.getQueryParam("mountoptions");
+      if (options.empty())
+      {
+       options="ro";
+      }
+    
+      //TODO: make configurable
+      list<string> filesystems;
+    
+      // if DVD, try UDF filesystem before iso9660
+      if ( _url.getScheme() == "dvd" )
+       filesystems.push_back("udf");
+    
+      filesystems.push_back("iso9660");
+    
+      // try all devices in sequence
+      for (DeviceList::iterator it = _devices.begin()
+       ; !mountsucceeded && it != _devices.end()
+       ; ++it, count++ )
+      {
+       DBG << "count " << count << endl;
+       if (next && count<=_lastdev )
+       {
+               DBG << "skip" << endl;
+               continue;
+       }
+    
+       // close tray
+       closeTray( *it );
+    
+       // try all filesystems in sequence
+       for(list<string>::iterator fsit = filesystems.begin()
+           ; !mountsucceeded && fsit != filesystems.end()
+           ; ++fsit)
+       {
+         try {
+           mount.mount (*it, mountpoint, *fsit, options);
+           _mounteddevice = *it;
+           _lastdev = count;
+           mountsucceeded = true;
+         }
+         catch (const MediaException & excpt_r)
+         {
+           ZYPP_CAUGHT(excpt_r);
+         }
+       }
+      }
+    
+      if (!mountsucceeded)
+      {
+       _mounteddevice.erase();
+       _lastdev = -1;
+       // FIXME not suitable for MediaMountExeption, as device cannot be
+       // specified here
+       // errors might be different as well
+       ZYPP_THROW(MediaException("Error::E_mount_failed"));
+      }
+      DBG << _lastdev << " " << count << endl;
+    }
+
+
+    ///////////////////////////////////////////////////////////////////
+    //
+    //
+    // METHOD NAME : MediaCD::releaseFrom
+    // METHOD TYPE : PMError
+    //
+    // DESCRIPTION : Asserted that media is attached.
+    //
+    void MediaCD::releaseFrom( bool eject )
+    {
+      if (_mounteddevice.empty())              // no device mounted
+      {
+       if (eject)                      // eject wanted -> eject all devices
+       {
+           for (DeviceList::iterator it = _devices.begin()
+               ; it != _devices.end()
+               ; ++it )
+           {
+               openTray( *it );
+           }
+           return;
+       }
+       ZYPP_THROW(MediaNotAttachedException(url()));
+      }
+    
+      Mount mount;
+      mount.umount(attachPoint().asString());
+    
+      // eject device
+      if (eject)
+      {
+       openTray( _mounteddevice );
+      }
+    
+      _mounteddevice.erase();
+    }
+
+    ///////////////////////////////////////////////////////////////////
+    //
+    //
+    // METHOD NAME : MediaCD::forceEject
+    // METHOD TYPE : void
+    //
+    // Asserted that media is not attached.
+    //
+    void MediaCD::forceEject()
+    {
+      if ( _mounteddevice.empty() ) {  // no device mounted
+       for ( DeviceList::iterator it = _devices.begin(); it != _devices.end(); ++it ) {
+         if ( openTray( *it ) )
+           break; // on 1st success
+       }
+      }
+    }
+
+    ///////////////////////////////////////////////////////////////////
+    //
+    // METHOD NAME : MediaCD::getFile
+    // METHOD TYPE : PMError
+    //
+    // DESCRIPTION : Asserted that media is attached.
+    //
+    void MediaCD::getFile( const Pathname & filename ) const
+    {
+      MediaHandler::getFile( filename );
+    }
+
+    ///////////////////////////////////////////////////////////////////
+    //
+    // METHOD NAME : MediaCD::getDir
+    // METHOD TYPE : PMError
+    //
+    // DESCRIPTION : Asserted that media is attached.
+    //
+    void MediaCD::getDir( const Pathname & dirname, bool recurse_r ) const
+    {
+      MediaHandler::getDir( dirname, recurse_r );
+    }
+
+    ///////////////////////////////////////////////////////////////////
+    //
+    //
+    // METHOD NAME : MediaCD::getDirInfo
+    // METHOD TYPE : PMError
+    //
+    // DESCRIPTION : Asserted that media is attached and retlist is empty.
+    //
+    void MediaCD::getDirInfo( std::list<std::string> & retlist,
+                             const Pathname & dirname, bool dots ) const
+    {
+      MediaHandler::getDirInfo( retlist, dirname, dots );
+    }
+
+    ///////////////////////////////////////////////////////////////////
+    //
+    //
+    // METHOD NAME : MediaCD::getDirInfo
+    // METHOD TYPE : PMError
+    //
+    // DESCRIPTION : Asserted that media is attached and retlist is empty.
+    //
+    void MediaCD::getDirInfo( filesystem::DirContent & retlist,
+                             const Pathname & dirname, bool dots ) const
+    {
+      MediaHandler::getDirInfo( retlist, dirname, dots );
+    }
+
+  } // namespace media
+} // namespace zypp
diff --git a/zypp/media/MediaCD.h b/zypp/media/MediaCD.h
new file mode 100644 (file)
index 0000000..87ff697
--- /dev/null
@@ -0,0 +1,63 @@
+/*---------------------------------------------------------------------\
+|                          ____ _   __ __ ___                          |
+|                         |__  / \ / / . \ . \                         |
+|                           / / \ V /|  _/  _/                         |
+|                          / /__ | | | | | |                           |
+|                         /_____||_| |_| |_|                           |
+|                                                                      |
+\---------------------------------------------------------------------*/
+/** \file zypp/media/MediaCD.h
+ *
+*/
+#ifndef ZYPP_MEDIA_MEDIACD_H
+#define ZYPP_MEDIA_MEDIACD_H
+
+#include "zypp/media/MediaHandler.h"
+
+namespace zypp {
+  namespace media {
+
+    ///////////////////////////////////////////////////////////////////
+    //
+    // CLASS NAME : MediaCD
+    /**
+     * @short Implementation class for CD/DVD MediaHandler
+     * @see MediaHandler
+     **/
+    class MediaCD : public MediaHandler {
+    
+      private:
+    
+        unsigned long _mountflags;
+    
+        typedef std::list<std::string> DeviceList;
+        /** list of devices to try to mount */
+        DeviceList _devices;
+    
+        /** which device has been mounted */
+        std::string _mounteddevice;
+    
+        /** number of last successful mounted device in list */
+        int _lastdev;
+    
+        static bool openTray( const std::string & device_r );
+        static bool closeTray( const std::string & device_r );
+    
+      protected:
+    
+        MEDIA_HANDLER_API;
+    
+        virtual void forceEject();
+    
+      public:
+    
+        MediaCD( const Url &      url_r,
+                const Pathname & attach_point_hint_r );
+    
+        virtual ~MediaCD() { release(); }
+    };
+
+///////////////////////////////////////////////////////////////////
+  } // namespace media
+} // namespace zypp
+#endif // ZYPP_MEDIA_MEDIACD_H
diff --git a/zypp/media/MediaCIFS.cc b/zypp/media/MediaCIFS.cc
new file mode 100644 (file)
index 0000000..f4f2133
--- /dev/null
@@ -0,0 +1,16 @@
+/*---------------------------------------------------------------------\
+|                          ____ _   __ __ ___                          |
+|                         |__  / \ / / . \ . \                         |
+|                           / / \ V /|  _/  _/                         |
+|                          / /__ | | | | | |                           |
+|                         /_____||_| |_| |_|                           |
+|                                                                      |
+\---------------------------------------------------------------------*/
+/** \file zypp/media/MediaCIFS.cc
+ *
+*/
+
+//
+// NOTE: It's actually MediaSMB, but using "cifs"
+// as vfstype for mount.
+//
diff --git a/zypp/media/MediaCIFS.h b/zypp/media/MediaCIFS.h
new file mode 100644 (file)
index 0000000..f05b912
--- /dev/null
@@ -0,0 +1,47 @@
+/*---------------------------------------------------------------------\
+|                          ____ _   __ __ ___                          |
+|                         |__  / \ / / . \ . \                         |
+|                           / / \ V /|  _/  _/                         |
+|                          / /__ | | | | | |                           |
+|                         /_____||_| |_| |_|                           |
+|                                                                      |
+\---------------------------------------------------------------------*/
+/** \file zypp/media/MediaCIFS.h
+ *
+*/
+#ifndef ZYPP_MEDIA_MEDIACIFS_H
+#define ZYPP_MEDIA_MEDIACIFS_H
+
+#include "zypp/media/MediaSMB.h"
+
+namespace zypp {
+  namespace media {
+
+    ///////////////////////////////////////////////////////////////////
+    //
+    // CLASS NAME : MediaCIFS
+    /**
+     * @short Implementation class for CIFS MediaHandler
+     *
+     * NOTE: It's actually MediaSMB, but using "cifs"
+     * as vfstype for mount.
+     * @see MediaHandler
+     **/
+    class MediaCIFS : public MediaSMB {
+    
+    public:
+    
+      MediaCIFS( const Url&       url_r,
+                const Pathname & attach_point_hint_r )
+       : MediaSMB( url_r, attach_point_hint_r )
+      {
+       mountAsCIFS();
+      }
+    };
+
+  } // namespace media
+} // namespace zypp
+
+///////////////////////////////////////////////////////////////////
+
+#endif // ZYPP_MEDIA_MEDIACIFS_H
diff --git a/zypp/media/MediaCallbacks.cc b/zypp/media/MediaCallbacks.cc
new file mode 100644 (file)
index 0000000..fe577ca
--- /dev/null
@@ -0,0 +1,52 @@
+/*---------------------------------------------------------------------\
+|                          ____ _   __ __ ___                          |
+|                         |__  / \ / / . \ . \                         |
+|                           / / \ V /|  _/  _/                         |
+|                          / /__ | | | | | |                           |
+|                         /_____||_| |_| |_|                           |
+|                                                                      |
+\---------------------------------------------------------------------*/
+/** \file zypp/media/MediaCallbacks.cc
+ *
+*/
+
+#include <iostream>
+
+#include <y2pm/MediaCallbacks.h>
+
+using namespace std;
+
+///////////////////////////////////////////////////////////////////
+namespace MediaCallbacks {
+///////////////////////////////////////////////////////////////////
+
+  ///////////////////////////////////////////////////////////////////
+  // Reporting progress of download
+  ///////////////////////////////////////////////////////////////////
+  DownloadProgressReport downloadProgressReport;
+
+  void DownloadProgressCallback::start( const Url & url_r, const Pathname & localpath_r ) {
+  }
+  bool DownloadProgressCallback::progress( const ProgressData & prg ) {
+    return true; // continue download
+  }
+  void DownloadProgressCallback::stop( PMError error ) {
+  }
+
+#if 0
+  ///////////////////////////////////////////////////////////////////
+  // Reporting @
+  ///////////////////////////////////////////////////////////////////
+  @Report @Report;
+
+  void @Callback::start() {
+  }
+  void @Callback::progress( const ProgressData & prg ) {
+  }
+  void @Callback::stop( PMError error ) {
+  }
+#endif
+
+///////////////////////////////////////////////////////////////////
+} // namespace MediaCallbacks
+///////////////////////////////////////////////////////////////////
diff --git a/zypp/media/MediaCallbacks.h b/zypp/media/MediaCallbacks.h
new file mode 100644 (file)
index 0000000..a5a7690
--- /dev/null
@@ -0,0 +1,43 @@
+/*---------------------------------------------------------------------\
+|                          ____ _   __ __ ___                          |
+|                         |__  / \ / / . \ . \                         |
+|                           / / \ V /|  _/  _/                         |
+|                          / /__ | | | | | |                           |
+|                         /_____||_| |_| |_|                           |
+|                                                                      |
+\---------------------------------------------------------------------*/
+/** \file zypp/media/MediaCallbacks.h
+ *
+*/
+
+#ifndef ZYPP_MEDIA_MEDIACALLBACKS_H
+#define ZYPP_MEDIA_MEDIACALLBACKS_H
+
+#include <iosfwd>
+
+#include "zypp/Url.h"
+#include "zypp/Callback.h"
+
+namespace zypp {
+  namespace media {
+
+    ///////////////////////////////////////////////////////////////////
+    // Reporting progress of download
+    ///////////////////////////////////////////////////////////////////
+    class DownloadProgressReport : public HACK::Callback {
+      virtual ~DownloadProgressReport()
+      {}
+      virtual void start( const Url & url_r, const Pathname & localpath_r )
+      { }
+      virtual bool progress( /*const ProgressData & prg*/ )
+      { return false; }
+      virtual void stop( Exception & excpt_r )
+      { }
+    };
+  
+    extern DownloadProgressReport downloadProgressReport;
+
+  } // namespace media
+} // namespace zypp
+
+#endif // ZYPP_MEDIA_MEDIACALLBACKS_H
index ad1ec6f..cfe2472 100644 (file)
@@ -18,7 +18,7 @@
 //#include <y2util/SysConfig.h>
 
 #include "zypp/media/MediaCurl.h"
-//#include "zypp/media/MediaCallbacks.h"
+#include "zypp/media/MediaCallbacks.h"
 
 #include <sys/types.h>
 #include <sys/mount.h>
@@ -29,7 +29,6 @@
 
 using namespace std;
 using namespace zypp::base;
-//using namespace MediaCallbacks;
 
 namespace zypp {
   namespace media {
@@ -102,11 +101,8 @@ void MediaCurl::attachTo (bool next)
   if ( next )
     ZYPP_THROW( MediaException("Error::E_not_supported_by_media") );
 
-#warning FIXME implement check for URL validity
-#if 0
   if ( !_url.isValid() )
-    ZYPP_THROW( MediaException("Error::E_bad_url") );
-#endif
+    ZYPP_THROW(MediaBadUrlException(_url));
 
   _curl = curl_easy_init();
   if ( !_curl ) {
@@ -368,11 +364,8 @@ void MediaCurl::getFileCopy( const Pathname & filename , const Pathname & target
 {
     DBG << filename.asString() << endl;
 
-#warning FIXME implement check for URL validity
-#if 0
     if(!_url.isValid())
-      ZYPP_THROW( MediaException(string("Error::E_bad_url") + " " + _url.toString()) );
-#endif
+      ZYPP_THROW(MediaBadUrlException(_url));
 
     if(_url.getHost().empty())
       ZYPP_THROW( MediaException("Error::E_no_host_specified") );
@@ -553,19 +546,9 @@ void MediaCurl::getFileCopy( const Pathname & filename , const Pathname & target
 void MediaCurl::getDir( const Pathname & dirname, bool recurse_r ) const
 {
   filesystem::DirContent content;
-  try {
-    getDirInfo( content, dirname, /*dots*/false );
-  }
-  catch (const MediaException & excpt_r)
-  {
-#warning FIXME rethrow
-#if 0
-    ZYPP_RETHROW(excpt_r);
-#endif
-  }
+  getDirInfo( content, dirname, /*dots*/false );
 
   for ( filesystem::DirContent::const_iterator it = content.begin(); it != content.end(); ++it ) {
-    try {
       Pathname filename = dirname + it->name;
       int res = 0;
 
@@ -588,14 +571,6 @@ void MediaCurl::getDir( const Pathname & dirname, bool recurse_r ) const
        // don't provide devices, sockets, etc.
        break;
       }
-    }
-    catch (const MediaException & excpt_r)
-    {
-#warning FIXME rethrow
-#if 0
-      ZYPP_RETHROW(excpt_r);
-#endif
-    }
   }
 }
 
@@ -610,13 +585,7 @@ void MediaCurl::getDir( const Pathname & dirname, bool recurse_r ) const
 void MediaCurl::getDirInfo( std::list<std::string> & retlist,
                               const Pathname & dirname, bool dots ) const
 {
-  try {
-    getDirectoryYast( retlist, dirname, dots );
-  }
-  catch (const MediaException & excpt_r)
-  {
-    ZYPP_THROW( MediaException("Error::E_not_supported_by_media") );
-  }
+  getDirectoryYast( retlist, dirname, dots );
 }
 
 ///////////////////////////////////////////////////////////////////
@@ -630,13 +599,7 @@ void MediaCurl::getDirInfo( std::list<std::string> & retlist,
 void MediaCurl::getDirInfo( filesystem::DirContent & retlist,
                             const Pathname & dirname, bool dots ) const
 {
-  try {
-    getDirectoryYast( retlist, dirname, dots );
-  }
-  catch (const MediaException & excpt_r)
-  {
-    ZYPP_THROW( MediaException("Error::E_not_supported_by_media") );
-  }
+  getDirectoryYast( retlist, dirname, dots );
 }
 
 ///////////////////////////////////////////////////////////////////
diff --git a/zypp/media/MediaDIR.cc b/zypp/media/MediaDIR.cc
new file mode 100644 (file)
index 0000000..447c2d8
--- /dev/null
@@ -0,0 +1,131 @@
+/*---------------------------------------------------------------------\
+|                          ____ _   __ __ ___                          |
+|                         |__  / \ / / . \ . \                         |
+|                           / / \ V /|  _/  _/                         |
+|                          / /__ | | | | | |                           |
+|                         /_____||_| |_| |_|                           |
+|                                                                      |
+\---------------------------------------------------------------------*/
+/** \file zypp/media/MediaDIR.cc
+ *
+*/
+
+#include <iostream>
+
+#include "zypp/base/Logger.h"
+#include "zypp/media/MediaDIR.h"
+
+#include <sys/mount.h>
+#include <errno.h>
+
+using namespace std;
+
+namespace zypp {
+  namespace media {
+
+    ///////////////////////////////////////////////////////////////////
+    //
+    // CLASS NAME : MediaDIR
+    //
+    ///////////////////////////////////////////////////////////////////
+    
+    ///////////////////////////////////////////////////////////////////
+    //
+    //
+    // METHOD NAME : MediaDIR::MediaDIR
+    // METHOD TYPE : Constructor
+    //
+    // DESCRIPTION : Attach point is always '/', as files are not copied.
+    //                    Thus attach_point_hint_r is ignored.
+    //
+    MediaDIR::MediaDIR( const Url &      url_r,
+                       const Pathname & /*attach_point_hint_r*/ )
+        : MediaHandler( url_r, url_r.getPathName(),
+                   "/", // urlpath at attachpoint
+                   false ) // does_download
+    {
+    }
+
+    ///////////////////////////////////////////////////////////////////
+    //
+    //
+    // METHOD NAME : MediaDIR::attachTo
+    // METHOD TYPE : PMError
+    //
+    // DESCRIPTION : Asserted that not already attached, and attachPoint is a directory.
+    //
+    void MediaDIR::attachTo(bool next)
+    {
+      if(next)
+       ZYPP_THROW(MediaNotSupportedException(url()));
+    }
+
+
+    ///////////////////////////////////////////////////////////////////
+    //
+    //
+    // METHOD NAME : MediaDIR::releaseFrom
+    // METHOD TYPE : PMError
+    //
+    // DESCRIPTION : Asserted that media is attached.
+    //
+    void MediaDIR::releaseFrom( bool eject )
+    {
+      return;
+    }
+
+    ///////////////////////////////////////////////////////////////////
+    //
+    //
+    // METHOD NAME : MediaDIR::getFile
+    // METHOD TYPE : PMError
+    //
+    // DESCRIPTION : Asserted that media is attached.
+    //
+    void MediaDIR::getFile( const Pathname & filename ) const
+    {
+      MediaHandler::getFile( filename );
+    }
+
+    ///////////////////////////////////////////////////////////////////
+    //
+    // METHOD NAME : MediaDIR::getDir
+    // METHOD TYPE : PMError
+    //
+    // DESCRIPTION : Asserted that media is attached.
+    //
+    void MediaDIR::getDir( const Pathname & dirname, bool recurse_r ) const
+    {
+      MediaHandler::getDir( dirname, recurse_r );
+    }
+
+    ///////////////////////////////////////////////////////////////////
+    //
+    //
+    // METHOD NAME : MediaDIR::getDirInfo
+    // METHOD TYPE : PMError
+    //
+    // DESCRIPTION : Asserted that media is attached and retlist is empty.
+    //
+    void MediaDIR::getDirInfo( std::list<std::string> & retlist,
+                              const Pathname & dirname, bool dots ) const
+    {
+      MediaHandler::getDirInfo( retlist, dirname, dots );
+    }
+
+    ///////////////////////////////////////////////////////////////////
+    //
+    //
+    // METHOD NAME : MediaDIR::getDirInfo
+    // METHOD TYPE : PMError
+    //
+    // DESCRIPTION : Asserted that media is attached and retlist is empty.
+    //
+    void MediaDIR::getDirInfo( filesystem::DirContent & retlist,
+                              const Pathname & dirname, bool dots ) const
+    {
+      MediaHandler::getDirInfo( retlist, dirname, dots );
+    }
+
+  } // namespace media
+} // namespace zypp
diff --git a/zypp/media/MediaDIR.h b/zypp/media/MediaDIR.h
new file mode 100644 (file)
index 0000000..0c6056d
--- /dev/null
@@ -0,0 +1,47 @@
+/*---------------------------------------------------------------------\
+|                          ____ _   __ __ ___                          |
+|                         |__  / \ / / . \ . \                         |
+|                           / / \ V /|  _/  _/                         |
+|                          / /__ | | | | | |                           |
+|                         /_____||_| |_| |_|                           |
+|                                                                      |
+\---------------------------------------------------------------------*/
+/** \file zypp/media/MediaDIR.h
+ *
+*/
+#ifndef ZYPP_MEDIA_MEDIADIR_H
+#define ZYPP_MEDIA_MEDIADIR_H
+
+#include "zypp/media/MediaHandler.h"
+
+namespace zypp {
+  namespace media {
+
+    ///////////////////////////////////////////////////////////////////
+    //
+    // CLASS NAME : MediaDIR
+    
+    /**
+     * @short Implementation class for DIR MediaHandler
+     * @see MediaHandler
+     **/
+    class MediaDIR : public MediaHandler {
+    
+      protected:
+    
+       MEDIA_HANDLER_API;
+    
+      public:
+    
+        MediaDIR( const Url &      url_r,
+                 const Pathname & attach_point_hint_r );
+    
+        virtual ~MediaDIR() { release(); }
+    };
+    
+    ///////////////////////////////////////////////////////////////////
+
+  } // namespace media
+} // namespace zypp
+
+#endif // ZYPP_MEDIA_MEDIADIR_H
diff --git a/zypp/media/MediaDISK.cc b/zypp/media/MediaDISK.cc
new file mode 100644 (file)
index 0000000..7921a7f
--- /dev/null
@@ -0,0 +1,160 @@
+/*---------------------------------------------------------------------\
+|                          ____ _   __ __ ___                          |
+|                         |__  / \ / / . \ . \                         |
+|                           / / \ V /|  _/  _/                         |
+|                          / /__ | | | | | |                           |
+|                         /_____||_| |_| |_|                           |
+|                                                                      |
+\---------------------------------------------------------------------*/
+/** \file zypp/media/MediaDISK.h
+ *
+*/
+
+#include <iostream>
+
+#include "zypp/base/Logger.h"
+#include "zypp/media/Mount.h"
+#include "zypp/media/MediaDISK.h"
+
+#include <sys/types.h>
+#include <sys/mount.h>
+#include <errno.h>
+#include <dirent.h>
+
+using namespace std;
+
+namespace zypp {
+  namespace media {
+
+    ///////////////////////////////////////////////////////////////////
+    //
+    // CLASS NAME : MediaDISK
+    //
+    ///////////////////////////////////////////////////////////////////
+
+    ///////////////////////////////////////////////////////////////////
+    //
+    //
+    // METHOD NAME : MediaDISK::MediaDISK
+    // METHOD TYPE : Constructor
+    //
+    // DESCRIPTION :
+    //
+    MediaDISK::MediaDISK( const Url &      url_r,
+                         const Pathname & attach_point_hint_r )
+        : MediaHandler( url_r, attach_point_hint_r,
+                   url_r.getPathName(), // urlpath below attachpoint
+                   false ) // does_download
+    {
+      _device = _url.getQueryParam("device");
+      _filesystem = _url.getQueryParam("filesystem");
+      if(_filesystem.empty())
+       _filesystem="auto";
+    }
+
+    ///////////////////////////////////////////////////////////////////
+    //
+    //
+    // METHOD NAME : MediaDISK::attachTo
+    // METHOD TYPE : PMError
+    //
+    // DESCRIPTION : Asserted that not already attached, and attachPoint is a directory.
+    //
+    void MediaDISK::attachTo(bool next)
+    {
+      if(next)
+       ZYPP_THROW(MediaNotSupportedException(url()));
+      // FIXME
+      // do mount --bind <partition>/<dir> to <to>
+      //   mount /dev/<partition> /tmp_mount
+      //   mount /tmp_mount/<dir> <to> --bind -o ro
+      // FIXME: try all filesystems
+    
+      if(_device.empty())
+       ZYPP_THROW(MediaBadUrlEmptyDestinationException(url()));
+    
+      if(_filesystem.empty())
+       ZYPP_THROW(MediaBadUrlEmptyFilesystemException(url()));
+    
+      Mount mount;
+      const char *mountpoint = attachPoint().asString().c_str();
+      string options = _url.getQueryParam("mountoptions");
+      if(options.empty())
+      {
+       options="ro";
+      }
+    
+      mount.mount(_device,mountpoint,_filesystem,options);
+    }
+
+
+    ///////////////////////////////////////////////////////////////////
+    //
+    //
+    // METHOD NAME : MediaDISK::releaseFrom
+    // METHOD TYPE : PMError
+    //
+    // DESCRIPTION : Asserted that media is attached.
+    //
+    void MediaDISK::releaseFrom( bool eject )
+    {
+      Mount mount;
+    
+      mount.umount(attachPoint().asString());
+    }
+
+
+    ///////////////////////////////////////////////////////////////////
+    //
+    // METHOD NAME : MediaDISK::getFile
+    // METHOD TYPE : PMError
+    //
+    // DESCRIPTION : Asserted that media is attached.
+    //
+    void MediaDISK::getFile (const Pathname & filename) const
+    {
+      MediaHandler::getFile( filename );
+    }
+    
+    ///////////////////////////////////////////////////////////////////
+    //
+    // METHOD NAME : MediaDISK::getDir
+    // METHOD TYPE : PMError
+    //
+    // DESCRIPTION : Asserted that media is attached.
+    //
+    void MediaDISK::getDir( const Pathname & dirname, bool recurse_r ) const
+    {
+      MediaHandler::getDir( dirname, recurse_r );
+    }
+    
+    ///////////////////////////////////////////////////////////////////
+    //
+    //
+    // METHOD NAME : MediaDISK::getDirInfo
+    // METHOD TYPE : PMError
+    //
+    // DESCRIPTION : Asserted that media is attached and retlist is empty.
+    //
+    void MediaDISK::getDirInfo( std::list<std::string> & retlist,
+                               const Pathname & dirname, bool dots ) const
+    {
+      MediaHandler::getDirInfo( retlist, dirname, dots );
+    }
+    
+    ///////////////////////////////////////////////////////////////////
+    //
+    //
+    // METHOD NAME : MediaDISK::getDirInfo
+    // METHOD TYPE : PMError
+    //
+    // DESCRIPTION : Asserted that media is attached and retlist is empty.
+    //
+    void MediaDISK::getDirInfo( filesystem::DirContent & retlist,
+                               const Pathname & dirname, bool dots ) const
+    {
+      MediaHandler::getDirInfo( retlist, dirname, dots );
+    }
+
+  } // namespace media
+} // namespace zypp
diff --git a/zypp/media/MediaDISK.h b/zypp/media/MediaDISK.h
new file mode 100644 (file)
index 0000000..ea6d4b0
--- /dev/null
@@ -0,0 +1,53 @@
+/*---------------------------------------------------------------------\
+|                          ____ _   __ __ ___                          |
+|                         |__  / \ / / . \ . \                         |
+|                           / / \ V /|  _/  _/                         |
+|                          / /__ | | | | | |                           |
+|                         /_____||_| |_| |_|                           |
+|                                                                      |
+\---------------------------------------------------------------------*/
+/** \file zypp/media/MediaDISK.h
+ *
+*/
+#ifndef ZYPP_MEDIA_MEDIADISK_H
+#define ZYPP_MEDIA_MEDIADISK_H
+
+#include "zypp/media/MediaHandler.h"
+
+namespace zypp {
+  namespace media {
+
+    ///////////////////////////////////////////////////////////////////
+    //
+    // CLASS NAME : MediaDISK
+    /**
+     * @short Implementation class for DISK MediaHandler
+     * @see MediaHandler
+     **/
+    class MediaDISK : public MediaHandler {
+    
+      private:
+    
+        unsigned long _mountflags;
+    
+        std::string _device;
+        std::string _filesystem;
+    
+      protected:
+    
+        MEDIA_HANDLER_API;
+    
+      public:
+    
+        MediaDISK( const Url &      url_r,
+                  const Pathname & attach_point_hint_r );
+    
+        virtual ~MediaDISK() { release(); }
+    };
+
+///////////////////////////////////////////////////////////////////
+
+  } // namespace media
+} // namespace zypp
+
+#endif // ZYPP_MEDIA_MEDIADISK_H
index 9be0079..a7ac548 100644 (file)
@@ -86,6 +86,31 @@ namespace zypp
       return str << "Malformed URL: " << _url << endl;
     }
 
+    std::ostream & MediaBadUrlEmptyHostException::dumpOn( std::ostream & str) const
+    {
+      return str << "Empty host name in URL: " << _url << endl;
+    }
+
+    std::ostream & MediaBadUrlEmptyFilesystemException::dumpOn( std::ostream & str) const
+    {
+      return str << "Empty filesystem in URL: " << _url << endl;
+    }
+
+    std::ostream & MediaBadUrlEmptyDestinationException::dumpOn( std::ostream & str) const
+    {
+      return str << "Empty destination in URL: " << _url << endl;
+    }
+
+    std::ostream & MediaUnsupportedUrlSchemeException::dumpOn( std::ostream & str) const
+    {
+      return str << "Unsupported URL scheme in URL: " << _url << endl;
+    }
+
+    std::ostream & MediaNotSupportedException::dumpOn( std::ostream & str) const
+    {
+      return str << "Operation not supported by media: " << _url << endl;
+    }
+
 
   /////////////////////////////////////////////////////////////////
   } // namespace media
index 798c1bf..8c285e8 100644 (file)
@@ -227,11 +227,65 @@ namespace zypp
       virtual ~MediaBadUrlException() throw() {};
     protected:
       virtual std::ostream & dumpOn( std::ostream & str ) const;
-    private:
       std::string _url;
     };
 
+    class MediaBadUrlEmptyHostException : public MediaBadUrlException
+    {
+    public:
+      MediaBadUrlEmptyHostException(const Url & url_r)
+      : MediaBadUrlException(url_r)
+      {}
+      virtual ~MediaBadUrlEmptyHostException() throw() {};
+    protected:
+      virtual std::ostream & dumpOn( std::ostream & str ) const;
+    };
 
+    class MediaBadUrlEmptyFilesystemException : public MediaBadUrlException
+    {
+    public:
+      MediaBadUrlEmptyFilesystemException(const Url & url_r)
+      : MediaBadUrlException(url_r)
+      {}
+      virtual ~MediaBadUrlEmptyFilesystemException() throw() {};
+    protected:
+      virtual std::ostream & dumpOn( std::ostream & str ) const;
+    };
+
+    class MediaBadUrlEmptyDestinationException : public MediaBadUrlException
+    {
+    public:
+      MediaBadUrlEmptyDestinationException(const Url & url_r)
+      : MediaBadUrlException(url_r)
+      {}
+      virtual ~MediaBadUrlEmptyDestinationException() throw() {};
+    protected:
+      virtual std::ostream & dumpOn( std::ostream & str ) const;
+    };
+
+    class MediaUnsupportedUrlSchemeException : public MediaBadUrlException
+    {
+    public:
+      MediaUnsupportedUrlSchemeException(const Url & url_r)
+      : MediaBadUrlException(url_r)
+      {}
+      virtual ~MediaUnsupportedUrlSchemeException() throw() {};
+    protected:
+      virtual std::ostream & dumpOn( std::ostream & str ) const;
+    };
+
+    class MediaNotSupportedException : public MediaException
+    {
+    public:
+      MediaNotSupportedException(const Url & url_r)
+      : MediaException()
+      , _url(url_r.toString())
+      {}
+      virtual ~MediaNotSupportedException() throw() {};
+    protected:
+      virtual std::ostream & dumpOn( std::ostream & str ) const;
+      std::string _url;
+    };
 
   /////////////////////////////////////////////////////////////////
   } // namespace media
diff --git a/zypp/media/MediaNFS.cc b/zypp/media/MediaNFS.cc
new file mode 100644 (file)
index 0000000..8fd3963
--- /dev/null
@@ -0,0 +1,170 @@
+/*---------------------------------------------------------------------\
+|                          ____ _   __ __ ___                          |
+|                         |__  / \ / / . \ . \                         |
+|                           / / \ V /|  _/  _/                         |
+|                          / /__ | | | | | |                           |
+|                         /_____||_| |_| |_|                           |
+|                                                                      |
+\---------------------------------------------------------------------*/
+/** \file zypp/media/MediaNFS.cc
+ *
+*/
+
+#include <iostream>
+
+#include "zypp/base/Logger.h"
+#include "zypp/base/String.h"
+#include "zypp/media/MediaNFS.h"
+#include "zypp/media/Mount.h"
+
+#include <dirent.h>
+
+using namespace std;
+
+namespace zypp {
+  namespace media {
+
+    ///////////////////////////////////////////////////////////////////
+    //
+    // CLASS NAME : MediaNFS
+    //
+    ///////////////////////////////////////////////////////////////////
+    
+    ///////////////////////////////////////////////////////////////////
+    //
+    //
+    // METHOD NAME : MediaNFS::MediaNFS
+    // METHOD TYPE : Constructor
+    //
+    // DESCRIPTION :
+    //
+    MediaNFS::MediaNFS( const Url &      url_r,
+                       const Pathname & attach_point_hint_r )
+      : MediaHandler( url_r, attach_point_hint_r,
+                     "/", // urlpath at attachpoint
+                     false ) // does_download
+    {
+    }
+
+    ///////////////////////////////////////////////////////////////////
+    //
+    //
+    // METHOD NAME : MediaNFS::attachTo
+    // METHOD TYPE : PMError
+    //
+    // DESCRIPTION : Asserted that not already attached, and attachPoint is a directory.
+    //
+    void MediaNFS::attachTo(bool next)
+    {
+      if(_url.getHost().empty())
+       ZYPP_THROW(MediaBadUrlEmptyHostException(_url));
+      if(next)
+       ZYPP_THROW(MediaNotSupportedException(_url));
+    
+      const char* const filesystem = "nfs";
+      const char *mountpoint = attachPoint().asString().c_str();
+      Mount mount;
+    
+      string path = _url.getHost();
+      path += ':';
+      path += _url.getPathName();
+    
+      string options = _url.getQueryParam("mountoptions");
+      if(options.empty())
+      {
+       options="ro";
+      }
+    
+      // Add option "nolock", unless option "lock" or "unlock" is already set.
+      // This should prevent the mount command hanging when the portmapper isn't
+      // running.
+      vector<string> optionList;
+#warning FIXME once the function is in str namespace
+#if 0
+      str::split( options, optionList, "," );
+#endif
+      vector<string>::const_iterator it;
+      for( it = optionList.begin(); it != optionList.end(); ++it ) {
+       if ( *it == "lock" || *it == "nolock" ) break;
+      }
+      if ( it == optionList.end() ) {
+       optionList.push_back( "nolock" );
+#warning FIXME once the function is in str namespace
+#if 0
+       options = str::join( optionList, "," );
+#endif
+      }
+    
+      mount.mount(path,mountpoint,filesystem,options);
+    }
+
+
+    ///////////////////////////////////////////////////////////////////
+    //
+    //
+    // METHOD NAME : MediaNFS::releaseFrom
+    // METHOD TYPE : PMError
+    //
+    // DESCRIPTION : Asserted that media is attached.
+    //
+    void MediaNFS::releaseFrom( bool eject )
+    {
+      Mount mount;
+      mount.umount(attachPoint().asString());
+    }
+    
+    
+    ///////////////////////////////////////////////////////////////////
+    //
+    // METHOD NAME : MediaNFS::getFile
+    // METHOD TYPE : PMError
+    //
+    // DESCRIPTION : Asserted that media is attached.
+    //
+    void MediaNFS::getFile (const Pathname & filename) const
+    {
+      MediaHandler::getFile( filename );;
+    }
+    
+    ///////////////////////////////////////////////////////////////////
+    //
+    // METHOD NAME : MediaNFS::getDir
+    // METHOD TYPE : PMError
+    //
+    // DESCRIPTION : Asserted that media is attached.
+    //
+    void MediaNFS::getDir( const Pathname & dirname, bool recurse_r ) const
+    {
+      MediaHandler::getDir( dirname, recurse_r );
+    }
+    
+    ///////////////////////////////////////////////////////////////////
+    //
+    //
+    // METHOD NAME : MediaNFS::getDirInfo
+    // METHOD TYPE : PMError
+    //
+    // DESCRIPTION : Asserted that media is attached and retlist is empty.
+    //
+    void MediaNFS::getDirInfo( std::list<std::string> & retlist,
+                             const Pathname & dirname, bool dots ) const
+    {
+      MediaHandler::getDirInfo( retlist, dirname, dots );
+    }
+    
+    ///////////////////////////////////////////////////////////////////
+    //
+    //
+    // METHOD NAME : MediaNFS::getDirInfo
+    // METHOD TYPE : PMError
+    //
+    // DESCRIPTION : Asserted that media is attached and retlist is empty.
+    //
+    void MediaNFS::getDirInfo( filesystem::DirContent & retlist,
+                          const Pathname & dirname, bool dots ) const
+    {
+      MediaHandler::getDirInfo( retlist, dirname, dots );
+    }
+
+  } // namespace media
+} // namespace zypp
diff --git a/zypp/media/MediaNFS.h b/zypp/media/MediaNFS.h
new file mode 100644 (file)
index 0000000..4962b7a
--- /dev/null
@@ -0,0 +1,45 @@
+/*---------------------------------------------------------------------\
+|                          ____ _   __ __ ___                          |
+|                         |__  / \ / / . \ . \                         |
+|                           / / \ V /|  _/  _/                         |
+|                          / /__ | | | | | |                           |
+|                         /_____||_| |_| |_|                           |
+|                                                                      |
+\---------------------------------------------------------------------*/
+/** \file zypp/media/MediaNFS.h
+ *
+*/
+#ifndef ZYPP_MEDIA_MEDIANFS_H
+#define ZYPP_MEDIA_MEDIANFS_H
+
+#include "zypp/media/MediaHandler.h"
+
+namespace zypp {
+  namespace media {
+
+    ///////////////////////////////////////////////////////////////////
+    //
+    // CLASS NAME : MediaNFS
+    /**
+     * @short Implementation class for NFS MediaHandler
+     * @see MediaHandler
+     **/
+    class MediaNFS : public MediaHandler {
+    
+      protected:
+    
+        MEDIA_HANDLER_API;
+    
+      public:
+    
+        MediaNFS( const Url&       url_r,
+                 const Pathname & attach_point_hint_r );
+    
+        virtual ~MediaNFS() { release(); }
+    };
+    
+    ///////////////////////////////////////////////////////////////////
+  } // namespace media
+} // namespace zypp
+
+#endif // ZYPP_MEDIA_MEDIANFS_H
diff --git a/zypp/media/MediaSMB.cc b/zypp/media/MediaSMB.cc
new file mode 100644 (file)
index 0000000..ea8e83c
--- /dev/null
@@ -0,0 +1,273 @@
+/*---------------------------------------------------------------------\
+|                          ____ _   __ __ ___                          |
+|                         |__  / \ / / . \ . \                         |
+|                           / / \ V /|  _/  _/                         |
+|                          / /__ | | | | | |                           |
+|                         /_____||_| |_| |_|                           |
+|                                                                      |
+\---------------------------------------------------------------------*/
+/** \file zypp/media/MediaSMB.cc
+ *
+*/
+
+#include <iostream>
+#include <fstream>
+
+#include "zypp/base/Logger.h"
+#include "zypp/TmpPath.h"
+#include "zypp/KVMap.h"
+#include "zypp/media/Mount.h"
+#include "zypp/media/MediaSMB.h"
+
+#include <sys/types.h>
+#include <sys/mount.h>
+#include <errno.h>
+#include <dirent.h>
+
+using namespace std;
+
+namespace zypp {
+  namespace media {
+
+    /******************************************************************
+    **
+    **
+    ** FUNCTION NAME : getShare
+    ** FUNCTION TYPE : inline Pathname
+    **
+    ** Get the 1st path component (CIFS share name).
+    */
+    inline string getShare( Pathname spath_r )
+    {
+      if ( spath_r.empty() )
+        return string();
+    
+      string share( spath_r.absolutename().asString() );
+      string::size_type sep = share.find( "/", 1 );
+      if ( sep == string::npos )
+        share = share.erase( 0, 1 ); // nothing but the share name in spath_r
+      else
+        share = share.substr( 1, sep-1 );
+    
+      // deescape %2f in sharename
+      while ( (sep = share.find( "%2f" )) != string::npos ) {
+        share.replace( sep, 3, "/" );
+      }
+    
+      return share;
+    }
+
+    /******************************************************************
+    **
+    **
+    ** FUNCTION NAME : stripShare
+    ** FUNCTION TYPE : inline Pathname
+    **
+    ** Strip off the 1st path component (CIFS share name).
+    */
+    inline Pathname stripShare( Pathname spath_r )
+    {
+      if ( spath_r.empty() )
+        return Pathname();
+    
+      string striped( spath_r.absolutename().asString() );
+      string::size_type sep = striped.find( "/", 1 );
+      if ( sep == string::npos )
+        return "/"; // nothing but the share name in spath_r
+    
+      return striped.substr( sep );
+    }
+
+    ///////////////////////////////////////////////////////////////////
+    //
+    // CLASS NAME : MediaSMB
+    //
+    ///////////////////////////////////////////////////////////////////
+
+    ///////////////////////////////////////////////////////////////////
+    //
+    //
+    // METHOD NAME : MediaSMB::MediaSMB
+    // METHOD TYPE : Constructor
+    //
+    // DESCRIPTION :
+    //
+    MediaSMB::MediaSMB( const Url &      url_r,
+                       const Pathname & attach_point_hint_r )
+        : MediaHandler( url_r, attach_point_hint_r,
+                   stripShare( url_r.getPathName() ), // urlpath WITHOUT share name at attachpoint
+                   false )       // does_download
+        , _vfstype( "smbfs" )
+    {
+    }
+
+    ///////////////////////////////////////////////////////////////////
+    //
+    //
+    // METHOD NAME : MediaSMB::attachTo
+    // METHOD TYPE : PMError
+    //
+    // DESCRIPTION : Asserted that not already attached, and attachPoint
+    //      is a directory.
+    //
+    //      NOTE: The implementation currently serves both, "smbfs"
+    //      and "cifs". The only difference is the vfstype passed to
+    //      the mount command.
+    //
+    void MediaSMB::attachTo(bool next)
+    {
+      if(_url.getHost().empty())
+       ZYPP_THROW(MediaBadUrlEmptyHostException(_url));
+      if(next)
+       ZYPP_THROW(MediaNotSupportedException(_url));
+    
+      const char *mountpoint = attachPoint().asString().c_str();
+      Mount mount;
+    
+      string path = "//";
+      path += _url.getHost() + "/" + getShare( _url.getPathName() );
+   
+      Mount::Options options( _url.getQueryParam("mountoptions") );
+      string username = _url.getUsername();
+      string password = _url.getPassword();
+    
+      options["guest"]; // prevent smbmount from asking for password
+    
+      if ( ! options.has( "rw" ) ) {
+        options["ro"];
+      }
+    
+      Mount::Options::iterator toEnv;
+    
+      // extract 'username', do not overwrite any _url.username
+      toEnv = options.find("username");
+      if ( toEnv != options.end() ) {
+        if ( username.empty() )
+       username = toEnv->second;
+        options.erase( toEnv );
+      }
+      toEnv = options.find("user"); // actually cifs specific
+      if ( toEnv != options.end() ) {
+        if ( username.empty() )
+       username = toEnv->second;
+        options.erase( toEnv );
+      }
+    
+      // extract 'password', do not overwrite any _url.password
+      toEnv = options.find("password");
+      if ( toEnv != options.end() ) {
+        if ( password.empty() )
+       password = toEnv->second;
+        options.erase( toEnv );
+      }
+      toEnv = options.find("pass"); // actually cifs specific
+      if ( toEnv != options.end() ) {
+        if ( password.empty() )
+       password = toEnv->second;
+        options.erase( toEnv );
+      }
+    
+      // look for a workgroup
+      string workgroup = _url.getQueryParam("workgroup");
+      if ( workgroup.size() ) {
+        options["workgroup"] = workgroup;
+      }
+    
+      // pass 'username' and 'password' via environment
+      Mount::Environment environment;
+      if ( username.size() )
+        environment["USER"] = username;
+      if ( password.size() )
+        environment["PASSWD"] = password;
+    
+      //////////////////////////////////////////////////////
+      // In case we need a tmpfile, credentials will remove
+      // it in it's destructor after the mout call below.
+      filesystem::TmpPath credentials;
+      if ( username.size() || password.size() )
+        {
+          filesystem::TmpFile tmp;
+          ofstream outs( tmp.path().asString().c_str() );
+          outs << "username=" <<  username << endl;
+          outs << "password=" <<  password << endl;
+          outs.close();
+    
+          credentials = tmp;
+          options["credentials"] = credentials.path().asString();
+        }
+      //
+      //////////////////////////////////////////////////////
+    
+      mount.mount( path, mountpoint, _vfstype,
+                  options.asString(), environment );
+    }
+
+    ///////////////////////////////////////////////////////////////////
+    //
+    //
+    // METHOD NAME : MediaSMB::releaseFrom
+    // METHOD TYPE : PMError
+    //
+    // DESCRIPTION : Asserted that media is attached.
+    //
+    void MediaSMB::releaseFrom( bool eject )
+    {
+      Mount mount;
+      mount.umount(attachPoint().asString());
+    }
+
+
+    ///////////////////////////////////////////////////////////////////
+    //
+    // METHOD NAME : MediaSMB::getFile
+    // METHOD TYPE : PMError
+    //
+    // DESCRIPTION : Asserted that media is attached.
+    //
+    void MediaSMB::getFile (const Pathname & filename) const
+    {
+      MediaHandler::getFile( filename );
+    }
+
+    ///////////////////////////////////////////////////////////////////
+    //
+    // METHOD NAME : MediaSMB::getDir
+    // METHOD TYPE : PMError
+    //
+    // DESCRIPTION : Asserted that media is attached.
+    //
+    void MediaSMB::getDir( const Pathname & dirname, bool recurse_r ) const
+    {
+      MediaHandler::getDir( dirname, recurse_r );
+    }
+
+    ///////////////////////////////////////////////////////////////////
+    //
+    //
+    // METHOD NAME : MediaSMB::getDirInfo
+    // METHOD TYPE : PMError
+    //
+    // DESCRIPTION : Asserted that media is attached and retlist is empty.
+    //
+    void MediaSMB::getDirInfo( std::list<std::string> & retlist,
+                              const Pathname & dirname, bool dots ) const
+    {
+      MediaHandler::getDirInfo( retlist, dirname, dots );
+    }
+
+    ///////////////////////////////////////////////////////////////////
+    //
+    //
+    // METHOD NAME : MediaSMB::getDirInfo
+    // METHOD TYPE : PMError
+    //
+    // DESCRIPTION : Asserted that media is attached and retlist is empty.
+    //
+    void MediaSMB::getDirInfo( filesystem::DirContent & retlist,
+                              const Pathname & dirname, bool dots ) const
+    {
+      MediaHandler::getDirInfo( retlist, dirname, dots );
+    }
+
+  } // namespace media
+} // namespace zypp
diff --git a/zypp/media/MediaSMB.h b/zypp/media/MediaSMB.h
new file mode 100644 (file)
index 0000000..cb1495f
--- /dev/null
@@ -0,0 +1,63 @@
+/*---------------------------------------------------------------------\
+|                          ____ _   __ __ ___                          |
+|                         |__  / \ / / . \ . \                         |
+|                           / / \ V /|  _/  _/                         |
+|                          / /__ | | | | | |                           |
+|                         /_____||_| |_| |_|                           |
+|                                                                      |
+\---------------------------------------------------------------------*/
+/** \file zypp/media/MediaSMB.h
+ *
+*/
+#ifndef ZYPP_MEDIA_MEDIASMB_H
+#define ZYPP_MEDIA_MEDIASMB_H
+
+#include "zypp/media/MediaHandler.h"
+
+namespace zypp {
+  namespace media {
+
+    ///////////////////////////////////////////////////////////////////
+    //
+    // CLASS NAME : MediaSMB
+    /**
+     * @short Implementation class for SMB MediaHandler
+     *
+     * NOTE: The implementation currently serves both, "smbfs"
+     * and "cifs". The only difference is the vfstype passed to
+     * the mount command.
+     * @see MediaHandler
+     **/
+    class MediaSMB : public MediaHandler {
+    
+    private:
+    
+      /**
+       * vfstype for mount. This is either "smbfs"
+       * or "cifs" (rewritten by MediaCIFS).
+       **/
+      const char* _vfstype;
+    
+    protected:
+    
+      MEDIA_HANDLER_API;
+    
+      /**
+       * MediaCIFS rewrites the vfstype to "cifs"
+       * within it's constructor.
+       **/
+      void mountAsCIFS() { _vfstype = "cifs"; }
+    
+    public:
+    
+      MediaSMB( const Url&       url_r,
+               const Pathname & attach_point_hint_r );
+    
+      virtual ~MediaSMB() { release(); }
+    };
+
+///////////////////////////////////////////////////////////////////A
+  } // namespace media
+} // namespace zypp
+
+#endif // ZYPP_MEDIA_MEDIASMB_H
index 2d01dea..3dfd8d5 100644 (file)
@@ -1,22 +1,14 @@
 /*---------------------------------------------------------------------\
+|                          ____ _   __ __ ___                          |
+|                         |__  / \ / / . \ . \                         |
+|                           / / \ V /|  _/  _/                         |
+|                          / /__ | | | | | |                           |
+|                         /_____||_| |_| |_|                           |
 |                                                                      |
-|                      __   __    ____ _____ ____                      |
-|                      \ \ / /_ _/ ___|_   _|___ \                     |
-|                       \ V / _` \___ \ | |   __) |                    |
-|                        | | (_| |___) || |  / __/                     |
-|                        |_|\__,_|____/ |_| |_____|                    |
-|                                                                      |
-|                               core system                            |
-|                                                     (C) 2002 SuSE AG |
-\----------------------------------------------------------------------/
-
-   File:       Mount.cc
-   Purpose:    Implement interface to mount program
-   Author:     Ludwig Nussel <lnussel@suse.de>
-   Maintainer: Ludwig Nussel <lnussel@suse.de>
-
-/-*/
-
+\---------------------------------------------------------------------*/
+/** \file zypp/media/Mount.cc
+ *
+*/
 
 #include <sys/stat.h>
 #include <unistd.h>
index 4aa76b3..662965f 100644 (file)
@@ -1,22 +1,14 @@
 /*---------------------------------------------------------------------\
+|                          ____ _   __ __ ___                          |
+|                         |__  / \ / / . \ . \                         |
+|                           / / \ V /|  _/  _/                         |
+|                          / /__ | | | | | |                           |
+|                         /_____||_| |_| |_|                           |
 |                                                                      |
-|                      __   __    ____ _____ ____                      |
-|                      \ \ / /_ _/ ___|_   _|___ \                     |
-|                       \ V / _` \___ \ | |   __) |                    |
-|                        | | (_| |___) || |  / __/                     |
-|                        |_|\__,_|____/ |_| |_____|                    |
-|                                                                      |
-|                               core system                            |
-|                                                     (C) 2002 SuSE AG |
-\----------------------------------------------------------------------/
-
-   File:       Wget.h
-   Purpose:    Declare interface to mount program
-   Author:     Ludwig Nussel <lnussel@suse.de>
-   Maintainer: Ludwig Nussel <lnussel@suse.de>
-
-/-*/
-
+\---------------------------------------------------------------------*/
+/** \file zypp/media/Mount.h
+ *
+*/
 
 // -*- C++ -*-
 
@@ -27,6 +19,7 @@
 #include <string>
 
 #include "zypp/ExternalProgram.h"
+#include "zypp/KVMap.h"
 
 namespace zypp {
   namespace media {
@@ -47,10 +40,7 @@ namespace zypp {
        /**
         * Mount options. 'key' or 'key=value' pairs, separated by ','
         **/
-#warning Uncomment Options type if it is needed
-#if 0
-       typedef KVMap<_KVMap::CharSep<'=',','> > Options;
-#endif
+       typedef KVMap<kvmap::KVMapBase::CharSep<'=',','> > Options;
 
     public: