MediaAccess.cc

Go to the documentation of this file.
00001 /*---------------------------------------------------------------------\
00002 |                          ____ _   __ __ ___                          |
00003 |                         |__  / \ / / . \ . \                         |
00004 |                           / / \ V /|  _/  _/                         |
00005 |                          / /__ | | | | | |                           |
00006 |                         /_____||_| |_| |_|                           |
00007 |                                                                      |
00008 \---------------------------------------------------------------------*/
00013 #include <ctype.h>
00014 
00015 #include <iostream>
00016 
00017 #include "zypp/base/Logger.h"
00018 
00019 #include "zypp/media/MediaException.h"
00020 #include "zypp/media/MediaAccess.h"
00021 #include "zypp/media/MediaHandler.h"
00022 
00023 #include "zypp/media/MediaNFS.h"
00024 #include "zypp/media/MediaCD.h"
00025 #include "zypp/media/MediaDIR.h"
00026 #include "zypp/media/MediaDISK.h"
00027 #include "zypp/media/MediaSMB.h"
00028 #include "zypp/media/MediaCIFS.h"
00029 #include "zypp/media/MediaCurl.h"
00030 #include "zypp/media/MediaISO.h"
00031 
00032 using namespace std;
00033 
00034 namespace zypp {
00035   namespace media {
00036 
00038 //
00039 //      CLASS NAME : MediaAccess
00040 //
00042 
00043 const Pathname MediaAccess::_noPath; // empty path
00044 
00046 // constructor
00047 MediaAccess::MediaAccess ()
00048     : _handler (0)
00049 {
00050 }
00051 
00052 // destructor
00053 MediaAccess::~MediaAccess()
00054 {
00055   try
00056     {
00057       close(); // !!! make sure handler gets properly deleted.
00058     }
00059   catch(...) {}
00060 }
00061 
00062 AttachedMedia
00063 MediaAccess::attachedMedia() const
00064 {
00065         return _handler ? _handler->attachedMedia()
00066                         : AttachedMedia();
00067 }
00068 
00069 bool
00070 MediaAccess::isSharedMedia() const
00071 {
00072         return _handler ? _handler->isSharedMedia()
00073                         : false;
00074 }
00075 
00076 void
00077 MediaAccess::resetParentId()
00078 {
00079         if( _handler) _handler->resetParentId();
00080 }
00081 
00082 bool
00083 MediaAccess::dependsOnParent() const
00084 {
00085         return _handler ? _handler->dependsOnParent() : false;
00086 }
00087 
00088 bool
00089 MediaAccess::dependsOnParent(MediaAccessId parentId,
00090                              bool exactIdMatch) const
00091 {
00092         return _handler ? _handler->dependsOnParent(parentId, exactIdMatch)
00093                         : false;
00094 }
00095 
00096 // open URL
00097 void
00098 MediaAccess::open (const Url& url, const Pathname & preferred_attach_point)
00099 {
00100     if(!url.isValid()) {
00101         MIL << "Url is not valid" << endl;
00102         ZYPP_THROW(MediaBadUrlException(url));
00103     }
00104 
00105     close();
00106 
00107     std::string scheme = url.getScheme();
00108 
00109     MIL << "Trying scheme '" << scheme << "'" << endl;
00110     /*
00111     ** WARNING: Don't forget to update MediaAccess::downloads(url)
00112     **          if you are adding a new url scheme / handler!
00113     */
00114     if (scheme == "cd" || scheme == "dvd")
00115         _handler = new MediaCD (url,preferred_attach_point);
00116     else if (scheme == "nfs")
00117         _handler = new MediaNFS (url,preferred_attach_point);
00118     else if (scheme == "iso")
00119         _handler = new MediaISO (url,preferred_attach_point);
00120     else if (scheme == "file" || scheme == "dir")
00121         _handler = new MediaDIR (url,preferred_attach_point);
00122     else if (scheme == "hd")
00123         _handler = new MediaDISK (url,preferred_attach_point);
00124     else if (scheme == "smb")
00125         _handler = new MediaSMB (url,preferred_attach_point);
00126     else if (scheme == "cifs")
00127         _handler = new MediaCIFS (url,preferred_attach_point);
00128     else if (scheme == "ftp" || scheme == "http" || scheme == "https")
00129         _handler = new MediaCurl (url,preferred_attach_point);
00130     else
00131     {
00132         ZYPP_THROW(MediaUnsupportedUrlSchemeException(url));
00133     }
00134 
00135     // check created handler
00136     if ( !_handler ){
00137       ERR << "Failed to create media handler" << endl;
00138       ZYPP_THROW(MediaSystemException(url, "Failed to create media handler"));
00139     }
00140 
00141     MIL << "Opened: " << *this << endl;
00142 }
00143 
00144 // STATIC
00145 bool
00146 MediaAccess::downloads(const Url &url)
00147 {
00148     std::string scheme( url.getScheme());
00149     return (scheme == "ftp" || scheme == "http" || scheme == "https");
00150 }
00151 
00152 // STATIC
00153 bool
00154 MediaAccess::canBeVolatile(const Url &url)
00155 {
00156     std::string scheme( url.getScheme());
00157     return ! (scheme == "cd" || scheme == "dvd");
00158 }
00159 
00160 // Type of media if open, otherwise NONE.
00161 std::string
00162 MediaAccess::protocol() const
00163 {
00164   if ( !_handler )
00165     return "unknown";
00166 
00167   return _handler->protocol();
00168 }
00169 
00170 bool
00171 MediaAccess::downloads() const
00172 {
00173         return _handler ? _handler->downloads() : false;
00174 }
00175 
00177 //
00178 //
00179 //      METHOD NAME : MediaAccess::url
00180 //      METHOD TYPE : Url
00181 //
00182 Url MediaAccess::url() const
00183 {
00184   if ( !_handler )
00185     return Url();
00186 
00187   return _handler->url();
00188 }
00189 
00190 // close handler
00191 void
00192 MediaAccess::close ()
00193 {
00195   // !!! make shure handler gets properly deleted.
00196   // I.e. release attached media before deleting the handler.
00198   if ( _handler ) {
00199     try {
00200       _handler->release();
00201     }
00202     catch (const MediaException & excpt_r)
00203     {
00204       ZYPP_CAUGHT(excpt_r);
00205       WAR << "Close: " << *this << " (" << excpt_r << ")" << endl;
00206       ZYPP_RETHROW(excpt_r);
00207     }
00208     MIL << "Close: " << *this << " (OK)" << endl;
00209     delete _handler;
00210     _handler = 0;
00211   }
00212 }
00213 
00214 
00215 // attach media
00216 void MediaAccess::attach (bool next)
00217 {
00218   if ( !_handler ) {
00219     ZYPP_THROW(MediaNotOpenException("attach"));
00220   }
00221   _handler->attach(next);
00222 }
00223 
00224 // True if media is open and attached.
00225 bool
00226 MediaAccess::isAttached() const
00227 {
00228   return( _handler && _handler->isAttached() );
00229 }
00230 
00231 
00232 bool MediaAccess::hasMoreDevices() const
00233 {
00234   return _handler && _handler->hasMoreDevices();
00235 }
00236 
00237 
00238 // local directory that corresponds to medias url
00239 // If media is not open an empty pathname.
00240 Pathname
00241 MediaAccess::localRoot() const
00242 {
00243   if ( !_handler )
00244     return _noPath;
00245 
00246   return _handler->localRoot();
00247 }
00248 
00249 // Short for 'localRoot() + pathname', but returns an empty
00250 // * pathname if media is not open.
00251 Pathname
00252 MediaAccess::localPath( const Pathname & pathname ) const
00253 {
00254   if ( !_handler )
00255     return _noPath;
00256 
00257   return _handler->localPath( pathname );
00258 }
00259 
00260 void
00261 MediaAccess::disconnect()
00262 {
00263   if ( !_handler )
00264     ZYPP_THROW(MediaNotOpenException("disconnect"));
00265 
00266   _handler->disconnect();
00267 }
00268 
00269 // release attached media
00270 void
00271 MediaAccess::release( bool eject )
00272 {
00273   if ( !_handler )
00274     return;
00275 
00276   _handler->release( eject );
00277 }
00278 
00279 
00280 // provide file denoted by path to attach dir
00281 //
00282 // filename is interpreted relative to the attached url
00283 // and a path prefix is preserved to destination
00284 void
00285 MediaAccess::provideFile( const Pathname & filename, bool cached, bool checkonly) const
00286 {
00287   if ( cached ) {
00288     PathInfo pi( localPath( filename ) );
00289     if ( pi.isExist() )
00290       return;
00291   }
00292 
00293   if(checkonly)
00294     ZYPP_THROW(MediaFileNotFoundException(url(), filename));
00295 
00296   if ( !_handler ) {
00297     ZYPP_THROW(MediaNotOpenException("provideFile(" + filename.asString() + ")"));
00298   }
00299 
00300   _handler->provideFile( filename );
00301 }
00302 
00303 void
00304 MediaAccess::releaseFile( const Pathname & filename ) const
00305 {
00306   if ( !_handler )
00307     return;
00308 
00309   _handler->releaseFile( filename );
00310 }
00311 
00312 // provide directory tree denoted by path to attach dir
00313 //
00314 // dirname is interpreted relative to the attached url
00315 // and a path prefix is preserved to destination
00316 void
00317 MediaAccess::provideDir( const Pathname & dirname ) const
00318 {
00319   if ( !_handler ) {
00320     ZYPP_THROW(MediaNotOpenException("provideDir(" + dirname.asString() + ")"));
00321   }
00322 
00323   _handler->provideDir( dirname );
00324 }
00325 
00326 void
00327 MediaAccess::provideDirTree( const Pathname & dirname ) const
00328 {
00329   if ( !_handler ) {
00330     ZYPP_THROW(MediaNotOpenException("provideDirTree(" + dirname.asString() + ")"));
00331   }
00332 
00333   _handler->provideDirTree( dirname );
00334 }
00335 
00336 void
00337 MediaAccess::releaseDir( const Pathname & dirname ) const
00338 {
00339   if ( !_handler )
00340     return;
00341 
00342   _handler->releaseDir( dirname );
00343 }
00344 
00345 void
00346 MediaAccess::releasePath( const Pathname & pathname ) const
00347 {
00348   if ( !_handler )
00349     return;
00350 
00351   _handler->releasePath( pathname );
00352 }
00353 
00354 // Return content of directory on media
00355 void
00356 MediaAccess::dirInfo( std::list<std::string> & retlist, const Pathname & dirname, bool dots ) const
00357 {
00358   retlist.clear();
00359 
00360   if ( !_handler ) {
00361     ZYPP_THROW(MediaNotOpenException("dirInfo(" + dirname.asString() + ")"));
00362   }
00363 
00364   _handler->dirInfo( retlist, dirname, dots );
00365 }
00366 
00367 // Return content of directory on media
00368 void
00369 MediaAccess::dirInfo( filesystem::DirContent & retlist, const Pathname & dirname, bool dots ) const
00370 {
00371   retlist.clear();
00372 
00373   if ( !_handler ) {
00374     ZYPP_THROW(MediaNotOpenException("dirInfo(" + dirname.asString() + ")"));
00375   }
00376 
00377   _handler->dirInfo( retlist, dirname, dots );
00378 }
00379 
00380 // return if a file exists
00381 bool
00382 MediaAccess::doesFileExist( const Pathname & filename ) const
00383 {
00384   if ( !_handler ) {
00385     ZYPP_THROW(MediaNotOpenException("doesFileExist(" + filename.asString() + ")"));
00386   }
00387 
00388   return _handler->doesFileExist( filename );
00389 }
00390 
00391 std::ostream &
00392 MediaAccess::dumpOn( std::ostream & str ) const
00393 {
00394   if ( !_handler )
00395     return str << "MediaAccess( closed )";
00396 
00397   str << _handler->protocol() << "(" << *_handler << ")";
00398   return str;
00399 }
00400 
00401 void MediaAccess::getFile( const Url &from, const Pathname &to )
00402 {
00403   DBG << "From: " << from << endl << "To: " << to << endl;
00404 
00405   Pathname path = from.getPathData();
00406   Pathname dir = path.dirname();
00407   string base = path.basename();
00408 
00409   Url u = from;
00410   u.setPathData( dir.asString() );
00411 
00412   MediaAccess media;
00413 
00414   try {
00415     media.open( u );
00416     media.attach();
00417     media._handler->provideFileCopy( base, to );
00418     media.release();
00419   }
00420   catch (const MediaException & excpt_r)
00421   {
00422     ZYPP_RETHROW(excpt_r);
00423   }
00424 }
00425 
00426     std::ostream & operator<<( std::ostream & str, const MediaAccess & obj )
00427     { return obj.dumpOn( str ); }
00428 
00430   } // namespace media
00431 } // namespace zypp

Generated on Tue Sep 25 19:23:01 2007 for libzypp by  doxygen 1.5.3