2006-08-03 Tatsuhiro Tsujikawa <tujikawa at rednoah dot com>

* src/Option.h
	(getAsBool): New function.
	* src/Option.cc
	(prefs.h): Included.
	(defined): 0-length value is now recognized as undefined.
	(getAsInt): Rewritten.
	(getAsLLInt): Rewritten.
	(getAsBool): New function.
	
	* src/FeatureConfig.h: Rewritten.
	* src/FeatureConfig.cc: Rewritten.

	* src/prefs.h
	(PREF_STDOUT_LOG): New definition.
	(PREF_LOG): New definition.
	(PREF_DIR): New definition.
	(PREF_OUT): New definition.
	(PREF_SPLIT): New definition.
	(PREF_DAEMON): New definition.
	(PREF_REFERER): New definition.
	(PREF_TORRENT_FILE): New definition.
	(PREF_LISTEN_PORT): New definition.
	(PREF_METALINK_FILE): New definition.
	(PREF_METALINK_VERSION): New definition.
	(PREF_METALINK_LANGUAGE): New definition.
	(PREF_METALINK_OS): New definition.
	(PREF_METALINK_SERVERS): New definition.

	* src/main.cc
	(main): Following command-line parameters are now put into 
Option
	class: stdoutLog, logfile, dir, ufilename, split, daemonMode,
	referer, torrentFile, metalinkFile, listenPort, metalinkVersion,
	metalinkLanguage, metalinkOs, metalinkServers
	To fix the bug that aria2 can not handle http response header 
properly.
	
	* src/HttpHeader.cc
	(put): Made name lowercased.
	(defined): Made name lowercased.
	(getFirst): Made name lowercased.
	(get): Made name lowercased.
	(getFirstAsInt): Rewritten.
	(getFirstAsLLInt): Rewritten.
pull/1/head
Tatsuhiro Tsujikawa 2006-08-03 12:36:02 +00:00
parent 928465b7bc
commit 9251b47f6c
11 changed files with 280 additions and 145 deletions

View File

@ -1,3 +1,48 @@
2006-08-03 Tatsuhiro Tsujikawa <tujikawa at rednoah dot com>
* src/Option.h
(getAsBool): New function.
* src/Option.cc
(prefs.h): Included.
(defined): 0-length value is now recognized as undefined.
(getAsInt): Rewritten.
(getAsLLInt): Rewritten.
(getAsBool): New function.
* src/FeatureConfig.h: Rewritten.
* src/FeatureConfig.cc: Rewritten.
* src/prefs.h
(PREF_STDOUT_LOG): New definition.
(PREF_LOG): New definition.
(PREF_DIR): New definition.
(PREF_OUT): New definition.
(PREF_SPLIT): New definition.
(PREF_DAEMON): New definition.
(PREF_REFERER): New definition.
(PREF_TORRENT_FILE): New definition.
(PREF_LISTEN_PORT): New definition.
(PREF_METALINK_FILE): New definition.
(PREF_METALINK_VERSION): New definition.
(PREF_METALINK_LANGUAGE): New definition.
(PREF_METALINK_OS): New definition.
(PREF_METALINK_SERVERS): New definition.
* src/main.cc
(main): Following command-line parameters are now put into Option
class: stdoutLog, logfile, dir, ufilename, split, daemonMode,
referer, torrentFile, metalinkFile, listenPort, metalinkVersion,
metalinkLanguage, metalinkOs, metalinkServers
To fix the bug that aria2 can not handle http response header properly.
* src/HttpHeader.cc
(put): Made name lowercased.
(defined): Made name lowercased.
(getFirst): Made name lowercased.
(get): Made name lowercased.
(getFirstAsInt): Rewritten.
(getFirstAsLLInt): Rewritten.
2006-07-30 Tatsuhiro Tsujikawa <tujikawa at rednoah dot com> 2006-07-30 Tatsuhiro Tsujikawa <tujikawa at rednoah dot com>
* src/TorrentMan.h: * src/TorrentMan.h:

4
TODO
View File

@ -12,4 +12,6 @@
* Query resource by location * Query resource by location
* Log version * Log version
* List available os, version, etc for metalink * List available os, version, etc for metalink
* Performance Profiling * bittorrent in metalink
* rename Time to something appropriate
* ipv6(RFC2428 for ftp)

View File

