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