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 for ( const auto & el : custom_headers ) {
175 std::string header { el.first };
178 MIL << "Added custom header -> " << header << endl;
179 curl->settings().addHeader( std::move(header) );
183 else if (scheme == "plugin" )
184 _handler = new MediaPlugin (url,preferred_attach_point);
187 ZYPP_THROW(MediaUnsupportedUrlSchemeException(url));
190 // check created handler
192 ERR << "Failed to create media handler" << endl;
193 ZYPP_THROW(MediaSystemException(url, "Failed to create media handler"));
196 MIL << "Opened: " << *this << endl;
199 // Type of media if open, otherwise NONE.
201 MediaAccess::protocol() const
206 return _handler->protocol();
210 MediaAccess::downloads() const
212 return _handler ? _handler->downloads() : false;
215 ///////////////////////////////////////////////////////////////////
218 // METHOD NAME : MediaAccess::url
221 Url MediaAccess::url() const
226 return _handler->url();
231 MediaAccess::close ()
233 ///////////////////////////////////////////////////////////////////
234 // !!! make shure handler gets properly deleted.
235 // I.e. release attached media before deleting the handler.
236 ///////////////////////////////////////////////////////////////////
241 catch (const MediaException & excpt_r)
243 ZYPP_CAUGHT(excpt_r);
244 WAR << "Close: " << *this << " (" << excpt_r << ")" << endl;
245 ZYPP_RETHROW(excpt_r);
247 MIL << "Close: " << *this << " (OK)" << endl;
255 void MediaAccess::attach (bool next)
258 ZYPP_THROW(MediaNotOpenException("attach"));
260 _handler->attach(next);
263 // True if media is open and attached.
265 MediaAccess::isAttached() const
267 return( _handler && _handler->isAttached() );
271 bool MediaAccess::hasMoreDevices() const
273 return _handler && _handler->hasMoreDevices();
278 MediaAccess::getDetectedDevices(std::vector<std::string> & devices,
279 unsigned int & index) const
283 _handler->getDetectedDevices(devices, index);
287 if (!devices.empty())
293 // local directory that corresponds to medias url
294 // If media is not open an empty pathname.
296 MediaAccess::localRoot() const
301 return _handler->localRoot();
304 // Short for 'localRoot() + pathname', but returns an empty
305 // * pathname if media is not open.
307 MediaAccess::localPath( const Pathname & pathname ) const
312 return _handler->localPath( pathname );
316 MediaAccess::disconnect()
319 ZYPP_THROW(MediaNotOpenException("disconnect"));
321 _handler->disconnect();
326 MediaAccess::release( const std::string & ejectDev )
331 _handler->release( ejectDev );
334 // provide file denoted by path to attach dir
336 // filename is interpreted relative to the attached url
337 // and a path prefix is preserved to destination
339 MediaAccess::provideFile(const Pathname & filename , const ByteCount &expectedFileSize) const
342 ZYPP_THROW(MediaNotOpenException("provideFile(" + filename.asString() + ")"));
345 _handler->provideFile( filename, expectedFileSize );
349 MediaAccess::setDeltafile( const Pathname & filename ) const
352 ZYPP_THROW(MediaNotOpenException("setDeltafile(" + filename.asString() + ")"));
355 _handler->setDeltafile( filename );
359 MediaAccess::releaseFile( const Pathname & filename ) const
364 _handler->releaseFile( filename );
367 // provide directory tree denoted by path to attach dir
369 // dirname is interpreted relative to the attached url
370 // and a path prefix is preserved to destination
372 MediaAccess::provideDir( const Pathname & dirname ) const
375 ZYPP_THROW(MediaNotOpenException("provideDir(" + dirname.asString() + ")"));
378 _handler->provideDir( dirname );
382 MediaAccess::provideDirTree( const Pathname & dirname ) const
385 ZYPP_THROW(MediaNotOpenException("provideDirTree(" + dirname.asString() + ")"));
388 _handler->provideDirTree( dirname );
392 MediaAccess::releaseDir( const Pathname & dirname ) const
397 _handler->releaseDir( dirname );
401 MediaAccess::releasePath( const Pathname & pathname ) const
406 _handler->releasePath( pathname );
409 // Return content of directory on media
411 MediaAccess::dirInfo( std::list<std::string> & retlist, const Pathname & dirname, bool dots ) const
416 ZYPP_THROW(MediaNotOpenException("dirInfo(" + dirname.asString() + ")"));
419 _handler->dirInfo( retlist, dirname, dots );
422 // Return content of directory on media
424 MediaAccess::dirInfo( filesystem::DirContent & retlist, const Pathname & dirname, bool dots ) const
429 ZYPP_THROW(MediaNotOpenException("dirInfo(" + dirname.asString() + ")"));
432 _handler->dirInfo( retlist, dirname, dots );
435 // return if a file exists
437 MediaAccess::doesFileExist( const Pathname & filename ) const
440 ZYPP_THROW(MediaNotOpenException("doesFileExist(" + filename.asString() + ")"));
443 return _handler->doesFileExist( filename );
447 MediaAccess::dumpOn( std::ostream & str ) const
450 return str << "MediaAccess( closed )";
452 str << _handler->protocol() << "(" << *_handler << ")";
456 void MediaAccess::getFile( const Url &from, const Pathname &to )
458 DBG << "From: " << from << endl << "To: " << to << endl;
460 Pathname path = from.getPathData();
461 Pathname dir = path.dirname();
462 string base = path.basename();
465 u.setPathData( dir.asString() );
472 media._handler->provideFileCopy( base, to, 0 );
475 catch (const MediaException & excpt_r)
477 ZYPP_RETHROW(excpt_r);
481 std::ostream & operator<<( std::ostream & str, const MediaAccess & obj )
482 { return obj.dumpOn( str ); }
484 ///////////////////////////////////////////////////////////////////