@ -21,36 +21,63 @@
/* copyright --> */ /* copyright --> */
#include "FeatureConfig.h" #include "FeatureConfig.h"
string FeatureConfig::FEATURE_HTTP = "http"; FeatureConfig* FeatureConfig::featureConfig = 0;
string FeatureConfig::FEATURE_HTTPS = "https";
string FeatureConfig::FEATURE_FTP = "ftp";
string FeatureConfig::FEATURE_BITTORRENT = "bittorrent";
string FeatureConfig::FEATURE_METALINK = "metalink";
static ProtocolPortMap::value_type defaultPortsArray[] = { #define FEATURE_HTTP "http"
ProtocolPortMap::value_type(FeatureConfig::FEATURE_HTTP, 80), #define FEATURE_HTTPS "https"
ProtocolPortMap::value_type(FeatureConfig::FEATURE_HTTPS, 443), #define FEATURE_FTP "ftp"
ProtocolPortMap::value_type(FeatureConfig::FEATURE_FTP, 21), #define FEATURE_BITTORRENT "bittorrent"
}; #define FEATURE_METALINK "metalink"
#define FEATURE_MESSAGE_DIGEST "message digest"
ProtocolPortMap FeatureConfig::defaultPorts(&defaultPortsArray[0], FeatureConfig::FeatureConfig() {
&defaultPortsArray[3]); static PortMap::value_type portArray[] = {
PortMap::value_type("http", 80),
PortMap::value_type("https", 443),
PortMap::value_type("ftp", 21),
};
int portArraySize = sizeof(portArray)/sizeof(PortMap::value_type);
defaultPorts.insert(&portArray[0],
&portArray[portArraySize]);
static SupportedFeatureMap::value_type supportedFeaturesArray[] = { static FeatureMap::value_type featureArray[] = {
SupportedFeatureMap::value_type(FeatureConfig::FEATURE_HTTP, true), FeatureMap::value_type(FEATURE_HTTP, true),
FeatureMap::value_type(FEATURE_HTTPS,
#ifdef ENABLE_SSL #ifdef ENABLE_SSL
SupportedFeatureMap::value_type(FeatureConfig::FEATURE_HTTPS, true), true
#else
false
#endif // ENABLE_SSL #endif // ENABLE_SSL
SupportedFeatureMap::value_type(FeatureConfig::FEATURE_FTP, true), ),
FeatureMap::value_type(FEATURE_FTP, true),
FeatureMap::value_type(FEATURE_BITTORRENT,
#ifdef ENABLE_BITTORRENT #ifdef ENABLE_BITTORRENT
SupportedFeatureMap::value_type(FeatureConfig::FEATURE_BITTORRENT, true), true
#else
false
#endif // ENABLE_BITTORRENT #endif // ENABLE_BITTORRENT
),
FeatureMap::value_type(FEATURE_METALINK,
#ifdef ENABLE_METALINK #ifdef ENABLE_METALINK
SupportedFeatureMap::value_type(FeatureConfig::FEATURE_METALINK, true), true
#else
false
#endif // ENABLE_METALINK #endif // ENABLE_METALINK
}; ),
FeatureMap::value_type(FEATURE_MESSAGE_DIGEST,
#ifdef ENABLE_MESSAGE_DIGEST
true
#else
false
#endif // ENABLE_MESSAGE_DIGEST
),
};
SupportedFeatureMap int featureArraySize = sizeof(featureArray)/sizeof(FeatureMap::value_type);
FeatureConfig::supportedFeatures(&supportedFeaturesArray[0], supportedFeatures.insert(&featureArray[0],
&supportedFeaturesArray[sizeof(supportedFeaturesArray)/sizeof(SupportedFeatureMap::value_type)]); &featureArray[featureArraySize]);
for(int i = 0; i < featureArraySize; i++) {
features.push_back(featureArray[i].first);
}
}

View File

