17 #include <boost/lexical_cast.hpp>
43 #include <sys/types.h>
45 #include <sys/mount.h>
49 #include <boost/format.hpp>
51 #define DETECT_DIR_INDEX 0
52 #define CONNECT_TIMEOUT 60
53 #define TRANSFER_TIMEOUT 60 * 3
54 #define TRANSFER_TIMEOUT_MAX 60 * 60
56 #define ARIA_BINARY "aria2c"
59 using namespace zypp::base;
66 Pathname MediaAria2c::_cookieFile =
"/var/lib/YaST2/cookies";
67 std::string MediaAria2c::_aria2cVersion =
"WE DON'T KNOW ARIA2C VERSION";
71 MediaAria2c::existsAria2cmd()
73 static const char* argv[] =
80 return( aria.
close() == 0 );
92 const Pathname &destination,
99 list<string> file_options;
103 args.push_back(
"--summary-interval=1");
104 args.push_back(
"--follow-metalink=mem");
105 args.push_back(
"--check-integrity=true");
106 args.push_back(
"--file-allocation=none");
109 Pathname statsFile = ZConfig::instance().repoCachePath() /
"aria2.stats";
110 args.push_back(
str::form(
"--server-stat-of=%s", statsFile.c_str()));
111 args.push_back(
str::form(
"--server-stat-if=%s", statsFile.c_str()));
112 args.push_back(
"--uri-selector=adaptive");
115 vector<string> fields;
117 str::split( ariaver, std::back_inserter(fields));
118 if ( fields.size() == 3 )
121 args.push_back(
"--use-head=false");
132 WAR <<
"aria2c is older than 1.2.0, some features may be disabled" << endl;
138 for ( TransferSettings::Headers::const_iterator it = s.
headersBegin();
141 args.push_back(
str::form(
"--header=%s", it->c_str() ));
150 args.push_back(
str::form(
"--ftp-user=%s",
"suseuser" ));
151 args.push_back(
str::form(
"--ftp-passwd=%s", VERSION ));
155 DBG <<
"Anonymous FTP identification: '" <<
id <<
"'" << endl;
160 MIL <<
"Passing " << url.
getScheme() <<
" credentials '" << s.
username() <<
':' << (s.
password().empty() ?
"" :
"PASSWORD")<<
"'" << endl;
182 MIL <<
"Passing " <<
"http" <<
"-proxy credentials '" << s.
proxyUsername() <<
':' << (s.
proxyPassword().empty() ?
"" :
"PASSWORD")<<
"'" << endl;
189 if ( ! destination.empty() )
190 args.push_back(
str::form(
"--dir=%s", destination.c_str()));
193 if ( ! file_options.empty() )
197 for_( it, file_options.begin(), file_options.end() )
208 - url::ViewOptions::WITH_USERNAME
209 - url::ViewOptions::WITH_PASSWORD ).c_str());
218 Target_Ptr target = zypp::getZYpp()->getTarget();
220 static const std::string
_value(
224 , MediaAria2c::_aria2cVersion.c_str()
225 , Target::targetDistribution( Pathname() ).c_str()
228 return _value.c_str();
233 MediaAria2c::MediaAria2c(
const Url & url_r,
234 const Pathname & attach_point_hint_r )
235 :
MediaCurl( url_r, attach_point_hint_r )
237 MIL <<
"MediaAria2c::MediaAria2c(" << url_r <<
", " << attach_point_hint_r <<
")" << endl;
288 report->start(fileurl, target.
asString() );
299 "^\\[#[0-9]+ SIZE:[0-9\\.]+(|Ki|Mi|Ti)B/[0-9\\.]+(|Ki|Mi|Ti)B\\(?([0-9]+)?%?\\)? CN:[0-9]+ SPD:([0-9\\.]+)(|Ki|Mi|Ti)Bs.*\\]$");
302 bool gotProgress =
false;
306 double current_speed = 0;
308 double average_speed = 0;
310 long average_speed_count = 0;
313 vector<string> ariaExceptions;
316 bool partialDownload =
false;
318 bool userAbort =
false;
322 ariaResponse.length();
340 progress = std::atoi(progressValues[3].c_str());
345 if (progressValues[5] ==
"Ki")
347 else if (progressValues[5] ==
"Mi")
349 else if (progressValues[5] ==
"Ti")
353 current_speed = boost::lexical_cast<
double>(progressValues[4]);
355 current_speed *= factor;
357 catch (
const std::exception&) {
358 ERR <<
"Can't parse speed from '" << progressValues[4] <<
"'" << endl;
363 ERR <<
"Can't parse progress line '" << line <<
"'" << endl;
369 if (!line.substr(0,31).compare(
"Exception: Authorization failed") )
372 _url,
"Login failed.",
"Login failed",
"auth hint"
376 string excpMsg = line.substr(10, line.size());
377 DBG <<
"aria2c reported: '" << excpMsg <<
"'" << endl;
378 ariaExceptions.push_back(excpMsg);
385 string theFile(line.substr(6, line.size()));
398 average_speed_count++;
403 (((average_speed_count - 1)*average_speed) + current_speed)
404 / average_speed_count;
406 if (!partialDownload && progress > 0)
407 partialDownload =
true;
409 if ( ! report->progress ( progress, fileurl, average_speed, current_speed ) )
417 WAR <<
"aria2c reported a file, but no progress data available" << endl;
422 DBG <<
"Progress is not about '" << target <<
"' but '" << theFile <<
"'" << endl;
443 if ( ! PathInfo( target ).isExist() )
449 std::string msg(
str::form(
_(
"Failed to download %s from %s"),
453 for_( it, ariaExceptions.begin(), ariaExceptions.end() )
463 for_(it, ariaExceptions.begin(), ariaExceptions.end())
473 for_(it, ariaExceptions.begin(), ariaExceptions.end())
485 if ( partialDownload )
490 for_(it, ariaExceptions.begin(), ariaExceptions.end())
503 msg =
_(
"Download interrupted by user");
506 msg =
str::form(
_(
"Failed to download %s from %s"),
510 for_(it, ariaExceptions.begin(), ariaExceptions.end())
566 const Pathname & dirname,
bool dots )
const
572 const Pathname & dirname,
bool dots )
const
579 static const char* argv[] =