summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorTatsuhiro Tsujikawa <tatsuhiro.t@gmail.com>2006-08-14 13:48:31 +0000
committerTatsuhiro Tsujikawa <tatsuhiro.t@gmail.com>2006-08-14 13:48:31 +0000
commit2f14fec78dfc96b88a905621d35f1d726df0791d (patch)
tree8eb4dc9cf94f021ccbdf77dca88924c2c9bf4cea /src
parent43dae4fd916bb35bf7fd8554fc86ce34c3e7a31b (diff)
parent7ca1b43eddd1aba1c71a38dfb46b5ac5685b43d0 (diff)
Tagging 0.7.0 release of aria2release-0.7.0
Diffstat (limited to 'src')
-rw-r--r--src/AbstractCommand.h2
-rw-r--r--src/AbstractDiskWriter.cc20
-rw-r--r--src/Checksum.h64
-rw-r--r--src/Command.cc24
-rw-r--r--src/ConsoleDownloadEngine.h2
-rw-r--r--src/DownloadCommand.cc11
-rw-r--r--src/DownloadCommand.h2
-rw-r--r--src/DownloadEngine.cc161
-rw-r--r--src/DownloadEngine.h55
-rw-r--r--src/DownloadEngineFactory.cc123
-rw-r--r--src/DownloadEngineFactory.h46
-rw-r--r--src/FtpNegotiationCommand.cc8
-rw-r--r--src/Makefile.am17
-rw-r--r--src/Makefile.in56
-rw-r--r--src/MetalinkEntry.cc29
-rw-r--r--src/MetalinkEntry.h9
-rw-r--r--src/MetalinkRequestInfo.cc111
-rw-r--r--src/MetalinkRequestInfo.h41
-rw-r--r--src/MetalinkResource.h1
-rw-r--r--src/MultiDiskWriter.cc27
-rw-r--r--src/MultiDiskWriter.h2
-rw-r--r--src/PeerAbstractCommand.h2
-rw-r--r--src/PeerChokeCommand.cc2
-rw-r--r--src/PeerChokeCommand.h4
-rw-r--r--src/PeerInteractionCommand.h2
-rw-r--r--src/RequestInfo.h116
-rw-r--r--src/RequestSlot.h2
-rw-r--r--src/ShaVisitor.cc49
-rw-r--r--src/ShaVisitor.h4
-rw-r--r--src/SleepCommand.h2
-rw-r--r--src/TimeA2.cc (renamed from src/Time.cc)2
-rw-r--r--src/TimeA2.h (renamed from src/Time.h)0
-rw-r--r--src/TorrentAutoSaveCommand.h2
-rw-r--r--src/TorrentDownloadEngine.h2
-rw-r--r--src/TorrentMan.cc14
-rw-r--r--src/TorrentMan.h2
-rw-r--r--src/TorrentRequestInfo.cc81
-rw-r--r--src/TorrentRequestInfo.h51
-rw-r--r--src/TrackerWatcherCommand.h2
-rw-r--r--src/UrlRequestInfo.cc146
-rw-r--r--src/UrlRequestInfo.h52
-rw-r--r--src/Util.cc23
-rw-r--r--src/Util.h2
-rw-r--r--src/Xml2MetalinkProcessor.cc18
-rw-r--r--src/main.cc405
-rw-r--r--src/messageDigest.h119
-rw-r--r--src/prefs.h8
47 files changed, 1300 insertions, 623 deletions
diff --git a/src/AbstractCommand.h b/src/AbstractCommand.h
index 6d84013d..5289d14e 100644
--- a/src/AbstractCommand.h
+++ b/src/AbstractCommand.h
@@ -26,7 +26,7 @@
#include "Request.h"
#include "DownloadEngine.h"
#include "SegmentMan.h"
-#include "Time.h"
+#include "TimeA2.h"
class AbstractCommand : public Command {
private:
diff --git a/src/AbstractDiskWriter.cc b/src/AbstractDiskWriter.cc
index 7f6f85c8..ff56fa57 100644
--- a/src/AbstractDiskWriter.cc
+++ b/src/AbstractDiskWriter.cc
@@ -30,17 +30,21 @@
#include <errno.h>
#include <fcntl.h>
-AbstractDiskWriter::AbstractDiskWriter():fd(0) {
+AbstractDiskWriter::AbstractDiskWriter():
+ fd(0)
+#ifdef ENABLE_MESSAGE_DIGEST
+ ,ctx(DIGEST_ALGO_SHA1)
+#endif // ENABLE_MESSAGE_DIGEST
+{
#ifdef ENABLE_MESSAGE_DIGEST
- ctx.setAlgo(MessageDigestContext::ALGO_SHA1);
- digestInit(ctx);
+ ctx.digestInit();
#endif // ENABLE_MESSAGE_DIGEST
}
AbstractDiskWriter::~AbstractDiskWriter() {
closeFile();
#ifdef ENABLE_MESSAGE_DIGEST
- digestFree(ctx);
+ ctx.digestFree();
#endif // ENABLE_MESSAGE_DIGEST
}
@@ -100,7 +104,7 @@ int AbstractDiskWriter::readDataInternal(char* data, int len) {
string AbstractDiskWriter::sha1Sum(long long int offset, long long int length) {
#ifdef ENABLE_MESSAGE_DIGEST
- digestReset(ctx);
+ ctx.digestReset();
try {
int BUFSIZE = 16*1024;
char buf[BUFSIZE];
@@ -108,7 +112,7 @@ string AbstractDiskWriter::sha1Sum(long long int offset, long long int length) {
if(BUFSIZE != readData(buf, BUFSIZE, offset)) {
throw string("error");
}
- digestUpdate(ctx, buf, BUFSIZE);
+ ctx.digestUpdate(buf, BUFSIZE);
offset += BUFSIZE;
}
int r = length%BUFSIZE;
@@ -116,10 +120,10 @@ string AbstractDiskWriter::sha1Sum(long long int offset, long long int length) {
if(r != readData(buf, r, offset)) {
throw string("error");
}
- digestUpdate(ctx, buf, r);
+ ctx.digestUpdate(buf, r);
}
unsigned char hashValue[20];
- digestFinal(ctx, hashValue);
+ ctx.digestFinal(hashValue);
return Util::toHex(hashValue, 20);
} catch(string ex) {
throw new DlAbortEx(EX_FILE_SHA1SUM, filename.c_str(), strerror(errno));
diff --git a/src/Checksum.h b/src/Checksum.h
new file mode 100644
index 00000000..220befe7
--- /dev/null
+++ b/src/Checksum.h
@@ -0,0 +1,64 @@
+/* <!-- copyright */
+/*
+ * aria2 - a simple utility for downloading files faster
+ *
+ * Copyright (C) 2006 Tatsuhiro Tsujikawa
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+/* copyright --> */
+#ifndef _D_CHECKSUM_H_
+#define _D_CHECKSUM_H_
+
+#include "common.h"
+#include "messageDigest.h"
+
+#ifdef ENABLE_MESSAGE_DIGEST
+class Checksum {
+private:
+ string md;
+ MessageDigestContext::DigestAlgo algo;
+public:
+ Checksum(const string& md, MessageDigestContext::DigestAlgo algo):
+ md(md),
+ algo(algo) {}
+ Checksum():
+ algo(DIGEST_ALGO_SHA1) {}
+ ~Checksum() {}
+
+ bool isEmpty() const {
+ return md.size() == 0;
+ }
+
+ void setMessageDigest(const string& md) {
+ this->md = md;
+ }
+ const string& getMessageDigest() const {
+ return md;
+ }
+
+ void setDigestAlgo(MessageDigestContext::DigestAlgo algo) {
+ this->algo = algo;
+ }
+ const MessageDigestContext::DigestAlgo& getDigestAlgo() const {
+ return algo;
+ }
+};
+#else
+class Checksum {
+};
+#endif // ENABLE_MESSAGE_DIGEST
+
+#endif // _D_CHECKSUM_H_
diff --git a/src/Command.cc b/src/Command.cc
new file mode 100644
index 00000000..6227aee2
--- /dev/null
+++ b/src/Command.cc
@@ -0,0 +1,24 @@
+/* <!-- copyright */
+/*
+ * aria2 - a simple utility for downloading files faster
+ *
+ * Copyright (C) 2006 Tatsuhiro Tsujikawa
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+/* copyright --> */
+#include "Command.h"
+
+int Command::uuidGen = 0;
diff --git a/src/ConsoleDownloadEngine.h b/src/ConsoleDownloadEngine.h
index f708c008..8b009f75 100644
--- a/src/ConsoleDownloadEngine.h
+++ b/src/ConsoleDownloadEngine.h
@@ -23,7 +23,7 @@
#define _D_CONSOLE_DOWNLOAD_ENGINE_H_
#include "DownloadEngine.h"
-#include "Time.h"
+#include "TimeA2.h"
class ConsoleDownloadEngine : public DownloadEngine {
private:
diff --git a/src/DownloadCommand.cc b/src/DownloadCommand.cc
index 441b00de..4e948f53 100644
--- a/src/DownloadCommand.cc
+++ b/src/DownloadCommand.cc
@@ -20,12 +20,14 @@
*/
/* copyright --> */
#include "DownloadCommand.h"
-#include <sys/time.h>
#include "Util.h"
#include "DlRetryEx.h"
+#include "DlAbortEx.h"
#include "HttpInitiateConnectionCommand.h"
#include "InitiateConnectionCommandFactory.h"
#include "message.h"
+#include "prefs.h"
+#include <sys/time.h>
DownloadCommand::DownloadCommand(int cuid, Request* req, DownloadEngine* e,
const SocketHandle& s):
@@ -59,6 +61,13 @@ bool DownloadCommand::executeInternal(Segment seg) {
seg.speed = (int)((seg.ds-lastSize)/(diff*1.0));
sw.reset();
lastSize = seg.ds;
+ int lowestLimit = e->option->getAsInt(PREF_LOWEST_SPEED_LIMIT);
+ if(lowestLimit > 0 && seg.speed <= lowestLimit) {
+ throw new DlAbortEx("CUID#%d - Too slow Downloading speed: %d <= %d(B/s)",
+ cuid,
+ seg.speed,
+ lowestLimit);
+ }
}
if(e->segmentMan->totalSize != 0 && bufSize == 0) {
throw new DlRetryEx(EX_GOT_EOF);
diff --git a/src/DownloadCommand.h b/src/DownloadCommand.h
index 9f10de02..60403adf 100644
--- a/src/DownloadCommand.h
+++ b/src/DownloadCommand.h
@@ -24,7 +24,7 @@
#include "AbstractCommand.h"
#include "TransferEncoding.h"
-#include "Time.h"
+#include "TimeA2.h"
using namespace std;
diff --git a/src/DownloadEngine.cc b/src/DownloadEngine.cc
index 0f6f36af..912381da 100644
--- a/src/DownloadEngine.cc
+++ b/src/DownloadEngine.cc
@@ -22,7 +22,7 @@
#include "DownloadEngine.h"
#include "Util.h"
#include "LogFactory.h"
-#include "Time.h"
+#include "TimeA2.h"
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
@@ -32,14 +32,13 @@
using namespace std;
-DownloadEngine::DownloadEngine():noWait(false), segmentMan(NULL) {
+DownloadEngine::DownloadEngine():noWait(false), segmentMan(0) {
logger = LogFactory::getInstance();
}
DownloadEngine::~DownloadEngine() {
- if(segmentMan != NULL) {
- delete segmentMan;
- }
+ delete segmentMan;
+ cleanQueue();
}
void DownloadEngine::cleanQueue() {
@@ -66,7 +65,7 @@ public:
void DownloadEngine::run() {
initStatistics();
Time cp;
- CommandUuids activeCommandUuids;
+ CommandUuids activeUuids;
while(!commands.empty()) {
if(cp.elapsed(1)) {
cp.reset();
@@ -79,8 +78,8 @@ void DownloadEngine::run() {
}
}
} else {
- for(CommandUuids::iterator itr = activeCommandUuids.begin();
- itr != activeCommandUuids.end(); itr++) {
+ for(CommandUuids::iterator itr = activeUuids.begin();
+ itr != activeUuids.end(); itr++) {
Commands::iterator comItr = find_if(commands.begin(), commands.end(),
FindCommand(*itr));
assert(comItr != commands.end());
@@ -92,9 +91,9 @@ void DownloadEngine::run() {
}
}
afterEachIteration();
- activeCommandUuids.clear();
+ activeUuids.clear();
if(!noWait && !commands.empty()) {
- waitData(activeCommandUuids);
+ waitData(activeUuids);
}
noWait = false;
calculateStatistics();
@@ -113,63 +112,86 @@ void DownloadEngine::shortSleep() const {
class SetDescriptor {
private:
- fd_set* fds_ptr;
int* max_ptr;
+ fd_set* rfds_ptr;
+ fd_set* wfds_ptr;
public:
- SetDescriptor(int* max_ptr, fd_set* fds_ptr)
- :fds_ptr(fds_ptr), max_ptr(max_ptr) {}
-
- void operator()(const SockCmdMap::value_type& pa) {
- int fd = pa.first->getSockfd();
- FD_SET(fd, fds_ptr);
+ SetDescriptor(int* max_ptr, fd_set* rfds_ptr, fd_set* wfds_ptr):
+ max_ptr(max_ptr),
+ rfds_ptr(rfds_ptr),
+ wfds_ptr(wfds_ptr) {}
+
+ void operator()(const SocketEntry& entry) {
+ int fd = entry.socket->getSockfd();
+ switch(entry.type) {
+ case SocketEntry::TYPE_RD:
+ FD_SET(fd, rfds_ptr);
+ break;
+ case SocketEntry::TYPE_WR:
+ FD_SET(fd, wfds_ptr);
+ break;
+ }
if(*max_ptr < fd) {
*max_ptr = fd;
}
}
};
-class AccumulateActiveCommandUuid {
+class AccumulateActiveUuid {
private:
- CommandUuids* activeCommandUuids_ptr;
- fd_set* fds_ptr;
+ CommandUuids* activeUuids_ptr;
+ fd_set* rfds_ptr;
+ fd_set* wfds_ptr;
public:
- AccumulateActiveCommandUuid(CommandUuids* activeCommandUuids_ptr,
- fd_set* fds_ptr)
- :activeCommandUuids_ptr(activeCommandUuids_ptr), fds_ptr(fds_ptr) {}
-
- void operator()(const SockCmdMap::value_type& pa) {
- if(FD_ISSET(pa.first->getSockfd(), fds_ptr)) {
- activeCommandUuids_ptr->push_back(pa.second);
+ AccumulateActiveUuid(CommandUuids* activeUuids_ptr,
+ fd_set* rfds_ptr,
+ fd_set* wfds_ptr):
+ activeUuids_ptr(activeUuids_ptr),
+ rfds_ptr(rfds_ptr),
+ wfds_ptr(wfds_ptr) {}
+
+ void operator()(const SocketEntry& entry) {
+ if(FD_ISSET(entry.socket->getSockfd(), rfds_ptr) ||
+ FD_ISSET(entry.socket->getSockfd(), wfds_ptr)) {
+ activeUuids_ptr->push_back(entry.commandUuid);
}
+ /*
+ switch(entry.type) {
+ case SocketEntry::TYPE_RD:
+ if(FD_ISSET(entry.socket->getSockfd(), rfds_ptr)) {
+ activeUuids_ptr->push_back(entry.commandUuid);
+ }
+ break;
+ case SocketEntry::TYPE_WR:
+ if(FD_ISSET(entry.socket->getSockfd(), wfds_ptr)) {
+ activeUuids_ptr->push_back(entry.commandUuid);
+ }
+ break;
+ }
+ */
}
};
-void DownloadEngine::waitData(CommandUuids& activeCommandUuids) {
+void DownloadEngine::waitData(CommandUuids& activeUuids) {
fd_set rfds;
fd_set wfds;
int retval = 0;
- while(1) {
- struct timeval tv;
-
- memcpy(&rfds, &rfdset, sizeof(fd_set));
- memcpy(&wfds, &wfdset, sizeof(fd_set));
-
- tv.tv_sec = 1;
- tv.tv_usec = 0;
- retval = select(fdmax+1, &rfds, &wfds, NULL, &tv);
- if(retval != -1 || errno != EINTR) {
- break;
- }
- }
+ struct timeval tv;
+
+ memcpy(&rfds, &rfdset, sizeof(fd_set));
+ memcpy(&wfds, &wfdset, sizeof(fd_set));
+
+ tv.tv_sec = 1;
+ tv.tv_usec = 0;
+ retval = select(fdmax+1, &rfds, &wfds, NULL, &tv);
if(retval > 0) {
- for_each(rsockmap.begin(), rsockmap.end(),
- AccumulateActiveCommandUuid(&activeCommandUuids, &rfds));
- for_each(wsockmap.begin(), wsockmap.end(),
- AccumulateActiveCommandUuid(&activeCommandUuids, &wfds));
- sort(activeCommandUuids.begin(), activeCommandUuids.end());
- activeCommandUuids.erase(unique(activeCommandUuids.begin(),
- activeCommandUuids.end()),
- activeCommandUuids.end());
+ for_each(socketEntries.begin(), socketEntries.end(),
+ AccumulateActiveUuid(&activeUuids, &rfds, &wfds));
+
+ sort(activeUuids.begin(), activeUuids.end());
+ activeUuids.erase(unique(activeUuids.begin(),
+ activeUuids.end()),
+ activeUuids.end());
}
}
@@ -177,18 +199,15 @@ void DownloadEngine::updateFdSet() {
fdmax = 0;
FD_ZERO(&rfdset);
FD_ZERO(&wfdset);
- for_each(rsockmap.begin(), rsockmap.end(), SetDescriptor(&fdmax, &rfdset));
- for_each(wsockmap.begin(), wsockmap.end(), SetDescriptor(&fdmax, &wfdset));
+ for_each(socketEntries.begin(), socketEntries.end(),
+ SetDescriptor(&fdmax, &rfdset, &wfdset));
}
-bool DownloadEngine::addSocket(SockCmdMap& sockmap,
- const SocketHandle& socket,
- const CommandUuid& commandUuid) {
- SockCmdMap::iterator itr = find_if(sockmap.begin(), sockmap.end(),
- PairFind<SocketHandle, CommandUuid>(socket, commandUuid));
- if(itr == sockmap.end()) {
- SockCmdMap::value_type vt(socket, commandUuid);
- sockmap.insert(vt);
+bool DownloadEngine::addSocket(const SocketEntry& entry) {
+ SocketEntries::iterator itr =
+ find(socketEntries.begin(), socketEntries.end(), entry);
+ if(itr == socketEntries.end()) {
+ socketEntries.push_back(entry);
updateFdSet();
return true;
} else {
@@ -196,15 +215,13 @@ bool DownloadEngine::addSocket(SockCmdMap& sockmap,
}
}
-bool DownloadEngine::deleteSocket(SockCmdMap& sockmap,
- const SocketHandle& socket,
- const CommandUuid& commandUuid) {
- SockCmdMap::iterator itr = find_if(sockmap.begin(), sockmap.end(),
- PairFind<SocketHandle, CommandUuid>(socket, commandUuid));
- if(itr == sockmap.end()) {
+bool DownloadEngine::deleteSocket(const SocketEntry& entry) {
+ SocketEntries::iterator itr =
+ find(socketEntries.begin(), socketEntries.end(), entry);
+ if(itr == socketEntries.end()) {
return false;
} else {
- sockmap.erase(itr);
+ socketEntries.erase(itr);
updateFdSet();
return true;
}
@@ -212,20 +229,24 @@ bool DownloadEngine::deleteSocket(SockCmdMap& sockmap,
bool DownloadEngine::addSocketForReadCheck(const SocketHandle& socket,
const CommandUuid& commandUuid) {
- return addSocket(rsockmap, socket, commandUuid);
+ SocketEntry entry(socket, commandUuid, SocketEntry::TYPE_RD);
+ return addSocket(entry);
}
bool DownloadEngine::deleteSocketForReadCheck(const SocketHandle& socket,
const CommandUuid& commandUuid) {
- return deleteSocket(rsockmap, socket, commandUuid);
+ SocketEntry entry(socket, commandUuid, SocketEntry::TYPE_RD);
+ return deleteSocket(entry);
}
bool DownloadEngine::addSocketForWriteCheck(const SocketHandle& socket,
const CommandUuid& commandUuid) {
- return addSocket(wsockmap, socket, commandUuid);
+ SocketEntry entry(socket, commandUuid, SocketEntry::TYPE_WR);
+ return addSocket(entry);
}
bool DownloadEngine::deleteSocketForWriteCheck(const SocketHandle& socket,
const CommandUuid& commandUuid) {
- return deleteSocket(wsockmap, socket, commandUuid);
+ SocketEntry entry(socket, commandUuid, SocketEntry::TYPE_WR);
+ return deleteSocket(entry);
}
diff --git a/src/DownloadEngine.h b/src/DownloadEngine.h
index d2dd0521..aa118ac7 100644
--- a/src/DownloadEngine.h
+++ b/src/DownloadEngine.h
@@ -32,22 +32,44 @@
typedef deque<SocketHandle> Sockets;
typedef deque<Command*> Commands;
typedef deque<CommandUuid> CommandUuids;
-typedef multimap<SocketHandle, int> SockCmdMap;
+
+class SocketEntry {
+public:
+ enum TYPE {
+ TYPE_RD,
+ TYPE_WR,
+ };
+
+ SocketHandle socket;
+ CommandUuid commandUuid;
+ TYPE type;
+public:
+ SocketEntry(const SocketHandle& socket,
+ const CommandUuid& commandUuid,
+ TYPE type):
+ socket(socket), commandUuid(commandUuid), type(type) {}
+ ~SocketEntry() {}
+
+ bool operator==(const SocketEntry& entry) {
+ return socket == entry.socket &&
+ commandUuid == entry.commandUuid &&
+ type == entry.type;
+ }
+};
+
+typedef deque<SocketEntry> SocketEntries;
class DownloadEngine {
private:
- void waitData(CommandUuids& activeCommandUuids);
- SockCmdMap rsockmap;
- SockCmdMap wsockmap;
+ void waitData(CommandUuids& activeUuids);
+ SocketEntries socketEntries;
fd_set rfdset;
fd_set wfdset;
int fdmax;
void shortSleep() const;
- bool addSocket(SockCmdMap& sockmap, const SocketHandle& socket,
- const CommandUuid& commandUuid);
- bool deleteSocket(SockCmdMap& sockmap, const SocketHandle& socket,
- const CommandUuid& commandUuid);
+ bool addSocket(const SocketEntry& socketEntry);
+ bool deleteSocket(const SocketEntry& socketEntry);
protected:
const Logger* logger;
virtual void initStatistics() = 0;
@@ -80,22 +102,5 @@ public:
};
-template<class T1, class T2>
-class PairFind {
-private:
- T1 first;
- T2 second;
-public:
- PairFind(T1 t1, T2 t2):first(t1), second(t2) {}
-
- bool operator()(const pair<T1, T2>& pa) {
- if(pa.first == first && pa.second == second) {
- return true;
- } else {
- return false;
- }
- }
-};
-
#endif // _D_DOWNLOAD_ENGINE_H_
diff --git a/src/DownloadEngineFactory.cc b/src/DownloadEngineFactory.cc
new file mode 100644
index 00000000..52da662c
--- /dev/null
+++ b/src/DownloadEngineFactory.cc
@@ -0,0 +1,123 @@
+/* <!-- copyright */
+/*
+ * aria2 - a simple utility for downloading files faster
+ *
+ * Copyright (C) 2006 Tatsuhiro Tsujikawa
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+/* copyright --> */
+#include "DownloadEngineFactory.h"
+#include "prefs.h"
+#include "DefaultDiskWriter.h"
+#include "SplitSlowestSegmentSplitter.h"
+#include "InitiateConnectionCommandFactory.h"
+#include "ByteArrayDiskWriter.h"
+#include "Util.h"
+#ifdef ENABLE_BITTORRENT
+# include "PeerListenCommand.h"
+# include "TrackerWatcherCommand.h"
+# include "TrackerUpdateCommand.h"
+# include "TorrentAutoSaveCommand.h"
+# include "PeerChokeCommand.h"
+# include "HaveEraseCommand.h"
+#endif // ENABLE_BITTORRENT
+
+ConsoleDownloadEngine*
+DownloadEngineFactory::newConsoleEngine(const Option* op,
+ const Requests& requests,
+ const Requests& reserved)
+{
+ ConsoleDownloadEngine* e = new ConsoleDownloadEngine();
+ e->option = op;
+ e->segmentMan = new SegmentMan();
+ e->segmentMan->diskWriter = new DefaultDiskWriter();
+ 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));
+ e->segmentMan->reserved = reserved;
+
+ int cuidCounter = 1;
+ for(Requests::const_iterator itr = requests.begin();
+ itr != requests.end();
+ itr++, cuidCounter++) {
+ e->commands.push_back(InitiateConnectionCommandFactory::createInitiateConnectionCommand(cuidCounter, *itr, e));
+ }
+ return e;
+}
+
+#ifdef ENABLE_BITTORRENT
+TorrentConsoleDownloadEngine*
+DownloadEngineFactory::newTorrentConsoleEngine(const Option* op,
+ const string& torrentFile,
+ const Strings& targetFiles)
+{
+ Request* req = new Request();
+ req->isTorrent = true;
+ req->setTrackerEvent(Request::STARTED);
+ TorrentConsoleDownloadEngine* te = new TorrentConsoleDownloadEngine();
+ te->option = op;
+ ByteArrayDiskWriter* byteArrayDiskWriter = new ByteArrayDiskWriter();
+ te->segmentMan = new SegmentMan();
+ te->segmentMan->diskWriter = byteArrayDiskWriter;
+ te->segmentMan->option = op;
+ te->segmentMan->splitter = new SplitSlowestSegmentSplitter();
+ te->segmentMan->splitter->setMinSegmentSize(op->getAsLLInt(PREF_MIN_SEGMENT_SIZE));
+ te->torrentMan = new TorrentMan();
+ te->torrentMan->setStoreDir(op->get(PREF_DIR));
+ te->torrentMan->option = op;
+ te->torrentMan->req = req;
+ Integers selectIndexes;
+ Util::unfoldRange(op->get(PREF_SELECT_FILE), selectIndexes);
+ if(selectIndexes.size()) {
+ te->torrentMan->setup(torrentFile, selectIndexes);
+ } else {
+ te->torrentMan->setup(torrentFile, targetFiles);
+ }
+
+ 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 {
+ port = listenCommand->bindPort(listenPort, listenPort);
+ }
+ if(port == -1) {
+ printf(_("Errors occurred while binding port.\n"));
+ exit(EXIT_FAILURE);
+ }
+ te->torrentMan->setPort(port);
+ te->commands.push_back(listenCommand);
+
+ te->commands.push_back(new TrackerWatcherCommand(te->torrentMan->getNewCuid(),
+ te,
+ te->torrentMan->minInterval));
+ te->commands.push_back(new TrackerUpdateCommand(te->torrentMan->getNewCuid(),
+ te));
+ te->commands.push_back(new TorrentAutoSaveCommand(te->torrentMan->getNewCuid(),
+ te,
+ op->getAsInt(PREF_AUTO_SAVE_INTERVAL)));
+ te->commands.push_back(new PeerChokeCommand(te->torrentMan->getNewCuid(),
+ te, 10));
+ te->commands.push_back(new HaveEraseCommand(te->torrentMan->getNewCuid(),
+ te, 10));
+
+ return te;
+}
+#endif // ENABLE_BITTORRENT
diff --git a/src/DownloadEngineFactory.h b/src/DownloadEngineFactory.h
new file mode 100644
index 00000000..10108fbc
--- /dev/null
+++ b/src/DownloadEngineFactory.h
@@ -0,0 +1,46 @@
+/* <!-- copyright */
+/*
+ * aria2 - a simple utility for downloading files faster
+ *
+ * Copyright (C) 2006 Tatsuhiro Tsujikawa
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+/* copyright --> */
+#ifndef _D_DOWNLOAD_ENGINE_FACTORY_H_
+#define _D_DOWNLOAD_ENGINE_FACTORY_H_
+
+#include "common.h"
+#include "ConsoleDownloadEngine.h"
+#ifdef ENABLE_BITTORRENT
+# include "TorrentConsoleDownloadEngine.h"
+#endif // ENABLE_BITTORRENT
+
+class DownloadEngineFactory {
+public:
+ static ConsoleDownloadEngine*
+ newConsoleEngine(const Option* option,
+ const Requests& requests,
+ const Requests& reserved);
+
+#ifdef ENABLE_BITTORRENT
+ static TorrentConsoleDownloadEngine*
+ newTorrentConsoleEngine(const Option* option,
+ const string& torrentFile,
+ const Strings& targetFiles);
+#endif // ENABLE_BITTORRENT
+};
+
+#endif // _D_DOWNLOAD_ENGINE_FACTORY_H_
diff --git a/src/FtpNegotiationCommand.cc b/src/FtpNegotiationCommand.cc
index 67b08f6b..34641e27 100644
--- a/src/FtpNegotiationCommand.cc
+++ b/src/FtpNegotiationCommand.cc
@@ -57,6 +57,9 @@ bool FtpNegotiationCommand::executeInternal(Segment segment) {
bool FtpNegotiationCommand::recvGreeting() {
socket->setBlockingMode();
+ disableWriteCheckSocket();
+ setReadCheckSocket(socket);
+
int status = ftp->receiveResponse();
if(status == 0) {
return false;
@@ -66,9 +69,6 @@ bool FtpNegotiationCommand::recvGreeting() {
}
sequence = SEQ_SEND_USER;
- setReadCheckSocket(socket);
- disableWriteCheckSocket();
-
return true;
}
@@ -264,7 +264,7 @@ bool FtpNegotiationCommand::recvRetr() {
if(status == 0) {
return false;
}
- if(status != 150) {
+ if(status != 150 && status != 125) {
throw new DlRetryEx(EX_BAD_STATUS, status);
}
if(e->option->get(PREF_FTP_PASV_ENABLED) != V_TRUE) {
diff --git a/src/Makefile.am b/src/Makefile.am
index 1cfbac55..5344ccfa 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -50,9 +50,12 @@ SRCS = Socket.h\
messageDigest.h\
LogFactory.cc LogFactory.h\
NullLogger.h\
- Time.cc Time.h\
+ TimeA2.cc TimeA2.h\
SharedHandle.h\
- FeatureConfig.cc FeatureConfig.h
+ FeatureConfig.cc FeatureConfig.h\
+ DownloadEngineFactory.cc DownloadEngineFactory.h\
+ RequestInfo.h\
+ UrlRequestInfo.cc UrlRequestInfo.h
if ENABLE_BITTORRENT
SRCS += MetaEntry.h\
@@ -108,7 +111,8 @@ SRCS += MetaEntry.h\
SuggestPieceMessage.cc SuggestPieceMessage.h\
SimplePeerMessage.cc SimplePeerMessage.h\
PeerMessageFactory.cc PeerMessageFactory.h\
- HaveEraseCommand.cc HaveEraseCommand.h
+ HaveEraseCommand.cc HaveEraseCommand.h\
+ TorrentRequestInfo.cc TorrentRequestInfo.h
endif # ENABLE_BITTORRENT
if ENABLE_METALINK
@@ -116,15 +120,16 @@ SRCS += Metalinker.cc Metalinker.h\
MetalinkEntry.cc MetalinkEntry.h\
MetalinkResource.cc MetalinkResource.h\
MetalinkProcessor.h\
- Xml2MetalinkProcessor.cc Xml2MetalinkProcessor.h
+ Xml2MetalinkProcessor.cc Xml2MetalinkProcessor.h\
+ MetalinkRequestInfo.cc MetalinkRequestInfo.h
endif # ENABLE_METALINK
noinst_LIBRARIES = libaria2c.a
libaria2c_a_SOURCES = $(SRCS)
aria2c_LDADD = libaria2c.a @LIBINTL@ @ALLOCA@ @LIBGNUTLS_LIBS@\
@LIBGCRYPT_LIBS@ @OPENSSL_LIBS@ @XML_LIBS@
-aria2c_LDFLAGS = -pg
+#aria2c_LDFLAGS = -pg
AM_CPPFLAGS = -Wall\
-I../lib -I../intl -I$(top_srcdir)/intl\
@LIBGNUTLS_CFLAGS@ @LIBGCRYPT_CFLAGS@ @OPENSSL_CFLAGS@ @XML_CPPFLAGS@\
- -D_FILE_OFFSET_BITS=64 -DLOCALEDIR=\"$(localedir)\" @DEFS@ -pg \ No newline at end of file
+ -D_FILE_OFFSET_BITS=64 -DLOCALEDIR=\"$(localedir)\" @DEFS@# -pg \ No newline at end of file
diff --git a/src/Makefile.in b/src/Makefile.in
index 12f65d27..f542ff0c 100644
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -91,13 +91,15 @@ bin_PROGRAMS = aria2c$(EXEEXT)
@ENABLE_BITTORRENT_TRUE@ SuggestPieceMessage.cc SuggestPieceMessage.h\
@ENABLE_BITTORRENT_TRUE@ SimplePeerMessage.cc SimplePeerMessage.h\
@ENABLE_BITTORRENT_TRUE@ PeerMessageFactory.cc PeerMessageFactory.h\
-@ENABLE_BITTORRENT_TRUE@ HaveEraseCommand.cc HaveEraseCommand.h
+@ENABLE_BITTORRENT_TRUE@ HaveEraseCommand.cc HaveEraseCommand.h\
+@ENABLE_BITTORRENT_TRUE@ TorrentRequestInfo.cc TorrentRequestInfo.h
@ENABLE_METALINK_TRUE@am__append_2 = Metalinker.cc Metalinker.h\
@ENABLE_METALINK_TRUE@ MetalinkEntry.cc MetalinkEntry.h\
@ENABLE_METALINK_TRUE@ MetalinkResource.cc MetalinkResource.h\
@ENABLE_METALINK_TRUE@ MetalinkProcessor.h\
-@ENABLE_METALINK_TRUE@ Xml2MetalinkProcessor.cc Xml2MetalinkProcessor.h
+@ENABLE_METALINK_TRUE@ Xml2MetalinkProcessor.cc Xml2MetalinkProcessor.h\
+@ENABLE_METALINK_TRUE@ MetalinkRequestInfo.cc MetalinkRequestInfo.h
subdir = src
DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in alloca.c
@@ -154,14 +156,15 @@ am__libaria2c_a_SOURCES_DIST = Socket.h SocketCore.cc SocketCore.h \
PreAllocationDiskWriter.h AbstractDiskWriter.cc \
AbstractDiskWriter.h File.cc File.h Option.cc Option.h \
Base64.cc Base64.h CookieBox.cc CookieBox.h messageDigest.h \
- LogFactory.cc LogFactory.h NullLogger.h Time.cc Time.h \
- SharedHandle.h FeatureConfig.cc FeatureConfig.h MetaEntry.h \
- Data.cc Data.h Dictionary.cc Dictionary.h List.cc List.h \
- MetaFileUtil.cc MetaFileUtil.h MetaEntryVisitor.h \
- ShaVisitor.cc ShaVisitor.h TorrentMan.cc TorrentMan.h \
- PeerConnection.cc PeerConnection.h PeerMessageUtil.cc \
- PeerMessageUtil.h PeerAbstractCommand.cc PeerAbstractCommand.h \
- PeerInitiateConnectionCommand.cc \
+ LogFactory.cc LogFactory.h NullLogger.h TimeA2.cc TimeA2.h \
+ SharedHandle.h FeatureConfig.cc FeatureConfig.h \
+ DownloadEngineFactory.cc DownloadEngineFactory.h RequestInfo.h \
+ UrlRequestInfo.cc UrlRequestInfo.h MetaEntry.h Data.cc Data.h \
+ Dictionary.cc Dictionary.h List.cc List.h MetaFileUtil.cc \
+ MetaFileUtil.h MetaEntryVisitor.h ShaVisitor.cc ShaVisitor.h \
+ TorrentMan.cc TorrentMan.h PeerConnection.cc PeerConnection.h \
+ PeerMessageUtil.cc PeerMessageUtil.h PeerAbstractCommand.cc \
+ PeerAbstractCommand.h PeerInitiateConnectionCommand.cc \
PeerInitiateConnectionCommand.h PeerInteractionCommand.cc \
PeerInteractionCommand.h Peer.cc Peer.h BitfieldMan.cc \
BitfieldMan.h TorrentDownloadEngine.cc TorrentDownloadEngine.h \
@@ -191,9 +194,11 @@ am__libaria2c_a_SOURCES_DIST = Socket.h SocketCore.cc SocketCore.h \
SuggestPieceMessage.cc SuggestPieceMessage.h \
SimplePeerMessage.cc SimplePeerMessage.h PeerMessageFactory.cc \
PeerMessageFactory.h HaveEraseCommand.cc HaveEraseCommand.h \
- Metalinker.cc Metalinker.h MetalinkEntry.cc MetalinkEntry.h \
+ TorrentRequestInfo.cc TorrentRequestInfo.h Metalinker.cc \
+ Metalinker.h MetalinkEntry.cc MetalinkEntry.h \
MetalinkResource.cc MetalinkResource.h MetalinkProcessor.h \
- Xml2MetalinkProcessor.cc Xml2MetalinkProcessor.h
+ Xml2MetalinkProcessor.cc Xml2MetalinkProcessor.h \
+ MetalinkRequestInfo.cc MetalinkRequestInfo.h
@ENABLE_BITTORRENT_TRUE@am__objects_1 = Data.$(OBJEXT) \
@ENABLE_BITTORRENT_TRUE@ Dictionary.$(OBJEXT) List.$(OBJEXT) \
@ENABLE_BITTORRENT_TRUE@ MetaFileUtil.$(OBJEXT) \
@@ -241,11 +246,13 @@ am__libaria2c_a_SOURCES_DIST = Socket.h SocketCore.cc SocketCore.h \
@ENABLE_BITTORRENT_TRUE@ SuggestPieceMessage.$(OBJEXT) \
@ENABLE_BITTORRENT_TRUE@ SimplePeerMessage.$(OBJEXT) \
@ENABLE_BITTORRENT_TRUE@ PeerMessageFactory.$(OBJEXT) \
-@ENABLE_BITTORRENT_TRUE@ HaveEraseCommand.$(OBJEXT)
+@ENABLE_BITTORRENT_TRUE@ HaveEraseCommand.$(OBJEXT) \
+@ENABLE_BITTORRENT_TRUE@ TorrentRequestInfo.$(OBJEXT)
@ENABLE_METALINK_TRUE@am__objects_2 = Metalinker.$(OBJEXT) \
@ENABLE_METALINK_TRUE@ MetalinkEntry.$(OBJEXT) \
@ENABLE_METALINK_TRUE@ MetalinkResource.$(OBJEXT) \
-@ENABLE_METALINK_TRUE@ Xml2MetalinkProcessor.$(OBJEXT)
+@ENABLE_METALINK_TRUE@ Xml2MetalinkProcessor.$(OBJEXT) \
+@ENABLE_METALINK_TRUE@ MetalinkRequestInfo.$(OBJEXT)
am__objects_3 = SocketCore.$(OBJEXT) Command.$(OBJEXT) \
AbstractCommand.$(OBJEXT) \
InitiateConnectionCommandFactory.$(OBJEXT) \
@@ -268,8 +275,9 @@ am__objects_3 = SocketCore.$(OBJEXT) Command.$(OBJEXT) \
ChunkedEncoding.$(OBJEXT) DefaultDiskWriter.$(OBJEXT) \
PreAllocationDiskWriter.$(OBJEXT) AbstractDiskWriter.$(OBJEXT) \
File.$(OBJEXT) Option.$(OBJEXT) Base64.$(OBJEXT) \
- CookieBox.$(OBJEXT) LogFactory.$(OBJEXT) Time.$(OBJEXT) \
- FeatureConfig.$(OBJEXT) $(am__objects_1) $(am__objects_2)
+ CookieBox.$(OBJEXT) LogFactory.$(OBJEXT) TimeA2.$(OBJEXT) \
+ FeatureConfig.$(OBJEXT) DownloadEngineFactory.$(OBJEXT) \
+ UrlRequestInfo.$(OBJEXT) $(am__objects_1) $(am__objects_2)
am_libaria2c_a_OBJECTS = $(am__objects_3)
libaria2c_a_OBJECTS = $(am_libaria2c_a_OBJECTS)
am__installdirs = "$(DESTDIR)$(bindir)"
@@ -457,19 +465,21 @@ SRCS = Socket.h SocketCore.cc SocketCore.h Command.cc Command.h \
PreAllocationDiskWriter.h AbstractDiskWriter.cc \
AbstractDiskWriter.h File.cc File.h Option.cc Option.h \
Base64.cc Base64.h CookieBox.cc CookieBox.h messageDigest.h \
- LogFactory.cc LogFactory.h NullLogger.h Time.cc Time.h \
+ LogFactory.cc LogFactory.h NullLogger.h TimeA2.cc TimeA2.h \
SharedHandle.h FeatureConfig.cc FeatureConfig.h \
- $(am__append_1) $(am__append_2)
+ DownloadEngineFactory.cc DownloadEngineFactory.h RequestInfo.h \
+ UrlRequestInfo.cc UrlRequestInfo.h $(am__append_1) \
+ $(am__append_2)
noinst_LIBRARIES = libaria2c.a
libaria2c_a_SOURCES = $(SRCS)
aria2c_LDADD = libaria2c.a @LIBINTL@ @ALLOCA@ @LIBGNUTLS_LIBS@\
@LIBGCRYPT_LIBS@ @OPENSSL_LIBS@ @XML_LIBS@
-aria2c_LDFLAGS = -pg
+#aria2c_LDFLAGS = -pg
AM_CPPFLAGS = -Wall\
-I../lib -I../intl -I$(top_srcdir)/intl\
@LIBGNUTLS_CFLAGS@ @LIBGCRYPT_CFLAGS@ @OPENSSL_CFLAGS@ @XML_CPPFLAGS@\
- -D_FILE_OFFSET_BITS=64 -DLOCALEDIR=\"$(localedir)\" @DEFS@ -pg
+ -D_FILE_OFFSET_BITS=64 -DLOCALEDIR=\"$(localedir)\" @DEFS@# -pg
all: all-am
@@ -567,6 +577,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/DiskAdaptor.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/DownloadCommand.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/DownloadEngine.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/DownloadEngineFactory.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/FeatureConfig.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/File.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/FtpConnection.Po@am__quote@
@@ -595,6 +606,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/LogFactory.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/MetaFileUtil.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/MetalinkEntry.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/MetalinkRequestInfo.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/MetalinkResource.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Metalinker.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/MultiDiskAdaptor.Po@am__quote@
@@ -630,14 +642,16 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/SplitFirstSegmentSplitter.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/SplitSlowestSegmentSplitter.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/SuggestPieceMessage.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Time.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/TimeA2.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/TorrentAutoSaveCommand.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/TorrentConsoleDownloadEngine.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/TorrentDownloadEngine.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/TorrentMan.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/TorrentRequestInfo.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/TrackerUpdateCommand.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/TrackerWatcherCommand.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/UnchokeMessage.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/UrlRequestInfo.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Util.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Xml2MetalinkProcessor.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/main.Po@am__quote@
diff --git a/src/MetalinkEntry.cc b/src/MetalinkEntry.cc
index 6eb86f50..4a4327a8 100644
--- a/src/MetalinkEntry.cc
+++ b/src/MetalinkEntry.cc
@@ -29,30 +29,6 @@ MetalinkEntry::~MetalinkEntry() {
for_each(resources.begin(), resources.end(), Deleter());
}
-bool MetalinkEntry::check(const string& filename) const {
-#ifdef ENABLE_MESSAGE_DIGEST
- unsigned char buf[20];
- int digestLength;
- const string* digestPtr;
- MessageDigestContext::HashAlgo algo;
- if(!sha1.empty()) {
- digestLength = 20;
- algo = MessageDigestContext::ALGO_SHA1;
- digestPtr = &sha1;
- } else if(!md5.empty()) {
- digestLength = 16;
- algo = MessageDigestContext::ALGO_MD5;
- digestPtr = &md5;
- } else {
- return true;
- }
- Util::fileChecksum(filename, buf, algo);
- return *digestPtr == Util::toHex(buf, digestLength);
-#else
- return true;
-#endif //ENABLE_MESSAGE_DIGEST
-}
-
class PrefOrder {
public:
bool operator()(const MetalinkResource* res1, const MetalinkResource* res2) {
@@ -71,6 +47,10 @@ public:
switch(res->type) {
case MetalinkResource::TYPE_FTP:
case MetalinkResource::TYPE_HTTP:
+ case MetalinkResource::TYPE_HTTPS:
+#ifdef ENABLE_BITTORRENT
+ case MetalinkResource::TYPE_BITTORRENT:
+#endif // ENABLE_BITTORRENT
return true;
default:
return false;
@@ -81,5 +61,6 @@ public:
void MetalinkEntry::dropUnsupportedResource() {
MetalinkResources::iterator split =
partition(resources.begin(), resources.end(), Supported());
+ for_each(split, resources.end(), Deleter());
resources.erase(split, resources.end());
}
diff --git a/src/MetalinkEntry.h b/src/MetalinkEntry.h
index 8e1f98e8..2d6c3a96 100644
--- a/src/MetalinkEntry.h
+++ b/src/MetalinkEntry.h
@@ -24,6 +24,7 @@
#include "common.h"
#include "MetalinkResource.h"
+#include "Checksum.h"
#include <deque>
typedef deque<MetalinkResource*> MetalinkResources;
@@ -35,8 +36,7 @@ public:
string language;
string os;
long long int size;
- string md5;
- string sha1;
+ Checksum checksum;
public:
MetalinkResources resources;
public:
@@ -50,14 +50,11 @@ public:
this->language = metalinkEntry.language;
this->os = metalinkEntry.os;
this->size = metalinkEntry.size;
- this->md5 = metalinkEntry.md5;
- this->sha1 = metalinkEntry.sha1;
+ this->checksum = metalinkEntry.checksum;
}
return *this;
}
- bool check(const string& filename) const;
-
void dropUnsupportedResource();
void reorderResourcesByPreference();
diff --git a/src/MetalinkRequestInfo.cc b/src/MetalinkRequestInfo.cc
new file mode 100644
index 00000000..6b58c102
--- /dev/null
+++ b/src/MetalinkRequestInfo.cc
@@ -0,0 +1,111 @@
+/* <!-- copyright */
+/*
+ * aria2 - a simple utility for downloading files faster
+ *
+ * Copyright (C) 2006 Tatsuhiro Tsujikawa
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+/* copyright --> */
+#include "MetalinkRequestInfo.h"
+#include "Xml2MetalinkProcessor.h"
+#include "prefs.h"
+#include "DlAbortEx.h"
+#include "UrlRequestInfo.h"
+
+class AccumulateNonP2PUrl {
+private:
+ Strings* urlsPtr;
+ int split;
+public:
+ AccumulateNonP2PUrl(Strings* urlsPtr,
+ int split)
+ :urlsPtr(urlsPtr),
+ split(split) {}
+
+ void operator()(const MetalinkResource* resource) {
+ switch(resource->type) {
+ case MetalinkResource::TYPE_HTTP:
+ case MetalinkResource::TYPE_HTTPS:
+ case MetalinkResource::TYPE_FTP:
+ for(int s = 1; s <= split; s++) {
+ urlsPtr->push_back(resource->url);
+ }
+ break;
+ }
+ }
+};
+
+class FindBitTorrentUrl {
+public:
+ FindBitTorrentUrl() {}
+
+ bool operator()(const MetalinkResource* resource) {
+ if(resource->type == MetalinkResource::TYPE_BITTORRENT) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+};
+
+RequestInfo* MetalinkRequestInfo::execute() {
+ RequestInfo* next = 0;
+ Xml2MetalinkProcessor proc;
+ Metalinker* metalinker = 0;
+ try {
+ metalinker = proc.parseFile(metalinkFile);
+
+ MetalinkEntry* entry =
+ metalinker->queryEntry(op->get(PREF_METALINK_VERSION),
+ op->get(PREF_METALINK_LANGUAGE),
+ op->get(PREF_METALINK_OS));
+ if(entry == 0) {
+ printf("No file matched with your preference.\n");
+ throw new DlAbortEx("No file matched with your preference.");
+ }
+ entry->dropUnsupportedResource();
+ MetalinkResources::iterator itr =
+ find_if(entry->resources.begin(),
+ entry->resources.end(),
+ FindBitTorrentUrl());
+ Strings urls;
+ int maxConnection = 0;
+ Checksum checksum;
+ if(itr == entry->resources.end()) {
+ entry->reorderResourcesByPreference();
+
+ for_each(entry->resources.begin(), entry->resources.end(),
+ AccumulateNonP2PUrl(&urls, op->getAsInt(PREF_SPLIT)));
+ maxConnection =
+ op->getAsInt(PREF_METALINK_SERVERS)*op->getAsInt(PREF_SPLIT);
+
+ // TODO
+ // set checksum
+ checksum = entry->checksum;
+ } else {
+ // BitTorrent downloading
+ urls.push_back((*itr)->url);
+ }
+ next = new UrlRequestInfo(urls, maxConnection, op);
+ next->setChecksum(checksum);
+ } catch(Exception* e) {
+ logger->error("Exception caught", e);
+ delete e;
+ fail = true;
+ }
+ delete metalinker;
+ return next;
+}
diff --git a/src/MetalinkRequestInfo.h b/src/MetalinkRequestInfo.h
new file mode 100644
index 00000000..763537d5
--- /dev/null
+++ b/src/MetalinkRequestInfo.h
@@ -0,0 +1,41 @@
+/* <!-- copyright */
+/*
+ * aria2 - a simple utility for downloading files faster
+ *
+ * Copyright (C) 2006 Tatsuhiro Tsujikawa
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+/* copyright --> */
+#ifndef _D_METALINK_REQUEST_INFO_H_
+#define _D_METALINK_REQUEST_INFO_H_
+
+#include "RequestInfo.h"
+
+class MetalinkRequestInfo : public RequestInfo {
+private:
+ string metalinkFile;
+public:
+ MetalinkRequestInfo(const string& metalinkFile, const Option* op):
+ RequestInfo(op),
+ metalinkFile(metalinkFile) {}
+ virtual ~MetalinkRequestInfo() {}
+
+ virtual RequestInfo* execute();
+
+ virtual DownloadEngine* getDownloadEngine() { return 0; }
+};
+
+#endif // _D_METALINK_REQUEST_INFO_H_
diff --git a/src/MetalinkResource.h b/src/MetalinkResource.h
index 497e65c8..44ddc23b 100644
--- a/src/MetalinkResource.h
+++ b/src/MetalinkResource.h
@@ -29,6 +29,7 @@ public:
enum TYPE {
TYPE_FTP,
TYPE_HTTP,
+ TYPE_HTTPS,
TYPE_BITTORRENT,
TYPE_NOT_SUPPORTED
};
diff --git a/src/MultiDiskWriter.cc b/src/MultiDiskWriter.cc
index f40f6da0..d0a13776 100644
--- a/src/MultiDiskWriter.cc
+++ b/src/MultiDiskWriter.cc
@@ -25,18 +25,15 @@
#include "message.h"
#include <errno.h>
-MultiDiskWriter::MultiDiskWriter(int pieceLength):pieceLength(pieceLength) {
-#ifdef ENABLE_MESSAGE_DIGEST
- ctx.setAlgo(MessageDigestContext::ALGO_SHA1);
- digestInit(ctx);
-#endif // ENABLE_MESSAGE_DIGEST
+MultiDiskWriter::MultiDiskWriter(int pieceLength):
+ pieceLength(pieceLength),
+ ctx(DIGEST_ALGO_SHA1) {
+ ctx.digestInit();
}
MultiDiskWriter::~MultiDiskWriter() {
clearEntries();
-#ifdef ENABLE_MESSAGE_DIGEST
- digestFree(ctx);
-#endif // ENABLE_MESSAGE_DIGEST
+ ctx.digestFree();
}
void MultiDiskWriter::clearEntries() {
@@ -143,7 +140,6 @@ int MultiDiskWriter::readData(char* data, int len, long long int offset) {
return totalReadLength;
}
-#ifdef ENABLE_MESSAGE_DIGEST
void MultiDiskWriter::hashUpdate(DiskWriterEntry* entry, long long int offset, long long int length) {
int BUFSIZE = 16*1024;
char buf[BUFSIZE];
@@ -151,7 +147,7 @@ void MultiDiskWriter::hashUpdate(DiskWriterEntry* entry, long long int offset, l
if(BUFSIZE != entry->diskWriter->readData(buf, BUFSIZE, offset)) {
throw string("error");
}
- digestUpdate(ctx, buf, BUFSIZE);
+ ctx.digestUpdate(buf, BUFSIZE);
offset += BUFSIZE;
}
int r = length%BUFSIZE;
@@ -159,17 +155,15 @@ void MultiDiskWriter::hashUpdate(DiskWriterEntry* entry, long long int offset, l
if(r != entry->diskWriter->readData(buf, r, offset)) {
throw string("error");
}
- digestUpdate(ctx, buf, r);
+ ctx.digestUpdate(buf, r);
}
}
-#endif // ENABLE_MESSAGE_DIGEST
string MultiDiskWriter::sha1Sum(long long int offset, long long int length) {
-#ifdef ENABLE_MESSAGE_DIGEST
long long int fileOffset = offset;
bool reading = false;
int rem = length;
- digestReset(ctx);
+ ctx.digestReset();
try {
for(DiskWriterEntries::iterator itr = diskWriterEntries.begin();
itr != diskWriterEntries.end() && rem != 0; itr++) {
@@ -187,13 +181,10 @@ string MultiDiskWriter::sha1Sum(long long int offset, long long int length) {
throw new DlAbortEx(EX_FILE_OFFSET_OUT_OF_RANGE, offset);
}
unsigned char hashValue[20];
- digestFinal(ctx, hashValue);
+ ctx.digestFinal(hashValue);
return Util::toHex(hashValue, 20);
} catch(string ex) {
throw new DlAbortEx(EX_FILE_SHA1SUM, "", strerror(errno));
}
-#else
- return "";
-#endif // ENABLE_MESSAGE_DIGEST
}
diff --git a/src/MultiDiskWriter.h b/src/MultiDiskWriter.h
index 0cd18cb5..a903424d 100644
--- a/src/MultiDiskWriter.h
+++ b/src/MultiDiskWriter.h
@@ -48,10 +48,8 @@ private:
bool isInRange(const DiskWriterEntry* entry, long long int offset) const;
int calculateLength(const DiskWriterEntry* entry, long long int fileOffset, int rem) const;
void clearEntries();
-#ifdef ENABLE_MESSAGE_DIGEST
MessageDigestContext ctx;
void hashUpdate(DiskWriterEntry* entry, long long int offset, long long int length);
-#endif // ENABLE_MESSAGE_DIGEST
public:
MultiDiskWriter(int pieceLength);
diff --git a/src/PeerAbstractCommand.h b/src/PeerAbstractCommand.h
index 95d9a448..f0a71a8b 100644
--- a/src/PeerAbstractCommand.h
+++ b/src/PeerAbstractCommand.h
@@ -25,7 +25,7 @@
#include "Command.h"
#include "Request.h"
#include "TorrentDownloadEngine.h"
-#include "Time.h"
+#include "TimeA2.h"
class PeerAbstractCommand : public Command {
private:
diff --git a/src/PeerChokeCommand.cc b/src/PeerChokeCommand.cc
index 7a32e6da..8fdb44fa 100644
--- a/src/PeerChokeCommand.cc
+++ b/src/PeerChokeCommand.cc
@@ -22,7 +22,7 @@
#include "PeerChokeCommand.h"
#include "Util.h"
-PeerChokeCommand::PeerChokeCommand(int cuid, int interval, TorrentDownloadEngine* e):Command(cuid), interval(interval), e(e), rotate(0) {}
+PeerChokeCommand::PeerChokeCommand(int cuid, TorrentDownloadEngine* e, int interval):Command(cuid), interval(interval), e(e), rotate(0) {}
PeerChokeCommand::~PeerChokeCommand() {}
diff --git a/src/PeerChokeCommand.h b/src/PeerChokeCommand.h
index c0019bf6..c3f9b242 100644
--- a/src/PeerChokeCommand.h
+++ b/src/PeerChokeCommand.h
@@ -24,7 +24,7 @@
#include "Command.h"
#include "TorrentDownloadEngine.h"
-#include "Time.h"
+#include "TimeA2.h"
class PeerChokeCommand : public Command {
private:
@@ -38,7 +38,7 @@ private:
void optUnchokingPeer(Peers& peers) const;
public:
- PeerChokeCommand(int cuid, int interval, TorrentDownloadEngine* e);
+ PeerChokeCommand(int cuid, TorrentDownloadEngine* e, int interval);
virtual ~PeerChokeCommand();
bool execute();
diff --git a/src/PeerInteractionCommand.h b/src/PeerInteractionCommand.h
index ff0abb82..8f1ae0ed 100644
--- a/src/PeerInteractionCommand.h
+++ b/src/PeerInteractionCommand.h
@@ -25,7 +25,7 @@
#include "PeerAbstractCommand.h"
#include "PeerConnection.h"
#include "PeerInteraction.h"
-#include "Time.h"
+#include "TimeA2.h"
using namespace std;
diff --git a/src/RequestInfo.h b/src/RequestInfo.h
new file mode 100644
index 00000000..b8a6bdf0
--- /dev/null
+++ b/src/RequestInfo.h
@@ -0,0 +1,116 @@
+/* <!-- copyright */
+/*
+ * aria2 - a simple utility for downloading files faster
+ *
+ * Copyright (C) 2006 Tatsuhiro Tsujikawa
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+/* copyright --> */
+#ifndef _D_REQUEST_INFO_H_
+#define _D_REQUEST_INFO_H_
+
+#include "common.h"
+#include "LogFactory.h"
+#include "Option.h"
+#include "DownloadEngine.h"
+#include "Util.h"
+#include "Checksum.h"
+#include <signal.h>
+
+class FileInfo {
+public:
+ string filename;
+ long long int length;
+ Checksum checksum;
+public:
+ FileInfo():length(0) {}
+ ~FileInfo() {}
+
+ bool isEmpty() const {
+ return filename.size() == 0 && length == 0;
+ }
+
+ bool checkReady() const {
+#ifdef ENABLE_MESSAGE_DIGEST
+ return !isEmpty() && !checksum.isEmpty();
+#else
+ return false;
+#endif // ENABLE_MESSAGE_DIGEST
+ }
+
+ bool check() const {
+#ifdef ENABLE_MESSAGE_DIGEST
+ unsigned char md[MAX_MD_LENGTH];
+ Util::fileChecksum(filename, md, checksum.getDigestAlgo());
+ return Util::toHex(md,
+ MessageDigestContext::digestLength(checksum.getDigestAlgo()))
+ == checksum.getMessageDigest();
+#else
+ return false;
+#endif // ENABLE_MESSAGE_DIGEST
+ }
+
+ bool isTorrentFile() const {
+ return Util::endsWith(filename, ".torrent");
+ }
+
+ bool isMetalinkFile() const {
+ return Util::endsWith(filename, ".metalink");
+ }
+};
+
+class RequestInfo {
+protected:
+ const Option* op;
+ const Logger* logger;
+ Checksum checksum;
+ FileInfo fileInfo;
+ bool fail;
+
+ void printDownloadCompeleteMessage(const string& filename) {
+ printf(_("\nThe download was complete. <%s>\n"), filename.c_str());
+ }
+
+ void printDownloadCompeleteMessage() {
+ printf("\nThe download was complete.\n");
+ }
+
+ void printDownloadAbortMessage() {
+ printf(_("\nThe download was not complete because of errors. Check the log.\n"));
+ }
+public:
+ RequestInfo(const Option* op):
+ op(op),
+ fail(false)
+ {
+ logger = LogFactory::getInstance();
+ }
+ virtual ~RequestInfo() {}
+
+ virtual RequestInfo* execute() = 0;
+
+ virtual DownloadEngine* getDownloadEngine() = 0;
+
+ bool isFail() const { return fail; }
+
+ void setChecksum(const Checksum& checksum) {
+ this->checksum = checksum;
+ }
+ const Checksum& getChecksum() const { return checksum; }
+ const FileInfo& getFileInfo() const { return fileInfo; }
+};
+
+#endif // _D_REQUEST_INFO_H_
diff --git a/src/RequestSlot.h b/src/RequestSlot.h
index 4946ce84..46d6a269 100644
--- a/src/RequestSlot.h
+++ b/src/RequestSlot.h
@@ -23,7 +23,7 @@
#define _D_REQUEST_SLOT_H_
#include "common.h"
-#include "Time.h"
+#include "TimeA2.h"
class RequestSlot {
private:
diff --git a/src/ShaVisitor.cc b/src/ShaVisitor.cc
index 6807e7c2..e1cbc2c3 100644
--- a/src/ShaVisitor.cc
+++ b/src/ShaVisitor.cc
@@ -22,60 +22,49 @@
#include "ShaVisitor.h"
#include "Util.h"
-ShaVisitor::ShaVisitor() {
-#ifdef ENABLE_MESSAGE_DIGEST
- ctx.setAlgo(MessageDigestContext::ALGO_SHA1);
- digestInit(ctx);
- digestReset(ctx);
-#endif // ENABLE_MESSAGE_DIGEST
+ShaVisitor::ShaVisitor():
+ ctx(DIGEST_ALGO_SHA1) {
+ ctx.digestInit();
}
ShaVisitor::~ShaVisitor() {
-#ifdef ENABLE_MESSAGE_DIGEST
- digestFree(ctx);
-#endif // ENABLE_MESSAGE_DIGEST
+ ctx.digestFree();
}
void ShaVisitor::visit(const Data* d) {
-#ifdef ENABLE_MESSAGE_DIGEST
if(d->isNumber()) {
- digestUpdate(ctx, "i", 1);
+ ctx.digestUpdate("i", 1);
} else {
string lenStr = Util::llitos(d->getLen());
- digestUpdate(ctx, lenStr.c_str(), lenStr.size());
- digestUpdate(ctx, ":", 1);
+ ctx.digestUpdate(lenStr.c_str(), lenStr.size());
+ ctx.digestUpdate(":", 1);
}
- digestUpdate(ctx, d->getData(), d->getLen());
+ ctx.digestUpdate(d->getData(), d->getLen());
if(d->isNumber()) {
- digestUpdate(ctx, "e", 1);
+ ctx.digestUpdate("e", 1);
}
-#endif // ENABLE_MESSAGE_DIGEST
}
void ShaVisitor::visit(const Dictionary* d) {
-#ifdef ENABLE_MESSAGE_DIGEST
- digestUpdate(ctx, "d", 1);
+ ctx.digestUpdate("d", 1);
const Order& v = d->getOrder();
for(Order::const_iterator itr = v.begin(); itr != v.end(); itr++) {
string lenStr = Util::llitos(itr->size());
- digestUpdate(ctx, lenStr.c_str(), lenStr.size());
- digestUpdate(ctx, ":", 1);
- digestUpdate(ctx, itr->c_str(), itr->size());
+ ctx.digestUpdate(lenStr.c_str(), lenStr.size());
+ ctx.digestUpdate(":", 1);
+ ctx.digestUpdate(itr->c_str(), itr->size());
const MetaEntry* e = d->get(*itr);
this->visit(e);
}
- digestUpdate(ctx, "e", 1);
-#endif // ENABLE_MESSAGE_DIGEST
+ ctx.digestUpdate("e", 1);
}
void ShaVisitor::visit(const List* l) {
-#ifdef ENABLE_MESSAGE_DIGEST
- digestUpdate(ctx, "l", 1);
+ ctx.digestUpdate("l", 1);
for(MetaList::const_iterator itr = l->getList().begin(); itr != l->getList().end(); itr++) {
this->visit(*itr);
}
- digestUpdate(ctx, "e", 1);
-#endif // ENABLE_MESSAGE_DIGEST
+ ctx.digestUpdate("e", 1);
}
void ShaVisitor::visit(const MetaEntry* e) {
@@ -89,8 +78,6 @@ void ShaVisitor::visit(const MetaEntry* e) {
}
void ShaVisitor::getHash(unsigned char* hashValue, int& len) {
-#ifdef ENABLE_MESSAGE_DIGEST
- digestFinal(ctx, hashValue);
- len = 20;
-#endif // ENABLE_MESSAGE_DIGEST
+ len = ctx.digestLength();
+ ctx.digestFinal(hashValue);
}
diff --git a/src/ShaVisitor.h b/src/ShaVisitor.h
index 87f98d9a..cecced65 100644
--- a/src/ShaVisitor.h
+++ b/src/ShaVisitor.h
@@ -27,15 +27,11 @@
#include "Dictionary.h"
#include "List.h"
#include "common.h"
-#ifdef ENABLE_MESSAGE_DIGEST
#include "messageDigest.h"
-#endif // ENABLE_MESSAGE_DIGEST
class ShaVisitor : public MetaEntryVisitor {
private:
-#ifdef ENABLE_MESSAGE_DIGEST
MessageDigestContext ctx;
-#endif // ENABLE_MESSAGE_DIGEST
public:
ShaVisitor();
~ShaVisitor();
diff --git a/src/SleepCommand.h b/src/SleepCommand.h
index 06310daa..ecf8e676 100644
--- a/src/SleepCommand.h
+++ b/src/SleepCommand.h
@@ -24,7 +24,7 @@
#include "DownloadEngine.h"
#include "Command.h"
-#include "Time.h"
+#include "TimeA2.h"
class SleepCommand:public Command {
private:
diff --git a/src/Time.cc b/src/TimeA2.cc
index 03a77afa..2d38b2ad 100644
--- a/src/Time.cc
+++ b/src/TimeA2.cc
@@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/* copyright --> */
-#include "Time.h"
+#include "TimeA2.h"
#include "Util.h"
Time::Time() {
diff --git a/src/Time.h b/src/TimeA2.h
index c7cc1fad..c7cc1fad 100644
--- a/src/Time.h
+++ b/src/TimeA2.h
diff --git a/src/TorrentAutoSaveCommand.h b/src/TorrentAutoSaveCommand.h
index a770f4c2..cbf880a9 100644
--- a/src/TorrentAutoSaveCommand.h
+++ b/src/TorrentAutoSaveCommand.h
@@ -24,7 +24,7 @@
#include "Command.h"
#include "TorrentDownloadEngine.h"
-#include "Time.h"
+#include "TimeA2.h"
class TorrentAutoSaveCommand : public Command {
private:
diff --git a/src/TorrentDownloadEngine.h b/src/TorrentDownloadEngine.h
index facbedf7..a2ecc634 100644
--- a/src/TorrentDownloadEngine.h
+++ b/src/TorrentDownloadEngine.h
@@ -24,7 +24,7 @@
#include "DownloadEngine.h"
#include "TorrentMan.h"
-#include "Time.h"
+#include "TimeA2.h"
class TorrentDownloadEngine : public DownloadEngine {
private:
diff --git a/src/TorrentMan.cc b/src/TorrentMan.cc
index 0e97453e..5704bdd5 100644
--- a/src/TorrentMan.cc
+++ b/src/TorrentMan.cc
@@ -43,7 +43,7 @@
extern PeerHandle nullPeer;
-TorrentMan::TorrentMan():bitfield(NULL),
+TorrentMan::TorrentMan():bitfield(0),
peerEntryIdCounter(0),
cuidCounter(0),
downloadLength(0),
@@ -61,18 +61,16 @@ TorrentMan::TorrentMan():bitfield(NULL),
incomplete(0),
connections(0),
trackers(0),
- diskAdaptor(NULL)
+ req(0),
+ diskAdaptor(0)
{
logger = LogFactory::getInstance();
}
TorrentMan::~TorrentMan() {
- if(bitfield != NULL) {
- delete bitfield;
- }
- if(diskAdaptor != NULL) {
- delete diskAdaptor;
- }
+ delete bitfield;
+ delete diskAdaptor;
+ delete req;
}
// TODO do not use this method in application code
diff --git a/src/TorrentMan.h b/src/TorrentMan.h
index f9201787..219e7483 100644
--- a/src/TorrentMan.h
+++ b/src/TorrentMan.h
@@ -33,7 +33,7 @@
#include "FileEntry.h"
#include "DiskAdaptor.h"
#include "Request.h"
-#include "Time.h"
+#include "TimeA2.h"
#include <deque>
#include <map>
#include <string>
diff --git a/src/TorrentRequestInfo.cc b/src/TorrentRequestInfo.cc
new file mode 100644
index 00000000..bfc2945c
--- /dev/null
+++ b/src/TorrentRequestInfo.cc
@@ -0,0 +1,81 @@
+/* <!-- copyright */
+/*
+ * aria2 - a simple utility for downloading files faster
+ *
+ * Copyright (C) 2006 Tatsuhiro Tsujikawa
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+/* copyright --> */
+#include "TorrentRequestInfo.h"
+#include "DownloadEngineFactory.h"
+#include "prefs.h"
+#include "Util.h"
+
+extern RequestInfo* requestInfo;
+extern void setSignalHander(int signal, void (*handler)(int), int flags);
+
+void torrentHandler(int signal) {
+ ((TorrentDownloadEngine*)requestInfo->getDownloadEngine())->
+ torrentMan->setHalt(true);
+}
+
+RequestInfo* TorrentRequestInfo::execute() {
+ if(op->get(PREF_SHOW_FILES) == V_TRUE) {
+ showFileEntry();
+ return 0;
+ }
+ e = DownloadEngineFactory::newTorrentConsoleEngine(op,
+ torrentFile,
+ targetFiles);
+ setSignalHander(SIGINT, torrentHandler, SA_RESETHAND);
+ setSignalHander(SIGTERM, torrentHandler, SA_RESETHAND);
+
+ try {
+ e->run();
+ if(e->torrentMan->downloadComplete()) {
+ printDownloadCompeleteMessage();
+ }
+ } catch(Exception* e) {
+ logger->error("Exception caught", e);
+ delete e;
+ fail = true;
+ }
+ setSignalHander(SIGINT, SIG_DFL, 0);
+ setSignalHander(SIGTERM, SIG_DFL, 0);
+ delete e;
+
+ return 0;
+}
+
+// TODO should be const TorrentMan* torrentMan
+void TorrentRequestInfo::showFileEntry()
+{
+ TorrentMan torrentMan;
+ torrentMan.option = op;
+
+ FileEntries fileEntries =
+ torrentMan.readFileEntryFromMetaInfoFile(torrentFile);
+ cout << _("Files:") << endl;
+ cout << "idx|path/length" << endl;
+ cout << "===+===========================================================================" << endl;
+ int count = 1;
+ for(FileEntries::const_iterator itr = fileEntries.begin();
+ itr != fileEntries.end(); count++, itr++) {
+ printf("%3d|%s\n |%s Bytes\n", count, itr->path.c_str(),
+ Util::llitos(itr->length, true).c_str());
+ cout << "---+---------------------------------------------------------------------------" << endl;
+ }
+}
diff --git a/src/TorrentRequestInfo.h b/src/TorrentRequestInfo.h
new file mode 100644
index 00000000..f9e61d22
--- /dev/null
+++ b/src/TorrentRequestInfo.h
@@ -0,0 +1,51 @@
+/* <!-- copyright */
+/*
+ * aria2 - a simple utility for downloading files faster
+ *
+ * Copyright (C) 2006 Tatsuhiro Tsujikawa
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+/* copyright --> */
+#ifndef _D_TORRENT_REQUEST_INFO_H_
+#define _D_TORRENT_REQUEST_INFO_H_
+
+#include "RequestInfo.h"
+#include "TorrentDownloadEngine.h"
+
+class TorrentRequestInfo : public RequestInfo {
+private:
+ string torrentFile;
+ TorrentDownloadEngine* e;
+ Strings targetFiles;
+
+ void showFileEntry();
+public:
+ TorrentRequestInfo(const string& torrentFile, const Option* op):
+ RequestInfo(op),
+ torrentFile(torrentFile),
+ e(0) {}
+ virtual ~TorrentRequestInfo() {}
+
+ virtual RequestInfo* execute();
+
+ void setTargetFiles(const Strings& targetFiles) {
+ this->targetFiles = targetFiles;
+ }
+ virtual DownloadEngine* getDownloadEngine() { return e; }
+
+};
+
+#endif // _D_TORRENT_REQUEST_INFO_H_
diff --git a/src/TrackerWatcherCommand.h b/src/TrackerWatcherCommand.h
index fd0cccf7..c4da87f5 100644
--- a/src/TrackerWatcherCommand.h
+++ b/src/TrackerWatcherCommand.h
@@ -24,7 +24,7 @@
#include "Command.h"
#include "TorrentDownloadEngine.h"
-#include "Time.h"
+#include "TimeA2.h"
class TrackerWatcherCommand : public Command {
private:
diff --git a/src/UrlRequestInfo.cc b/src/UrlRequestInfo.cc
new file mode 100644
index 00000000..986dbc97
--- /dev/null
+++ b/src/UrlRequestInfo.cc
@@ -0,0 +1,146 @@
+/* <!-- copyright */
+/*
+ * aria2 - a simple utility for downloading files faster
+ *
+ * Copyright (C) 2006 Tatsuhiro Tsujikawa
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+/* copyright --> */
+#include "UrlRequestInfo.h"
+#include "TorrentRequestInfo.h"
+#include "MetalinkRequestInfo.h"
+#include "prefs.h"
+#include "DownloadEngineFactory.h"
+
+extern RequestInfo* requestInfo;
+extern void setSignalHander(int signal, void (*handler)(int), int flags);
+
+void UrlRequestInfo::adjustRequestSize(Requests& requests,
+ Requests& reserved,
+ int maxConnections) const
+{
+ if(maxConnections > 0 && (int)requests.size() > maxConnections) {
+ copy(requests.begin()+maxConnections, requests.end(),
+ back_inserter(reserved));
+ //insert_iterator<Requests>(reserved, reserved.end()));
+ requests.erase(requests.begin()+maxConnections, requests.end());
+ }
+}
+
+RequestInfo* UrlRequestInfo::createNextRequestInfo() const
+{
+#ifdef ENABLE_BITTORRENT
+ if(op->getAsBool(PREF_FOLLOW_TORRENT) &&
+ Util::endsWith(fileInfo.filename, ".torrent")) {
+ return new TorrentRequestInfo(fileInfo.filename, op);
+ } else
+#endif // ENABLE_BITTORRENT
+#ifdef ENABLE_METALINK
+ if(op->getAsBool(PREF_FOLLOW_METALINK) &&
+ Util::endsWith(fileInfo.filename, ".metalink")) {
+ return new MetalinkRequestInfo(fileInfo.filename, op);
+ } else
+#endif // ENABLE_METALINK
+ {
+ return 0;
+ }
+}
+
+void handler(int signal) {
+ printf(_("\nstopping application...\n"));
+ fflush(stdout);
+ requestInfo->getDownloadEngine()->segmentMan->save();
+ requestInfo->getDownloadEngine()->segmentMan->diskWriter->closeFile();
+ delete requestInfo->getDownloadEngine();
+ printf(_("done\n"));
+ exit(EXIT_SUCCESS);
+}
+
+class CreateRequest {
+private:
+ Requests* requestsPtr;
+ string referer;
+ int split;
+public:
+ CreateRequest(Requests* requestsPtr,
+ const string& referer,
+ int split)
+ :requestsPtr(requestsPtr),
+ referer(referer),
+ split(split) {}
+
+ void operator()(const string& url) {
+ for(int s = 1; s <= split; s++) {
+ Request* req = new Request();
+ req->setReferer(referer);
+ if(req->setUrl(url)) {
+ requestsPtr->push_back(req);
+ } else {
+ fprintf(stderr, _("Unrecognized URL or unsupported protocol: %s\n"),
+ req->getUrl().c_str());
+ delete req;
+ }
+ }
+ }
+};
+
+RequestInfo* UrlRequestInfo::execute() {
+ Requests requests;
+ Requests reserved;
+ for_each(urls.begin(), urls.end(),
+ CreateRequest(&requests,
+ op->get(PREF_REFERER),
+ op->getAsInt(PREF_SPLIT)));
+
+ adjustRequestSize(requests, reserved, maxConnections);
+
+ e = DownloadEngineFactory::newConsoleEngine(op, requests, reserved);
+
+ setSignalHander(SIGINT, handler, 0);
+ setSignalHander(SIGTERM, handler, 0);
+
+ RequestInfo* next = 0;
+ try {
+ e->run();
+
+ if(e->segmentMan->finished()) {
+ printDownloadCompeleteMessage(e->segmentMan->getFilePath());
+ fileInfo.filename = e->segmentMan->getFilePath();
+ fileInfo.length = e->segmentMan->totalSize;
+ fileInfo.checksum = checksum;
+
+ next = createNextRequestInfo();
+ } else {
+ e->segmentMan->save();
+ e->segmentMan->diskWriter->closeFile();
+ printDownloadAbortMessage();
+ }
+ } catch(Exception *e) {
+ logger->error("Exception caught", e);
+ delete e;
+ fail = true;
+ }
+ for_each(requests.begin(), requests.end(), Deleter());
+ for_each(reserved.begin(), reserved.end(), Deleter());
+
+ setSignalHander(SIGINT, SIG_DFL, 0);
+ setSignalHander(SIGTERM, SIG_DFL, 0);
+
+ delete e;
+ e = 0;
+
+ return next;
+}
diff --git a/src/UrlRequestInfo.h b/src/UrlRequestInfo.h
new file mode 100644
index 00000000..85172b29
--- /dev/null
+++ b/src/UrlRequestInfo.h
@@ -0,0 +1,52 @@
+/* <!-- copyright */
+/*
+ * aria2 - a simple utility for downloading files faster
+ *
+ * Copyright (C) 2006 Tatsuhiro Tsujikawa
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+/* copyright --> */
+#ifndef _D_URL_REQUEST_INFO_H_
+#define _D_URL_REQUEST_INFO_H_
+
+#include "RequestInfo.h"
+
+class UrlRequestInfo : public RequestInfo {
+private:
+ Strings urls;
+ int maxConnections;
+ DownloadEngine* e;
+
+ RequestInfo* createNextRequestInfo() const;
+ void adjustRequestSize(Requests& requests,
+ Requests& reserved,
+ int maxConnections) const;
+public:
+ UrlRequestInfo(const Strings& urls, int maxConnections, const Option* op):
+ RequestInfo(op),
+ urls(urls),
+ maxConnections(maxConnections),
+ e(0) {}
+ virtual ~UrlRequestInfo() {}
+
+ virtual RequestInfo* execute();
+
+ virtual DownloadEngine* getDownloadEngine() {
+ return e;
+ }
+};
+
+#endif // _D_URL_REQUEST_INFO_H_
diff --git a/src/Util.cc b/src/Util.cc
index 5780889d..846e8976 100644
--- a/src/Util.cc
+++ b/src/Util.cc
@@ -363,21 +363,20 @@ string Util::getContentDispositionFilename(const string& header) {
#ifdef ENABLE_MESSAGE_DIGEST
void Util::sha1Sum(unsigned char* digest, const void* data, int dataLength) {
- MessageDigestContext ctx(MessageDigestContext::ALGO_SHA1);
- digestInit(ctx);
- digestReset(ctx);
- digestUpdate(ctx, data, dataLength);
- digestFinal(ctx, digest);
- digestFree(ctx);
+ MessageDigestContext ctx(DIGEST_ALGO_SHA1);
+ ctx.digestInit();
+ ctx.digestUpdate(data, dataLength);
+ ctx.digestFinal(digest);
+ ctx.digestFree();
}
#endif // ENABLE_MESSAGE_DIGEST
#ifdef ENABLE_MESSAGE_DIGEST
void Util::fileChecksum(const string& filename, unsigned char* digest,
- MessageDigestContext::HashAlgo algo) {
+ MessageDigestContext::DigestAlgo algo) {
MessageDigestContext ctx(algo);
- digestInit(ctx);
- digestReset(ctx);
+ ctx.digestInit();
+ ctx.digestReset();
int BUFLEN = 4096;
char buf[BUFLEN];
@@ -396,14 +395,14 @@ void Util::fileChecksum(const string& filename, unsigned char* digest,
throw new DlAbortEx(EX_FILE_READ, filename.c_str(), strerror(errno));
}
} else if(size > 0) {
- digestUpdate(ctx, buf, size);
+ ctx.digestUpdate(buf, size);
}
if(size < BUFLEN) {
break;
}
}
- digestFinal(ctx, digest);
- digestFree(ctx);
+ ctx.digestFinal(digest);
+ ctx.digestFree();
}
#endif // ENABLE_MESSAGE_DIGEST
diff --git a/src/Util.h b/src/Util.h
index 98536864..9a01da8b 100644
--- a/src/Util.h
+++ b/src/Util.h
@@ -92,7 +92,7 @@ public:
// For sha1, you need 20 bytes. For md5, 16 bytes.
#ifdef ENABLE_MESSAGE_DIGEST
static void fileChecksum(const string& filename, unsigned char* digest,
- MessageDigestContext::HashAlgo algo);
+ MessageDigestContext::DigestAlgo algo);
#endif // ENABLE_MESSAGE_DIGEST
#ifdef ENABLE_BITTORRENT
diff --git a/src/Xml2MetalinkProcessor.cc b/src/Xml2MetalinkProcessor.cc
index bb3281a9..f68f2da2 100644
--- a/src/Xml2MetalinkProcessor.cc
+++ b/src/Xml2MetalinkProcessor.cc
@@ -88,8 +88,20 @@ MetalinkEntry* Xml2MetalinkProcessor::getEntry(const string& xpath) {
entry->version = Util::trim(xpathContent(xpath+"/m:version"));
entry->language = Util::trim(xpathContent(xpath+"/m:language"));
entry->os = Util::trim(xpathContent(xpath+"/m:os"));
- entry->md5 = Util::toLower(Util::trim(xpathContent(xpath+"/m:verification/m:hash[@type=\"md5\"]")));
- entry->sha1 = Util::toLower(Util::trim(xpathContent(xpath+"/m:verification/m:hash[@type=\"sha1\"]")));
+#ifdef ENABLE_MESSAGE_DIGEST
+ string md;
+ md = Util::toLower(Util::trim(xpathContent(xpath+"/m:verification/m:hash[@type=\"sha1\"]")));
+ if(md.size() > 0) {
+ entry->checksum.setMessageDigest(md);
+ entry->checksum.setDigestAlgo(DIGEST_ALGO_SHA1);
+ } else {
+ md = Util::toLower(Util::trim(xpathContent(xpath+"/m:verification/m:hash[@type=\"md5\"]")));
+ if(md.size() > 0) {
+ entry->checksum.setMessageDigest(md);
+ entry->checksum.setDigestAlgo(DIGEST_ALGO_MD5);
+ }
+ }
+#endif // ENABLE_MESSAGE_DIGEST
for(int index = 1; 1; index++) {
MetalinkResource* resource =
getResource(xpath+"/m:resources/m:url["+Util::itos(index)+"]");
@@ -121,6 +133,8 @@ MetalinkResource* Xml2MetalinkProcessor::getResource(const string& xpath) {
resource->type = MetalinkResource::TYPE_FTP;
} else if(type == "http") {
resource->type = MetalinkResource::TYPE_HTTP;
+ } else if(type == "https") {
+ resource->type = MetalinkResource::TYPE_HTTPS;
} else if(type == "bittorrent") {
resource->type = MetalinkResource::TYPE_BITTORRENT;
} else {
diff --git a/src/main.cc b/src/main.cc
index 943a54db..09543542 100644
--- a/src/main.cc
+++ b/src/main.cc
@@ -30,23 +30,11 @@
#include "InitiateConnectionCommandFactory.h"
#include "prefs.h"
#include "FeatureConfig.h"
-
-#ifdef ENABLE_BITTORRENT
-# include "TorrentConsoleDownloadEngine.h"
-# include "TorrentMan.h"
-# include "PeerListenCommand.h"
-# include "TorrentAutoSaveCommand.h"
-# include "TrackerWatcherCommand.h"
-# include "TrackerUpdateCommand.h"
-# include "HaveEraseCommand.h"
-# include "ByteArrayDiskWriter.h"
-# include "PeerChokeCommand.h"
-#endif // ENABLE_BITTORRENT
-
-#ifdef ENABLE_METALINK
-# include "Xml2MetalinkProcessor.h"
-#endif // ENABLE_METALINK
-
+#include "DownloadEngineFactory.h"
+#include "UrlRequestInfo.h"
+#include "TorrentRequestInfo.h"
+#include "MetalinkRequestInfo.h"
+#include "Xml2MetalinkProcessor.h"
#include <deque>
#include <algorithm>
#include <time.h>
@@ -69,22 +57,7 @@ extern int optind, opterr, optopt;
using namespace std;
-bool readyToTorrentMode = false;
-string downloadedTorrentFile;
-bool readyToMetalinkMode = false;
-string downloadedMetalinkFile;
-
-void printDownloadCompeleteMessage(string filename) {
- printf(_("\nThe download was complete. <%s>\n"), filename.c_str());
-}
-
-void printDownloadCompeleteMessage() {
- printf("\nThe download was complete.\n");
-}
-
-void printDownloadAbortMessage() {
- printf(_("\nThe download was not complete because of errors. Check the log.\n"));
-}
+RequestInfo* requestInfo;
void setSignalHander(int signal, void (*handler)(int), int flags) {
struct sigaction sigact;
@@ -94,39 +67,6 @@ void setSignalHander(int signal, void (*handler)(int), int flags) {
sigaction(signal, &sigact, NULL);
}
-DownloadEngine* e;
-#ifdef ENABLE_BITTORRENT
-TorrentDownloadEngine* te;
-#endif // ENABLE_BITTORRENT
-
-void handler(int signal) {
- printf(_("\nstopping application...\n"));
- fflush(stdout);
- e->segmentMan->save();
- e->segmentMan->diskWriter->closeFile();
- e->cleanQueue();
- delete e;
- printf(_("done\n"));
- exit(EXIT_SUCCESS);
-}
-
-#ifdef ENABLE_BITTORRENT
-void torrentHandler(int signal) {
- te->torrentMan->setHalt(true);
-}
-#endif // ENABLE_BITTORRENT
-
-void createRequest(int cuid, const string& url, string referer, Requests& requests) {
- Request* req = new Request();
- req->setReferer(referer);
- if(req->setUrl(url)) {
- requests.push_back(req);
- } else {
- fprintf(stderr, _("Unrecognized URL or unsupported protocol: %s\n"), req->getUrl().c_str());
- delete(req);
- }
-}
-
void showVersion() {
cout << PACKAGE << _(" version ") << PACKAGE_VERSION << endl;
cout << "Copyright (C) 2006 Tatsuhiro Tsujikawa" << endl;
@@ -182,7 +122,7 @@ void showUsage() {
cout << _(" --min-segment-size=SIZE[K|M] Set minimum segment size. You can append\n"
" K or M(1K = 1024, 1M = 1024K). This\n"
" value must be greater than or equal to\n"
- " 1024.") << endl;
+ " 1024. Default: 1M") << endl;
cout << _(" --http-proxy=HOST:PORT Use HTTP proxy server. This affects to all\n"
" URLs.") << endl;
cout << _(" --http-user=USER Set HTTP user. This affects to all URLs.") << endl;
@@ -207,6 +147,12 @@ void showUsage() {
cout << _(" --ftp-via-http-proxy=METHOD Use HTTP proxy in FTP. METHOD is either 'get' or\n"
" 'tunnel'.\n"
" Default: tunnel") << endl;
+ cout << _(" --lowest-speed-limit Close connection if download speed is lower than\n"
+ " or equal to this value. 0 means aria2 does not\n"
+ " care lowest speed limit. You can use K or M in\n"
+ " the same manner as in --min-segment-size option.\n"
+ " This option does not affect BitTorrent download.\n"
+ " Default: 0") << endl;
#ifdef ENABLE_BITTORRENT
cout << _(" -T, --torrent-file=TORRENT_FILE The file path to .torrent file.") << endl;
cout << _(" --follow-torrent=true|false Setting this option to false prevents aria2 to\n"
@@ -288,52 +234,19 @@ void showUsage() {
cout << endl;
}
-bool normalDownload(const Requests& requests,
- const Requests& reserved,
- Option* op,
- string& downloadedFilename) {
- setSignalHander(SIGINT, handler, 0);
- setSignalHander(SIGTERM, handler, 0);
-
- e = new ConsoleDownloadEngine();
- e->option = op;
- e->segmentMan = new SegmentMan();
- e->segmentMan->diskWriter = new DefaultDiskWriter();
- 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));
- e->segmentMan->reserved = reserved;
-
- int cuidCounter = 1;
- for(Requests::const_iterator itr = requests.begin();
- itr != requests.end();
- itr++, cuidCounter++) {
- e->commands.push_back(InitiateConnectionCommandFactory::createInitiateConnectionCommand(cuidCounter, *itr, e));
- }
- e->run();
- bool success = false;
- if(e->segmentMan->finished()) {
- printDownloadCompeleteMessage(e->segmentMan->getFilePath());
- if(Util::endsWith(e->segmentMan->getFilePath(), ".torrent")) {
- downloadedTorrentFile = e->segmentMan->getFilePath();
- readyToTorrentMode = true;
- } else if(Util::endsWith(e->segmentMan->getFilePath(), ".metalink")) {
- downloadedMetalinkFile = e->segmentMan->getFilePath();
- readyToMetalinkMode = true;
+long long int getRealSize(char* optarg) {
+ string::size_type p = string(optarg).find_first_of("KM");
+ int mult = 1;
+ if(p != string::npos) {
+ if(optarg[p] == 'K') {
+ mult = 1024;
+ } else if(optarg[p] == 'M') {
+ mult = 1024*1024;
}
- downloadedFilename = e->segmentMan->getFilePath();
- success = true;
- } else {
- e->segmentMan->save();
- e->segmentMan->diskWriter->closeFile();
- printDownloadAbortMessage();
+ optarg[p] = '\0';
}
- e->cleanQueue();
- delete e;
-
- return success;
+ long long int size = strtoll(optarg, NULL, 10)*mult;
+ return size;
}
int main(int argc, char* argv[]) {
@@ -343,18 +256,6 @@ int main(int argc, char* argv[]) {
bindtextdomain (PACKAGE, LOCALEDIR);
textdomain (PACKAGE);
#endif // ENABLE_NLS
- Integers selectFileIndexes;
-#ifdef ENABLE_BITTORRENT
- bool followTorrent = true;
-#else
- bool followTorrent = false;
-#endif // ENABLE_BITTORRENT
-#ifdef ENABLE_METALINK
- bool followMetalink = true;
-#else
- bool followMetalink = false;
-#endif // ENABLE_METALINK
-
int c;
Option* op = new Option();
op->put(PREF_STDOUT_LOG, V_FALSE);
@@ -363,6 +264,20 @@ int main(int argc, char* argv[]) {
op->put(PREF_DAEMON, V_FALSE);
op->put(PREF_LISTEN_PORT, "-1");
op->put(PREF_METALINK_SERVERS, "15");
+ op->put(PREF_FOLLOW_TORRENT,
+#ifdef ENABLE_BITTORRENT
+ V_TRUE
+#else
+ V_FALSE
+#endif // ENABLE_BITTORRENT
+ );
+ op->put(PREF_FOLLOW_METALINK,
+#ifdef ENABLE_METALINK
+ V_TRUE
+#else
+ V_FALSE
+#endif // ENABLE_METALINK
+ );
op->put(PREF_RETRY_WAIT, "5");
op->put(PREF_TIMEOUT, "60");
op->put(PREF_PEER_CONNECTION_TIMEOUT, "60");
@@ -377,6 +292,7 @@ int main(int argc, char* argv[]) {
op->put(PREF_AUTO_SAVE_INTERVAL, "60");
op->put(PREF_DIRECT_FILE_MAPPING, V_TRUE);
op->put(PREF_UPLOAD_LIMIT, "0");
+ op->put(PREF_LOWEST_SPEED_LIMIT, "4000");
while(1) {
int optIndex = 0;
int lopt;
@@ -403,6 +319,7 @@ int main(int argc, char* argv[]) {
{ "ftp-via-http-proxy", required_argument, &lopt, 12 },
{ "min-segment-size", required_argument, &lopt, 13 },
{ "http-proxy-method", required_argument, &lopt, 14 },
+ { "lowest-speed-limit", required_argument, &lopt, 200 },
#ifdef ENABLE_BITTORRENT
{ "torrent-file", required_argument, NULL, 'T' },
{ "listen-port", required_argument, &lopt, 15 },
@@ -506,17 +423,7 @@ int main(int argc, char* argv[]) {
}
break;
case 13: {
- string::size_type p = string(optarg).find_first_of("KM");
- int mult = 1;
- if(p != string::npos) {
- if(optarg[p] == 'K') {
- mult = 1024;
- } else if(optarg[p] == 'M') {
- mult = 1024*1024;
- }
- optarg[p] = '\0';
- }
- long long int size = strtoll(optarg, NULL, 10)*mult;
+ long long int size = getRealSize(optarg);
if(size < 1024) {
cerr << _("min-segment-size invalid") << endl;
showUsage();
@@ -546,9 +453,9 @@ int main(int argc, char* argv[]) {
}
case 16:
if(string(optarg) == "true") {
- followTorrent = true;
+ op->put(PREF_FOLLOW_TORRENT, V_TRUE);
} else if(string(optarg) == "false") {
- followTorrent = false;
+ op->put(PREF_FOLLOW_TORRENT, V_FALSE);
} else {
cerr << _("follow-torrent must be either 'true' or 'false'.") << endl;
showUsage();
@@ -580,7 +487,7 @@ int main(int argc, char* argv[]) {
break;
}
case 21:
- Util::unfoldRange(optarg, selectFileIndexes);
+ op->put(PREF_SELECT_FILE, optarg);
break;
case 100:
op->put(PREF_METALINK_VERSION, optarg);
@@ -593,15 +500,25 @@ int main(int argc, char* argv[]) {
break;
case 103:
if(string(optarg) == "true") {
- followMetalink = true;
+ op->put(PREF_FOLLOW_METALINK, V_TRUE);
} else if(string(optarg) == "false") {
- followMetalink = false;
+ op->put(PREF_FOLLOW_METALINK, V_FALSE);
} else {
cerr << _("follow-metalink must be either 'true' or 'false'.") << endl;
showUsage();
exit(EXIT_FAILURE);
}
break;
+ case 200: {
+ int limit = getRealSize(optarg);
+ if(limit < 0) {
+ cerr << _("lowest-speed-limit must be greater than or equal to 0") << endl;
+ showUsage();
+ exit(EXIT_FAILURE);
+ }
+ op->put(PREF_LOWEST_SPEED_LIMIT, Util::itos(limit));
+ break;
+ }
}
break;
}
@@ -720,190 +637,58 @@ int main(int argc, char* argv[]) {
}
// make sure logger is configured properly.
try {
- LogFactory::getInstance();
- } catch(Exception* ex) {
- cerr << ex->getMsg() << endl;
- delete ex;
- exit(EXIT_FAILURE);
- }
+ Logger* logger = LogFactory::getInstance();
+ logger->info("%s %s", PACKAGE, PACKAGE_VERSION);
+ logger->info("Logging started.");
- setSignalHander(SIGPIPE, SIG_IGN, 0);
+ setSignalHander(SIGPIPE, SIG_IGN, 0);
- 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 <= op->getAsInt(PREF_SPLIT); s++) {
- createRequest(cuidCounter, *itr, op->get(PREF_REFERER), requests);
- cuidCounter++;
+ requestInfo = 0;
+#ifdef ENABLE_BITTORRENT
+ if(op->defined(PREF_TORRENT_FILE)) {
+ requestInfo = new TorrentRequestInfo(op->get(PREF_TORRENT_FILE),
+ op);
+ Strings targetFiles;
+ if(op->defined(PREF_TORRENT_FILE) && !args.empty()) {
+ targetFiles = args;
}
+ ((TorrentRequestInfo*)requestInfo)->setTargetFiles(targetFiles);
}
- setSignalHander(SIGINT, handler, 0);
- setSignalHander(SIGTERM, handler, 0);
-
- Requests reserved;
- string downloadedFilename;
- normalDownload(requests, reserved, op, downloadedFilename);
-
- for_each(requests.begin(), requests.end(), Deleter());
- for_each(reserved.begin(), reserved.end(), Deleter());
- requests.clear();
- }
+ else
+#endif // ENABLE_BITTORRENT
#ifdef ENABLE_METALINK
- 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(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);
- }
- entry->dropUnsupportedResource();
- entry->reorderResourcesByPreference();
- Requests requests;
- int cuidCounter = 1;
- for(MetalinkResources::const_iterator itr = entry->resources.begin();
- itr != entry->resources.end(); itr++) {
- MetalinkResource* resource = *itr;
- for(int s = 1; s <= op->getAsInt(PREF_SPLIT); s++) {
- createRequest(cuidCounter, resource->url,
- op->get(PREF_REFERER), requests);
- cuidCounter++;
- }
- }
- Requests reserved;
- 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()));
- requests.erase(requests.begin()+maxConnection, requests.end());
- }
-
- setSignalHander(SIGINT, handler, 0);
- setSignalHander(SIGTERM, handler, 0);
-
- string downloadedFilename;
- bool success = normalDownload(requests, reserved, op, downloadedFilename);
-
- for_each(requests.begin(), requests.end(), Deleter());
- for_each(reserved.begin(), reserved.end(), Deleter());
- requests.clear();
+ if(op->defined(PREF_METALINK_FILE)) {
+ requestInfo = new MetalinkRequestInfo(op->get(PREF_METALINK_FILE),
+ op);
+ } else
+#endif // ENABLE_METALINK
+ {
+ requestInfo = new UrlRequestInfo(args, 0, op);
+ }
- if(success) {
-#ifdef ENABLE_MESSAGE_DIGEST
- if(entry->check(downloadedFilename)) {
- printf("checksum OK.\n");
- } else {
- printf("checksum ERROR.\n");
+ while(requestInfo) {
+ RequestInfo* next = requestInfo->execute();
+ if(requestInfo->isFail()) {
+ delete requestInfo;
exit(EXIT_FAILURE);
}
-#endif // ENABLE_MESSAGE_DIGEST
- }
-
- delete metalinker;
- }
-#endif // ENABLE_METALINK
-#ifdef ENABLE_BITTORRENT
- if(op->defined(PREF_TORRENT_FILE) ||
- followTorrent && readyToTorrentMode) {
- try {
- //op->put(PREF_MAX_TRIES, "0");
- setSignalHander(SIGINT, torrentHandler, SA_RESETHAND);
- setSignalHander(SIGTERM, torrentHandler, SA_RESETHAND);
-
- Request* req = new Request();
- req->isTorrent = true;
- req->setTrackerEvent(Request::STARTED);
- te = new TorrentConsoleDownloadEngine();
- te->option = op;
- ByteArrayDiskWriter* byteArrayDiskWriter = new ByteArrayDiskWriter();
- te->segmentMan = new SegmentMan();
- te->segmentMan->diskWriter = byteArrayDiskWriter;
- te->segmentMan->option = op;
- te->segmentMan->splitter = new SplitSlowestSegmentSplitter();
- te->segmentMan->splitter->setMinSegmentSize(op->getAsLLInt(PREF_MIN_SEGMENT_SIZE));
- te->torrentMan = new TorrentMan();
- te->torrentMan->setStoreDir(op->get(PREF_DIR));
- te->torrentMan->option = op;
- te->torrentMan->req = req;
- 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);
- cout << _("Files:") << endl;
- cout << "idx|path/length" << endl;
- cout << "===+===========================================================================" << endl;
- int count = 1;
- for(FileEntries::const_iterator itr = fileEntries.begin();
- itr != fileEntries.end(); count++, itr++) {
- printf("%3d|%s\n |%s Bytes\n", count, itr->path.c_str(),
- Util::llitos(itr->length, true).c_str());
- cout << "---+---------------------------------------------------------------------------" << endl;
- }
- exit(EXIT_SUCCESS);
- } else {
- if(selectFileIndexes.empty()) {
- Strings targetFiles;
- if(op->defined(PREF_TORRENT_FILE) && !args.empty()) {
- targetFiles = args;
- }
- te->torrentMan->setup(targetTorrentFile, targetFiles);
+ if(requestInfo->getFileInfo().checkReady()) {
+ if(requestInfo->getFileInfo().check()) {
+ printf("checksum OK.\n");
} else {
- te->torrentMan->setup(targetTorrentFile, selectFileIndexes);
+ // TODO
+ printf("checksum ERROR.\n");
+ exit(EXIT_FAILURE);
}
}
- 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 {
- port = listenCommand->bindPort(listenPort, listenPort);
- }
- if(port == -1) {
- printf(_("Errors occurred while binding port.\n"));
- exit(EXIT_FAILURE);
- }
- te->torrentMan->setPort(port);
- te->commands.push_back(listenCommand);
-
- te->commands.push_back(new TrackerWatcherCommand(te->torrentMan->getNewCuid(),
- te,
- te->torrentMan->minInterval));
- te->commands.push_back(new TrackerUpdateCommand(te->torrentMan->getNewCuid(),
- te));
- te->commands.push_back(new TorrentAutoSaveCommand(te->torrentMan->getNewCuid(),
- te,
- op->getAsInt(PREF_AUTO_SAVE_INTERVAL)));
- te->commands.push_back(new PeerChokeCommand(te->torrentMan->getNewCuid(),
- 10, te));
- te->commands.push_back(new HaveEraseCommand(te->torrentMan->getNewCuid(),
- te, 10));
- te->run();
-
- if(te->torrentMan->downloadComplete()) {
- printDownloadCompeleteMessage();
- }
- delete req;
- te->cleanQueue();
- delete te;
- } catch(Exception* ex) {
- cerr << ex->getMsg() << endl;
- delete ex;
- exit(EXIT_FAILURE);
+ delete requestInfo;
+ requestInfo = next;
}
+ } catch(Exception* ex) {
+ cerr << ex->getMsg() << endl;
+ delete ex;
+ exit(EXIT_FAILURE);
}
-#endif // ENABLE_BITTORRENT
delete op;
LogFactory::release();
#ifdef HAVE_LIBGNUTLS
diff --git a/src/messageDigest.h b/src/messageDigest.h
index b084f07b..c14c4600 100644
--- a/src/messageDigest.h
+++ b/src/messageDigest.h
@@ -26,6 +26,8 @@
#ifdef ENABLE_SSL
+#define MAX_MD_LENGTH (16+20)
+
#ifdef HAVE_LIBSSL
#include <openssl/evp.h>
#endif // HAVE_LIBSSL
@@ -36,73 +38,80 @@
class MessageDigestContext {
public:
- enum HashAlgo {
- ALGO_MD5,
- ALGO_SHA1
- };
#ifdef HAVE_LIBSSL
- EVP_MD_CTX ctx;
- const EVP_MD* algo;
+ typedef const EVP_MD* DigestAlgo;
+# define DIGEST_ALGO_MD5 EVP_md5()
+# define DIGEST_ALGO_SHA1 EVP_sha1()
#endif // HAVE_LIBSSL
#ifdef HAVE_LIBGCRYPT
- gcry_md_hd_t ctx;
- int algo;
+ typedef int DigestAlgo;
+# define DIGEST_ALGO_MD5 GCRY_MD_MD5
+# define DIGEST_ALGO_SHA1 GCRY_MD_SHA1
#endif // HAVE_LIBGCRYPT
-
- MessageDigestContext() {}
- MessageDigestContext(HashAlgo algo) {
- setAlgo(algo);
- }
-
- void setAlgo(HashAlgo algo) {
- switch(algo) {
- case ALGO_MD5:
+private:
#ifdef HAVE_LIBSSL
- this->algo = EVP_md5();
-#endif // HAVE_LIBSSL
-#ifdef HAVE_LIBGCRYPT
- this->algo = GCRY_MD_MD5;
-#endif // HAVE_LIBGCRYPT
- break;
- case ALGO_SHA1:
-#ifdef HAVE_LIBSSL
- this->algo = EVP_sha1();
+ EVP_MD_CTX ctx;
#endif // HAVE_LIBSSL
#ifdef HAVE_LIBGCRYPT
- this->algo = GCRY_MD_SHA1;
-#endif // HAVE_LIBGCRYPT
- break;
- default:
- break;
- }
- }
-};
+ gcry_md_hd_t ctx;
+#endif // HAVE_LIBGCRYPT
+ DigestAlgo algo;
+public:
+ MessageDigestContext():
+ algo(DIGEST_ALGO_SHA1) {}
+ MessageDigestContext(DigestAlgo algo):
+ algo(algo) {}
#ifdef HAVE_LIBSSL
-#define digestInit(CTX) EVP_MD_CTX_init(&CTX.ctx)
-#define digestReset(CTX) EVP_DigestInit_ex(&CTX.ctx, CTX.algo, NULL)
-#define digestUpdate(CTX, DATA, LENGTH) EVP_DigestUpdate(&CTX.ctx, DATA, LENGTH)
-#define digestFinal(CTX, HASH) \
-{\
-int len;\
-EVP_DigestFinal_ex(&CTX.ctx, HASH, (unsigned int*)&len);\
-}
-#define digestFree(CTX) EVP_MD_CTX_cleanup(&CTX.ctx)
-
+ void digestInit() {
+ EVP_MD_CTX_init(&ctx);
+ digestReset();
+ }
+ void digestReset() {
+ EVP_DigestInit_ex(&ctx, algo, 0);
+ }
+ void digestUpdate(const void* data, int length) {
+ EVP_DigestUpdate(&ctx, data, length);
+ }
+ void digestFinal(unsigned char* md) {
+ int len;
+ EVP_DigestFinal_ex(&ctx, md, (unsigned int*)&len);
+ }
+ void digestFree() {
+ EVP_MD_CTX_cleanup(&ctx);
+ }
+ int digestLength() const {
+ return digestLength(algo);
+ }
+ static int digestLength(DigestAlgo algo) {
+ return EVP_MD_size(algo);
+ }
#endif // HAVE_LIBSSL
#ifdef HAVE_LIBGCRYPT
-#define digestInit(CTX) gcry_md_open(&CTX.ctx, CTX.algo, 0)
-#define digestReset(CTX) gcry_md_reset(CTX.ctx)
-#define digestUpdate(CTX, DATA, LENGTH) gcry_md_write(CTX.ctx, DATA, LENGTH)
-#define digestFinal(CTX, HASH) \
-{\
-gcry_md_final(CTX.ctx);\
-memcpy(HASH, gcry_md_read(CTX.ctx, 0), gcry_md_get_algo_dlen(CTX.algo));\
-}
-#define digestFree(CTX) gcry_md_close(CTX.ctx)
+ void digestInit() {
+ gcry_md_open(&ctx, algo, 0);
+ }
+ void digestReset() {
+ gcry_md_reset(ctx);
+ }
+ void digestUpdate(const void* data, int length) {
+ gcry_md_write(ctx, data, length);
+ }
+ void digestFinal(unsigned char* md) {
+ gcry_md_final(ctx);
+ memcpy(md, gcry_md_read(ctx, 0), gcry_md_get_algo_dlen(algo));
+ }
+ void digestFree() {
+ gcry_md_close(ctx);
+ }
+ int digestLength() const {
+ return digestLength(algo);
+ }
+ static int digestLength(DigestAlgo algo) {
+ return gcry_md_get_algo_dlen(algo);
+ }
#endif // HAVE_LIBGCRYPT
-
+};
#endif // ENABLE_SSL
-
#endif // _D_MESSAGE_DIGEST_H_
diff --git a/src/prefs.h b/src/prefs.h
index 6b48cb63..83fcaba7 100644
--- a/src/prefs.h
+++ b/src/prefs.h
@@ -57,6 +57,8 @@
#define PREF_DAEMON "daemon"
// value: a string
#define PREF_REFERER "referer"
+// value' 1*digit
+#define PREF_LOWEST_SPEED_LIMIT "lowest_speed_limit"
/**
* FTP related preferences
@@ -116,6 +118,10 @@
#define PREF_TORRENT_FILE "torrent_file"
// values: 1*digit
#define PREF_LISTEN_PORT "listen_port"
+// values: true | false
+#define PREF_FOLLOW_TORRENT "follow_torrent"
+// values: 1*digit *( (,|-) 1*digit)
+#define PREF_SELECT_FILE "select_file"
/**
* Metalink related preferences
@@ -130,5 +136,7 @@
#define PREF_METALINK_OS "metalink_os"
// values: 1*digit
#define PREF_METALINK_SERVERS "metalink_servers"
+// values: true | false
+#define PREF_FOLLOW_METALINK "follow_metalink"
#endif // _D_PREFS_H_