libzypp  17.25.2
MediaAccess.cc
Go to the documentation of this file.
1 /*---------------------------------------------------------------------\
2 | ____ _ __ __ ___ |
3 | |__ / \ / / . \ . \ |
4 | / / \ V /| _/ _/ |
5 | / /__ | | | | | | |
6 | /_____||_| |_| |_| |
7 | |
8 \---------------------------------------------------------------------*/
13 #include <ctype.h>
14 
15 #include <iostream>
16 #include <map>
17 
18 #include <zypp/base/Logger.h>
19 #include <zypp/ZConfig.h>
20 #include <zypp/PluginScript.h>
21 #include <zypp/ExternalProgram.h>
22 
24 #include <zypp/media/MediaAccess.h>
26 
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>
34 #include <zypp/media/MediaISO.h>
35 #include <zypp/media/MediaPlugin.h>
37 #include <zypp/zyppng/media/MediaNetwork>
38 
39 using std::endl;
40 
41 namespace zypp {
42  namespace media {
43 
45 //
46 // CLASS NAME : MediaAccess
47 //
49 
50 const Pathname MediaAccess::_noPath; // empty path
51 
53 // constructor
55  : _handler (0)
56 {
57 }
58 
59 // destructor
61 {
62  try
63  {
64  close(); // !!! make sure handler gets properly deleted.
65  }
66  catch(...) {}
67 }
68 
71 {
72  return _handler ? _handler->attachedMedia()
73  : AttachedMedia();
74 }
75 
76 bool
78 {
79  return _handler ? _handler->isSharedMedia()
80  : false;
81 }
82 
83 void
85 {
87 }
88 
89 bool
91 {
92  return _handler ? _handler->dependsOnParent() : false;
93 }
94 
95 bool
97  bool exactIdMatch) const
98 {
99  return _handler ? _handler->dependsOnParent(parentId, exactIdMatch)
100  : false;
101 }
102 
103 // open URL
104 void
105 MediaAccess::open (const Url& o_url, const Pathname & preferred_attach_point)
106 {
107  if(!o_url.isValid()) {
108  MIL << "Url is not valid" << endl;
110  }
111 
112  close();
113 
114  UrlResolverPlugin::HeaderList custom_headers;
115  Url url = UrlResolverPlugin::resolveUrl(o_url, custom_headers);
116 
117  std::string scheme = url.getScheme();
118  MIL << "Trying scheme '" << scheme << "'" << endl;
119 
120  /*
121  ** WARNING: Don't forget to update MediaAccess::downloads(url)
122  ** if you are adding a new url scheme / handler!
123  */
124  if (scheme == "cd" || scheme == "dvd")
125  _handler = new MediaCD (url,preferred_attach_point);
126  else if (scheme == "nfs" || scheme == "nfs4")
127  _handler = new MediaNFS (url,preferred_attach_point);
128  else if (scheme == "iso")
129  _handler = new MediaISO (url,preferred_attach_point);
130  else if (scheme == "file" || scheme == "dir")
131  _handler = new MediaDIR (url,preferred_attach_point);
132  else if (scheme == "hd")
133  _handler = new MediaDISK (url,preferred_attach_point);
134  else if (scheme == "cifs" || scheme == "smb")
135  _handler = new MediaCIFS (url,preferred_attach_point);
136  else if (scheme == "ftp" || scheme == "tftp" || scheme == "http" || scheme == "https")
137  {
138  const char *networkenv = getenv( "ZYPPNG_MEDIANETWORK" );
139  bool use_network = ( networkenv && strcmp(networkenv, "1" ) == 0 );
140  if ( use_network ) {
141  WAR << "network backend manually enabled." << endl;
142  zyppng::MediaHandlerNetwork *hdl = new zyppng::MediaHandlerNetwork (url,preferred_attach_point);
143 
144  UrlResolverPlugin::HeaderList::const_iterator it;
145  for ( const auto & el : custom_headers ) {
146  std::string header { el.first };
147  header += ": ";
148  header += el.second;
149  MIL << "Added custom header -> " << header << endl;
150  hdl->settings().addHeader( std::move(header) );
151  }
152  _handler = hdl;
153 
154 
155  } else {
156  bool use_multicurl = true;
157  std::string urlmediahandler ( url.getQueryParam("mediahandler") );
158  if ( urlmediahandler == "multicurl" )
159  {
160  use_multicurl = true;
161  }
162  else if ( urlmediahandler == "curl" )
163  {
164  use_multicurl = false;
165  }
166  else
167  {
168  if ( ! urlmediahandler.empty() )
169  {
170  WAR << "unknown mediahandler set: " << urlmediahandler << endl;
171  }
172  const char *multicurlenv = getenv( "ZYPP_MULTICURL" );
173  // if user disabled it manually
174  if ( use_multicurl && multicurlenv && ( strcmp(multicurlenv, "0" ) == 0 ) )
175  {
176  WAR << "multicurl manually disabled." << endl;
177  use_multicurl = false;
178  }
179  else if ( !use_multicurl && multicurlenv && ( strcmp(multicurlenv, "1" ) == 0 ) )
180  {
181  WAR << "multicurl manually enabled." << endl;
182  use_multicurl = true;
183  }
184  }
185 
186  MediaCurl *curl;
187 
188  if ( use_multicurl )
189  curl = new MediaMultiCurl (url,preferred_attach_point);
190  else
191  curl = new MediaCurl (url,preferred_attach_point);
192 
193  for ( const auto & el : custom_headers ) {
194  std::string header { el.first };
195  header += ": ";
196  header += el.second;
197  MIL << "Added custom header -> " << header << endl;
198  curl->settings().addHeader( std::move(header) );
199  }
200  _handler = curl;
201  }
202  }
203  else if (scheme == "plugin" )
204  _handler = new MediaPlugin (url,preferred_attach_point);
205  else
206  {
208  }
209 
210  // check created handler
211  if ( !_handler ){
212  ERR << "Failed to create media handler" << endl;
213  ZYPP_THROW(MediaSystemException(url, "Failed to create media handler"));
214  }
215 
216  MIL << "Opened: " << *this << endl;
217 }
218 
219 // Type of media if open, otherwise NONE.
220 std::string
222 {
223  if ( !_handler )
224  return "unknown";
225 
226  return _handler->protocol();
227 }
228 
229 bool
231 {
232  return _handler ? _handler->downloads() : false;
233 }
234 
236 //
237 //
238 // METHOD NAME : MediaAccess::url
239 // METHOD TYPE : Url
240 //
242 {
243  if ( !_handler )
244  return Url();
245 
246  return _handler->url();
247 }
248 
249 // close handler
250 void
252 {
254  // !!! make shure handler gets properly deleted.
255  // I.e. release attached media before deleting the handler.
257  if ( _handler ) {
258  try {
259  _handler->release();
260  }
261  catch (const MediaException & excpt_r)
262  {
263  ZYPP_CAUGHT(excpt_r);
264  WAR << "Close: " << *this << " (" << excpt_r << ")" << endl;
265  ZYPP_RETHROW(excpt_r);
266  }
267  MIL << "Close: " << *this << " (OK)" << endl;
268  delete _handler;
269  _handler = 0;
270  }
271 }
272 
273 
274 // attach media
275 void MediaAccess::attach (bool next)
276 {
277  if ( !_handler ) {
279  }
280  _handler->attach(next);
281 }
282 
283 // True if media is open and attached.
284 bool
286 {
287  return( _handler && _handler->isAttached() );
288 }
289 
290 
292 {
293  return _handler && _handler->hasMoreDevices();
294 }
295 
296 
297 void
298 MediaAccess::getDetectedDevices(std::vector<std::string> & devices,
299  unsigned int & index) const
300 {
301  if (_handler)
302  {
303  _handler->getDetectedDevices(devices, index);
304  return;
305  }
306 
307  if (!devices.empty())
308  devices.clear();
309  index = 0;
310 }
311 
312 
313 // local directory that corresponds to medias url
314 // If media is not open an empty pathname.
315 Pathname
317 {
318  if ( !_handler )
319  return _noPath;
320 
321  return _handler->localRoot();
322 }
323 
324 // Short for 'localRoot() + pathname', but returns an empty
325 // * pathname if media is not open.
326 Pathname
327 MediaAccess::localPath( const Pathname & pathname ) const
328 {
329  if ( !_handler )
330  return _noPath;
331 
332  return _handler->localPath( pathname );
333 }
334 
335 void
337 {
338  if ( !_handler )
339  ZYPP_THROW(MediaNotOpenException("disconnect"));
340 
341  _handler->disconnect();
342 }
343 
344 
345 void
346 MediaAccess::release( const std::string & ejectDev )
347 {
348  if ( !_handler )
349  return;
350 
351  _handler->release( ejectDev );
352 }
353 
354 // provide file denoted by path to attach dir
355 //
356 // filename is interpreted relative to the attached url
357 // and a path prefix is preserved to destination
358 void
359 MediaAccess::provideFile(const Pathname & filename , const ByteCount &expectedFileSize) const
360 {
361  if ( !_handler ) {
362  ZYPP_THROW(MediaNotOpenException("provideFile(" + filename.asString() + ")"));
363  }
364 
365  _handler->provideFile( filename, expectedFileSize );
366 }
367 
368 void
369 MediaAccess::setDeltafile( const Pathname & filename ) const
370 {
371  if ( !_handler ) {
372  ZYPP_THROW(MediaNotOpenException("setDeltafile(" + filename.asString() + ")"));
373  }
374 
375  _handler->setDeltafile( filename );
376 }
377 
378 void
379 MediaAccess::releaseFile( const Pathname & filename ) const
380 {
381  if ( !_handler )
382  return;
383 
384  _handler->releaseFile( filename );
385 }
386 
387 // provide directory tree denoted by path to attach dir
388 //
389 // dirname is interpreted relative to the attached url
390 // and a path prefix is preserved to destination
391 void
392 MediaAccess::provideDir( const Pathname & dirname ) const
393 {
394  if ( !_handler ) {
395  ZYPP_THROW(MediaNotOpenException("provideDir(" + dirname.asString() + ")"));
396  }
397 
398  _handler->provideDir( dirname );
399 }
400 
401 void
402 MediaAccess::provideDirTree( const Pathname & dirname ) const
403 {
404  if ( !_handler ) {
405  ZYPP_THROW(MediaNotOpenException("provideDirTree(" + dirname.asString() + ")"));
406  }
407 
408  _handler->provideDirTree( dirname );
409 }
410 
411 void
412 MediaAccess::releaseDir( const Pathname & dirname ) const
413 {
414  if ( !_handler )
415  return;
416 
417  _handler->releaseDir( dirname );
418 }
419 
420 void
421 MediaAccess::releasePath( const Pathname & pathname ) const
422 {
423  if ( !_handler )
424  return;
425 
426  _handler->releasePath( pathname );
427 }
428 
429 // Return content of directory on media
430 void
431 MediaAccess::dirInfo( std::list<std::string> & retlist, const Pathname & dirname, bool dots ) const
432 {
433  retlist.clear();
434 
435  if ( !_handler ) {
436  ZYPP_THROW(MediaNotOpenException("dirInfo(" + dirname.asString() + ")"));
437  }
438 
439  _handler->dirInfo( retlist, dirname, dots );
440 }
441 
442 // Return content of directory on media
443 void
444 MediaAccess::dirInfo( filesystem::DirContent & retlist, const Pathname & dirname, bool dots ) const
445 {
446  retlist.clear();
447 
448  if ( !_handler ) {
449  ZYPP_THROW(MediaNotOpenException("dirInfo(" + dirname.asString() + ")"));
450  }
451 
452  _handler->dirInfo( retlist, dirname, dots );
453 }
454 
455 // return if a file exists
456 bool
457 MediaAccess::doesFileExist( const Pathname & filename ) const
458 {
459  if ( !_handler ) {
460  ZYPP_THROW(MediaNotOpenException("doesFileExist(" + filename.asString() + ")"));
461  }
462 
463  return _handler->doesFileExist( filename );
464 }
465 
466 void MediaAccess::precacheFiles(const std::vector<OnMediaLocation> &files)
467 {
468  if ( !_handler ) {
469  ZYPP_THROW(MediaNotOpenException("precacheFiles()"));
470  }
471 
472  return _handler->precacheFiles( files );
473 }
474 
475 std::ostream &
476 MediaAccess::dumpOn( std::ostream & str ) const
477 {
478  if ( !_handler )
479  return str << "MediaAccess( closed )";
480 
481  str << _handler->protocol() << "(" << *_handler << ")";
482  return str;
483 }
484 
485 void MediaAccess::getFile( const Url &from, const Pathname &to )
486 {
487  DBG << "From: " << from << endl << "To: " << to << endl;
488 
489  Pathname path = from.getPathData();
490  Pathname dir = path.dirname();
491  std::string base = path.basename();
492 
493  Url u = from;
494  u.setPathData( dir.asString() );
495 
496  MediaAccess media;
497 
498  try {
499  media.open( u );
500  media.attach();
501  media._handler->provideFileCopy( base, to, 0 );
502  media.release();
503  }
504  catch (const MediaException & excpt_r)
505  {
506  ZYPP_RETHROW(excpt_r);
507  }
508 }
509 
510  std::ostream & operator<<( std::ostream & str, const MediaAccess & obj )
511  { return obj.dumpOn( str ); }
512 
514  } // namespace media
515 } // namespace zypp
std::string getScheme() const
Returns the scheme name of the URL.
Definition: Url.cc:528
MediaAccess()
constructor
Definition: MediaAccess.cc:54
Implementation class for NFS MediaHandler.
Definition: MediaNFS.h:36
void resetParentId()
Called in case, where the media manager takes over the destruction of the parent id (e...
#define MIL
Definition: Logger.h:79
void open(const Url &url, const Pathname &preferred_attach_point="")
open url.
Definition: MediaAccess.cc:105
void close()
close url
Definition: MediaAccess.cc:251
void addHeader(std::string &&val_r)
add a header, on the form "Foo: Bar"
Pathname localRoot() const
Return the local directory that corresponds to medias url, no matter if media isAttached or not...
Definition: MediaAccess.cc:316
void provideDirTree(const Pathname &dirname) const
Use concrete handler to provide directory tree denoted by path below &#39;attach point&#39; (recursive!!)...
Definition: MediaAccess.cc:402
#define ZYPP_THROW(EXCPT)
Drops a logline and throws the Exception.
Definition: Exception.h:392
Implementation class for CD/DVD MediaHandler.
Definition: MediaCD.h:28
Implementation class for FTP, HTTP and HTTPS MediaHandler.
Definition: MediaCurl.h:31
Handle access to a medium.
Definition: MediaAccess.h:51
void setDeltafile(const Pathname &filename) const
set a deltafile to be used in the next download
Definition: MediaAccess.cc:369
std::string protocol() const
Used Protocol if media is opened, otherwise &#39;unknown&#39;.
Definition: MediaAccess.cc:221
AttachedMedia attachedMedia() const
Returns the attached media.
Store and operate with byte count.
Definition: ByteCount.h:30
TransferSettings & settings()
Definition: MediaCurl.cc:107
static Url resolveUrl(const Url &url, HeaderList &headers)
Resolves an url using the installed plugins If no plugin is found the url is resolved as its current ...
std::string protocol() const
Protocol hint for MediaAccess.
Definition: MediaHandler.h:516
void disconnect()
Use concrete handler to disconnect the media.
Definition: MediaAccess.cc:336
Pathname localPath(const Pathname &pathname) const
Short for &#39;localRoot() + pathname&#39;, but returns an empty pathname if media is not open...
Definition: MediaAccess.cc:327
void release(const std::string &ejectDev="")
Use concrete handler to release the media.
Definition: MediaAccess.cc:346
bool isSharedMedia() const
Definition: MediaAccess.cc:77
void dirInfo(std::list< std::string > &retlist, const Pathname &dirname, bool dots=true) const
Return content of directory on media via retlist.
Url url() const
Url if media is opened, otherwise empty.
Definition: MediaAccess.cc:241
String related utilities and Regular expression matching.
Implementation class for DISK MediaHandler.
Definition: MediaDISK.h:27
void provideDir(Pathname dirname) const
Use concrete handler to provide directory denoted by path below &#39;localRoot&#39; (not recursive!).
void releasePath(Pathname pathname) const
Remove pathname below localRoot IFF handler downloads files to the local filesystem.
std::string basename() const
Return the last component of this path.
Definition: Pathname.h:128
void setDeltafile(const Pathname &filename=Pathname()) const
bool doesFileExist(const Pathname &filename) const
check if a file exists
#define ERR
Definition: Logger.h:81
unsigned int MediaAccessId
Media manager access Id type.
Definition: MediaSource.h:29
void provideFile(const Pathname &filename, const ByteCount &expectedFileSize) const
Use concrete handler to provide file denoted by path below &#39;attach point&#39;.
Definition: MediaAccess.cc:359
Pathname localPath(const Pathname &pathname) const
Files provided will be available at &#39;localPath(filename)&#39;.
std::ostream & operator<<(std::ostream &str, const MediaAccess &obj)
Definition: MediaAccess.cc:510
MediaHandler * _handler
handler for &#39;physical&#39; media == 0 if not open
Definition: MediaAccess.h:65
bool hasMoreDevices() const
Definition: MediaAccess.cc:291
void provideDir(const Pathname &dirname) const
Use concrete handler to provide directory denoted by path below &#39;attach point&#39; (not recursive!)...
Definition: MediaAccess.cc:392
void releaseDir(const Pathname &dirname) const
Remove directory tree below localRoot IFF handler downloads files to the local filesystem.
Definition: MediaHandler.h:641
virtual std::ostream & dumpOn(std::ostream &str) const
Overload to realize std::ostream & operator<<.
Definition: MediaAccess.cc:476
#define ZYPP_RETHROW(EXCPT)
Drops a logline and rethrows, updating the CodeLocation.
Definition: Exception.h:400
std::string getPathData() const
Returns the encoded path component of the URL.
Definition: Url.cc:543
Implementation class for CIFS MediaHandler.
Definition: MediaCIFS.h:32
void provideDirTree(Pathname dirname) const
Use concrete handler to provide directory tree denoted by path below &#39;localRoot&#39; (recursive!!).
std::string getQueryParam(const std::string &param, EEncoding eflag=zypp::url::E_DECODED) const
Return the value for the specified query parameter.
Definition: Url.cc:655
Implementation class for DIR MediaHandler.
Definition: MediaDIR.h:28
A simple structure containing references to a media source and its attach point.
Definition: MediaSource.h:133
virtual ~MediaAccess()
Destructor.
Definition: MediaAccess.cc:60
const std::string & asString() const
String representation.
Definition: Pathname.h:91
Just inherits Exception to separate media exceptions.
void disconnect()
Use concrete handler to isconnect media.
void attach(bool next)
Use concrete handler to attach the media.
Pathname dirname() const
Return all but the last component od this path.
Definition: Pathname.h:124
bool isSharedMedia() const
Returns a hint if the media is shared or not.
#define WAR
Definition: Logger.h:80
void setPathData(const std::string &pathdata)
Set the path data component in the URL.
Definition: Url.cc:701
std::list< DirEntry > DirContent
Returned by readdir.
Definition: PathInfo.h:547
bool downloads() const
Hint if files are downloaded or not.
Definition: MediaAccess.cc:230
void releaseDir(const Pathname &dirname) const
Remove directory tree below attach point IFF handler downloads files to the local filesystem...
Definition: MediaAccess.cc:412
void attach(bool next=false)
Use concrete handler to attach the media.
Definition: MediaAccess.cc:275
static const Pathname _noPath
Definition: MediaAccess.h:59
virtual bool hasMoreDevices()
Check if the media has one more device available for attach(true).
bool isValid() const
Verifies the Url.
Definition: Url.cc:484
void releaseFile(const Pathname &filename) const
Remove filename below attach point IFF handler downloads files to the local filesystem.
Definition: MediaAccess.cc:379
void provideFile(Pathname filename, const ByteCount &expectedFileSize_r) const
Use concrete handler to provide file denoted by path below &#39;localRoot&#39;.
bool doesFileExist(const Pathname &filename) const
check if a file exists
Definition: MediaAccess.cc:457
virtual void precacheFiles(const std::vector< OnMediaLocation > &files)
Tries to fetch the given files and precaches them.
Pathname localRoot() const
Return the local directory that corresponds to medias url, no matter if media isAttached or not...
#define ZYPP_CAUGHT(EXCPT)
Drops a logline telling the Exception was caught (in order to handle it).
Definition: Exception.h:396
void releaseFile(const Pathname &filename) const
Remove filename below localRoot IFF handler downloads files to the local filesystem.
Definition: MediaHandler.h:632
bool downloads() const
Hint if files are downloaded or not.
Definition: MediaHandler.h:511
bool dependsOnParent(MediaAccessId parentId, bool exactIdMatch)
Check if the current media handler depends on an another handler specified by media access id...
bool isAttached() const
True if media is attached.
Definition: MediaAccess.cc:285
Url url() const
Url used.
Definition: MediaHandler.h:521
virtual void getDetectedDevices(std::vector< std::string > &devices, unsigned int &index) const
Fill in a vector of detected ejectable devices and the index of the currently attached device within ...
void precacheFiles(const std::vector< OnMediaLocation > &files)
Definition: MediaAccess.cc:466
void releasePath(const Pathname &pathname) const
Remove pathname below attach point IFF handler downloads files to the local filesystem.
Definition: MediaAccess.cc:421
std::multimap< std::string, std::string > HeaderList
Implementation class for plugin MediaHandler.
Definition: MediaPlugin.h:29
AttachedMedia attachedMedia() const
Definition: MediaAccess.cc:70
virtual void getDetectedDevices(std::vector< std::string > &devices, unsigned int &index) const
Fill in a vector of detected ejectable devices and the index of the currently attached device within ...
Definition: MediaAccess.cc:298
virtual bool isAttached() const
True if media is attached.
Definition: MediaHandler.h:538
Easy-to use interface to the ZYPP dependency resolver.
Definition: CodePitfalls.doc:1
void release(const std::string &ejectDev="")
Use concrete handler to release the media.
bool dependsOnParent() const
Definition: MediaAccess.cc:90
Implementation class for ISO MediaHandler.
Definition: MediaISO.h:35
void dirInfo(std::list< std::string > &retlist, const Pathname &dirname, bool dots=true) const
Return content of directory on media via retlist.
Definition: MediaAccess.cc:431
Url manipulation class.
Definition: Url.h:87
#define DBG
Definition: Logger.h:78
void getFile(const Url &from, const Pathname &to)
Get file from location at specified by URL and copy it to destination.
Definition: MediaAccess.cc:485
void provideFileCopy(Pathname srcFilename, Pathname targetFilename, const ByteCount &expectedFileSize_r) const
Call concrete handler to provide a copy of a file under a different place in the file system (usually...