MediaAccess.cc
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00013 #include <ctype.h>
00014
00015 #include <iostream>
00016 #include <map>
00017
00018 #include "zypp/base/Logger.h"
00019 #include "zypp/ZConfig.h"
00020 #include "zypp/PluginScript.h"
00021 #include "zypp/ExternalProgram.h"
00022
00023 #include "zypp/media/MediaException.h"
00024 #include "zypp/media/MediaAccess.h"
00025 #include "zypp/media/MediaHandler.h"
00026
00027 #include "zypp/media/MediaNFS.h"
00028 #include "zypp/media/MediaCD.h"
00029 #include "zypp/media/MediaDIR.h"
00030 #include "zypp/media/MediaDISK.h"
00031 #include "zypp/media/MediaCIFS.h"
00032 #include "zypp/media/MediaCurl.h"
00033 #include "zypp/media/MediaAria2c.h"
00034 #include "zypp/media/MediaISO.h"
00035 #include "zypp/media/MediaPlugin.h"
00036 #include "zypp/media/UrlResolverPlugin.h"
00037
00038 using namespace std;
00039
00040 namespace zypp {
00041 namespace media {
00042
00044
00045
00046
00048
00049 const Pathname MediaAccess::_noPath;
00050
00052
00053 MediaAccess::MediaAccess ()
00054 : _handler (0)
00055 {
00056 }
00057
00058
00059 MediaAccess::~MediaAccess()
00060 {
00061 try
00062 {
00063 close();
00064 }
00065 catch(...) {}
00066 }
00067
00068 AttachedMedia
00069 MediaAccess::attachedMedia() const
00070 {
00071 return _handler ? _handler->attachedMedia()
00072 : AttachedMedia();
00073 }
00074
00075 bool
00076 MediaAccess::isSharedMedia() const
00077 {
00078 return _handler ? _handler->isSharedMedia()
00079 : false;
00080 }
00081
00082 void
00083 MediaAccess::resetParentId()
00084 {
00085 if( _handler) _handler->resetParentId();
00086 }
00087
00088 bool
00089 MediaAccess::dependsOnParent() const
00090 {
00091 return _handler ? _handler->dependsOnParent() : false;
00092 }
00093
00094 bool
00095 MediaAccess::dependsOnParent(MediaAccessId parentId,
00096 bool exactIdMatch) const
00097 {
00098 return _handler ? _handler->dependsOnParent(parentId, exactIdMatch)
00099 : false;
00100 }
00101
00102
00103 void
00104 MediaAccess::open (const Url& o_url, const Pathname & preferred_attach_point)
00105 {
00106 if(!o_url.isValid()) {
00107 MIL << "Url is not valid" << endl;
00108 ZYPP_THROW(MediaBadUrlException(o_url));
00109 }
00110
00111 close();
00112
00113 UrlResolverPlugin::HeaderList custom_headers;
00114 Url url = UrlResolverPlugin::resolveUrl(o_url, custom_headers);
00115
00116 std::string scheme = url.getScheme();
00117 MIL << "Trying scheme '" << scheme << "'" << endl;
00118
00119
00120
00121
00122
00123 if (scheme == "cd" || scheme == "dvd")
00124 _handler = new MediaCD (url,preferred_attach_point);
00125 else if (scheme == "nfs" || scheme == "nfs4")
00126 _handler = new MediaNFS (url,preferred_attach_point);
00127 else if (scheme == "iso")
00128 _handler = new MediaISO (url,preferred_attach_point);
00129 else if (scheme == "file" || scheme == "dir")
00130 _handler = new MediaDIR (url,preferred_attach_point);
00131 else if (scheme == "hd")
00132 _handler = new MediaDISK (url,preferred_attach_point);
00133 else if (scheme == "cifs" || scheme == "smb")
00134 _handler = new MediaCIFS (url,preferred_attach_point);
00135 else if (scheme == "ftp" || scheme == "http" || scheme == "https")
00136 {
00137
00138 bool use_aria = false;
00139 bool use_multicurl = true;
00140 const char *ariaenv = getenv( "ZYPP_ARIA2C" );
00141 const char *multicurlenv = getenv( "ZYPP_MULTICURL" );
00142
00143 if ( use_multicurl && multicurlenv && ( strcmp(multicurlenv, "0" ) == 0 ) )
00144 {
00145 WAR << "multicurl manually disabled." << endl;
00146 use_multicurl = false;
00147 }
00148 else if ( !use_multicurl && multicurlenv && ( strcmp(multicurlenv, "1" ) == 0 ) )
00149 {
00150 WAR << "multicurl manually enabled." << endl;
00151 use_multicurl = true;
00152 }
00153
00154 if ( use_aria && ariaenv && ( strcmp(ariaenv, "0" ) == 0 ) )
00155 {
00156 WAR << "aria2c manually disabled. Falling back to curl" << endl;
00157 use_aria = false;
00158 }
00159 else if ( !use_aria && ariaenv && ( strcmp(ariaenv, "1" ) == 0 ) )
00160 {
00161 WAR << "aria2c manually enabled." << endl;
00162 use_aria = true;
00163 }
00164
00165
00166 if ( use_aria && ! MediaAria2c::existsAria2cmd() )
00167 {
00168 WAR << "aria2c not found. Falling back to curl" << endl;
00169 use_aria = false;
00170 }
00171
00172 MediaCurl *curl;
00173
00174 if ( use_aria )
00175 curl = new MediaAria2c (url,preferred_attach_point);
00176 else
00177 curl = new MediaCurl (url,preferred_attach_point);
00178
00179 UrlResolverPlugin::HeaderList::const_iterator it;
00180 for (it = custom_headers.begin();
00181 it != custom_headers.end();
00182 ++it) {
00183 std::string header = it->first + ": " + it->second;
00184 MIL << "Added custom header -> " << header << endl;
00185 curl->settings().addHeader(header);
00186 }
00187 _handler = curl;
00188 }
00189 else if (scheme == "plugin" )
00190 _handler = new MediaPlugin (url,preferred_attach_point);
00191 else
00192 {
00193 ZYPP_THROW(MediaUnsupportedUrlSchemeException(url));
00194 }
00195
00196
00197 if ( !_handler ){
00198 ERR << "Failed to create media handler" << endl;
00199 ZYPP_THROW(MediaSystemException(url, "Failed to create media handler"));
00200 }
00201
00202 MIL << "Opened: " << *this << endl;
00203 }
00204
00205
00206 std::string
00207 MediaAccess::protocol() const
00208 {
00209 if ( !_handler )
00210 return "unknown";
00211
00212 return _handler->protocol();
00213 }
00214
00215 bool
00216 MediaAccess::downloads() const
00217 {
00218 return _handler ? _handler->downloads() : false;
00219 }
00220
00222
00223
00224
00225
00226
00227 Url MediaAccess::url() const
00228 {
00229 if ( !_handler )
00230 return Url();
00231
00232 return _handler->url();
00233 }
00234
00235
00236 void
00237 MediaAccess::close ()
00238 {
00240
00241
00243 if ( _handler ) {
00244 try {
00245 _handler->release();
00246 }
00247 catch (const MediaException & excpt_r)
00248 {
00249 ZYPP_CAUGHT(excpt_r);
00250 WAR << "Close: " << *this << " (" << excpt_r << ")" << endl;
00251 ZYPP_RETHROW(excpt_r);
00252 }
00253 MIL << "Close: " << *this << " (OK)" << endl;
00254 delete _handler;
00255 _handler = 0;
00256 }
00257 }
00258
00259
00260
00261 void MediaAccess::attach (bool next)
00262 {
00263 if ( !_handler ) {
00264 ZYPP_THROW(MediaNotOpenException("attach"));
00265 }
00266 _handler->attach(next);
00267 }
00268
00269
00270 bool
00271 MediaAccess::isAttached() const
00272 {
00273 return( _handler && _handler->isAttached() );
00274 }
00275
00276
00277 bool MediaAccess::hasMoreDevices() const
00278 {
00279 return _handler && _handler->hasMoreDevices();
00280 }
00281
00282
00283 void
00284 MediaAccess::getDetectedDevices(std::vector<std::string> & devices,
00285 unsigned int & index) const
00286 {
00287 if (_handler)
00288 {
00289 _handler->getDetectedDevices(devices, index);
00290 return;
00291 }
00292
00293 if (!devices.empty())
00294 devices.clear();
00295 index = 0;
00296 }
00297
00298
00299
00300
00301 Pathname
00302 MediaAccess::localRoot() const
00303 {
00304 if ( !_handler )
00305 return _noPath;
00306
00307 return _handler->localRoot();
00308 }
00309
00310
00311
00312 Pathname
00313 MediaAccess::localPath( const Pathname & pathname ) const
00314 {
00315 if ( !_handler )
00316 return _noPath;
00317
00318 return _handler->localPath( pathname );
00319 }
00320
00321 void
00322 MediaAccess::disconnect()
00323 {
00324 if ( !_handler )
00325 ZYPP_THROW(MediaNotOpenException("disconnect"));
00326
00327 _handler->disconnect();
00328 }
00329
00330
00331 void
00332 MediaAccess::release( const std::string & ejectDev )
00333 {
00334 if ( !_handler )
00335 return;
00336
00337 _handler->release( ejectDev );
00338 }
00339
00340
00341
00342
00343
00344 void
00345 MediaAccess::provideFile( const Pathname & filename ) const
00346 {
00347 if ( !_handler ) {
00348 ZYPP_THROW(MediaNotOpenException("provideFile(" + filename.asString() + ")"));
00349 }
00350
00351 _handler->provideFile( filename );
00352 }
00353
00354 void
00355 MediaAccess::releaseFile( const Pathname & filename ) const
00356 {
00357 if ( !_handler )
00358 return;
00359
00360 _handler->releaseFile( filename );
00361 }
00362
00363
00364
00365
00366
00367 void
00368 MediaAccess::provideDir( const Pathname & dirname ) const
00369 {
00370 if ( !_handler ) {
00371 ZYPP_THROW(MediaNotOpenException("provideDir(" + dirname.asString() + ")"));
00372 }
00373
00374 _handler->provideDir( dirname );
00375 }
00376
00377 void
00378 MediaAccess::provideDirTree( const Pathname & dirname ) const
00379 {
00380 if ( !_handler ) {
00381 ZYPP_THROW(MediaNotOpenException("provideDirTree(" + dirname.asString() + ")"));
00382 }
00383
00384 _handler->provideDirTree( dirname );
00385 }
00386
00387 void
00388 MediaAccess::releaseDir( const Pathname & dirname ) const
00389 {
00390 if ( !_handler )
00391 return;
00392
00393 _handler->releaseDir( dirname );
00394 }
00395
00396 void
00397 MediaAccess::releasePath( const Pathname & pathname ) const
00398 {
00399 if ( !_handler )
00400 return;
00401
00402 _handler->releasePath( pathname );
00403 }
00404
00405
00406 void
00407 MediaAccess::dirInfo( std::list<std::string> & retlist, const Pathname & dirname, bool dots ) const
00408 {
00409 retlist.clear();
00410
00411 if ( !_handler ) {
00412 ZYPP_THROW(MediaNotOpenException("dirInfo(" + dirname.asString() + ")"));
00413 }
00414
00415 _handler->dirInfo( retlist, dirname, dots );
00416 }
00417
00418
00419 void
00420 MediaAccess::dirInfo( filesystem::DirContent & retlist, const Pathname & dirname, bool dots ) const
00421 {
00422 retlist.clear();
00423
00424 if ( !_handler ) {
00425 ZYPP_THROW(MediaNotOpenException("dirInfo(" + dirname.asString() + ")"));
00426 }
00427
00428 _handler->dirInfo( retlist, dirname, dots );
00429 }
00430
00431
00432 bool
00433 MediaAccess::doesFileExist( const Pathname & filename ) const
00434 {
00435 if ( !_handler ) {
00436 ZYPP_THROW(MediaNotOpenException("doesFileExist(" + filename.asString() + ")"));
00437 }
00438
00439 return _handler->doesFileExist( filename );
00440 }
00441
00442 std::ostream &
00443 MediaAccess::dumpOn( std::ostream & str ) const
00444 {
00445 if ( !_handler )
00446 return str << "MediaAccess( closed )";
00447
00448 str << _handler->protocol() << "(" << *_handler << ")";
00449 return str;
00450 }
00451
00452 void MediaAccess::getFile( const Url &from, const Pathname &to )
00453 {
00454 DBG << "From: " << from << endl << "To: " << to << endl;
00455
00456 Pathname path = from.getPathData();
00457 Pathname dir = path.dirname();
00458 string base = path.basename();
00459
00460 Url u = from;
00461 u.setPathData( dir.asString() );
00462
00463 MediaAccess media;
00464
00465 try {
00466 media.open( u );
00467 media.attach();
00468 media._handler->provideFileCopy( base, to );
00469 media.release();
00470 }
00471 catch (const MediaException & excpt_r)
00472 {
00473 ZYPP_RETHROW(excpt_r);
00474 }
00475 }
00476
00477 std::ostream & operator<<( std::ostream & str, const MediaAccess & obj )
00478 { return obj.dumpOn( str ); }
00479
00481 }
00482 }