@ -25,48 +25,60 @@
#include "common.h" #include "common.h"
#include <map> #include <map>
typedef map<string, int> ProtocolPortMap; typedef map<string, int> PortMap;
typedef map<string, bool> SupportedFeatureMap; typedef map<string, bool> FeatureMap;
class FeatureConfig { class FeatureConfig {
private: private:
static ProtocolPortMap defaultPorts; static FeatureConfig* featureConfig;
static SupportedFeatureMap supportedFeatures;
PortMap defaultPorts;
FeatureMap supportedFeatures;
Strings features;
FeatureConfig();
~FeatureConfig() {}
public: public:
static string FEATURE_HTTP; static FeatureConfig* getInstance() {
static string FEATURE_HTTPS; if(!featureConfig) {
static string FEATURE_FTP; featureConfig = new FeatureConfig();
static string FEATURE_BITTORRENT; }
static string FEATURE_METALINK; return featureConfig;
}
static int getDefaultPort(const string& protocol) { static void release() {
if(defaultPorts.count(protocol)) { delete featureConfig;
return defaultPorts[protocol]; featureConfig = 0;
} else { }
int getDefaultPort(const string& protocol) const {
PortMap::const_iterator itr = defaultPorts.find(protocol);
if(itr == defaultPorts.end()) {
return 0; return 0;
} else {
return itr->second;
} }
} }
static bool isSupported(const string& protocol) { bool isSupported(const string& feature) const {
if(supportedFeatures.count(protocol)) { FeatureMap::const_iterator itr = supportedFeatures.find(feature);
return supportedFeatures[protocol]; if(itr == supportedFeatures.end()) {
} else {
return false; return false;
} else {
return itr->second;
} }
} }
static string getConfigurationSummary() { const Strings& getFeatures() const {
string protos[] = { return features;
FEATURE_HTTP, }
FEATURE_HTTPS,
FEATURE_FTP, string getConfigurationSummary() const {
FEATURE_BITTORRENT,
FEATURE_METALINK
};
string summary; string summary;
for(int i = 0; i < (int)(sizeof(protos)/sizeof(string)); i++) { for(Strings::const_iterator itr = features.begin();
summary += protos[i]; itr != features.end(); itr++) {
if(isSupported(protos[i])) { summary += *itr;
if(isSupported(*itr)) {
summary += ": yes"; summary += ": yes";
} else { } else {
summary += ": no"; summary += ": no";

View File

@ -20,18 +20,19 @@
*/ */
/* copyright --> */ /* copyright --> */
#include "HttpHeader.h" #include "HttpHeader.h"
#include "Util.h"
void HttpHeader::put(const string& name, const string& value) { void HttpHeader::put(const string& name, const string& value) {
multimap<string, string>::value_type vt(name, value); multimap<string, string>::value_type vt(Util::toLower(name), value);
table.insert(vt); table.insert(vt);
} }
bool HttpHeader::defined(const string& name) const { bool HttpHeader::defined(const string& name) const {
return table.count(name) == 1; return table.count(Util::toLower(name)) >= 1;
} }
string HttpHeader::getFirst(const string& name) const { string HttpHeader::getFirst(const string& name) const {
multimap<string, string>::const_iterator itr = table.find(name); multimap<string, string>::const_iterator itr = table.find(Util::toLower(name));
if(itr == table.end()) { if(itr == table.end()) {
return ""; return "";
} else { } else {
@ -41,26 +42,21 @@ string HttpHeader::getFirst(const string& name) const {
Strings HttpHeader::get(const string& name) const { Strings HttpHeader::get(const string& name) const {
Strings v; Strings v;
for(multimap<string, string>::const_iterator itr = table.find(name); itr != table.end(); itr++) { for(multimap<string, string>::const_iterator itr = table.find(Util::toLower(name)); itr != table.end(); itr++) {
v.push_back((*itr).second); v.push_back((*itr).second);
} }
return v; return v;
} }
int HttpHeader::getFirstAsInt(const string& name) const { int HttpHeader::getFirstAsInt(const string& name) const {
multimap<string, string>::const_iterator itr = table.find(name); return (int)getFirstAsLLInt(name);
if(itr == table.end()) {
return 0;
} else {
return (int)strtol((*itr).second.c_str(), NULL, 10);
}
} }
long long int HttpHeader::getFirstAsLLInt(const string& name) const { long long int HttpHeader::getFirstAsLLInt(const string& name) const {
multimap<string, string>::const_iterator itr = table.find(name); string value = getFirst(name);
if(itr == table.end()) { if(value == "") {
return 0; return 0;
} else { } else {
return strtoll((*itr).second.c_str(), NULL, 10); return strtoll(value.c_str(), NULL, 10);
} }
} }

View File

@ -20,6 +20,7 @@
*/ */
/* copyright --> */ /* copyright --> */
#include "Option.h" #include "Option.h"
#include "prefs.h"
Option::Option() {} Option::Option() {}
@ -43,19 +44,28 @@ string Option::get(const string& name) const {
} }
int Option::getAsInt(const string& name) const { int Option::getAsInt(const string& name) const {
map<string, string>::const_iterator itr = table.find(name); string value = get(name);
if(itr == table.end()) { if(value == "") {
return 0; return 0;
} else { } else {
return (int)strtol((*itr).second.c_str(), NULL, 10); return (int)strtol(value.c_str(), NULL, 10);
} }
} }
long long int Option::getAsLLInt(const string& name) const { long long int Option::getAsLLInt(const string& name) const {
map<string, string>::const_iterator itr = table.find(name); string value = get(name);
if(itr == table.end()) { if(value == "") {
return 0; return 0;
} else { } else {
return (int)strtoll((*itr).second.c_str(), NULL, 10); return strtoll(value.c_str(), NULL, 10);
}
}
bool Option::getAsBool(const string& name) const {
string value = get(name);
if(value == V_TRUE) {
return true;
} else {
return false;
} }
} }

View File

@ -40,6 +40,7 @@ public:
string get(const string& name) const; string get(const string& name) const;
int getAsInt(const string& name) const; int getAsInt(const string& name) const;
long long int getAsLLInt(const string& name) const; long long int getAsLLInt(const string& name) const;
bool getAsBool(const string& name) const;
}; };
#endif // _D_OPTION_H_ #endif // _D_OPTION_H_

View File

@ -54,7 +54,7 @@ bool Request::parseUrl(const string& url) {
string tempUrl; string tempUrl;
string::size_type sharpIndex = url.find("#"); string::size_type sharpIndex = url.find("#");
if(sharpIndex != string::npos) { if(sharpIndex != string::npos) {
if(FeatureConfig::isSupported(FeatureConfig::FEATURE_METALINK) && if(FeatureConfig::getInstance()->isSupported("metalink") &&
url.find(METALINK_MARK) == sharpIndex) { url.find(METALINK_MARK) == sharpIndex) {
tempUrl = url.substr(sharpIndex+strlen(METALINK_MARK)); tempUrl = url.substr(sharpIndex+strlen(METALINK_MARK));
} else { } else {
@ -82,7 +82,7 @@ bool Request::parseUrl(const string& url) {
if(hp == string::npos) return false; if(hp == string::npos) return false;
protocol = tempUrl.substr(0, hp); protocol = tempUrl.substr(0, hp);
int defPort; int defPort;
if((defPort = FeatureConfig::getDefaultPort(protocol)) == 0) { if((defPort = FeatureConfig::getInstance()->getDefaultPort(protocol)) == 0) {
return false; return false;
} }
hp += 3; hp += 3;

View File

@ -132,7 +132,7 @@ void showVersion() {
cout << "Copyright (C) 2006 Tatsuhiro Tsujikawa" << endl; cout << "Copyright (C) 2006 Tatsuhiro Tsujikawa" << endl;
cout << endl; cout << endl;
cout << "**Configuration**" << endl; cout << "**Configuration**" << endl;
cout << FeatureConfig::getConfigurationSummary(); cout << FeatureConfig::getInstance()->getConfigurationSummary();
cout << endl; cout << endl;
cout << cout <<
_("This program is free software; you can redistribute it and/or modify\n" _("This program is free software; you can redistribute it and/or modify\n"
@ -291,8 +291,6 @@ void showUsage() {
bool normalDownload(const Requests& requests, bool normalDownload(const Requests& requests,
const Requests& reserved, const Requests& reserved,
Option* op, Option* op,
const string& dir,
const string& ufilename,
string& downloadedFilename) { string& downloadedFilename) {
setSignalHander(SIGINT, handler, 0); setSignalHander(SIGINT, handler, 0);
setSignalHander(SIGTERM, handler, 0); setSignalHander(SIGTERM, handler, 0);
@ -301,8 +299,8 @@ bool normalDownload(const Requests& requests,
e->option = op; e->option = op;
e->segmentMan = new SegmentMan(); e->segmentMan = new SegmentMan();
e->segmentMan->diskWriter = new DefaultDiskWriter(); e->segmentMan->diskWriter = new DefaultDiskWriter();
e->segmentMan->dir = dir; e->segmentMan->dir = op->get(PREF_DIR);
e->segmentMan->ufilename = ufilename; e->segmentMan->ufilename = op->get(PREF_OUT);
e->segmentMan->option = op; e->segmentMan->option = op;
e->segmentMan->splitter = new SplitSlowestSegmentSplitter(); e->segmentMan->splitter = new SplitSlowestSegmentSplitter();
e->segmentMan->splitter->setMinSegmentSize(op->getAsLLInt(PREF_MIN_SEGMENT_SIZE)); e->segmentMan->splitter->setMinSegmentSize(op->getAsLLInt(PREF_MIN_SEGMENT_SIZE));
@ -345,20 +343,6 @@ int main(int argc, char* argv[]) {
bindtextdomain (PACKAGE, LOCALEDIR); bindtextdomain (PACKAGE, LOCALEDIR);
textdomain (PACKAGE); textdomain (PACKAGE);
#endif // ENABLE_NLS #endif // ENABLE_NLS
bool stdoutLog = false;
string logfile;
string dir = ".";
string ufilename;
int split = 1;
bool daemonMode = false;
string referer;
string torrentFile;
string metalinkFile;
int listenPort = -1;
string metalinkVersion;
string metalinkLanguage;
string metalinkOs;
int metalinkServers = 15;
Integers selectFileIndexes; Integers selectFileIndexes;
#ifdef ENABLE_BITTORRENT #ifdef ENABLE_BITTORRENT
bool followTorrent = true; bool followTorrent = true;
@ -373,6 +357,12 @@ int main(int argc, char* argv[]) {
int c; int c;
Option* op = new Option(); Option* op = new Option();
op->put(PREF_STDOUT_LOG, V_FALSE);
op->put(PREF_DIR, ".");
op->put(PREF_SPLIT, "1");
op->put(PREF_DAEMON, V_FALSE);
op->put(PREF_LISTEN_PORT, "-1");
op->put(PREF_METALINK_SERVERS, "15");
op->put(PREF_RETRY_WAIT, "5"); op->put(PREF_RETRY_WAIT, "5");
op->put(PREF_TIMEOUT, "60"); op->put(PREF_TIMEOUT, "60");
op->put(PREF_PEER_CONNECTION_TIMEOUT, "60"); op->put(PREF_PEER_CONNECTION_TIMEOUT, "60");
@ -479,7 +469,7 @@ int main(int argc, char* argv[]) {
} }
break; break;
case 7: case 7:
referer = optarg; op->put(PREF_REFERER, optarg);
break; break;
case 8: { case 8: {
int wait = (int)strtol(optarg, NULL, 10); int wait = (int)strtol(optarg, NULL, 10);
@ -544,14 +534,16 @@ int main(int argc, char* argv[]) {
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
break; break;
case 15: case 15: {
listenPort = (int)strtol(optarg, NULL, 10); int listenPort = (int)strtol(optarg, NULL, 10);
if(!(1024 <= listenPort && listenPort <= 65535)) { if(!(1024 <= listenPort && listenPort <= 65535)) {
cerr << _("listen-port must be between 1024 and 65535.") << endl; cerr << _("listen-port must be between 1024 and 65535.") << endl;
showUsage(); showUsage();
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
op->put(PREF_LISTEN_PORT, Util::itos(listenPort));
break; break;
}
case 16: case 16:
if(string(optarg) == "true") { if(string(optarg) == "true") {
followTorrent = true; followTorrent = true;
@ -591,13 +583,13 @@ int main(int argc, char* argv[]) {
Util::unfoldRange(optarg, selectFileIndexes); Util::unfoldRange(optarg, selectFileIndexes);
break; break;
case 100: case 100:
metalinkVersion = string(optarg); op->put(PREF_METALINK_VERSION, optarg);
break; break;
case 101: case 101:
metalinkLanguage = string(optarg); op->put(PREF_METALINK_LANGUAGE, optarg);
break; break;
case 102: case 102:
metalinkOs = string(optarg); op->put(PREF_METALINK_OS, optarg);
break; break;
case 103: case 103:
if(string(optarg) == "true") { if(string(optarg) == "true") {
@ -614,29 +606,31 @@ int main(int argc, char* argv[]) {
break; break;
} }
case 'D': case 'D':
daemonMode = true; op->put(PREF_DAEMON, V_TRUE);
break; break;
case 'd': case 'd':
dir = optarg; op->put(PREF_DIR, optarg);
break; break;
case 'o': case 'o':
ufilename = optarg; op->put(PREF_OUT, optarg);
break; break;
case 'l': case 'l':
if(strcmp("-", optarg) == 0) { if(strcmp("-", optarg) == 0) {
stdoutLog = true; op->put(PREF_STDOUT_LOG, V_TRUE);
} else { } else {
logfile = optarg; op->put(PREF_LOG, optarg);
} }
break; break;
case 's': case 's': {
split = (int)strtol(optarg, NULL, 10); int split = (int)strtol(optarg, NULL, 10);
if(!(1 <= split && split <= 5)) { if(!(1 <= split && split <= 5)) {
cerr << _("split must be between 1 and 5.") << endl; cerr << _("split must be between 1 and 5.") << endl;
showUsage(); showUsage();
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
op->put(PREF_SPLIT, Util::itos(split));
break; break;
}
case 't': { case 't': {
int timeout = (int)strtol(optarg, NULL, 10); int timeout = (int)strtol(optarg, NULL, 10);
if(1 <= timeout && timeout <= 600) { if(1 <= timeout && timeout <= 600) {
@ -665,19 +659,21 @@ int main(int argc, char* argv[]) {
op->put(PREF_SHOW_FILES, V_TRUE); op->put(PREF_SHOW_FILES, V_TRUE);
break; break;
case 'T': case 'T':
torrentFile = string(optarg); op->put(PREF_TORRENT_FILE, optarg);
break; break;
case 'M': case 'M':
metalinkFile = string(optarg); op->put(PREF_METALINK_FILE, optarg);
break; break;
case 'C': case 'C': {
metalinkServers = (int)strtol(optarg, NULL, 10); int metalinkServers = (int)strtol(optarg, NULL, 10);
if(metalinkServers <= 0) { if(metalinkServers <= 0) {
cerr << _("metalink-servers must be greater than 0.") << endl; cerr << _("metalink-servers must be greater than 0.") << endl;
showUsage(); showUsage();
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
break; op->put(PREF_METALINK_SERVERS, Util::itos(metalinkServers));
break;
}
case 'v': case 'v':
showVersion(); showVersion();
exit(EXIT_SUCCESS); exit(EXIT_SUCCESS);
@ -689,14 +685,14 @@ int main(int argc, char* argv[]) {
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
} }
if(torrentFile.empty() && metalinkFile.empty()) { if(!op->defined(PREF_TORRENT_FILE) && !op->defined(PREF_METALINK_FILE)) {
if(optind == argc) { if(optind == argc) {
cerr << _("specify at least one URL") << endl; cerr << _("specify at least one URL") << endl;
showUsage(); showUsage();
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
} }
if(daemonMode) { if(op->getAsBool(PREF_DAEMON)) {
if(daemon(1, 1) < 0) { if(daemon(1, 1) < 0) {
perror(_("daemon failed")); perror(_("daemon failed"));
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
@ -704,7 +700,7 @@ int main(int argc, char* argv[]) {
} }
Strings args(argv+optind, argv+argc); Strings args(argv+optind, argv+argc);
#ifdef HAVE_LIBSSL #ifdef HAVE_LIBSSL
// for SSL initialization // for SSL initialization
SSL_load_error_strings(); SSL_load_error_strings();
@ -717,10 +713,10 @@ int main(int argc, char* argv[]) {
xmlInitParser(); xmlInitParser();
#endif // ENABLE_METALINK #endif // ENABLE_METALINK
srandom(time(NULL)); srandom(time(NULL));
if(stdoutLog) { if(op->getAsBool(PREF_STDOUT_LOG)) {
LogFactory::setLogFile("/dev/stdout"); LogFactory::setLogFile("/dev/stdout");
} else if(logfile.size()) { } else if(op->get(PREF_LOG).size()) {
LogFactory::setLogFile(logfile); LogFactory::setLogFile(op->get(PREF_LOG));
} }
// make sure logger is configured properly. // make sure logger is configured properly.
try { try {
@ -733,12 +729,12 @@ int main(int argc, char* argv[]) {
setSignalHander(SIGPIPE, SIG_IGN, 0); setSignalHander(SIGPIPE, SIG_IGN, 0);
if(torrentFile.empty() && metalinkFile.empty()) { if(!op->defined(PREF_TORRENT_FILE) && !op->defined(PREF_METALINK_FILE)) {
Requests requests; Requests requests;
int cuidCounter = 1; int cuidCounter = 1;
for(Strings::const_iterator itr = args.begin(); itr != args.end(); itr++) { for(Strings::const_iterator itr = args.begin(); itr != args.end(); itr++) {
for(int s = 1; s <= split; s++) { for(int s = 1; s <= op->getAsInt(PREF_SPLIT); s++) {
createRequest(cuidCounter, *itr, referer, requests); createRequest(cuidCounter, *itr, op->get(PREF_REFERER), requests);
cuidCounter++; cuidCounter++;
} }
} }
@ -747,22 +743,24 @@ int main(int argc, char* argv[]) {
Requests reserved; Requests reserved;
string downloadedFilename; string downloadedFilename;
normalDownload(requests, reserved, op, dir, ufilename, downloadedFilename); normalDownload(requests, reserved, op, downloadedFilename);
for_each(requests.begin(), requests.end(), Deleter()); for_each(requests.begin(), requests.end(), Deleter());
for_each(reserved.begin(), reserved.end(), Deleter()); for_each(reserved.begin(), reserved.end(), Deleter());
requests.clear(); requests.clear();
} }
#ifdef ENABLE_METALINK #ifdef ENABLE_METALINK
if(!metalinkFile.empty() || followMetalink && readyToMetalinkMode) { if(op->defined(PREF_METALINK_FILE) ||
string targetMetalinkFile = metalinkFile.empty() ? followMetalink && readyToMetalinkMode) {
downloadedMetalinkFile : metalinkFile; string targetMetalinkFile = op->defined(PREF_METALINK_FILE) ?
op->get(PREF_METALINK_FILE) : downloadedMetalinkFile;
Xml2MetalinkProcessor proc; Xml2MetalinkProcessor proc;
Metalinker* metalinker = proc.parseFile(targetMetalinkFile); Metalinker* metalinker = proc.parseFile(targetMetalinkFile);
MetalinkEntry* entry = metalinker->queryEntry(metalinkVersion, MetalinkEntry* entry =
metalinkLanguage, metalinker->queryEntry(op->get(PREF_METALINK_VERSION),
metalinkOs); op->get(PREF_METALINK_LANGUAGE),
op->get(PREF_METALINK_OS));
if(entry == NULL) { if(entry == NULL) {
printf("No file matched with your preference.\n"); printf("No file matched with your preference.\n");
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
@ -774,13 +772,15 @@ int main(int argc, char* argv[]) {
for(MetalinkResources::const_iterator itr = entry->resources.begin(); for(MetalinkResources::const_iterator itr = entry->resources.begin();
itr != entry->resources.end(); itr++) { itr != entry->resources.end(); itr++) {
MetalinkResource* resource = *itr; MetalinkResource* resource = *itr;
for(int s = 1; s <= split; s++) { for(int s = 1; s <= op->getAsInt(PREF_SPLIT); s++) {
createRequest(cuidCounter, resource->url, referer, requests); createRequest(cuidCounter, resource->url,
op->get(PREF_REFERER), requests);
cuidCounter++; cuidCounter++;
} }
} }
Requests reserved; Requests reserved;
int maxConnection = metalinkServers*split; int maxConnection =
op->getAsInt(PREF_METALINK_SERVERS)*op->getAsInt(PREF_SPLIT);
if((int)requests.size() > maxConnection) { if((int)requests.size() > maxConnection) {
copy(requests.begin()+maxConnection, requests.end(), copy(requests.begin()+maxConnection, requests.end(),
insert_iterator<Requests>(reserved, reserved.end())); insert_iterator<Requests>(reserved, reserved.end()));
@ -791,8 +791,7 @@ int main(int argc, char* argv[]) {
setSignalHander(SIGTERM, handler, 0); setSignalHander(SIGTERM, handler, 0);
string downloadedFilename; string downloadedFilename;
bool success = normalDownload(requests, reserved, op, dir, ufilename, bool success = normalDownload(requests, reserved, op, downloadedFilename);
downloadedFilename);
for_each(requests.begin(), requests.end(), Deleter()); for_each(requests.begin(), requests.end(), Deleter());
for_each(reserved.begin(), reserved.end(), Deleter()); for_each(reserved.begin(), reserved.end(), Deleter());
@ -813,7 +812,8 @@ int main(int argc, char* argv[]) {
} }
#endif // ENABLE_METALINK #endif // ENABLE_METALINK
#ifdef ENABLE_BITTORRENT #ifdef ENABLE_BITTORRENT
if(!torrentFile.empty() || followTorrent && readyToTorrentMode) { if(op->defined(PREF_TORRENT_FILE) ||
followTorrent && readyToTorrentMode) {
try { try {
//op->put(PREF_MAX_TRIES, "0"); //op->put(PREF_MAX_TRIES, "0");
setSignalHander(SIGINT, torrentHandler, SA_RESETHAND); setSignalHander(SIGINT, torrentHandler, SA_RESETHAND);
@ -831,11 +831,11 @@ int main(int argc, char* argv[]) {
te->segmentMan->splitter = new SplitSlowestSegmentSplitter(); te->segmentMan->splitter = new SplitSlowestSegmentSplitter();
te->segmentMan->splitter->setMinSegmentSize(op->getAsLLInt(PREF_MIN_SEGMENT_SIZE)); te->segmentMan->splitter->setMinSegmentSize(op->getAsLLInt(PREF_MIN_SEGMENT_SIZE));
te->torrentMan = new TorrentMan(); te->torrentMan = new TorrentMan();
te->torrentMan->setStoreDir(dir); te->torrentMan->setStoreDir(op->get(PREF_DIR));
te->torrentMan->option = op; te->torrentMan->option = op;
te->torrentMan->req = req; te->torrentMan->req = req;
string targetTorrentFile = torrentFile.empty() ? string targetTorrentFile = op->defined(PREF_TORRENT_FILE) ?
downloadedTorrentFile : torrentFile; op->get(PREF_TORRENT_FILE) : downloadedTorrentFile;
if(op->get(PREF_SHOW_FILES) == V_TRUE) { if(op->get(PREF_SHOW_FILES) == V_TRUE) {
FileEntries fileEntries = FileEntries fileEntries =
te->torrentMan->readFileEntryFromMetaInfoFile(targetTorrentFile); te->torrentMan->readFileEntryFromMetaInfoFile(targetTorrentFile);
@ -853,7 +853,7 @@ int main(int argc, char* argv[]) {
} else { } else {
if(selectFileIndexes.empty()) { if(selectFileIndexes.empty()) {
Strings targetFiles; Strings targetFiles;
if(!torrentFile.empty() && !args.empty()) { if(op->defined(PREF_TORRENT_FILE) && !args.empty()) {
targetFiles = args; targetFiles = args;
} }
te->torrentMan->setup(targetTorrentFile, targetFiles); te->torrentMan->setup(targetTorrentFile, targetFiles);
@ -864,6 +864,7 @@ int main(int argc, char* argv[]) {
PeerListenCommand* listenCommand = PeerListenCommand* listenCommand =
new PeerListenCommand(te->torrentMan->getNewCuid(), te); new PeerListenCommand(te->torrentMan->getNewCuid(), te);
int port; int port;
int listenPort = op->getAsInt(PREF_LISTEN_PORT);
if(listenPort == -1) { if(listenPort == -1) {
port = listenCommand->bindPort(6881, 6999); port = listenCommand->bindPort(6881, 6999);
} else { } else {
@ -911,5 +912,6 @@ int main(int argc, char* argv[]) {
#ifdef ENABLE_METALINK #ifdef ENABLE_METALINK
xmlCleanupParser(); xmlCleanupParser();
#endif // ENABLE_METALINK #endif // ENABLE_METALINK
FeatureConfig::release();
return 0; return 0;
} }

View File

@ -43,6 +43,20 @@
#define PREF_MIN_SEGMENT_SIZE "min_segment_size" #define PREF_MIN_SEGMENT_SIZE "min_segment_size"
// values: 1*digit // values: 1*digit
#define PREF_AUTO_SAVE_INTERVAL "auto_save_interval" #define PREF_AUTO_SAVE_INTERVAL "auto_save_interval"
// values: true | false
#define PREF_STDOUT_LOG "stdout_log"
// values: a string that your file system recognizes as a file name.
#define PREF_LOG "log"
// values: a string that your file system recognizes as a directory.
#define PREF_DIR "dir"
// values: a string that your file system recognizes as a file name.
#define PREF_OUT "out"
// values: 1*digit
#define PREF_SPLIT "split"
// value: true | false
#define PREF_DAEMON "daemon"
// value: a string
#define PREF_REFERER "referer"
/** /**
* FTP related preferences * FTP related preferences
@ -98,5 +112,23 @@
#define PREF_DIRECT_FILE_MAPPING "direct_file_mapping" #define PREF_DIRECT_FILE_MAPPING "direct_file_mapping"
// values: 1*digit // values: 1*digit
#define PREF_UPLOAD_LIMIT "upload_limit" #define PREF_UPLOAD_LIMIT "upload_limit"
// values: a string that your file system recognizes as a file name.
#define PREF_TORRENT_FILE "torrent_file"
// values: 1*digit
#define PREF_LISTEN_PORT "listen_port"
/**
* Metalink related preferences
*/
// values: a string that your file system recognizes as a file name.
#define PREF_METALINK_FILE "metalink_file"
// values: a string
#define PREF_METALINK_VERSION "metalink_version"
// values: a string
#define PREF_METALINK_LANGUAGE "metalink_language"
// values: a string
#define PREF_METALINK_OS "metalink_os"
// values: 1*digit
#define PREF_METALINK_SERVERS "metalink_servers"
#endif // _D_PREFS_H_ #endif // _D_PREFS_H_

View File

@ -20,16 +20,23 @@ public:
CPPUNIT_TEST_SUITE_REGISTRATION(FeatureConfigTest); CPPUNIT_TEST_SUITE_REGISTRATION(FeatureConfigTest);
void FeatureConfigTest::testGetDefaultPort() { void FeatureConfigTest::testGetDefaultPort() {
CPPUNIT_ASSERT_EQUAL(80, FeatureConfig::getDefaultPort("http")); CPPUNIT_ASSERT_EQUAL(80,
CPPUNIT_ASSERT_EQUAL(443, FeatureConfig::getDefaultPort("https")); FeatureConfig::getInstance()->getDefaultPort("http"));
CPPUNIT_ASSERT_EQUAL(21, FeatureConfig::getDefaultPort("ftp")); CPPUNIT_ASSERT_EQUAL(443,
FeatureConfig::getInstance()->getDefaultPort("https"));
CPPUNIT_ASSERT_EQUAL(21,
FeatureConfig::getInstance()->getDefaultPort("ftp"));
} }
void FeatureConfigTest::testIsSupported() { void FeatureConfigTest::testIsSupported() {
CPPUNIT_ASSERT_EQUAL(true, FeatureConfig::isSupported("http")); CPPUNIT_ASSERT_EQUAL(true,
CPPUNIT_ASSERT_EQUAL(true, FeatureConfig::isSupported("https")); FeatureConfig::getInstance()->isSupported("http"));
CPPUNIT_ASSERT_EQUAL(true, FeatureConfig::isSupported("ftp")); CPPUNIT_ASSERT_EQUAL(true,
CPPUNIT_ASSERT_EQUAL(false, FeatureConfig::isSupported("ftps")); FeatureConfig::getInstance()->isSupported("https"));
CPPUNIT_ASSERT_EQUAL(true,
FeatureConfig::getInstance()->isSupported("ftp"));
CPPUNIT_ASSERT_EQUAL(false,
FeatureConfig::getInstance()->isSupported("ftps"));
} }
void FeatureConfigTest::testGetConfigurationSummary() { void FeatureConfigTest::testGetConfigurationSummary() {
@ -37,6 +44,7 @@ void FeatureConfigTest::testGetConfigurationSummary() {
+"https: yes\n" +"https: yes\n"
+"ftp: yes\n" +"ftp: yes\n"
+"bittorrent: yes\n" +"bittorrent: yes\n"
+"metalink: yes\n", +"metalink: yes\n"
FeatureConfig::getConfigurationSummary()); +"message digest: yes\n",
FeatureConfig::getInstance()->getConfigurationSummary());
} }