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