--- /dev/null
+/*---------------------------------------------------------------------\
+| |
+| __ __ ____ _____ ____ |
+| \ \ / /_ _/ ___|_ _|___ \ |
+| \ 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
Pathname.h \
PathInfo.h \
Digest.h \
- Url.h
+ Url.h \
+ TmpPath.h \
+ KVMap.h \
+ Callback.h
## ##################################################
ExternalProgram.cc\
PathInfo.cc \
Digest.cc \
- Url.cc
+ Url.cc \
+ TmpPath.cc
lib@PACKAGE@_la_LDFLAGS = @LIB_VERSION_INFO@
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
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
#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;
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.
--- /dev/null
+/*---------------------------------------------------------------------\
+| ____ _ __ __ ___ |
+| |__ / \ / / . \ . \ |
+| / / \ 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
--- /dev/null
+/*---------------------------------------------------------------------\
+| ____ _ __ __ ___ |
+| |__ / \ / / . \ . \ |
+| / / \ 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
--- /dev/null
+/*---------------------------------------------------------------------\
+| ____ _ __ __ ___ |
+| |__ / \ / / . \ . \ |
+| / / \ V /| _/ _/ |
+| / /__ | | | | | | |
+| /_____||_| |_| |_| |
+| |
+\---------------------------------------------------------------------*/
+/** \file zypp/media/MediaCIFS.cc
+ *
+*/
+
+//
+// NOTE: It's actually MediaSMB, but using "cifs"
+// as vfstype for mount.
+//
--- /dev/null
+/*---------------------------------------------------------------------\
+| ____ _ __ __ ___ |
+| |__ / \ / / . \ . \ |
+| / / \ 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
--- /dev/null
+/*---------------------------------------------------------------------\
+| ____ _ __ __ ___ |
+| |__ / \ / / . \ . \ |
+| / / \ 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
+///////////////////////////////////////////////////////////////////
--- /dev/null
+/*---------------------------------------------------------------------\
+| ____ _ __ __ ___ |
+| |__ / \ / / . \ . \ |
+| / / \ 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
//#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>
using namespace std;
using namespace zypp::base;
-//using namespace MediaCallbacks;
namespace zypp {
namespace media {
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 ) {
{
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") );
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;
// don't provide devices, sockets, etc.
break;
}
- }
- catch (const MediaException & excpt_r)
- {
-#warning FIXME rethrow
-#if 0
- ZYPP_RETHROW(excpt_r);
-#endif
- }
}
}
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 );
}
///////////////////////////////////////////////////////////////////
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 );
}
///////////////////////////////////////////////////////////////////
--- /dev/null
+/*---------------------------------------------------------------------\
+| ____ _ __ __ ___ |
+| |__ / \ / / . \ . \ |
+| / / \ 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
--- /dev/null
+/*---------------------------------------------------------------------\
+| ____ _ __ __ ___ |
+| |__ / \ / / . \ . \ |
+| / / \ 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
--- /dev/null
+/*---------------------------------------------------------------------\
+| ____ _ __ __ ___ |
+| |__ / \ / / . \ . \ |
+| / / \ 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
--- /dev/null
+/*---------------------------------------------------------------------\
+| ____ _ __ __ ___ |
+| |__ / \ / / . \ . \ |
+| / / \ 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
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
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
--- /dev/null
+/*---------------------------------------------------------------------\
+| ____ _ __ __ ___ |
+| |__ / \ / / . \ . \ |
+| / / \ 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
--- /dev/null
+/*---------------------------------------------------------------------\
+| ____ _ __ __ ___ |
+| |__ / \ / / . \ . \ |
+| / / \ 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
--- /dev/null
+/*---------------------------------------------------------------------\
+| ____ _ __ __ ___ |
+| |__ / \ / / . \ . \ |
+| / / \ 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
--- /dev/null
+/*---------------------------------------------------------------------\
+| ____ _ __ __ ___ |
+| |__ / \ / / . \ . \ |
+| / / \ 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
/*---------------------------------------------------------------------\
+| ____ _ __ __ ___ |
+| |__ / \ / / . \ . \ |
+| / / \ 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>
/*---------------------------------------------------------------------\
+| ____ _ __ __ ___ |
+| |__ / \ / / . \ . \ |
+| / / \ 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++ -*-
#include <string>
#include "zypp/ExternalProgram.h"
+#include "zypp/KVMap.h"
namespace zypp {
namespace media {
/**
* 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: