libzypp 17.25.7
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>
22
26
27#include <zypp/media/MediaNFS.h>
28#include <zypp/media/MediaCD.h>
29#include <zypp/media/MediaDIR.h>
34#include <zypp/media/MediaISO.h>
37
38using std::endl;
39
40namespace zypp {
41 namespace media {
42
44//
45// CLASS NAME : MediaAccess
46//
48
49const Pathname MediaAccess::_noPath; // empty path
50
52// constructor
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{
72 : AttachedMedia();
73}
74
75bool
77{
79 : false;
80}
81
82void
84{
86}
87
88bool
90{
91 return _handler ? _handler->dependsOnParent() : false;
92}
93
94bool
96 bool exactIdMatch) const
97{
98 return _handler ? _handler->dependsOnParent(parentId, exactIdMatch)
99 : false;
100}
101
102// open URL
103void
104MediaAccess::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 std::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
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 for ( const auto & el : custom_headers ) {
175 std::string header { el.first };
176 header += ": ";
177 header += el.second;
178 MIL << "Added custom header -> " << header << endl;
179 curl->settings().addHeader( std::move(header) );
180 }
181 _handler = curl;
182 }
183 else if (scheme == "plugin" )
184 _handler = new MediaPlugin (url,preferred_attach_point);
185 else
186 {
188 }
189
190 // check created handler
191 if ( !_handler ){
192 ERR << "Failed to create media handler" << endl;
193 ZYPP_THROW(MediaSystemException(url, "Failed to create media handler"));
194 }
195
196 MIL << "Opened: " << *this << endl;
197}
198
199// Type of media if open, otherwise NONE.
200std::string
202{
203 if ( !_handler )
204 return "unknown";
205
206 return _handler->protocol();
207}
208
209bool
211{
212 return _handler ? _handler->downloads() : false;
213}
214
216//
217//
218// METHOD NAME : MediaAccess::url
219// METHOD TYPE : Url
220//
222{
223 if ( !_handler )
224 return Url();
225
226 return _handler->url();
227}
228
229// close handler
230void
232{
234 // !!! make shure handler gets properly deleted.
235 // I.e. release attached media before deleting the handler.
237 if ( _handler ) {
238 try {
239 _handler->release();
240 }
241 catch (const MediaException & excpt_r)
242 {
243 ZYPP_CAUGHT(excpt_r);
244 WAR << "Close: " << *this << " (" << excpt_r << ")" << endl;
245 ZYPP_RETHROW(excpt_r);
246 }
247 MIL << "Close: " << *this << " (OK)" << endl;
248 delete _handler;
249 _handler = 0;
250 }
251}
252
253
254// attach media
255void MediaAccess::attach (bool next)
256{
257 if ( !_handler ) {
259 }
260 _handler->attach(next);
261}
262
263// True if media is open and attached.
264bool
266{
267 return( _handler && _handler->isAttached() );
268}
269
270
272{
273 return _handler && _handler->hasMoreDevices();
274}
275
276
277void
278MediaAccess::getDetectedDevices(std::vector<std::string> & devices,
279 unsigned int & index) const
280{
281 if (_handler)
282 {
283 _handler->getDetectedDevices(devices, index);
284 return;
285 }
286
287 if (!devices.empty())
288 devices.clear();
289 index = 0;
290}
291
292
293// local directory that corresponds to medias url
294// If media is not open an empty pathname.
297{
298 if ( !_handler )
299 return _noPath;
300
301 return _handler->localRoot();
302}
303
304// Short for 'localRoot() + pathname', but returns an empty
305// * pathname if media is not open.
307MediaAccess::localPath( const Pathname & pathname ) const
308{
309 if ( !_handler )
310 return _noPath;
311
312 return _handler->localPath( pathname );
313}
314
315void
317{
318 if ( !_handler )
319 ZYPP_THROW(MediaNotOpenException("disconnect"));
320
322}
323
324
325void
326MediaAccess::release( const std::string & ejectDev )
327{
328 if ( !_handler )
329 return;
330
331 _handler->release( ejectDev );
332}
333
334// provide file denoted by path to attach dir
335//
336// filename is interpreted relative to the attached url
337// and a path prefix is preserved to destination
338void
339MediaAccess::provideFile(const Pathname & filename , const ByteCount &expectedFileSize) const
340{
341 if ( !_handler ) {
342 ZYPP_THROW(MediaNotOpenException("provideFile(" + filename.asString() + ")"));
343 }
344
345 _handler->provideFile( filename, expectedFileSize );
346}
347
348void
349MediaAccess::setDeltafile( const Pathname & filename ) const
350{
351 if ( !_handler ) {
352 ZYPP_THROW(MediaNotOpenException("setDeltafile(" + filename.asString() + ")"));
353 }
354
355 _handler->setDeltafile( filename );
356}
357
358void
359MediaAccess::releaseFile( const Pathname & filename ) const
360{
361 if ( !_handler )
362 return;
363
364 _handler->releaseFile( filename );
365}
366
367// provide directory tree denoted by path to attach dir
368//
369// dirname is interpreted relative to the attached url
370// and a path prefix is preserved to destination
371void
372MediaAccess::provideDir( const Pathname & dirname ) const
373{
374 if ( !_handler ) {
375 ZYPP_THROW(MediaNotOpenException("provideDir(" + dirname.asString() + ")"));
376 }
377
378 _handler->provideDir( dirname );
379}
380
381void
382MediaAccess::provideDirTree( const Pathname & dirname ) const
383{
384 if ( !_handler ) {
385 ZYPP_THROW(MediaNotOpenException("provideDirTree(" + dirname.asString() + ")"));
386 }
387
388 _handler->provideDirTree( dirname );
389}
390
391void
392MediaAccess::releaseDir( const Pathname & dirname ) const
393{
394 if ( !_handler )
395 return;
396
397 _handler->releaseDir( dirname );
398}
399
400void
401MediaAccess::releasePath( const Pathname & pathname ) const
402{
403 if ( !_handler )
404 return;
405
406 _handler->releasePath( pathname );
407}
408
409// Return content of directory on media
410void
411MediaAccess::dirInfo( std::list<std::string> & retlist, const Pathname & dirname, bool dots ) const
412{
413 retlist.clear();
414
415 if ( !_handler ) {
416 ZYPP_THROW(MediaNotOpenException("dirInfo(" + dirname.asString() + ")"));
417 }
418
419 _handler->dirInfo( retlist, dirname, dots );
420}
421
422// Return content of directory on media
423void
424MediaAccess::dirInfo( filesystem::DirContent & retlist, const Pathname & dirname, bool dots ) const
425{
426 retlist.clear();
427
428 if ( !_handler ) {
429 ZYPP_THROW(MediaNotOpenException("dirInfo(" + dirname.asString() + ")"));
430 }
431
432 _handler->dirInfo( retlist, dirname, dots );
433}
434
435// return if a file exists
436bool
437MediaAccess::doesFileExist( const Pathname & filename ) const
438{
439 if ( !_handler ) {
440 ZYPP_THROW(MediaNotOpenException("doesFileExist(" + filename.asString() + ")"));
441 }
442
443 return _handler->doesFileExist( filename );
444}
445
446std::ostream &
447MediaAccess::dumpOn( std::ostream & str ) const
448{
449 if ( !_handler )
450 return str << "MediaAccess( closed )";
451
452 str << _handler->protocol() << "(" << *_handler << ")";
453 return str;
454}
455
456void MediaAccess::getFile( const Url &from, const Pathname &to )
457{
458 DBG << "From: " << from << endl << "To: " << to << endl;
459
460 Pathname path = from.getPathData();
461 Pathname dir = path.dirname();
462 std::string base = path.basename();
463
464 Url u = from;
465 u.setPathData( dir.asString() );
466
467 MediaAccess media;
468
469 try {
470 media.open( u );
471 media.attach();
472 media._handler->provideFileCopy( base, to, 0 );
473 media.release();
474 }
475 catch (const MediaException & excpt_r)
476 {
477 ZYPP_RETHROW(excpt_r);
478 }
479}
480
481 std::ostream & operator<<( std::ostream & str, const MediaAccess & obj )
482 { return obj.dumpOn( str ); }
483
485 } // namespace media
486} // namespace zypp
#define ZYPP_RETHROW(EXCPT)
Drops a logline and rethrows, updating the CodeLocation.
Definition: Exception.h:400
#define ZYPP_CAUGHT(EXCPT)
Drops a logline telling the Exception was caught (in order to handle it).
Definition: Exception.h:396
#define ZYPP_THROW(EXCPT)
Drops a logline and throws the Exception.
Definition: Exception.h:392
#define DBG
Definition: Logger.h:78
#define MIL
Definition: Logger.h:79
#define ERR
Definition: Logger.h:81
#define WAR
Definition: Logger.h:80
CURL * curl
Definition: MediaCurl.cc:65
Store and operate with byte count.
Definition: ByteCount.h:31
Url manipulation class.
Definition: Url.h:92
std::string getScheme() const
Returns the scheme name of the URL.
Definition: Url.cc:528
std::string getPathData() const
Returns the encoded path component of the URL.
Definition: Url.cc:543
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
void setPathData(const std::string &pathdata)
Set the path data component in the URL.
Definition: Url.cc:701
bool isValid() const
Verifies the Url.
Definition: Url.cc:484
Pathname dirname() const
Return all but the last component od this path.
Definition: Pathname.h:124
const std::string & asString() const
String representation.
Definition: Pathname.h:91
std::string basename() const
Return the last component of this path.
Definition: Pathname.h:128
Handle access to a medium.
Definition: MediaAccess.h:51
void getFile(const Url &from, const Pathname &to)
Get file from location at specified by URL and copy it to destination.
Definition: MediaAccess.cc:456
Pathname localPath(const Pathname &pathname) const
Short for 'localRoot() + pathname', but returns an empty pathname if media is not open.
Definition: MediaAccess.cc:307
void releaseFile(const Pathname &filename) const
Remove filename below attach point IFF handler downloads files to the local filesystem.
Definition: MediaAccess.cc:359
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:411
bool downloads() const
Hint if files are downloaded or not.
Definition: MediaAccess.cc:210
void releaseDir(const Pathname &dirname) const
Remove directory tree below attach point IFF handler downloads files to the local filesystem.
Definition: MediaAccess.cc:392
void releasePath(const Pathname &pathname) const
Remove pathname below attach point IFF handler downloads files to the local filesystem.
Definition: MediaAccess.cc:401
bool dependsOnParent() const
Definition: MediaAccess.cc:89
void open(const Url &url, const Pathname &preferred_attach_point="")
open url.
Definition: MediaAccess.cc:104
virtual ~MediaAccess()
Destructor.
Definition: MediaAccess.cc:59
void release(const std::string &ejectDev="")
Use concrete handler to release the media.
Definition: MediaAccess.cc:326
static const Pathname _noPath
Definition: MediaAccess.h:58
void provideFile(const Pathname &filename, const ByteCount &expectedFileSize) const
Use concrete handler to provide file denoted by path below 'attach point'.
Definition: MediaAccess.cc:339
void disconnect()
Use concrete handler to disconnect the media.
Definition: MediaAccess.cc:316
void provideDir(const Pathname &dirname) const
Use concrete handler to provide directory denoted by path below 'attach point' (not recursive!...
Definition: MediaAccess.cc:372
void close()
close url
Definition: MediaAccess.cc:231
bool doesFileExist(const Pathname &filename) const
check if a file exists
Definition: MediaAccess.cc:437
void provideDirTree(const Pathname &dirname) const
Use concrete handler to provide directory tree denoted by path below 'attach point' (recursive!...
Definition: MediaAccess.cc:382
void attach(bool next=false)
Use concrete handler to attach the media.
Definition: MediaAccess.cc:255
AttachedMedia attachedMedia() const
Definition: MediaAccess.cc:69
MediaHandler * _handler
handler for 'physical' media == 0 if not open
Definition: MediaAccess.h:64
bool hasMoreDevices() const
Definition: MediaAccess.cc:271
bool isSharedMedia() const
Definition: MediaAccess.cc:76
virtual std::ostream & dumpOn(std::ostream &str) const
Overload to realize std::ostream & operator<<.
Definition: MediaAccess.cc:447
std::string protocol() const
Used Protocol if media is opened, otherwise 'unknown'.
Definition: MediaAccess.cc:201
void setDeltafile(const Pathname &filename) const
set a deltafile to be used in the next download
Definition: MediaAccess.cc:349
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:278
Pathname localRoot() const
Return the local directory that corresponds to medias url, no matter if media isAttached or not.
Definition: MediaAccess.cc:296
bool isAttached() const
True if media is attached.
Definition: MediaAccess.cc:265
MediaAccess()
constructor
Definition: MediaAccess.cc:53
Url url() const
Url if media is opened, otherwise empty.
Definition: MediaAccess.cc:221
Implementation class for CD/DVD MediaHandler.
Definition: MediaCD.h:28
Implementation class for CIFS MediaHandler.
Definition: MediaCIFS.h:32
Implementation class for FTP, HTTP and HTTPS MediaHandler.
Definition: MediaCurl.h:33
Implementation class for DIR MediaHandler.
Definition: MediaDIR.h:28
Implementation class for DISK MediaHandler.
Definition: MediaDISK.h:27
Just inherits Exception to separate media exceptions.
Url url() const
Url used.
Definition: MediaHandler.h:507
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 provideDirTree(Pathname dirname) const
Use concrete handler to provide directory tree denoted by path below 'localRoot' (recursive!...
void disconnect()
Use concrete handler to isconnect media.
void attach(bool next)
Use concrete handler to attach the media.
void resetParentId()
Called in case, where the media manager takes over the destruction of the parent id (e....
virtual bool isAttached() const
True if media is attached.
Definition: MediaHandler.h:524
virtual bool hasMoreDevices()
Check if the media has one more device available for attach(true).
bool downloads() const
Hint if files are downloaded or not.
Definition: MediaHandler.h:497
void dirInfo(std::list< std::string > &retlist, const Pathname &dirname, bool dots=true) const
Return content of directory on media via retlist.
void releaseDir(const Pathname &dirname) const
Remove directory tree below localRoot IFF handler downloads files to the local filesystem.
Definition: MediaHandler.h:627
bool doesFileExist(const Pathname &filename) const
check if a file exists
void releasePath(Pathname pathname) const
Remove pathname below localRoot IFF handler downloads files to the local filesystem.
bool dependsOnParent(MediaAccessId parentId, bool exactIdMatch)
Check if the current media handler depends on an another handler specified by media access id.
Pathname localPath(const Pathname &pathname) const
Files provided will be available at 'localPath(filename)'.
std::string protocol() const
Protocol hint for MediaAccess.
Definition: MediaHandler.h:502
void release(const std::string &ejectDev="")
Use concrete handler to release the media.
void releaseFile(const Pathname &filename) const
Remove filename below localRoot IFF handler downloads files to the local filesystem.
Definition: MediaHandler.h:618
Pathname localRoot() const
Return the local directory that corresponds to medias url, no matter if media isAttached or not.
void provideDir(Pathname dirname) const
Use concrete handler to provide directory denoted by path below 'localRoot' (not recursive!...
void setDeltafile(const Pathname &filename=Pathname()) const
bool isSharedMedia() const
Returns a hint if the media is shared or not.
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...
void provideFile(Pathname filename, const ByteCount &expectedFileSize_r) const
Use concrete handler to provide file denoted by path below 'localRoot'.
AttachedMedia attachedMedia() const
Returns the attached media.
Implementation class for ISO MediaHandler.
Definition: MediaISO.h:36
Implementation class for NFS MediaHandler.
Definition: MediaNFS.h:36
Implementation class for plugin MediaHandler.
Definition: MediaPlugin.h:30
std::multimap< std::string, std::string > HeaderList
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 ...
String related utilities and Regular expression matching.
std::list< DirEntry > DirContent
Returned by readdir.
Definition: PathInfo.h:547
std::ostream & operator<<(std::ostream &str, const MediaAccess &obj)
Definition: MediaAccess.cc:481
unsigned int MediaAccessId
Media manager access Id type.
Definition: MediaSource.h:29
Easy-to use interface to the ZYPP dependency resolver.
Definition: CodePitfalls.doc:2
A simple structure containing references to a media source and its attach point.
Definition: MediaSource.h:134