1 /*---------------------------------------------------------------------\
3 | |__ / \ / / . \ . \ |
8 \---------------------------------------------------------------------*/
9 /** \file zypp/media/MediaAccess.cc
18 #include "zypp/base/Logger.h"
19 #include "zypp/ZConfig.h"
20 #include "zypp/PluginScript.h"
21 #include "zypp/ExternalProgram.h"
23 #include "zypp/media/MediaException.h"
24 #include "zypp/media/MediaAccess.h"
25 #include "zypp/media/MediaHandler.h"
27 #include "zypp/media/MediaNFS.h"
28 #include "zypp/media/MediaCD.h"
29 #include "zypp/media/MediaDIR.h"
30 #include "zypp/media/MediaDISK.h"
31 #include "zypp/media/MediaCIFS.h"
32 #include "zypp/media/MediaCurl.h"
33 #include "zypp/media/MediaMultiCurl.h"
34 #include "zypp/media/MediaISO.h"
35 #include "zypp/media/MediaPlugin.h"
36 #include "zypp/media/UrlResolverPlugin.h"
43 ///////////////////////////////////////////////////////////////////
45 // CLASS NAME : MediaAccess
47 ///////////////////////////////////////////////////////////////////
49 const Pathname MediaAccess::_noPath; // empty path
51 ///////////////////////////////////////////////////////////////////
53 MediaAccess::MediaAccess ()
59 MediaAccess::~MediaAccess()
63 close(); // !!! make sure handler gets properly deleted.
69 MediaAccess::attachedMedia() const
71 return _handler ? _handler->attachedMedia()
76 MediaAccess::isSharedMedia() const
78 return _handler ? _handler->isSharedMedia()
83 MediaAccess::resetParentId()
85 if( _handler) _handler->resetParentId();
89 MediaAccess::dependsOnParent() const
91 return _handler ? _handler->dependsOnParent() : false;
95 MediaAccess::dependsOnParent(MediaAccessId parentId,
96 bool exactIdMatch) const
98 return _handler ? _handler->dependsOnParent(parentId, exactIdMatch)
104 MediaAccess::open (const Url& o_url, const Pathname & preferred_attach_point)
106 if(!o_url.isValid()) {
107 MIL << "Url is not valid" << endl;
108 ZYPP_THROW(MediaBadUrlException(o_url));
113 UrlResolverPlugin::HeaderList custom_headers;
114 Url url = UrlResolverPlugin::resolveUrl(o_url, custom_headers);
116 std::string scheme = url.getScheme();
117 MIL << "Trying scheme '" << scheme << "'" << endl;
120 ** WARNING: Don't forget to update MediaAccess::downloads(url)
121 ** if you are adding a new url scheme / handler!
123 if (scheme == "cd" || scheme == "dvd")
124 _handler = new MediaCD (url,preferred_attach_point);
125 else if (scheme == "nfs" || scheme == "nfs4")
126 _handler = new MediaNFS (url,preferred_attach_point);
127 else if (scheme == "iso")
128 _handler = new MediaISO (url,preferred_attach_point);
129 else if (scheme == "file" || scheme == "dir")
130 _handler = new MediaDIR (url,preferred_attach_point);
131 else if (scheme == "hd")
132 _handler = new MediaDISK (url,preferred_attach_point);
133 else if (scheme == "cifs" || scheme == "smb")
134 _handler = new MediaCIFS (url,preferred_attach_point);
135 else if (scheme == "ftp" || scheme == "tftp" || scheme == "http" || scheme == "https")
137 bool use_multicurl = true;
138 string urlmediahandler ( url.getQueryParam("mediahandler") );
139 if ( urlmediahandler == "multicurl" )
141 use_multicurl = true;
143 else if ( urlmediahandler == "curl" )
145 use_multicurl = false;
149 if ( ! urlmediahandler.empty() )
151 WAR << "unknown mediahandler set: " << urlmediahandler << endl;
153 const char *multicurlenv = getenv( "ZYPP_MULTICURL" );
154 // if user disabled it manually
155 if ( use_multicurl && multicurlenv && ( strcmp(multicurlenv, "0" ) == 0 ) )
157 WAR << "multicurl manually disabled." << endl;
158 use_multicurl = false;
160 else if ( !use_multicurl && multicurlenv && ( strcmp(multicurlenv, "1" ) == 0 ) )
162 WAR << "multicurl manually enabled." << endl;
163 use_multicurl = true;
170 curl = new MediaMultiCurl (url,preferred_attach_point);
172 curl = new MediaCurl (url,preferred_attach_point);
174 UrlResolverPlugin::HeaderList::const_iterator it;
175 for (it = custom_headers.begin();
176 it != custom_headers.end();
178 std::string header = it->first + ": " + it->second;
179 MIL << "Added custom header -> " << header << endl;
180 curl->settings().addHeader(header);
184 else if (scheme == "plugin" )
185 _handler = new MediaPlugin (url,preferred_attach_point);
188 ZYPP_THROW(MediaUnsupportedUrlSchemeException(url));
191 // check created handler
193 ERR << "Failed to create media handler" << endl;
194 ZYPP_THROW(MediaSystemException(url, "Failed to create media handler"));
197 MIL << "Opened: " << *this << endl;
200 // Type of media if open, otherwise NONE.
202 MediaAccess::protocol() const
207 return _handler->protocol();
211 MediaAccess::downloads() const
213 return _handler ? _handler->downloads() : false;
216 ///////////////////////////////////////////////////////////////////
219 // METHOD NAME : MediaAccess::url
222 Url MediaAccess::url() const
227 return _handler->url();
232 MediaAccess::close ()
234 ///////////////////////////////////////////////////////////////////
235 // !!! make shure handler gets properly deleted.
236 // I.e. release attached media before deleting the handler.
237 ///////////////////////////////////////////////////////////////////
242 catch (const MediaException & excpt_r)
244 ZYPP_CAUGHT(excpt_r);
245 WAR << "Close: " << *this << " (" << excpt_r << ")" << endl;
246 ZYPP_RETHROW(excpt_r);
248 MIL << "Close: " << *this << " (OK)" << endl;
256 void MediaAccess::attach (bool next)
259 ZYPP_THROW(MediaNotOpenException("attach"));
261 _handler->attach(next);
264 // True if media is open and attached.
266 MediaAccess::isAttached() const
268 return( _handler && _handler->isAttached() );
272 bool MediaAccess::hasMoreDevices() const
274 return _handler && _handler->hasMoreDevices();
279 MediaAccess::getDetectedDevices(std::vector<std::string> & devices,
280 unsigned int & index) const
284 _handler->getDetectedDevices(devices, index);
288 if (!devices.empty())
294 // local directory that corresponds to medias url
295 // If media is not open an empty pathname.
297 MediaAccess::localRoot() const
302 return _handler->localRoot();
305 // Short for 'localRoot() + pathname', but returns an empty
306 // * pathname if media is not open.
308 MediaAccess::localPath( const Pathname & pathname ) const
313 return _handler->localPath( pathname );
317 MediaAccess::disconnect()
320 ZYPP_THROW(MediaNotOpenException("disconnect"));
322 _handler->disconnect();
327 MediaAccess::release( const std::string & ejectDev )
332 _handler->release( ejectDev );
335 // provide file denoted by path to attach dir
337 // filename is interpreted relative to the attached url
338 // and a path prefix is preserved to destination
340 MediaAccess::provideFile(const Pathname & filename , const ByteCount &expectedFileSize) const
343 ZYPP_THROW(MediaNotOpenException("provideFile(" + filename.asString() + ")"));
346 _handler->provideFile( filename, expectedFileSize );
350 MediaAccess::setDeltafile( const Pathname & filename ) const
353 ZYPP_THROW(MediaNotOpenException("setDeltafile(" + filename.asString() + ")"));
356 _handler->setDeltafile( filename );
360 MediaAccess::releaseFile( const Pathname & filename ) const
365 _handler->releaseFile( filename );
368 // provide directory tree denoted by path to attach dir
370 // dirname is interpreted relative to the attached url
371 // and a path prefix is preserved to destination
373 MediaAccess::provideDir( const Pathname & dirname ) const
376 ZYPP_THROW(MediaNotOpenException("provideDir(" + dirname.asString() + ")"));
379 _handler->provideDir( dirname );
383 MediaAccess::provideDirTree( const Pathname & dirname ) const
386 ZYPP_THROW(MediaNotOpenException("provideDirTree(" + dirname.asString() + ")"));
389 _handler->provideDirTree( dirname );
393 MediaAccess::releaseDir( const Pathname & dirname ) const
398 _handler->releaseDir( dirname );
402 MediaAccess::releasePath( const Pathname & pathname ) const
407 _handler->releasePath( pathname );
410 // Return content of directory on media
412 MediaAccess::dirInfo( std::list<std::string> & retlist, const Pathname & dirname, bool dots ) const
417 ZYPP_THROW(MediaNotOpenException("dirInfo(" + dirname.asString() + ")"));
420 _handler->dirInfo( retlist, dirname, dots );
423 // Return content of directory on media
425 MediaAccess::dirInfo( filesystem::DirContent & retlist, const Pathname & dirname, bool dots ) const
430 ZYPP_THROW(MediaNotOpenException("dirInfo(" + dirname.asString() + ")"));
433 _handler->dirInfo( retlist, dirname, dots );
436 // return if a file exists
438 MediaAccess::doesFileExist( const Pathname & filename ) const
441 ZYPP_THROW(MediaNotOpenException("doesFileExist(" + filename.asString() + ")"));
444 return _handler->doesFileExist( filename );
448 MediaAccess::dumpOn( std::ostream & str ) const
451 return str << "MediaAccess( closed )";
453 str << _handler->protocol() << "(" << *_handler << ")";
457 void MediaAccess::getFile( const Url &from, const Pathname &to )
459 DBG << "From: " << from << endl << "To: " << to << endl;
461 Pathname path = from.getPathData();
462 Pathname dir = path.dirname();
463 string base = path.basename();
466 u.setPathData( dir.asString() );
473 media._handler->provideFileCopy( base, to, 0 );
476 catch (const MediaException & excpt_r)
478 ZYPP_RETHROW(excpt_r);
482 std::ostream & operator<<( std::ostream & str, const MediaAccess & obj )
483 { return obj.dumpOn( str ); }
485 ///////////////////////////////////////////////////////////////////