libzypp  15.28.6
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 
38 using namespace std;
39 
40 namespace zypp {
41  namespace media {
42 
44 //
45 // CLASS NAME : MediaAccess
46 //
48 
49 const Pathname MediaAccess::_noPath; // empty path
50 
52 // constructor
53 MediaAccess::MediaAccess ()
54  : _handler (0)
55 {
56 }
57 
58 // destructor
60 {
61  try
62  {
63  close(); // !!! make sure handler gets properly deleted.
64  }
65  catch(...) {}
66 }
67 
70 {
71  return _handler ? _handler->attachedMedia()
72  : AttachedMedia();
73 }
74 
75 bool
77 {
78  return _handler ? _handler->isSharedMedia()
79  : false;
80 }
81 
82 void
84 {
86 }
87 
88 bool
90 {
91  return _handler ? _handler->dependsOnParent() : false;
92 }
93 
94 bool
96  bool exactIdMatch) const
97 {
98  return _handler ? _handler->dependsOnParent(parentId, exactIdMatch)
99  : false;
100 }
101 
102 // open URL
103 void
104 MediaAccess::open (const Url& o_url, const Pathname & preferred_attach_point)
105 {
106  if(!o_url.isValid()) {
107  MIL << "Url is not valid" << endl;
109  }
110 
111  close();
112 
113  UrlResolverPlugin::HeaderList custom_headers;
114  Url url = UrlResolverPlugin::resolveUrl(o_url, custom_headers);
115 
116  std::string scheme = url.getScheme();
117  MIL << "Trying scheme '" << scheme << "'" << endl;
118 
119  /*
120  ** WARNING: Don't forget to update MediaAccess::downloads(url)
121  ** if you are adding a new url scheme / handler!
122  */
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")
136  {
137  bool use_multicurl = true;
138  string urlmediahandler ( url.getQueryParam("mediahandler") );
139  if ( urlmediahandler == "multicurl" )
140  {
141  use_multicurl = true;
142  }
143  else if ( urlmediahandler == "curl" )
144  {
145  use_multicurl = false;
146  }
147  else
148  {
149  if ( ! urlmediahandler.empty() )
150  {
151  WAR << "unknown mediahandler set: " << urlmediahandler << endl;
152  }
153  const char *multicurlenv = getenv( "ZYPP_MULTICURL" );
154  // if user disabled it manually
155  if ( use_multicurl && multicurlenv && ( strcmp(multicurlenv, "0" ) == 0 ) )
156  {
157  WAR << "multicurl manually disabled." << endl;
158  use_multicurl = false;
159  }
160  else if ( !use_multicurl && multicurlenv && ( strcmp(multicurlenv, "1" ) == 0 ) )
161  {
162  WAR << "multicurl manually enabled." << endl;
163  use_multicurl = true;
164  }
165  }
166 
167  MediaCurl *curl;
168 
169  if ( use_multicurl )
170  curl = new MediaMultiCurl (url,preferred_attach_point);
171  else
172  curl = new MediaCurl (url,preferred_attach_point);
173 
174  UrlResolverPlugin::HeaderList::const_iterator it;
175  for (it = custom_headers.begin();
176  it != custom_headers.end();
177  ++it) {
178  std::string header = it->first + ": " + it->second;
179  MIL << "Added custom header -> " << header << endl;
180  curl->settings().addHeader(header);
181  }
182  _handler = curl;
183  }
184  else if (scheme == "plugin" )
185  _handler = new MediaPlugin (url,preferred_attach_point);
186  else
187  {
189  }
190 
191  // check created handler
192  if ( !_handler ){
193  ERR << "Failed to create media handler" << endl;
194  ZYPP_THROW(MediaSystemException(url, "Failed to create media handler"));
195  }
196 
197  MIL << "Opened: " << *this << endl;
198 }
199 
200 // Type of media if open, otherwise NONE.
201 std::string
203 {
204  if ( !_handler )
205  return "unknown";
206 
207  return _handler->protocol();
208 }
209 
210 bool
212 {
213  return _handler ? _handler->downloads() : false;
214 }
215 
217 //
218 //
219 // METHOD NAME : MediaAccess::url
220 // METHOD TYPE : Url
221 //
223 {
224  if ( !_handler )
225  return Url();
226 
227  return _handler->url();
228 }
229 
230 // close handler
231 void
233 {
235  // !!! make shure handler gets properly deleted.
236  // I.e. release attached media before deleting the handler.
238  if ( _handler ) {
239  try {
240  _handler->release();
241  }
242  catch (const MediaException & excpt_r)
243  {
244  ZYPP_CAUGHT(excpt_r);
245  WAR << "Close: " << *this << " (" << excpt_r << ")" << endl;
246  ZYPP_RETHROW(excpt_r);
247  }
248  MIL << "Close: " << *this << " (OK)" << endl;
249  delete _handler;
250  _handler = 0;
251  }
252 }
253 
254 
255 // attach media
256 void MediaAccess::attach (bool next)
257 {
258  if ( !_handler ) {
260  }
261  _handler->attach(next);
262 }
263 
264 // True if media is open and attached.
265 bool
267 {
268  return( _handler && _handler->isAttached() );
269 }
270 
271 
273 {
274  return _handler && _handler->hasMoreDevices();
275 }
276 
277 
278 void
279 MediaAccess::getDetectedDevices(std::vector<std::string> & devices,
280  unsigned int & index) const
281 {
282  if (_handler)
283  {
284  _handler->getDetectedDevices(devices, index);
285  return;
286  }
287 
288  if (!devices.empty())
289  devices.clear();
290  index = 0;
291 }
292 
293 
294 // local directory that corresponds to medias url
295 // If media is not open an empty pathname.
296 Pathname
298 {
299  if ( !_handler )
300  return _noPath;
301 
302  return _handler->localRoot();
303 }
304 
305 // Short for 'localRoot() + pathname', but returns an empty
306 // * pathname if media is not open.
307 Pathname
308 MediaAccess::localPath( const Pathname & pathname ) const
309 {
310  if ( !_handler )
311  return _noPath;
312 
313  return _handler->localPath( pathname );
314 }
315 
316 void
318 {
319  if ( !_handler )
320  ZYPP_THROW(MediaNotOpenException("disconnect"));
321 
322  _handler->disconnect();
323 }
324 
325 
326 void
327 MediaAccess::release( const std::string & ejectDev )
328 {
329  if ( !_handler )
330  return;
331 
332  _handler->release( ejectDev );
333 }
334 
335 // provide file denoted by path to attach dir
336 //
337 // filename is interpreted relative to the attached url
338 // and a path prefix is preserved to destination
339 void
340 MediaAccess::provideFile(const Pathname & filename , const ByteCount &expectedFileSize) const
341 {
342  if ( !_handler ) {
343  ZYPP_THROW(MediaNotOpenException("provideFile(" + filename.asString() + ")"));
344  }
345 
346  _handler->provideFile( filename, expectedFileSize );
347 }
348 
349 void
350 MediaAccess::setDeltafile( const Pathname & filename ) const
351 {
352  if ( !_handler ) {
353  ZYPP_THROW(MediaNotOpenException("setDeltafile(" + filename.asString() + ")"));
354  }
355 
356  _handler->setDeltafile( filename );
357 }
358 
359 void
360 MediaAccess::releaseFile( const Pathname & filename ) const
361 {
362  if ( !_handler )
363  return;
364 
365  _handler->releaseFile( filename );
366 }
367 
368 // provide directory tree denoted by path to attach dir
369 //
370 // dirname is interpreted relative to the attached url
371 // and a path prefix is preserved to destination
372 void
373 MediaAccess::provideDir( const Pathname & dirname ) const
374 {
375  if ( !_handler ) {
376  ZYPP_THROW(MediaNotOpenException("provideDir(" + dirname.asString() + ")"));
377  }
378 
379  _handler->provideDir( dirname );
380 }
381 
382 void
383 MediaAccess::provideDirTree( const Pathname & dirname ) const
384 {
385  if ( !_handler ) {
386  ZYPP_THROW(MediaNotOpenException("provideDirTree(" + dirname.asString() + ")"));
387  }
388 
389  _handler->provideDirTree( dirname );
390 }
391 
392 void
393 MediaAccess::releaseDir( const Pathname & dirname ) const
394 {
395  if ( !_handler )
396  return;
397 
398  _handler->releaseDir( dirname );
399 }
400 
401 void
402 MediaAccess::releasePath( const Pathname & pathname ) const
403 {
404  if ( !_handler )
405  return;
406 
407  _handler->releasePath( pathname );
408 }
409 
410 // Return content of directory on media
411 void
412 MediaAccess::dirInfo( std::list<std::string> & retlist, const Pathname & dirname, bool dots ) const
413 {
414  retlist.clear();
415 
416  if ( !_handler ) {
417  ZYPP_THROW(MediaNotOpenException("dirInfo(" + dirname.asString() + ")"));
418  }
419 
420  _handler->dirInfo( retlist, dirname, dots );
421 }
422 
423 // Return content of directory on media
424 void
425 MediaAccess::dirInfo( filesystem::DirContent & retlist, const Pathname & dirname, bool dots ) const
426 {
427  retlist.clear();
428 
429  if ( !_handler ) {
430  ZYPP_THROW(MediaNotOpenException("dirInfo(" + dirname.asString() + ")"));
431  }
432 
433  _handler->dirInfo( retlist, dirname, dots );
434 }
435 
436 // return if a file exists
437 bool
438 MediaAccess::doesFileExist( const Pathname & filename ) const
439 {
440  if ( !_handler ) {
441  ZYPP_THROW(MediaNotOpenException("doesFileExist(" + filename.asString() + ")"));
442  }
443 
444  return _handler->doesFileExist( filename );
445 }
446 
447 std::ostream &
448 MediaAccess::dumpOn( std::ostream & str ) const
449 {
450  if ( !_handler )
451  return str << "MediaAccess( closed )";
452 
453  str << _handler->protocol() << "(" << *_handler << ")";
454  return str;
455 }
456 
457 void MediaAccess::getFile( const Url &from, const Pathname &to )
458 {
459  DBG << "From: " << from << endl << "To: " << to << endl;
460 
461  Pathname path = from.getPathData();
462  Pathname dir = path.dirname();
463  string base = path.basename();
464 
465  Url u = from;
466  u.setPathData( dir.asString() );
467 
468  MediaAccess media;
469 
470  try {
471  media.open( u );
472  media.attach();
473  media._handler->provideFileCopy( base, to, 0 );
474  media.release();
475  }
476  catch (const MediaException & excpt_r)
477  {
478  ZYPP_RETHROW(excpt_r);
479  }
480 }
481 
482  std::ostream & operator<<( std::ostream & str, const MediaAccess & obj )
483  { return obj.dumpOn( str ); }
484 
486  } // namespace media
487 } // namespace zypp
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:412
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:64
void open(const Url &url, const Pathname &preferred_attach_point="")
open url.
Definition: MediaAccess.cc:104
void close()
close url
Definition: MediaAccess.cc:232
void provideDir(const Pathname &dirname) const
Use concrete handler to provide directory denoted by path below 'attach point' (not recursive!)...
Definition: MediaAccess.cc:373
Url url() const
Url if media is opened, otherwise empty.
Definition: MediaAccess.cc:222
#define ZYPP_THROW(EXCPT)
Drops a logline and throws the Exception.
Definition: Exception.h:321
std::string getPathData() const
Returns the encoded path component of the URL.
Definition: Url.cc:542
bool isSharedMedia() const
Returns a hint if the media is shared or not.
Implementation class for CD/DVD MediaHandler.
Definition: MediaCD.h:28
Implementation class for FTP, HTTP and HTTPS MediaHandler.
Definition: MediaCurl.h:32
Handle access to a medium.
Definition: MediaAccess.h:50
std::string protocol() const
Used Protocol if media is opened, otherwise 'unknown'.
Definition: MediaAccess.cc:202
void provideDirTree(const Pathname &dirname) const
Use concrete handler to provide directory tree denoted by path below 'attach point' (recursive!!)...
Definition: MediaAccess.cc:383
Store and operate with byte count.
Definition: ByteCount.h:30
TransferSettings & settings()
Definition: MediaCurl.cc:599
bool downloads() const
Hint if files are downloaded or not.
Definition: MediaHandler.h:496
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 ...
bool downloads() const
Hint if files are downloaded or not.
Definition: MediaAccess.cc:211
void disconnect()
Use concrete handler to disconnect the media.
Definition: MediaAccess.cc:317
bool doesFileExist(const Pathname &filename) const
check if a file exists
void release(const std::string &ejectDev="")
Use concrete handler to release the media.
Definition: MediaAccess.cc:327
void releaseDir(const Pathname &dirname) const
Remove directory tree below attach point IFF handler downloads files to the local filesystem...
Definition: MediaAccess.cc:393
bool doesFileExist(const Pathname &filename) const
check if a file exists
Definition: MediaAccess.cc:438
Implementation class for DISK MediaHandler.
Definition: MediaDISK.h:27
bool isValid() const
Verifies the Url.
Definition: Url.cc:483
void provideDirTree(Pathname dirname) const
Use concrete handler to provide directory tree denoted by path below 'localRoot' (recursive!!).
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:279
Pathname localRoot() const
Return the local directory that corresponds to medias url, no matter if media isAttached or not...
Definition: MediaAccess.cc:297
#define ERR
Definition: Logger.h:66
unsigned int MediaAccessId
Media manager access Id type.
Definition: MediaSource.h:29
void releaseDir(const Pathname &dirname) const
Remove directory tree below localRoot IFF handler downloads files to the local filesystem.
Definition: MediaHandler.h:626
void dirInfo(std::list< std::string > &retlist, const Pathname &dirname, bool dots=true) const
Return content of directory on media via retlist.
std::ostream & operator<<(std::ostream &str, const MediaAccess &obj)
Definition: MediaAccess.cc:482
MediaHandler * _handler
handler for 'physical' media == 0 if not open
Definition: MediaAccess.h:64
#define ZYPP_RETHROW(EXCPT)
Drops a logline and rethrows, updating the CodeLocation.
Definition: Exception.h:329
bool isSharedMedia() const
Definition: MediaAccess.cc:76
Implementation class for CIFS MediaHandler.
Definition: MediaCIFS.h:32
void releaseFile(const Pathname &filename) const
Remove filename below attach point IFF handler downloads files to the local filesystem.
Definition: MediaAccess.cc:360
AttachedMedia attachedMedia() const
Returns the attached media.
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:59
Just inherits Exception to separate media exceptions.
void provideFile(Pathname filename, const ByteCount &expectedFileSize_r) const
Use concrete handler to provide file denoted by path below 'localRoot'.
void disconnect()
Use concrete handler to isconnect media.
void attach(bool next)
Use concrete handler to attach the media.
#define WAR
Definition: Logger.h:65
void provideFile(const Pathname &filename, const ByteCount &expectedFileSize) const
Use concrete handler to provide file denoted by path below 'attach point'.
Definition: MediaAccess.cc:340
void setDeltafile(const Pathname &filename=Pathname()) const
void releasePath(Pathname pathname) const
Remove pathname below localRoot IFF handler downloads files to the local filesystem.
void setPathData(const std::string &pathdata)
Set the path data component in the URL.
Definition: Url.cc:700
std::list< DirEntry > DirContent
Returned by readdir.
Definition: PathInfo.h:547
AttachedMedia attachedMedia() const
Definition: MediaAccess.cc:69
bool dependsOnParent() const
Definition: MediaAccess.cc:89
void attach(bool next=false)
Use concrete handler to attach the media.
Definition: MediaAccess.cc:256
static const Pathname _noPath
Definition: MediaAccess.h:58
virtual std::ostream & dumpOn(std::ostream &str) const
Overload to realize std::ostream & operator<<.
Definition: MediaAccess.cc:448
Pathname localPath(const Pathname &pathname) const
Files provided will be available at 'localPath(filename)'.
virtual bool hasMoreDevices()
Check if the media has one more device available for attach(true).
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:654
void setDeltafile(const Pathname &filename) const
set a deltafile to be used in the next download
Definition: MediaAccess.cc:350
virtual bool isAttached() const
True if media is attached.
Definition: MediaHandler.h:523
bool isAttached() const
True if media is attached.
Definition: MediaAccess.cc:266
Pathname localPath(const Pathname &pathname) const
Short for 'localRoot() + pathname', but returns an empty pathname if media is not open...
Definition: MediaAccess.cc:308
#define ZYPP_CAUGHT(EXCPT)
Drops a logline telling the Exception was caught (in order to handle it).
Definition: Exception.h:325
bool dependsOnParent(MediaAccessId parentId, bool exactIdMatch)
Check if the current media handler depends on an another handler specified by media access id...
void addHeader(const std::string &header)
add a header, on the form "Foo: Bar"
CURL * curl
Definition: MediaCurl.cc:179
std::string protocol() const
Protocol hint for MediaAccess.
Definition: MediaHandler.h:501
Pathname localRoot() const
Return the local directory that corresponds to medias url, no matter if media isAttached or not...
void releasePath(const Pathname &pathname) const
Remove pathname below attach point IFF handler downloads files to the local filesystem.
Definition: MediaAccess.cc:402
std::multimap< std::string, std::string > HeaderList
std::string getScheme() const
Returns the scheme name of the URL.
Definition: Url.cc:527
Implementation class for plugin MediaHandler.
Definition: MediaPlugin.h:29
void releaseFile(const Pathname &filename) const
Remove filename below localRoot IFF handler downloads files to the local filesystem.
Definition: MediaHandler.h:617
bool hasMoreDevices() const
Definition: MediaAccess.cc:272
void release(const std::string &ejectDev="")
Use concrete handler to release the media.
void provideDir(Pathname dirname) const
Use concrete handler to provide directory denoted by path below 'localRoot' (not recursive!).
Implementation class for ISO MediaHandler.
Definition: MediaISO.h:35
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 ...
Url url() const
Url used.
Definition: MediaHandler.h:506
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...
Url manipulation class.
Definition: Url.h:87
#define DBG
Definition: Logger.h:63
void getFile(const Url &from, const Pathname &to)
Get file from location at specified by URL and copy it to destination.
Definition: MediaAccess.cc:457