#include <ctype.h>
#include <iostream>
+#include <map>
#include "zypp/base/Logger.h"
+#include "zypp/ZConfig.h"
+#include "zypp/PluginScript.h"
+#include "zypp/ExternalProgram.h"
#include "zypp/media/MediaException.h"
#include "zypp/media/MediaAccess.h"
#include "zypp/media/MediaCD.h"
#include "zypp/media/MediaDIR.h"
#include "zypp/media/MediaDISK.h"
-#include "zypp/media/MediaSMB.h"
#include "zypp/media/MediaCIFS.h"
#include "zypp/media/MediaCurl.h"
+#include "zypp/media/MediaMultiCurl.h"
+#include "zypp/media/MediaISO.h"
+#include "zypp/media/MediaPlugin.h"
+#include "zypp/media/UrlResolverPlugin.h"
using namespace std;
: false;
}
+void
+MediaAccess::resetParentId()
+{
+ if( _handler) _handler->resetParentId();
+}
+
+bool
+MediaAccess::dependsOnParent() const
+{
+ return _handler ? _handler->dependsOnParent() : false;
+}
+
+bool
+MediaAccess::dependsOnParent(MediaAccessId parentId,
+ bool exactIdMatch) const
+{
+ return _handler ? _handler->dependsOnParent(parentId, exactIdMatch)
+ : false;
+}
+
// open URL
void
-MediaAccess::open (const Url& url, const Pathname & preferred_attach_point)
+MediaAccess::open (const Url& o_url, const Pathname & preferred_attach_point)
{
- if(!url.isValid()) {
+ if(!o_url.isValid()) {
MIL << "Url is not valid" << endl;
- ZYPP_THROW(MediaBadUrlException(url));
+ ZYPP_THROW(MediaBadUrlException(o_url));
}
close();
- std::string scheme = url.getScheme();
+ UrlResolverPlugin::HeaderList custom_headers;
+ Url url = UrlResolverPlugin::resolveUrl(o_url, custom_headers);
+ std::string scheme = url.getScheme();
MIL << "Trying scheme '" << scheme << "'" << endl;
+ /*
+ ** WARNING: Don't forget to update MediaAccess::downloads(url)
+ ** if you are adding a new url scheme / handler!
+ */
if (scheme == "cd" || scheme == "dvd")
_handler = new MediaCD (url,preferred_attach_point);
- else if (scheme == "nfs")
+ else if (scheme == "nfs" || scheme == "nfs4")
_handler = new MediaNFS (url,preferred_attach_point);
-// else if (scheme == "iso")
-// _handler = new MediaISO (url,preferred_attach_point);
+ else if (scheme == "iso")
+ _handler = new MediaISO (url,preferred_attach_point);
else if (scheme == "file" || scheme == "dir")
_handler = new MediaDIR (url,preferred_attach_point);
else if (scheme == "hd")
_handler = new MediaDISK (url,preferred_attach_point);
- else if (scheme == "smb")
- _handler = new MediaSMB (url,preferred_attach_point);
- else if (scheme == "cifs")
- _handler = new MediaCIFS (url,preferred_attach_point);
- else if (scheme == "ftp" || scheme == "http" || scheme == "https")
- _handler = new MediaCurl (url,preferred_attach_point);
+ else if (scheme == "cifs" || scheme == "smb")
+ _handler = new MediaCIFS (url,preferred_attach_point);
+ else if (scheme == "ftp" || scheme == "tftp" || scheme == "http" || scheme == "https")
+ {
+ bool use_multicurl = true;
+ string urlmediahandler ( url.getQueryParam("mediahandler") );
+ if ( urlmediahandler == "multicurl" )
+ {
+ use_multicurl = true;
+ }
+ else if ( urlmediahandler == "curl" )
+ {
+ use_multicurl = false;
+ }
+ else
+ {
+ if ( ! urlmediahandler.empty() )
+ {
+ WAR << "unknown mediahandler set: " << urlmediahandler << endl;
+ }
+ const char *multicurlenv = getenv( "ZYPP_MULTICURL" );
+ // if user disabled it manually
+ if ( use_multicurl && multicurlenv && ( strcmp(multicurlenv, "0" ) == 0 ) )
+ {
+ WAR << "multicurl manually disabled." << endl;
+ use_multicurl = false;
+ }
+ else if ( !use_multicurl && multicurlenv && ( strcmp(multicurlenv, "1" ) == 0 ) )
+ {
+ WAR << "multicurl manually enabled." << endl;
+ use_multicurl = true;
+ }
+ }
+
+ MediaCurl *curl;
+
+ if ( use_multicurl )
+ curl = new MediaMultiCurl (url,preferred_attach_point);
+ else
+ curl = new MediaCurl (url,preferred_attach_point);
+
+ for ( const auto & el : custom_headers ) {
+ std::string header { el.first };
+ header += ": ";
+ header += el.second;
+ MIL << "Added custom header -> " << header << endl;
+ curl->settings().addHeader( std::move(header) );
+ }
+ _handler = curl;
+ }
+ else if (scheme == "plugin" )
+ _handler = new MediaPlugin (url,preferred_attach_point);
else
{
ZYPP_THROW(MediaUnsupportedUrlSchemeException(url));
return _handler->protocol();
}
+bool
+MediaAccess::downloads() const
+{
+ return _handler ? _handler->downloads() : false;
+}
+
///////////////////////////////////////////////////////////////////
//
//
return( _handler && _handler->isAttached() );
}
+
+bool MediaAccess::hasMoreDevices() const
+{
+ return _handler && _handler->hasMoreDevices();
+}
+
+
+void
+MediaAccess::getDetectedDevices(std::vector<std::string> & devices,
+ unsigned int & index) const
+{
+ if (_handler)
+ {
+ _handler->getDetectedDevices(devices, index);
+ return;
+ }
+
+ if (!devices.empty())
+ devices.clear();
+ index = 0;
+}
+
+
// local directory that corresponds to medias url
// If media is not open an empty pathname.
-const Pathname &
+Pathname
MediaAccess::localRoot() const
{
if ( !_handler )
_handler->disconnect();
}
-// release attached media
+
void
-MediaAccess::release( bool eject )
+MediaAccess::release( const std::string & ejectDev )
{
if ( !_handler )
return;
- _handler->release( eject );
+ _handler->release( ejectDev );
}
-
// provide file denoted by path to attach dir
//
// filename is interpreted relative to the attached url
// and a path prefix is preserved to destination
void
-MediaAccess::provideFile( const Pathname & filename, bool cached, bool checkonly) const
+MediaAccess::provideFile(const Pathname & filename , const ByteCount &expectedFileSize) const
{
- if ( cached ) {
- PathInfo pi( localPath( filename ) );
- if ( pi.isExist() )
- return;
+ if ( !_handler ) {
+ ZYPP_THROW(MediaNotOpenException("provideFile(" + filename.asString() + ")"));
}
- if(checkonly)
- ZYPP_THROW(MediaFileNotFoundException(url(), filename));
+ _handler->provideFile( filename, expectedFileSize );
+}
+void
+MediaAccess::setDeltafile( const Pathname & filename ) const
+{
if ( !_handler ) {
- ZYPP_THROW(MediaNotOpenException("provideFile(" + filename.asString() + ")"));
+ ZYPP_THROW(MediaNotOpenException("setDeltafile(" + filename.asString() + ")"));
}
- _handler->provideFile( filename );
+ _handler->setDeltafile( filename );
}
void
// Return content of directory on media
void
-MediaAccess::dirInfo( list<string> & retlist, const Pathname & dirname, bool dots ) const
+MediaAccess::dirInfo( std::list<std::string> & retlist, const Pathname & dirname, bool dots ) const
{
retlist.clear();
_handler->dirInfo( retlist, dirname, dots );
}
+// return if a file exists
+bool
+MediaAccess::doesFileExist( const Pathname & filename ) const
+{
+ if ( !_handler ) {
+ ZYPP_THROW(MediaNotOpenException("doesFileExist(" + filename.asString() + ")"));
+ }
+
+ return _handler->doesFileExist( filename );
+}
+
std::ostream &
MediaAccess::dumpOn( std::ostream & str ) const
{
try {
media.open( u );
media.attach();
- media._handler->provideFileCopy( base, to );
+ media._handler->provideFileCopy( base, to, 0 );
media.release();
}
catch (const MediaException & excpt_r)
ZYPP_RETHROW(excpt_r);
}
}
+
std::ostream & operator<<( std::ostream & str, const MediaAccess & obj )
{ return obj.dumpOn( str ); }