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>
* src/TorrentMan.h:

4
TODO
View File

@ -12,4 +12,6 @@
* Query resource by location
* Log version
* 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 --> */
#include "FeatureConfig.h"
string FeatureConfig::FEATURE_HTTP = "http";
string FeatureConfig::FEATURE_HTTPS = "https";
string FeatureConfig::FEATURE_FTP = "ftp";
string FeatureConfig::FEATURE_BITTORRENT = "bittorrent";
string FeatureConfig::FEATURE_METALINK = "metalink";
FeatureConfig* FeatureConfig::featureConfig = 0;
static ProtocolPortMap::value_type defaultPortsArray[] = {
ProtocolPortMap::value_type(FeatureConfig::FEATURE_HTTP, 80),
ProtocolPortMap::value_type(FeatureConfig::FEATURE_HTTPS, 443),
ProtocolPortMap::value_type(FeatureConfig::FEATURE_FTP, 21),
};
#define FEATURE_HTTP "http"
#define FEATURE_HTTPS "https"
#define FEATURE_FTP "ftp"
#define FEATURE_BITTORRENT "bittorrent"
#define FEATURE_METALINK "metalink"
#define FEATURE_MESSAGE_DIGEST "message digest"
ProtocolPortMap FeatureConfig::defaultPorts(&defaultPortsArray[0],
&defaultPortsArray[3]);
FeatureConfig::FeatureConfig() {
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[] = {
SupportedFeatureMap::value_type(FeatureConfig::FEATURE_HTTP, true),
static FeatureMap::value_type featureArray[] = {
FeatureMap::value_type(FEATURE_HTTP, true),
FeatureMap::value_type(FEATURE_HTTPS,
#ifdef ENABLE_SSL
SupportedFeatureMap::value_type(FeatureConfig::FEATURE_HTTPS, true),
true
#else
false
#endif // ENABLE_SSL
SupportedFeatureMap::value_type(FeatureConfig::FEATURE_FTP, true),
),
FeatureMap::value_type(FEATURE_FTP, true),
FeatureMap::value_type(FEATURE_BITTORRENT,
#ifdef ENABLE_BITTORRENT
SupportedFeatureMap::value_type(FeatureConfig::FEATURE_BITTORRENT, true),
true
#else
false
#endif // ENABLE_BITTORRENT
),
FeatureMap::value_type(FEATURE_METALINK,
#ifdef ENABLE_METALINK
SupportedFeatureMap::value_type(FeatureConfig::FEATURE_METALINK, true),
true
#else
false
#endif // ENABLE_METALINK
};
),
FeatureMap::value_type(FEATURE_MESSAGE_DIGEST,
#ifdef ENABLE_MESSAGE_DIGEST
true
#else
false
#endif // ENABLE_MESSAGE_DIGEST
),
};
SupportedFeatureMap
FeatureConfig::supportedFeatures(&supportedFeaturesArray[0],
&supportedFeaturesArray[sizeof(supportedFeaturesArray)/sizeof(SupportedFeatureMap::value_type)]);
int featureArraySize = sizeof(featureArray)/sizeof(FeatureMap::value_type);
supportedFeatures.insert(&featureArray[0],
&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 <map>
typedef map<string, int> ProtocolPortMap;
typedef map<string, bool> SupportedFeatureMap;
typedef map<string, int> PortMap;
typedef map<string, bool> FeatureMap;
class FeatureConfig {
private:
static ProtocolPortMap defaultPorts;
static SupportedFeatureMap supportedFeatures;
static FeatureConfig* featureConfig;
PortMap defaultPorts;
FeatureMap supportedFeatures;
Strings features;
FeatureConfig();
~FeatureConfig() {}
public:
static string FEATURE_HTTP;
static string FEATURE_HTTPS;
static string FEATURE_FTP;
static string FEATURE_BITTORRENT;
static string FEATURE_METALINK;
static FeatureConfig* getInstance() {
if(!featureConfig) {
featureConfig = new FeatureConfig();
}
return featureConfig;
}
static int getDefaultPort(const string& protocol) {
if(defaultPorts.count(protocol)) {
return defaultPorts[protocol];
} else {
static void release() {
delete featureConfig;
featureConfig = 0;
}
int getDefaultPort(const string& protocol) const {
PortMap::const_iterator itr = defaultPorts.find(protocol);
if(itr == defaultPorts.end()) {
return 0;
} else {
return itr->second;
}
}
static bool isSupported(const string& protocol) {
if(supportedFeatures.count(protocol)) {
return supportedFeatures[protocol];
} else {
bool isSupported(const string& feature) const {
FeatureMap::const_iterator itr = supportedFeatures.find(feature);
if(itr == supportedFeatures.end()) {
return false;
} else {
return itr->second;
}
}
static string getConfigurationSummary() {
string protos[] = {
FEATURE_HTTP,
FEATURE_HTTPS,
FEATURE_FTP,
FEATURE_BITTORRENT,
FEATURE_METALINK
};
const Strings& getFeatures() const {
return features;
}
string getConfigurationSummary() const {
string summary;
for(int i = 0; i < (int)(sizeof(protos)/sizeof(string)); i++) {
summary += protos[i];
if(isSupported(protos[i])) {
for(Strings::const_iterator itr = features.begin();
itr != features.end(); itr++) {
summary += *itr;
if(isSupported(*itr)) {
summary += ": yes";
} else {
summary += ": no";

View File

@ -20,18 +20,19 @@
*/
/* copyright --> */
#include "HttpHeader.h"
#include "Util.h"
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);
}
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 {
multimap<string, string>::const_iterator itr = table.find(name);
multimap<string, string>::const_iterator itr = table.find(Util::toLower(name));
if(itr == table.end()) {
return "";
} else {
@ -41,26 +42,21 @@ string HttpHeader::getFirst(const string& name) const {
Strings HttpHeader::get(const string& name) const {
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);
}
return v;
}
int HttpHeader::getFirstAsInt(const string& name) const {
multimap<string, string>::const_iterator itr = table.find(name);
if(itr == table.end()) {
return 0;
} else {
return (int)strtol((*itr).second.c_str(), NULL, 10);
}
return (int)getFirstAsLLInt(name);
}
long long int HttpHeader::getFirstAsLLInt(const string& name) const {
multimap<string, string>::const_iterator itr = table.find(name);
if(itr == table.end()) {
string value = getFirst(name);
if(value == "") {
return 0;
} else {
return strtoll((*itr).second.c_str(), NULL, 10);
return strtoll(value.c_str(), NULL, 10);
}
}

View File

@ -20,6 +20,7 @@
*/
/* copyright --> */
#include "Option.h"
#include "prefs.h"
Option::Option() {}
@ -43,19 +44,28 @@ string Option::get(const string& name) const {
}
int Option::getAsInt(const string& name) const {
map<string, string>::const_iterator itr = table.find(name);
if(itr == table.end()) {
string value = get(name);
if(value == "") {
return 0;
} 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 {
map<string, string>::const_iterator itr = table.find(name);
if(itr == table.end()) {
string value = get(name);
if(value == "") {
return 0;
} 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;
int getAsInt(const string& name) const;
long long int getAsLLInt(const string& name) const;
bool getAsBool(const string& name) const;
};
#endif // _D_OPTION_H_

View File

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

View File

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

View File

@ -43,6 +43,20 @@
#define PREF_MIN_SEGMENT_SIZE "min_segment_size"
// values: 1*digit
#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
@ -98,5 +112,23 @@
#define PREF_DIRECT_FILE_MAPPING "direct_file_mapping"
// values: 1*digit
#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_

View File

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