#
SET(LIBZYPP_MAJOR "14")
SET(LIBZYPP_COMPATMINOR "39")
-SET(LIBZYPP_MINOR "46")
+SET(LIBZYPP_MINOR "47")
SET(LIBZYPP_PATCH "0")
#
-# LAST RELEASED: 14.46.0 (39)
+# LAST RELEASED: 14.47.0 (39)
# (The number in parenthesis is LIBZYPP_COMPATMINOR)
#=======
-------------------------------------------------------------------
+Tue Oct 2 16:00:15 CEST 2018 - ma@suse.de
+
+- Add filesize check for downloads with known size (bsc#408814)
+- MediaMultiCurl: Trigger aliveCallback when downloading metalink
+ files (bsc#1021291)
+- version 14.47.0 (39)
+
+-------------------------------------------------------------------
Tue Oct 2 12:36:18 CEST 2018 - ma@suse.de
- Fix conversion of string and glob to regex when compiling queries
// providing a file which does not exist should throw
BOOST_CHECK_THROW(setaccess.provideFile("/testBADNAME.txt"), media::MediaFileNotFoundException);
+
+ BOOST_CHECK(setaccess.doesFileExist("/test-big.txt"));
+ BOOST_CHECK(setaccess.doesFileExist("dir/test-big.txt"));
+
+ {
+ // providing a file with wrong filesize should throw
+ OnMediaLocation locPlain("dir/test-big.txt");
+ locPlain.setDownloadSize( zypp::ByteCount(500, zypp::ByteCount::B) );
+ BOOST_CHECK_THROW(setaccess.provideFile(locPlain), media::MediaFileSizeExceededException);
+
+ // using the correct file size should NOT throw
+ locPlain.setDownloadSize( zypp::ByteCount(7135, zypp::ByteCount::B) );
+ Pathname file = setaccess.provideFile( locPlain );
+ BOOST_CHECK(check_file_exists(file) == true);
+ }
+
+ {
+ // test the maximum filesize again with metalink downloads
+ // providing a file with wrong filesize should throw
+ OnMediaLocation locMeta("/test-big.txt");
+ locMeta.setDownloadSize( zypp::ByteCount(500, zypp::ByteCount::B) );
+ BOOST_CHECK_THROW(setaccess.provideFile(locMeta), media::MediaFileSizeExceededException);
+
+ // using the correct file size should NOT throw
+ locMeta.setDownloadSize( zypp::ByteCount(7135, zypp::ByteCount::B) );
+ Pathname file = setaccess.provideFile( locMeta );
+ BOOST_CHECK(check_file_exists(file) == true);
+ }
+
web.stop();
}
std::ostream & nlist( std::ostream & str, const TCont & set_r )
{
str << "[" << set_r.size() << "]: ";
- for ( const auto & solv : set_r )
- str << " \"" << solv.name() << "\"";
+ for_( it, set_r.begin(), set_r.end() )
+ str << " \"" << PoolItem(*it).satSolvable().name() << "\"";
return str << endl;
}
unsigned qtest( const std::string & pattern_r, Match::Mode mode_r, bool verbose_r = false )
{
- static constexpr const bool noMatchInvalidRegexException = false;
+ static const bool noMatchInvalidRegexException = false;
typedef std::set<sat::Solvable> Result;
PoolQuery q;
--- /dev/null
+Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.
+
+Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.
+
+Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.
+
+Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.
+
+Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.
+
+Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.
+
+Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.
+
+Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<metalink version="3.0"
+ xmlns="http://www.metalinker.org/"
+ generator="http://metalinks.sourceforge.net/"
+ >
+<files>
+ <file name="test-big.txt">
+ <size>7135</size>
+ <verification>
+ <hash type="md4">818dcbb0bbb033aa8b8c9ddd269648d2</hash>
+ <hash type="md5">f69a3e53751eb3249c3c36c50290b8da</hash>
+ <hash type="sha1">edf0cf52765c9b5cfeddfd83b62f8517b119ca77</hash>
+ <hash type="sha256">b0343a8ee06d97c9786b65bcb64c49fbb7e1d517159fac4633ba56f7a521fef0</hash>
+ <hash type="sha384">202d21693dabe53ff5f2305d6b78844ffaa3b566b9644d61ca087cab752965b16d6a188def7a9463b5f17fdc50b3d105</hash>
+ <hash type="sha512">caf260dd5420a6a6df6a558eac69a901cd3e43dbfd37b54e0fb176940f3e09c3f96c7faa22e505777106ebf056c471be7556c8cba80331d6efdb9e763e66190b</hash>
+ <hash type="ripemd160">77fc06ff936163cfb6c1b0c68cb47a295a5bf8e3</hash>
+ <hash type="tiger192">2fcd624ba2ad1adb2ff23af58049b6f7b062754eadd031b1</hash>
+ <hash type="crc32">011209ae</hash>
+ <hash type="ed2k">818dcbb0bbb033aa8b8c9ddd269648d2</hash>
+ <pieces length="262144" type="sha1">
+ <hash piece="0">edf0cf52765c9b5cfeddfd83b62f8517b119ca77</hash>
+ </pieces>
+ </verification>
+ <resources>
+ <url type="http">http://localhost:10002/dir/test-big.txt</url>
+ </resources>
+ </file>
+</files>
+</metalink>
struct ProvideFileOperation
{
Pathname result;
+ ByteCount expectedFileSize;
void operator()( media::MediaAccessId media, const Pathname &file )
{
media::MediaManager media_mgr;
- media_mgr.provideFile(media, file);
+ media_mgr.provideFile(media, file, expectedFileSize);
result = media_mgr.localPath(media, file);
}
};
Pathname MediaSetAccess::provideFile( const OnMediaLocation & resource, ProvideFileOptions options, const Pathname &deltafile )
{
ProvideFileOperation op;
+ op.expectedFileSize = resource.downloadSize();
provide( boost::ref(op), resource, options, deltafile );
return op.result;
}
// filename is interpreted relative to the attached url
// and a path prefix is preserved to destination
void
-MediaAccess::provideFile( const Pathname & filename ) const
+MediaAccess::provideFile(const Pathname & filename , const ByteCount &expectedFileSize) const
{
if ( !_handler ) {
ZYPP_THROW(MediaNotOpenException("provideFile(" + filename.asString() + ")"));
}
- _handler->provideFile( filename );
+ _handler->provideFile( filename, expectedFileSize );
}
void
try {
media.open( u );
media.attach();
- media._handler->provideFileCopy( base, to );
+ media._handler->provideFileCopy( base, to, 0 );
media.release();
}
catch (const MediaException & excpt_r)
* \throws MediaException
*
**/
- void provideFile( const Pathname & filename ) const;
+ void provideFile( const Pathname & filename, const ByteCount &expectedFileSize ) const;
/**
* Remove filename below attach point IFF handler downloads files
ZYPP_THROW(MediaBadFilenameException(_file.asString()));
} else if ( _media ) {
try {
- _media->provideFile( _file );
+ _media->provideFile( _file, 0 );
_local_file = _media->localPath( _file );
}
catch (const MediaException & excpt_r)
//
// DESCRIPTION : Asserted that media is attached.
//
- void MediaCD::getFile( const Pathname & filename ) const
+ void MediaCD::getFile(const Pathname & filename , const ByteCount &expectedFileSize_r) const
{
- MediaHandler::getFile( filename );
+ MediaHandler::getFile( filename, expectedFileSize_r );
}
///////////////////////////////////////////////////////////////////
virtual void attachTo (bool next = false);
virtual void releaseFrom( const std::string & ejectDev );
- virtual void getFile( const Pathname & filename ) const;
+ virtual void getFile(const Pathname & filename, const ByteCount &expectedFileSize_r ) const override;
virtual void getDir( const Pathname & dirname, bool recurse_r ) const;
virtual void getDirInfo( std::list<std::string> & retlist,
const Pathname & dirname, bool dots = true ) const;
//
// DESCRIPTION : Asserted that media is attached.
//
- void MediaCIFS::getFile (const Pathname & filename) const
+ void MediaCIFS::getFile (const Pathname & filename, const ByteCount &expectedFileSize_r) const
{
- MediaHandler::getFile( filename );
+ MediaHandler::getFile( filename, expectedFileSize_r );
}
///////////////////////////////////////////////////////////////////
virtual void attachTo (bool next = false);
virtual void releaseFrom( const std::string & ejectDev );
- virtual void getFile( const Pathname & filename ) const;
+ virtual void getFile( const Pathname & filename, const ByteCount &expectedFileSize_r ) const override;
virtual void getDir( const Pathname & dirname, bool recurse_r ) const;
virtual void getDirInfo( std::list<std::string> & retlist,
const Pathname & dirname, bool dots = true ) const;
namespace {
struct ProgressData
{
- ProgressData(CURL *_curl, const long _timeout, const zypp::Url &_url = zypp::Url(),
- callback::SendReport<DownloadProgressReport> *_report=NULL)
- : curl(_curl)
- , timeout(_timeout)
- , reached(false)
- , report(_report)
- , drate_period(-1)
- , dload_period(0)
- , secs(0)
- , drate_avg(-1)
- , ltime( time(NULL))
- , dload( 0)
- , uload( 0)
- , url(_url)
+ ProgressData( CURL *_curl, time_t _timeout = 0, const Url & _url = Url(),
+ ByteCount expectedFileSize_r = 0,
+ callback::SendReport<DownloadProgressReport> *_report = nullptr )
+ : curl( _curl )
+ , url( _url )
+ , timeout( _timeout )
+ , reached( false )
+ , fileSizeExceeded ( false )
+ , report( _report )
+ , _expectedFileSize( expectedFileSize_r )
{}
- CURL *curl;
- long timeout;
- bool reached;
+
+ CURL *curl;
+ Url url;
+ time_t timeout;
+ bool reached;
+ bool fileSizeExceeded;
callback::SendReport<DownloadProgressReport> *report;
+ ByteCount _expectedFileSize;
+
+ time_t _timeStart = 0; ///< Start total stats
+ time_t _timeLast = 0; ///< Start last period(~1sec)
+ time_t _timeRcv = 0; ///< Start of no-data timeout
+ time_t _timeNow = 0; ///< Now
+
+ double _dnlTotal = 0.0; ///< Bytes to download or 0 if unknown
+ double _dnlLast = 0.0; ///< Bytes downloaded at period start
+ double _dnlNow = 0.0; ///< Bytes downloaded now
+
+ int _dnlPercent= 0; ///< Percent completed or 0 if _dnlTotal is unknown
+
+ double _drateTotal= 0.0; ///< Download rate so far
+ double _drateLast = 0.0; ///< Download rate in last period
+
+ void updateStats( double dltotal = 0.0, double dlnow = 0.0 )
+ {
+ time_t now = _timeNow = time(0);
+
+ // If called without args (0.0), recompute based on the last values seen
+ if ( dltotal && dltotal != _dnlTotal )
+ _dnlTotal = dltotal;
+
+ if ( dlnow && dlnow != _dnlNow )
+ {
+ _timeRcv = now;
+ _dnlNow = dlnow;
+ }
+ else if ( !_dnlNow && !_dnlTotal )
+ {
+ // Start time counting as soon as first data arrives.
+ // Skip the connection / redirection time at begin.
+ return;
+ }
+
+ // init or reset if time jumps back
+ if ( !_timeStart || _timeStart > now )
+ _timeStart = _timeLast = _timeRcv = now;
+
+ // timeout condition
+ if ( timeout )
+ reached = ( (now - _timeRcv) > timeout );
+
+ // check if the downloaded data is already bigger than what we expected
+ fileSizeExceeded = _expectedFileSize > 0 && _expectedFileSize < static_cast<ByteCount::SizeType>(_dnlNow);
+
+ // percentage:
+ if ( _dnlTotal )
+ _dnlPercent = int(_dnlNow * 100 / _dnlTotal);
+
+ // download rates:
+ _drateTotal = _dnlNow / std::max( int(now - _timeStart), 1 );
+
+ if ( _timeLast < now )
+ {
+ _drateLast = (_dnlNow - _dnlLast) / int(now - _timeLast);
+ // start new period
+ _timeLast = now;
+ _dnlLast = _dnlNow;
+ }
+ else if ( _timeStart == _timeLast )
+ _drateLast = _drateTotal;
+ }
+
+ int reportProgress() const
+ {
+ if ( fileSizeExceeded )
+ return 1;
+ if ( reached )
+ return 1; // no-data timeout
+ if ( report && !(*report)->progress( _dnlPercent, url, _drateTotal, _drateLast ) )
+ return 1; // user requested abort
+ return 0;
+ }
+
+
// download rate of the last period (cca 1 sec)
double drate_period;
// bytes downloaded at the start of the last period
double dload;
// bytes uploaded at the moment the progress was last reported
double uload;
- zypp::Url url;
};
///////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////
-void MediaCurl::getFile( const Pathname & filename ) const
+void MediaCurl::getFile(const Pathname & filename , const ByteCount &expectedFileSize_r) const
{
// Use absolute file name to prevent access of files outside of the
// hierarchy below the attach point.
- getFileCopy(filename, localPath(filename).absolutename());
+ getFileCopy(filename, localPath(filename).absolutename(), expectedFileSize_r);
}
///////////////////////////////////////////////////////////////////
-void MediaCurl::getFileCopy( const Pathname & filename , const Pathname & target) const
+void MediaCurl::getFileCopy( const Pathname & filename , const Pathname & target, const ByteCount &expectedFileSize_r ) const
{
callback::SendReport<DownloadProgressReport> report;
{
try
{
- doGetFileCopy(filename, target, report);
+ doGetFileCopy(filename, target, report, expectedFileSize_r);
retry = false;
}
// retry with proper authentication data
///////////////////////////////////////////////////////////////////
-void MediaCurl::evaluateCurlCode( const Pathname &filename,
+void MediaCurl::evaluateCurlCode(const Pathname &filename,
CURLcode code,
- bool timeout_reached ) const
+ bool timeout_reached) const
{
if ( code != 0 )
{
url = _url;
else
url = getFileUrl(filename);
+
std::string err;
try
{
///////////////////////////////////////////////////////////////////
-void MediaCurl::doGetFileCopy( const Pathname & filename , const Pathname & target, callback::SendReport<DownloadProgressReport> & report, RequestOptions options ) const
+void MediaCurl::doGetFileCopy(const Pathname & filename , const Pathname & target, callback::SendReport<DownloadProgressReport> & report, const ByteCount &expectedFileSize_r, RequestOptions options ) const
{
Pathname dest = target.absolutename();
if( assert_dir( dest.dirname() ) )
}
try
{
- doGetFileCopyFile(filename, dest, file, report, options);
+ doGetFileCopyFile(filename, dest, file, report, expectedFileSize_r, options);
}
catch (Exception &e)
{
///////////////////////////////////////////////////////////////////
-void MediaCurl::doGetFileCopyFile( const Pathname & filename , const Pathname & dest, FILE *file, callback::SendReport<DownloadProgressReport> & report, RequestOptions options ) const
+void MediaCurl::doGetFileCopyFile(const Pathname & filename , const Pathname & dest, FILE *file, callback::SendReport<DownloadProgressReport> & report, const ByteCount &expectedFileSize_r, RequestOptions options ) const
{
DBG << filename.asString() << endl;
}
// Set callback and perform.
- ProgressData progressData(_curl, _settings.timeout(), url, &report);
+ ProgressData progressData(_curl, _settings.timeout(), url, expectedFileSize_r, &report);
if (!(options & OPTION_NO_REPORT_START))
report->start(url, dest);
if ( curl_easy_setopt( _curl, CURLOPT_PROGRESSDATA, &progressData ) != 0 ) {
// which holds whether the timeout was reached or not,
// otherwise it would be a user cancel
try {
- evaluateCurlCode( filename, ret, progressData.reached);
+
+ if ( progressData.fileSizeExceeded )
+ ZYPP_THROW(MediaFileSizeExceededException(url, progressData._expectedFileSize));
+
+ evaluateCurlCode( filename, ret, progressData.reached );
}
catch ( const MediaException &e ) {
// some error, we are not sure about file existence, rethrw
switch ( it->type ) {
case filesystem::FT_NOT_AVAIL: // old directory.yast contains no typeinfo at all
case filesystem::FT_FILE:
- getFile( filename );
+ getFile( filename, 0 );
break;
case filesystem::FT_DIR: // newer directory.yast contain at least directory info
if ( recurse_r ) {
}
///////////////////////////////////////////////////////////////////
+//
+int MediaCurl::aliveCallback( void *clientp, double /*dltotal*/, double dlnow, double /*ultotal*/, double /*ulnow*/ )
+{
+ ProgressData *pdata = reinterpret_cast<ProgressData *>( clientp );
+ if( pdata )
+ {
+ // Do not propagate dltotal in alive callbacks. MultiCurl uses this to
+ // prevent a percentage raise while downloading a metalink file. Download
+ // activity however is indicated by propagating the download rate (via dlnow).
+ pdata->updateStats( 0.0, dlnow );
+ return pdata->reportProgress();
+ }
+ return 0;
+}
-int MediaCurl::progressCallback( void *clientp,
- double dltotal, double dlnow,
- double ultotal, double ulnow)
+int MediaCurl::progressCallback( void *clientp, double dltotal, double dlnow, double ultotal, double ulnow )
{
- ProgressData *pdata = reinterpret_cast<ProgressData *>(clientp);
- if( pdata)
+ ProgressData *pdata = reinterpret_cast<ProgressData *>( clientp );
+ if( pdata )
{
// work around curl bug that gives us old data
long httpReturnCode = 0;
- if (curl_easy_getinfo(pdata->curl, CURLINFO_RESPONSE_CODE, &httpReturnCode) != CURLE_OK || httpReturnCode == 0)
- return 0;
+ if ( curl_easy_getinfo( pdata->curl, CURLINFO_RESPONSE_CODE, &httpReturnCode ) != CURLE_OK || httpReturnCode == 0 )
+ return aliveCallback( clientp, dltotal, dlnow, ultotal, ulnow );
- time_t now = time(NULL);
- if( now > 0)
- {
- // reset time of last change in case initial time()
- // failed or the time was adjusted (goes backward)
- if( pdata->ltime <= 0 || pdata->ltime > now)
- {
- pdata->ltime = now;
- }
-
- // start time counting as soon as first data arrives
- // (skip the connection / redirection time at begin)
- time_t dif = 0;
- if (dlnow > 0 || ulnow > 0)
- {
- dif = (now - pdata->ltime);
- dif = dif > 0 ? dif : 0;
-
- pdata->secs += dif;
- }
-
- // update the drate_avg and drate_period only after a second has passed
- // (this callback is called much more often than a second)
- // otherwise the values would be far from accurate when measuring
- // the time in seconds
- //! \todo more accurate download rate computationn, e.g. compute average value from last 5 seconds, or work with milliseconds instead of seconds
-
- if ( pdata->secs > 1 && (dif > 0 || dlnow == dltotal ))
- pdata->drate_avg = (dlnow / pdata->secs);
-
- if ( dif > 0 )
- {
- pdata->drate_period = ((dlnow - pdata->dload_period) / dif);
- pdata->dload_period = dlnow;
- }
- }
-
- // send progress report first, abort transfer if requested
- if( pdata->report)
- {
- if (!(*(pdata->report))->progress(int( dltotal ? dlnow * 100 / dltotal : 0 ),
- pdata->url,
- pdata->drate_avg,
- pdata->drate_period))
- {
- return 1; // abort transfer
- }
- }
-
- // check if we there is a timeout set
- if( pdata->timeout > 0)
- {
- if( now > 0)
- {
- bool progress = false;
-
- // update download data if changed, mark progress
- if( dlnow != pdata->dload)
- {
- progress = true;
- pdata->dload = dlnow;
- pdata->ltime = now;
- }
- // update upload data if changed, mark progress
- if( ulnow != pdata->uload)
- {
- progress = true;
- pdata->uload = ulnow;
- pdata->ltime = now;
- }
-
- if( !progress && (now >= (pdata->ltime + pdata->timeout)))
- {
- pdata->reached = true;
- return 1; // aborts transfer
- }
- }
- }
+ pdata->updateStats( dltotal, dlnow );
+ return pdata->reportProgress();
}
return 0;
}
return "";
}
+/**
+ * MediaMultiCurl needs to reset the expected filesize in case a metalink file is downloaded
+ * otherwise this function should not be called
+ */
+void MediaCurl::resetExpectedFileSize(void *clientp, const ByteCount &expectedFileSize)
+{
+ ProgressData *data = reinterpret_cast<ProgressData *>(clientp);
+ if ( data ) {
+ data->_expectedFileSize = expectedFileSize;
+ }
+}
+
///////////////////////////////////////////////////////////////////
bool MediaCurl::authenticate(const string & availAuthTypes, bool firstTry) const
virtual void attachTo (bool next = false);
virtual void releaseFrom( const std::string & ejectDev );
- virtual void getFile( const Pathname & filename ) const;
+ virtual void getFile( const Pathname & filename, const ByteCount &expectedFileSize_r ) const override;
virtual void getDir( const Pathname & dirname, bool recurse_r ) const;
virtual void getDirInfo( std::list<std::string> & retlist,
const Pathname & dirname, bool dots = true ) const;
* \throws MediaException
*
*/
- virtual void getFileCopy( const Pathname & srcFilename, const Pathname & targetFilename) const;
+ virtual void getFileCopy( const Pathname & srcFilename, const Pathname & targetFilename, const ByteCount &expectedFileSize_r) const override;
/**
*
* \throws MediaException
*
*/
- virtual void doGetFileCopy( const Pathname & srcFilename, const Pathname & targetFilename, callback::SendReport<DownloadProgressReport> & _report, RequestOptions options = OPTION_NONE ) const;
+ virtual void doGetFileCopy( const Pathname & srcFilename, const Pathname & targetFilename, callback::SendReport<DownloadProgressReport> & _report, const ByteCount &expectedFileSize_r, RequestOptions options = OPTION_NONE ) const;
virtual bool checkAttachPoint(const Pathname &apoint) const;
};
protected:
-
- static int progressCallback( void *clientp, double dltotal, double dlnow,
- double ultotal, double ulnow );
+// /** Callback sending just an alive trigger to the UI, without stats (e.g. during metalink download). */
+ static int aliveCallback( void *clientp, double dltotal, double dlnow, double ultotal, double ulnow );
+ /** Callback reporting download progress. */
+ static int progressCallback( void *clientp, double dltotal, double dlnow, double ultotal, double ulnow );
static CURL *progressCallback_getcurl( void *clientp );
/**
* check the url is supported by the curl library
*
* \throws MediaException If there is a problem
*/
- void evaluateCurlCode( const zypp::Pathname &filename, CURLcode code, bool timeout ) const;
+ void evaluateCurlCode(const zypp::Pathname &filename, CURLcode code, bool timeout) const;
+
+ void doGetFileCopyFile( const Pathname & srcFilename, const Pathname & dest, FILE *file, callback::SendReport<DownloadProgressReport> & _report, const ByteCount &expectedFileSize_r, RequestOptions options = OPTION_NONE ) const;
- void doGetFileCopyFile( const Pathname & srcFilename, const Pathname & dest, FILE *file, callback::SendReport<DownloadProgressReport> & _report, RequestOptions options = OPTION_NONE ) const;
+ static void resetExpectedFileSize ( void *clientp, const ByteCount &expectedFileSize );
private:
/**
//
// DESCRIPTION : Asserted that media is attached.
//
- void MediaDIR::getFile( const Pathname & filename ) const
+ void MediaDIR::getFile(const Pathname & filename , const ByteCount &expectedFileSize_r) const
{
- MediaHandler::getFile( filename );
+ MediaHandler::getFile( filename, expectedFileSize_r );
}
///////////////////////////////////////////////////////////////////
virtual void attachTo (bool next = false);
virtual void releaseFrom( const std::string & ejectDev );
- virtual void getFile( const Pathname & filename ) const;
+ virtual void getFile( const Pathname & filename, const ByteCount &expectedFileSize_r ) const override;
virtual void getDir( const Pathname & dirname, bool recurse_r ) const;
virtual void getDirInfo( std::list<std::string> & retlist,
const Pathname & dirname, bool dots = true ) const;
//
// DESCRIPTION : Asserted that media is attached.
//
- void MediaDISK::getFile (const Pathname & filename) const
+ void MediaDISK::getFile (const Pathname & filename, const ByteCount &expectedFileSize_r) const
{
- MediaHandler::getFile( filename );
+ MediaHandler::getFile( filename, expectedFileSize_r );
}
///////////////////////////////////////////////////////////////////
virtual void attachTo (bool next = false);
virtual void releaseFrom( const std::string & ejectDev );
- virtual void getFile( const Pathname & filename ) const;
+ virtual void getFile(const Pathname & filename, const ByteCount &expectedFileSize_r ) const override;
virtual void getDir( const Pathname & dirname, bool recurse_r ) const;
virtual void getDirInfo( std::list<std::string> & retlist,
const Pathname & dirname, bool dots = true ) const;
return str;
}
+ std::ostream &MediaFileSizeExceededException::dumpOn(std::ostream &str) const
+ {
+ str << form(_("Downloaded data exceeded the expected filesize '%s' of '%s'."), _expectedFileSize.asString().c_str(), _url.c_str() );
+ if ( !_msg.empty() )
+ str << endl << _msg;
+ return str;
+ }
+
std::ostream & MediaTemporaryProblemException::dumpOn( std::ostream & str ) const
{
str << form(_("Location '%s' is temporarily unaccessible."), _url.c_str()) << endl;
#include "zypp/base/Exception.h"
#include "zypp/Pathname.h"
#include "zypp/Url.h"
+#include "zypp/ByteCount.h"
///////////////////////////////////////////////////////////////////
namespace zypp
std::string _msg;
};
+ class MediaFileSizeExceededException : public MediaException
+ {
+ public:
+ MediaFileSizeExceededException(const Url & url_r, const ByteCount &cnt_r, const std::string & msg = "")
+ : MediaException(msg)
+ , _url(url_r.asString())
+ , _msg(msg)
+ , _expectedFileSize(cnt_r)
+ {}
+ virtual ~MediaFileSizeExceededException() throw() {};
+ protected:
+ virtual std::ostream & dumpOn( std::ostream & str ) const;
+ std::string _url;
+ std::string _msg;
+ ByteCount _expectedFileSize;
+ };
+
/** For HTTP 503 and similar. */
class MediaTemporaryProblemException : public MediaException
{
//
// DESCRIPTION :
//
-void MediaHandler::provideFileCopy( Pathname srcFilename,
- Pathname targetFilename ) const
+void MediaHandler::provideFileCopy(Pathname srcFilename,
+ Pathname targetFilename , const ByteCount &expectedFileSize_r) const
{
if ( !isAttached() ) {
INT << "Media not_attached on provideFileCopy(" << srcFilename
ZYPP_THROW(MediaNotAttachedException(url()));
}
- getFileCopy( srcFilename, targetFilename ); // pass to concrete handler
+ getFileCopy( srcFilename, targetFilename, expectedFileSize_r ); // pass to concrete handler
DBG << "provideFileCopy(" << srcFilename << "," << targetFilename << ")" << endl;
}
-void MediaHandler::provideFile( Pathname filename ) const
+void MediaHandler::provideFile(Pathname filename , const ByteCount &expectedFileSize_r) const
{
if ( !isAttached() ) {
INT << "Error: Not attached on provideFile(" << filename << ")" << endl;
ZYPP_THROW(MediaNotAttachedException(url()));
}
- getFile( filename ); // pass to concrete handler
+ getFile( filename, expectedFileSize_r ); // pass to concrete handler
DBG << "provideFile(" << filename << ")" << endl;
}
// look for directory.yast
Pathname dirFile = dirname + "directory.yast";
- getFile( dirFile );
+ getFile( dirFile, 0 );
DBG << "provideFile(" << dirFile << "): " << "OK" << endl;
// using directory.yast
// DESCRIPTION : Asserted that media is attached.
// Default implementation of pure virtual.
//
-void MediaHandler::getFile( const Pathname & filename ) const
+void MediaHandler::getFile(const Pathname & filename , const ByteCount &) const
{
PathInfo info( localPath( filename ) );
if( info.isFile() ) {
}
-void MediaHandler::getFileCopy ( const Pathname & srcFilename, const Pathname & targetFilename ) const
+void MediaHandler::getFileCopy (const Pathname & srcFilename, const Pathname & targetFilename , const ByteCount &expectedFileSize_r) const
{
- getFile(srcFilename);
+ getFile(srcFilename, expectedFileSize_r);
if ( copy( localPath( srcFilename ), targetFilename ) != 0 ) {
ZYPP_THROW(MediaWriteException(targetFilename));
* \throws MediaException
*
**/
- virtual void getFile( const Pathname & filename ) const = 0;
+ virtual void getFile( const Pathname & filename, const ByteCount &expectedFileSize_r ) const;
/**
* Call concrete handler to provide a file under a different place
* \throws MediaException
*
**/
- virtual void getFileCopy( const Pathname & srcFilename, const Pathname & targetFilename ) const;
+ virtual void getFileCopy( const Pathname & srcFilename, const Pathname & targetFilename, const ByteCount &expectedFileSize_r ) const;
/**
* \throws MediaException
*
**/
- void provideFile( Pathname filename ) const;
+ void provideFile( Pathname filename, const ByteCount &expectedFileSize_r ) const;
/**
* Call concrete handler to provide a copy of a file under a different place
* \throws MediaException
*
**/
- void provideFileCopy( Pathname srcFilename, Pathname targetFilename) const;
+ void provideFileCopy( Pathname srcFilename, Pathname targetFilename, const ByteCount &expectedFileSize_r ) const;
/**
* Use concrete handler to provide directory denoted
}
// ---------------------------------------------------------------
- void MediaISO::getFile(const Pathname &filename) const
+ void MediaISO::getFile(const Pathname &filename, const ByteCount &expectedFileSize_r) const
{
- MediaHandler::getFile(filename);
+ MediaHandler::getFile(filename, expectedFileSize_r);
}
// ---------------------------------------------------------------
virtual void attachTo (bool next = false);
virtual void releaseFrom( const std::string & ejectDev = "" );
- virtual void getFile( const Pathname & filename ) const;
+ virtual void getFile( const Pathname & filename, const ByteCount &expectedFileSize_r ) const;
virtual void getDir( const Pathname & dirname, bool recurse_r ) const;
virtual void getDirInfo( std::list<std::string> & retlist,
const Pathname & dirname, bool dots = true ) const;
return path;
}
- // ---------------------------------------------------------------
void
MediaManager::provideFile(MediaAccessId accessId,
- const Pathname &filename ) const
+ const Pathname &filename,
+ const ByteCount &expectedFileSize ) const
{
MutexLock glock(g_Mutex);
ref.checkDesired(accessId);
- ref.handler->provideFile(filename);
+ ref.handler->provideFile(filename, expectedFileSize);
+ }
+
+ // ---------------------------------------------------------------
+ void
+ MediaManager::provideFile(MediaAccessId accessId,
+ const Pathname &filename ) const
+ {
+ provideFile( accessId, filename, 0);
}
// ---------------------------------------------------------------
*
* \param accessId The media access id to use.
* \param filename The filename to provide, relative to localRoot().
+ * \param expectedFileSize The expected filesize, download will stop if it is exceeded
*
* \throws MediaNotOpenException in case of invalid access id.
* \throws MediaNotAttachedException in case, that the media is not attached.
*/
void
+ provideFile(MediaAccessId accessId,
+ const Pathname &filename,
+ const ByteCount &expectedFileSize) const;
+
+ void
provideFile(MediaAccessId accessId,
const Pathname &filename ) const;
worker->evaluateCurlCode(Pathname(), cc, false);
}
}
+
+ if ( _filesize > 0 && _fetchedgoodsize > _filesize ) {
+ ZYPP_THROW(MediaFileSizeExceededException(_baseurl, _filesize));
+ }
}
// send report
if (_report)
{
int percent = _totalsize ? (100 * (_fetchedgoodsize + _fetchedsize)) / (_totalsize + _fetchedsize) : 0;
+
double avg = 0;
if (now > _starttime)
avg = _fetchedsize / (now - _starttime);
}
// here we try to suppress all progress coming from a metalink download
+// bsc#1021291: Nevertheless send alive trigger (without stats), so UIs
+// are able to abort a hanging metalink download via callback response.
int MediaMultiCurl::progressCallback( void *clientp, double dltotal, double dlnow, double ultotal, double ulnow)
{
CURL *_curl = MediaCurl::progressCallback_getcurl(clientp);
if (!_curl)
- return 0;
+ return MediaCurl::aliveCallback(clientp, dltotal, dlnow, ultotal, ulnow);
+ // bsc#408814: Don't report any sizes before we don't have data on disk. Data reported
+ // due to redirection etc. are not interesting, but may disturb filesize checks.
+ FILE *fp = 0;
+ if ( curl_easy_getinfo( _curl, CURLINFO_PRIVATE, &fp ) != CURLE_OK || !fp )
+ return MediaCurl::aliveCallback( clientp, dltotal, dlnow, ultotal, ulnow );
+ if ( ftell( fp ) == 0 )
+ return MediaCurl::aliveCallback( clientp, dltotal, 0.0, ultotal, ulnow );
+
+ // (no longer needed due to the filesize check above?)
// work around curl bug that gives us old data
long httpReturnCode = 0;
if (curl_easy_getinfo(_curl, CURLINFO_RESPONSE_CODE, &httpReturnCode ) != CURLE_OK || httpReturnCode == 0)
- return 0;
+ return MediaCurl::aliveCallback(clientp, dltotal, dlnow, ultotal, ulnow);
char *ptr = NULL;
bool ismetalink = false;
}
if (!ismetalink && dlnow < 256)
{
- // can't tell yet, suppress callback
- return 0;
+ // can't tell yet, ...
+ return MediaCurl::aliveCallback(clientp, dltotal, dlnow, ultotal, ulnow);
}
if (!ismetalink)
{
- FILE *fp = 0;
- if (curl_easy_getinfo(_curl, CURLINFO_PRIVATE, &fp) != CURLE_OK)
- return 0;
- if (!fp)
- return 0; /* hmm */
fflush(fp);
ismetalink = looks_like_metalink_fd(fileno(fp));
DBG << "looks_like_metalink_fd: " << ismetalink << endl;
}
if (ismetalink)
{
- // we're downloading the metalink file. no progress please.
- curl_easy_setopt(_curl, CURLOPT_NOPROGRESS, 1L);
- return 0;
+ // this is a metalink file change the expected filesize
+ MediaCurl::resetExpectedFileSize( clientp, ByteCount( 2, ByteCount::MB) );
+ // we're downloading the metalink file. Just trigger aliveCallbacks
+ curl_easy_setopt(_curl, CURLOPT_PROGRESSFUNCTION, &MediaCurl::aliveCallback);
+ return MediaCurl::aliveCallback(clientp, dltotal, dlnow, ultotal, ulnow);
}
curl_easy_setopt(_curl, CURLOPT_PROGRESSFUNCTION, &MediaCurl::progressCallback);
return MediaCurl::progressCallback(clientp, dltotal, dlnow, ultotal, ulnow);
}
-void MediaMultiCurl::doGetFileCopy( const Pathname & filename , const Pathname & target, callback::SendReport<DownloadProgressReport> & report, RequestOptions options ) const
+void MediaMultiCurl::doGetFileCopy( const Pathname & filename , const Pathname & target, callback::SendReport<DownloadProgressReport> & report, const ByteCount &expectedFileSize_r, RequestOptions options ) const
{
Pathname dest = target.absolutename();
if( assert_dir( dest.dirname() ) )
curl_easy_setopt(_curl, CURLOPT_PRIVATE, file);
try
{
- MediaCurl::doGetFileCopyFile(filename, dest, file, report, options);
+ MediaCurl::doGetFileCopyFile(filename, dest, file, report, expectedFileSize_r, options);
}
catch (Exception &ex)
{
}
try
{
- multifetch(filename, file, &urls, &report, &bl);
+ multifetch(filename, file, &urls, &report, &bl, expectedFileSize_r);
}
catch (MediaCurlException &ex)
{
ZYPP_RETHROW(ex);
}
}
+ catch (MediaFileSizeExceededException &ex) {
+ ZYPP_RETHROW(ex);
+ }
catch (Exception &ex)
{
// something went wrong. fall back to normal download
file = fopen(destNew.c_str(), "w+e");
if (!file)
ZYPP_THROW(MediaWriteException(destNew));
- MediaCurl::doGetFileCopyFile(filename, dest, file, report, options | OPTION_NO_REPORT_START);
+ MediaCurl::doGetFileCopyFile(filename, dest, file, report, expectedFileSize_r, options | OPTION_NO_REPORT_START);
}
}
if (!_multi)
ZYPP_THROW(MediaCurlInitException(baseurl));
}
+
multifetchrequest req(this, filename, baseurl, _multi, fp, report, blklist, filesize);
req._timeout = _settings.timeout();
req._connect_timeout = _settings.connectTimeout();
MediaMultiCurl(const Url &url_r, const Pathname & attach_point_hint_r);
~MediaMultiCurl();
- virtual void doGetFileCopy( const Pathname & srcFilename, const Pathname & targetFilename, callback::SendReport<DownloadProgressReport> & _report, RequestOptions options = OPTION_NONE ) const;
+ virtual void doGetFileCopy( const Pathname & srcFilename, const Pathname & targetFilename, callback::SendReport<DownloadProgressReport> & _report, const ByteCount &expectedFileSize_r, RequestOptions options = OPTION_NONE ) const override;
void multifetch(const Pathname &filename, FILE *fp, std::vector<Url> *urllist, callback::SendReport<DownloadProgressReport> *report = 0, MediaBlockList *blklist = 0, off_t filesize = off_t(-1)) const;
//
// DESCRIPTION : Asserted that media is attached.
//
- void MediaNFS::getFile (const Pathname & filename) const
+ void MediaNFS::getFile (const Pathname & filename, const ByteCount &expectedFileSize_r) const
{
- MediaHandler::getFile( filename );;
+ MediaHandler::getFile( filename, expectedFileSize_r );
}
///////////////////////////////////////////////////////////////////
virtual void attachTo (bool next = false);
virtual void releaseFrom( const std::string & ejectDev );
- virtual void getFile( const Pathname & filename ) const;
+ virtual void getFile( const Pathname & filename, const ByteCount &expectedFileSize_r ) const;
virtual void getDir( const Pathname & dirname, bool recurse_r ) const;
virtual void getDirInfo( std::list<std::string> & retlist,
const Pathname & dirname, bool dots = true ) const;
void MediaPlugin::releaseFrom( const std::string & ejectDev_r )
{}
- void MediaPlugin::getFile( const Pathname & filename_r ) const
+ void MediaPlugin::getFile(const Pathname & filename_r , const ByteCount expectedFileSize_r) const
{}
void MediaPlugin::getDir( const Pathname & dirname_r, bool recurse_r ) const
protected:
virtual void attachTo( bool next_r = false );
virtual void releaseFrom( const std::string & ejectDev_r );
- virtual void getFile( const Pathname & filename_r ) const;
+ virtual void getFile( const Pathname & filename_r, const ByteCount expectedFileSize_r ) const;
virtual void getDir( const Pathname & dirname_r, bool recurse_r ) const;
virtual void getDirInfo( std::list<std::string> & retlist_r, const Pathname & dirname_r, bool dots_r = true ) const;
virtual void getDirInfo( filesystem::DirContent & retlist_r, const Pathname & dirname_r, bool dots_r = true ) const;
return true;
}
+ // xpath: /repomd/size
+ if ( reader_r->name() == "size" )
+ {
+ string size_value = reader_r.nodeText().asString();
+ zypp::ByteCount size = zypp::ByteCount( str::strtonum<ByteCount::SizeType>( size_value ) );
+ _location.setDownloadSize( size );
+ return true;
+ }
+
//! \todo xpath: /repomd/open-checksum (?)
}
Pathname keypath = masterIndex_r.extend( ".key" );
// always download them, even if repoGpgCheck is disabled
- enqueue( OnMediaLocation( sigpath, 1 ).setOptional( true ) );
- enqueue( OnMediaLocation( keypath, 1 ).setOptional( true ) );
+ enqueue( OnMediaLocation( sigpath, 1 ).setOptional( true ).setDownloadSize( ByteCount( 20, ByteCount::MB ) ) );
+ enqueue( OnMediaLocation( keypath, 1 ).setOptional( true ).setDownloadSize( ByteCount( 20, ByteCount::MB ) ) );
start( destdir_r, media_r );
reset();
WAR << "Signature checking disabled in config of repository " << repoInfo().alias() << endl;
}
- enqueue( OnMediaLocation( masterIndex_r, 1 ), checker ? checker : FileChecker(NullFileChecker()) );
+ enqueue( OnMediaLocation( masterIndex_r, 1 ).setDownloadSize( ByteCount( 20, ByteCount::MB ) ), checker ? checker : FileChecker(NullFileChecker()) );
start( destdir_r, media_r );
reset();
const ProgressData::ReceiverFnc & progressrcv )
{
Fetcher fetcher;
- fetcher.enqueue( OnMediaLocation("/media.1/media") );
+
+ //hardcode the max filesize to 20MB, to prevent unlimited data downloads but this limit will
+ //never be reached in a sane setup
+ fetcher.enqueue( OnMediaLocation("/media.1/media").setDownloadSize( ByteCount(20, ByteCount::MB ) ) );
fetcher.start( dest_dir, media, progressrcv );
// ready, go!
fetcher.reset();
\---------------------------------------------------------------------*/
#include <fstream>
+#include "zypp/base/Logger.h"
#include "zypp/repo/SUSEMediaVerifier.h"
using namespace std;
std::ifstream str(path_r.asString().c_str());
std::string vendor;
std::string id;
-
+
if ( str )
{
getline(str, _media_vendor);
if (_media_vendor.empty() || _media_id.empty())
return true;
- Pathname media_file = "/media." + str::numstring(_media_nr) + "/media";
- ref->provideFile (media_file);
- media_file = ref->localPath(media_file);
- std::ifstream str(media_file.asString().c_str());
- std::string vendor;
- std::string id;
-#warning check the stream status
- getline(str, vendor);
- getline(str, id);
+ Pathname media_file = "/media." + str::numstring(_media_nr) + "/media";
+ ref->provideFile (media_file, 0);
+ media_file = ref->localPath(media_file);
+ std::ifstream str(media_file.asString().c_str());
+ std::string vendor;
+ std::string id;
+ getline(str, vendor);
+ getline(str, id);
- return (vendor == _media_vendor && id == _media_id );
+ bool ret = ( vendor == _media_vendor && id == _media_id );
+ if ( !ret ) {
+ DBG << "cached vendor: " << _media_vendor << endl;
+ DBG << "repo vendor: " << vendor << endl;
+ DBG << "cached id: " << _media_id << endl;
+ DBG << "repo id: " << id << endl;
+ }
+ return ret;
}
}