summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorTatsuhiro Tsujikawa <tatsuhiro.t@gmail.com>2009-01-12 12:27:34 +0000
committerTatsuhiro Tsujikawa <tatsuhiro.t@gmail.com>2009-01-12 12:27:34 +0000
commit8a9d921465f80e231f9e1a99a0d93beafb474402 (patch)
tree85963269afe6e95da564e23f4c2da61c023c9a97 /src
parent0a4f43d0edeefb5bc49329b791984c7b2072d1df (diff)
2009-01-12 Tatsuhiro Tsujikawa <t-tujikawa@users.sourceforge.net>
Applied exit-status patch from Pascal Rigaux at Mandriva. aria2 now returns last error encountered in the HTTP/FTP downloads as a exit status value. If all downloads finished successfully, aria2 returns 0. The error code is defined in src/DownloadResult.h. The error occurred in the download currently in progress is not reported as a last error. If no error has encountered but there are in progress or waiting downloads, aria2 returns 7. * src/AbstractCommand.cc * src/DlAbortEx.h * src/DlRetryEx.h * src/DownloadCommand.cc * src/DownloadFailureException.h * src/DownloadResult.h * src/FtpNegotiationCommand.cc * src/HttpSkipResponseCommand.cc * src/Makefile.am * src/MultiUrlRequestInfo.cc * src/MultiUrlRequestInfo.h * src/RecoverableException.h * src/RequestGroup.cc * src/RequestGroup.h * src/RequestGroupMan.cc * src/RequestGroupMan.h * src/URIResult.cc * src/URIResult.h * src/main.cc * src/option_processing.cc * test/RequestGroupTest.cc
Diffstat (limited to 'src')
-rw-r--r--src/AbstractCommand.cc5
-rw-r--r--src/DlAbortEx.h2
-rw-r--r--src/DlRetryEx.h2
-rw-r--r--src/DownloadCommand.cc2
-rw-r--r--src/DownloadFailureException.h8
-rw-r--r--src/DownloadResult.h16
-rw-r--r--src/FtpNegotiationCommand.cc10
-rw-r--r--src/HttpSkipResponseCommand.cc3
-rw-r--r--src/Makefile.am5
-rw-r--r--src/Makefile.in40
-rw-r--r--src/MultiUrlRequestInfo.cc14
-rw-r--r--src/MultiUrlRequestInfo.h10
-rw-r--r--src/RecoverableException.h24
-rw-r--r--src/RequestGroup.cc31
-rw-r--r--src/RequestGroup.h16
-rw-r--r--src/RequestGroupMan.cc10
-rw-r--r--src/RequestGroupMan.h35
-rw-r--r--src/URIResult.cc52
-rw-r--r--src/URIResult.h62
-rw-r--r--src/main.cc20
-rw-r--r--src/option_processing.cc31
21 files changed, 309 insertions, 89 deletions
diff --git a/src/AbstractCommand.cc b/src/AbstractCommand.cc
index 5c2f3491..9ec238e0 100644
--- a/src/AbstractCommand.cc
+++ b/src/AbstractCommand.cc
@@ -149,13 +149,14 @@ bool AbstractCommand::execute() {
req->getProtocol());
ss->setError();
- throw DlRetryEx(EX_TIME_OUT);
+ throw DlRetryEx(EX_TIME_OUT, DownloadResult::TIME_OUT);
}
e->commands.push_back(this);
return false;
}
} catch(DlAbortEx& err) {
logger->error(MSG_DOWNLOAD_ABORTED, err, cuid, req->getUrl().c_str());
+ _requestGroup->addURIResult(req->getUrl(), err.getCode());
onAbort();
req->resetUrl();
tryReserved();
@@ -174,6 +175,7 @@ bool AbstractCommand::execute() {
if(isAbort) {
logger->info(MSG_MAX_TRY, cuid, req->getTryCount());
logger->error(MSG_DOWNLOAD_ABORTED, err, cuid, req->getUrl().c_str());
+ _requestGroup->addURIResult(req->getUrl(), err.getCode());
tryReserved();
return true;
} else {
@@ -181,6 +183,7 @@ bool AbstractCommand::execute() {
}
} catch(DownloadFailureException& err) {
logger->error(EX_EXCEPTION_CAUGHT, err);
+ _requestGroup->addURIResult(req->getUrl(), err.getCode());
_requestGroup->setHaltRequested(true);
return true;
}
diff --git a/src/DlAbortEx.h b/src/DlAbortEx.h
index 9f10305a..86da96cd 100644
--- a/src/DlAbortEx.h
+++ b/src/DlAbortEx.h
@@ -50,6 +50,8 @@ public:
DlAbortEx(const std::string& msg,
const Exception& cause):RecoverableException(msg, cause) {}
DlAbortEx(const RecoverableException& e):RecoverableException(e) {}
+ DlAbortEx(const std::string& msg, DownloadResult::RESULT code):
+ RecoverableException(msg, code) {}
};
} // namespace aria2
diff --git a/src/DlRetryEx.h b/src/DlRetryEx.h
index caaf8ea5..4a6dffba 100644
--- a/src/DlRetryEx.h
+++ b/src/DlRetryEx.h
@@ -50,6 +50,8 @@ public:
DlRetryEx(const std::string& msg,
const Exception& cause):RecoverableException(msg, cause) {}
DlRetryEx(const DlRetryEx& e):RecoverableException(e) {}
+ DlRetryEx(const std::string& msg, DownloadResult::RESULT code):
+ RecoverableException(msg, code) {}
};
} // namespace aria2
diff --git a/src/DownloadCommand.cc b/src/DownloadCommand.cc
index 7ef36a50..56c358da 100644
--- a/src/DownloadCommand.cc
+++ b/src/DownloadCommand.cc
@@ -243,7 +243,7 @@ void DownloadCommand::checkLowestDownloadSpeed() const
throw DlAbortEx(StringFormat(EX_TOO_SLOW_DOWNLOAD_SPEED,
nowSpeed,
lowestDownloadSpeedLimit,
- req->getHost().c_str()).str());
+ req->getHost().c_str()).str(), DownloadResult::TOO_SLOW_DOWNLOAD_SPEED);
}
}
}
diff --git a/src/DownloadFailureException.h b/src/DownloadFailureException.h
index d60231d7..c5fd32b0 100644
--- a/src/DownloadFailureException.h
+++ b/src/DownloadFailureException.h
@@ -52,8 +52,12 @@ protected:
public:
DownloadFailureException(const std::string& msg):RecoverableException(msg) {}
DownloadFailureException(const std::string& msg,
- const Exception& cause):RecoverableException(msg, cause) {}
- DownloadFailureException(const DownloadFailureException& e):RecoverableException(e) {}
+ const Exception& cause):
+ RecoverableException(msg, cause) {}
+ DownloadFailureException(const DownloadFailureException& e):
+ RecoverableException(e) {}
+ DownloadFailureException(const std::string& msg, DownloadResult::RESULT code):
+ RecoverableException(msg, code) {}
};
} // namespace aria2
diff --git a/src/DownloadResult.h b/src/DownloadResult.h
index 92fe1b84..d266a3d0 100644
--- a/src/DownloadResult.h
+++ b/src/DownloadResult.h
@@ -36,18 +36,28 @@
#define _D_DOWNLOAD_RESULT_H_
#include "common.h"
-#include "SharedHandle.h"
+
#include <stdint.h>
+
#include <string>
+#include "SharedHandle.h"
+
namespace aria2 {
class DownloadResult
{
public:
+ // RESULT is used as an exit status code.
enum RESULT {
- FINISHED,
- NOT_YET,
+ FINISHED = 0,
+ UNKNOWN_ERROR = 1,
+ TIME_OUT = 2,
+ RESOURCE_NOT_FOUND = 3,
+ MAX_FILE_NOT_FOUND = 4,
+ TOO_SLOW_DOWNLOAD_SPEED = 5,
+ NETWORK_PROBLEM = 6,
+ IN_PROGRESS = 7,
};
int32_t gid;
diff --git a/src/FtpNegotiationCommand.cc b/src/FtpNegotiationCommand.cc
index 654bc7ed..b1a730d4 100644
--- a/src/FtpNegotiationCommand.cc
+++ b/src/FtpNegotiationCommand.cc
@@ -261,7 +261,10 @@ bool FtpNegotiationCommand::recvCwd() {
if(status != 250) {
poolConnection();
_requestGroup->increaseAndValidateFileNotFoundCount();
- throw DlAbortEx(StringFormat(EX_BAD_STATUS, status).str());
+ if (status == 550)
+ throw DlAbortEx(MSG_RESOURCE_NOT_FOUND, DownloadResult::RESOURCE_NOT_FOUND);
+ else
+ throw DlAbortEx(StringFormat(EX_BAD_STATUS, status).str());
}
if(e->option->getAsBool(PREF_REMOTE_TIME)) {
sequence = SEQ_SEND_MDTM;
@@ -544,7 +547,10 @@ bool FtpNegotiationCommand::recvRetr() {
}
if(status != 150 && status != 125) {
_requestGroup->increaseAndValidateFileNotFoundCount();
- throw DlAbortEx(StringFormat(EX_BAD_STATUS, status).str());
+ if (status == 550)
+ throw DlAbortEx(MSG_RESOURCE_NOT_FOUND, DownloadResult::RESOURCE_NOT_FOUND);
+ else
+ throw DlAbortEx(StringFormat(EX_BAD_STATUS, status).str());
}
if(e->option->getAsBool(PREF_FTP_PASV)) {
sequence = SEQ_NEGOTIATION_COMPLETED;
diff --git a/src/HttpSkipResponseCommand.cc b/src/HttpSkipResponseCommand.cc
index f1ae1f03..358217c9 100644
--- a/src/HttpSkipResponseCommand.cc
+++ b/src/HttpSkipResponseCommand.cc
@@ -160,7 +160,8 @@ bool HttpSkipResponseCommand::processResponse()
if(_httpResponse->getResponseStatus() == HttpHeader::S401) {
throw DlAbortEx(EX_AUTH_FAILED);
}else if(_httpResponse->getResponseStatus() == HttpHeader::S404) {
- throw DlAbortEx(MSG_RESOURCE_NOT_FOUND);
+ throw DlAbortEx(MSG_RESOURCE_NOT_FOUND,
+ DownloadResult::RESOURCE_NOT_FOUND);
} else {
throw DlAbortEx(StringFormat(EX_BAD_STATUS, Util::parseUInt(_httpResponse->getResponseStatus())).str());
}
diff --git a/src/Makefile.am b/src/Makefile.am
index 53633eea..7739de9a 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -188,14 +188,15 @@ SRCS = Socket.h\
ServerStat.cc ServerStat.h\
ServerStatMan.cc ServerStatMan.h\
URISelector.h\
- AdaptiveURISelector.cc AdaptiveURISelector.h\
+ AdaptiveURISelector.cc AdaptiveURISelector.h\
InOrderURISelector.cc InOrderURISelector.h\
ServerStatURISelector.cc ServerStatURISelector.h\
NsCookieParser.cc NsCookieParser.h\
CookieStorage.cc CookieStorage.h\
SocketBuffer.cc SocketBuffer.h\
OptionHandlerException.cc OptionHandlerException.h\
- bencode.cc bencode.h
+ bencode.cc bencode.h\
+ URIResult.cc URIResult.h
if ENABLE_SSL
SRCS += TLSContext.h
diff --git a/src/Makefile.in b/src/Makefile.in
index aff2e2ca..60891f0b 100644
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -411,10 +411,10 @@ am__libaria2c_a_SOURCES_DIST = Socket.h SocketCore.cc SocketCore.h \
ServerStatURISelector.h NsCookieParser.cc NsCookieParser.h \
CookieStorage.cc CookieStorage.h SocketBuffer.cc \
SocketBuffer.h OptionHandlerException.cc \
- OptionHandlerException.h bencode.cc bencode.h TLSContext.h \
- LibgnutlsTLSContext.cc LibgnutlsTLSContext.h \
- LibsslTLSContext.cc LibsslTLSContext.h GZipDecoder.cc \
- GZipDecoder.h Sqlite3MozCookieParser.cc \
+ OptionHandlerException.h bencode.cc bencode.h URIResult.cc \
+ URIResult.h TLSContext.h LibgnutlsTLSContext.cc \
+ LibgnutlsTLSContext.h LibsslTLSContext.cc LibsslTLSContext.h \
+ GZipDecoder.cc GZipDecoder.h Sqlite3MozCookieParser.cc \
Sqlite3MozCookieParser.h AsyncNameResolver.cc \
AsyncNameResolver.h IteratableChunkChecksumValidator.cc \
IteratableChunkChecksumValidator.h \
@@ -802,13 +802,14 @@ am__objects_21 = SocketCore.$(OBJEXT) Command.$(OBJEXT) \
InOrderURISelector.$(OBJEXT) ServerStatURISelector.$(OBJEXT) \
NsCookieParser.$(OBJEXT) CookieStorage.$(OBJEXT) \
SocketBuffer.$(OBJEXT) OptionHandlerException.$(OBJEXT) \
- bencode.$(OBJEXT) $(am__objects_1) $(am__objects_2) \
- $(am__objects_3) $(am__objects_4) $(am__objects_5) \
- $(am__objects_6) $(am__objects_7) $(am__objects_8) \
- $(am__objects_9) $(am__objects_10) $(am__objects_11) \
- $(am__objects_12) $(am__objects_13) $(am__objects_14) \
- $(am__objects_15) $(am__objects_16) $(am__objects_17) \
- $(am__objects_18) $(am__objects_19) $(am__objects_20)
+ bencode.$(OBJEXT) URIResult.$(OBJEXT) $(am__objects_1) \
+ $(am__objects_2) $(am__objects_3) $(am__objects_4) \
+ $(am__objects_5) $(am__objects_6) $(am__objects_7) \
+ $(am__objects_8) $(am__objects_9) $(am__objects_10) \
+ $(am__objects_11) $(am__objects_12) $(am__objects_13) \
+ $(am__objects_14) $(am__objects_15) $(am__objects_16) \
+ $(am__objects_17) $(am__objects_18) $(am__objects_19) \
+ $(am__objects_20)
am_libaria2c_a_OBJECTS = $(am__objects_21)
libaria2c_a_OBJECTS = $(am_libaria2c_a_OBJECTS)
am__installdirs = "$(DESTDIR)$(bindir)"
@@ -1133,14 +1134,14 @@ SRCS = Socket.h SocketCore.cc SocketCore.h BinaryStream.h Command.cc \
ServerStatURISelector.h NsCookieParser.cc NsCookieParser.h \
CookieStorage.cc CookieStorage.h SocketBuffer.cc \
SocketBuffer.h OptionHandlerException.cc \
- OptionHandlerException.h bencode.cc bencode.h $(am__append_1) \
- $(am__append_2) $(am__append_3) $(am__append_4) \
- $(am__append_5) $(am__append_6) $(am__append_7) \
- $(am__append_8) $(am__append_9) $(am__append_10) \
- $(am__append_11) $(am__append_12) $(am__append_13) \
- $(am__append_14) $(am__append_15) $(am__append_16) \
- $(am__append_17) $(am__append_18) $(am__append_19) \
- $(am__append_20)
+ OptionHandlerException.h bencode.cc bencode.h URIResult.cc \
+ URIResult.h $(am__append_1) $(am__append_2) $(am__append_3) \
+ $(am__append_4) $(am__append_5) $(am__append_6) \
+ $(am__append_7) $(am__append_8) $(am__append_9) \
+ $(am__append_10) $(am__append_11) $(am__append_12) \
+ $(am__append_13) $(am__append_14) $(am__append_15) \
+ $(am__append_16) $(am__append_17) $(am__append_18) \
+ $(am__append_19) $(am__append_20)
noinst_LIBRARIES = libaria2c.a
libaria2c_a_SOURCES = $(SRCS)
aria2c_LDADD = libaria2c.a @LIBINTL@ @ALLOCA@ @LIBGNUTLS_LIBS@\
@@ -1499,6 +1500,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/TimedHaltCommand.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/TrackerWatcherCommand.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/TransferStat.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/URIResult.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/URLMetalinkParserState.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/UTPexExtensionMessage.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/UnknownLengthPieceStorage.Po@am__quote@
diff --git a/src/MultiUrlRequestInfo.cc b/src/MultiUrlRequestInfo.cc
index ddd1a87e..192eb128 100644
--- a/src/MultiUrlRequestInfo.cc
+++ b/src/MultiUrlRequestInfo.cc
@@ -99,9 +99,9 @@ void MultiUrlRequestInfo::printMessageForContinue()
<< "\n";
}
-int MultiUrlRequestInfo::execute()
+DownloadResult::RESULT MultiUrlRequestInfo::execute()
{
- int returnValue = 1;
+ DownloadResult::RESULT returnValue = DownloadResult::FINISHED;
try {
DownloadEngineHandle e =
DownloadEngineFactory().newDownloadEngine(_option, _requestGroups);
@@ -190,10 +190,14 @@ int MultiUrlRequestInfo::execute()
_summaryOut << std::flush;
RequestGroupMan::DownloadStat s = e->_requestGroupMan->getDownloadStat();
- if(s.allCompleted()) {
- returnValue = 0;
- } else {
+ if(!s.allCompleted()) {
printMessageForContinue();
+ if(s.getLastErrorResult() == DownloadResult::FINISHED &&
+ s.getInProgress() > 0) {
+ returnValue = DownloadResult::IN_PROGRESS;
+ } else {
+ returnValue = s.getLastErrorResult();
+ }
}
} catch(RecoverableException& e) {
_logger->error(EX_EXCEPTION_CAUGHT, e);
diff --git a/src/MultiUrlRequestInfo.h b/src/MultiUrlRequestInfo.h
index ccf37346..25742034 100644
--- a/src/MultiUrlRequestInfo.h
+++ b/src/MultiUrlRequestInfo.h
@@ -36,10 +36,13 @@
#define _D_MULTI_URL_REQUEST_INFO_H_
#include "common.h"
-#include "SharedHandle.h"
+
#include <deque>
#include <iosfwd>
+#include "SharedHandle.h"
+#include "DownloadResult.h"
+
namespace aria2 {
class RequestGroup;
@@ -71,9 +74,10 @@ public:
virtual ~MultiUrlRequestInfo();
/**
- * Returns 0 if all downloads have completed, otherwise returns 1.
+ * Returns FINISHED if all downloads have completed, otherwise returns the
+ * last download result.
*/
- int execute();
+ DownloadResult::RESULT execute();
};
typedef SharedHandle<MultiUrlRequestInfo> MultiUrlRequestInfoHandle;
diff --git a/src/RecoverableException.h b/src/RecoverableException.h
index 664ddc48..3064a220 100644
--- a/src/RecoverableException.h
+++ b/src/RecoverableException.h
@@ -35,10 +35,14 @@
#ifndef _D_RECOVERABLE_EXCEPTION_H_
#define _D_RECOVERABLE_EXCEPTION_H_
#include "Exception.h"
+#include "DownloadResult.h"
namespace aria2 {
class RecoverableException:public Exception {
+private:
+ DownloadResult::RESULT _code;
+
protected:
virtual SharedHandle<Exception> copy() const
{
@@ -46,10 +50,22 @@ protected:
return e;
}
public:
- RecoverableException(const std::string& msg):Exception(msg) {}
- RecoverableException(const std::string& msg,
- const Exception& cause):Exception(msg, cause) {}
- RecoverableException(const RecoverableException& e):Exception(e) {}
+ RecoverableException(const std::string& msg):
+ Exception(msg),
+ _code(DownloadResult::UNKNOWN_ERROR) {}
+
+ RecoverableException(const std::string& msg, const Exception& cause):
+ Exception(msg, cause),
+ _code(DownloadResult::UNKNOWN_ERROR) {}
+
+ RecoverableException(const RecoverableException& e):
+ Exception(e),
+ _code(DownloadResult::UNKNOWN_ERROR) {}
+
+ RecoverableException(const std::string& msg, DownloadResult::RESULT result):
+ Exception(msg), _code(result) {}
+
+ DownloadResult::RESULT getCode() const { return _code; }
};
} // namespace aria2
diff --git a/src/RequestGroup.cc b/src/RequestGroup.cc
index 57b421fc..e2550776 100644
--- a/src/RequestGroup.cc
+++ b/src/RequestGroup.cc
@@ -64,7 +64,6 @@
#include "RequestGroupMan.h"
#include "DefaultBtProgressInfoFile.h"
#include "DefaultPieceStorage.h"
-#include "DownloadResult.h"
#include "DownloadHandlerFactory.h"
#include "MemoryBufferPreDownloadHandler.h"
#include "DownloadHandlerConstants.h"
@@ -171,6 +170,19 @@ bool RequestGroup::allDownloadFinished() const
}
}
+DownloadResult::RESULT RequestGroup::downloadResult() const
+{
+ if (downloadFinished())
+ return DownloadResult::FINISHED;
+ else {
+ if (_uriResults.empty()) {
+ return DownloadResult::UNKNOWN_ERROR;
+ } else {
+ return _uriResults.back().getResult();
+ }
+ }
+}
+
void RequestGroup::closeFile()
{
if(!_pieceStorage.isNull()) {
@@ -902,9 +914,7 @@ DownloadResultHandle RequestGroup::createDownloadResult() const
uris.size(),
sessionDownloadLength,
_downloadContext->calculateSessionTime(),
- downloadFinished()?
- DownloadResult::FINISHED :
- DownloadResult::NOT_YET));
+ downloadResult()));
}
void RequestGroup::registerServerHost(const ServerHostHandle& serverHost)
@@ -1073,7 +1083,8 @@ void RequestGroup::increaseAndValidateFileNotFoundCount()
if(maxCount > 0 && _fileNotFoundCount >= maxCount &&
_segmentMan->calculateSessionDownloadLength() == 0) {
throw DownloadFailureException
- (StringFormat("Reached max-file-not-found count=%u", maxCount).str());
+ (StringFormat("Reached max-file-not-found count=%u", maxCount).str(),
+ DownloadResult::MAX_FILE_NOT_FOUND);
}
}
@@ -1097,4 +1108,14 @@ void RequestGroup::tuneDownloadCommand(DownloadCommand* command)
_uriSelector->tuneDownloadCommand(_uris, command);
}
+void RequestGroup::addURIResult(std::string uri, DownloadResult::RESULT result)
+{
+ _uriResults.push_back(URIResult(uri, result));
+}
+
+const std::deque<URIResult>& RequestGroup::getURIResults() const
+{
+ return _uriResults;
+}
+
} // namespace aria2
diff --git a/src/RequestGroup.h b/src/RequestGroup.h
index e9d6558c..cd5dec9a 100644
--- a/src/RequestGroup.h
+++ b/src/RequestGroup.h
@@ -44,6 +44,8 @@
#include "TransferStat.h"
#include "TimeA2.h"
#include "Request.h"
+#include "DownloadResult.h"
+#include "URIResult.h"
namespace aria2 {
@@ -112,6 +114,10 @@ private:
bool _forceHaltRequested;
+ // URIResult is stored in the ascending order of the time when its result is
+ // available.
+ std::deque<URIResult> _uriResults;
+
bool _singleHostMultiConnectionEnabled;
std::deque<SharedHandle<PreDownloadHandler> > _preDownloadHandlers;
@@ -154,6 +160,12 @@ private:
bool tryAutoFileRenaming();
+ // Returns the result code of this RequestGroup.
+ // If the download finished, then returns DownloadResult::FINISHED.
+ // If the download didn't finish and error result is available in _uriResults,
+ // then last result code is returned.
+ // Otherwise returns DownloadResult::UNKNOWN_ERROR.
+ DownloadResult::RESULT downloadResult() const;
public:
RequestGroup(const Option* option, const std::deque<std::string>& uris);
@@ -311,6 +323,10 @@ public:
return _forceHaltRequested;
}
+ void addURIResult(std::string uri, DownloadResult::RESULT result);
+
+ const std::deque<URIResult>& getURIResults() const;
+
void dependsOn(const SharedHandle<Dependency>& dep);
bool isDependencyResolved();
diff --git a/src/RequestGroupMan.cc b/src/RequestGroupMan.cc
index e64a07aa..e2ec7379 100644
--- a/src/RequestGroupMan.cc
+++ b/src/RequestGroupMan.cc
@@ -377,16 +377,17 @@ void RequestGroupMan::closeFile()
RequestGroupMan::DownloadStat RequestGroupMan::getDownloadStat() const
{
- DownloadStat stat;
size_t finished = 0;
size_t error = 0;
size_t inprogress = 0;
+ DownloadResult::RESULT lastError = DownloadResult::FINISHED;
for(std::deque<SharedHandle<DownloadResult> >::const_iterator itr = _downloadResults.begin();
itr != _downloadResults.end(); ++itr) {
if((*itr)->result == DownloadResult::FINISHED) {
++finished;
} else {
++error;
+ lastError = (*itr)->result;
}
}
for(RequestGroups::const_iterator itr = _requestGroups.begin();
@@ -398,11 +399,8 @@ RequestGroupMan::DownloadStat RequestGroupMan::getDownloadStat() const
++inprogress;
}
}
- stat.setCompleted(finished);
- stat.setError(error);
- stat.setInProgress(inprogress);
- stat.setWaiting(_reservedGroups.size());
- return stat;
+ return DownloadStat(finished, error, inprogress, _reservedGroups.size(),
+ lastError);
}
void RequestGroupMan::showDownloadResults(std::ostream& o) const
diff --git a/src/RequestGroupMan.h b/src/RequestGroupMan.h
index f793c4ec..3f7f5872 100644
--- a/src/RequestGroupMan.h
+++ b/src/RequestGroupMan.h
@@ -36,12 +36,15 @@
#define _D_REQUEST_GROUP_MAN_H_
#include "common.h"
-#include "SharedHandle.h"
-#include "TransferStat.h"
+
#include <string>
#include <deque>
#include <iosfwd>
+#include "SharedHandle.h"
+#include "DownloadResult.h"
+#include "TransferStat.h"
+
namespace aria2 {
class DownloadEngine;
@@ -117,18 +120,34 @@ public:
size_t _error;
size_t _inProgress;
size_t _waiting;
+ DownloadResult::RESULT _lastErrorResult;
public:
- DownloadStat():_completed(0), _error(0), _inProgress(0), _waiting(0) {}
-
- void setCompleted(size_t c) { _completed = c; }
- void setError(size_t c) { _error = c; }
- void setInProgress(size_t c) { _inProgress = c; }
- void setWaiting(size_t c) { _waiting = c; }
+ DownloadStat(size_t completed,
+ size_t error,
+ size_t inProgress,
+ size_t waiting,
+ DownloadResult::RESULT lastErrorResult =
+ DownloadResult::FINISHED):
+ _completed(completed),
+ _error(error),
+ _inProgress(inProgress),
+ _waiting(waiting),
+ _lastErrorResult(lastErrorResult) {}
+
+ DownloadResult::RESULT getLastErrorResult() const
+ {
+ return _lastErrorResult;
+ }
bool allCompleted() const
{
return _error == 0 && _inProgress == 0 && _waiting == 0;
}
+
+ size_t getInProgress() const
+ {
+ return _inProgress;
+ }
};
DownloadStat getDownloadStat() const;
diff --git a/src/URIResult.cc b/src/URIResult.cc
new file mode 100644
index 00000000..94992dfd
--- /dev/null
+++ b/src/URIResult.cc
@@ -0,0 +1,52 @@
+/* <!-- copyright */
+/*
+ * aria2 - The high speed download utility
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * In addition, as a special exception, the copyright holders give
+ * permission to link the code of portions of this program with the
+ * OpenSSL library under certain conditions as described in each
+ * individual source file, and distribute linked combinations
+ * including the two.
+ * You must obey the GNU General Public License in all respects
+ * for all of the code used other than OpenSSL. If you modify
+ * file(s) with this exception, you may extend this exception to your
+ * version of the file(s), but you are not obligated to do so. If you
+ * do not wish to do so, delete this exception statement from your
+ * version. If you delete this exception statement from all source
+ * files in the program, then also delete it here.
+ */
+/* copyright --> */
+#include "URIResult.h"
+
+namespace aria2 {
+
+URIResult::URIResult(const std::string& uri, DownloadResult::RESULT result):
+ _uri(uri), _result(result) {}
+
+const std::string& URIResult::getURI() const
+{
+ return _uri;
+}
+
+DownloadResult::RESULT URIResult::getResult() const
+{
+ return _result;
+}
+
+} // namespace aria2
diff --git a/src/URIResult.h b/src/URIResult.h
new file mode 100644
index 00000000..7a91e303
--- /dev/null
+++ b/src/URIResult.h
@@ -0,0 +1,62 @@
+/* <!-- copyright */
+/*
+ * aria2 - The high speed download utility
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * In addition, as a special exception, the copyright holders give
+ * permission to link the code of portions of this program with the
+ * OpenSSL library under certain conditions as described in each
+ * individual source file, and distribute linked combinations
+ * including the two.
+ * You must obey the GNU General Public License in all respects
+ * for all of the code used other than OpenSSL. If you modify
+ * file(s) with this exception, you may extend this exception to your
+ * version of the file(s), but you are not obligated to do so. If you
+ * do not wish to do so, delete this exception statement from your
+ * version. If you delete this exception statement from all source
+ * files in the program, then also delete it here.
+ */
+/* copyright --> */
+#ifndef _D_URI_RESULT_H_
+#define _D_URI_RESULT_H_
+
+#include "common.h"
+
+#include <string>
+
+#include "DownloadResult.h"
+
+namespace aria2 {
+
+// This class stores URI and its result code as a consequence of the download.
+class URIResult {
+private:
+ std::string _uri;
+
+ DownloadResult::RESULT _result;
+public:
+ URIResult(const std::string& uri, DownloadResult::RESULT result);
+
+ const std::string& getURI() const;
+
+ DownloadResult::RESULT getResult() const;
+};
+
+} // namespace aria2
+
+#endif // _D_URI_RESULT_H_
diff --git a/src/main.cc b/src/main.cc
index 94ee950e..d846d9c4 100644
--- a/src/main.cc
+++ b/src/main.cc
@@ -157,7 +157,7 @@ static void showFiles(const std::deque<std::string>& uris, const Option* op)
extern Option* option_processing(int argc, char* const argv[]);
-int main(int argc, char* argv[])
+DownloadResult::RESULT main(int argc, char* argv[])
{
Option* op = option_processing(argc, argv);
std::deque<std::string> args(argv+optind, argv+argc);
@@ -175,7 +175,7 @@ int main(int argc, char* argv[])
if(op->getAsBool(PREF_QUIET)) {
LogFactory::setConsoleOutput(false);
}
- int32_t exitStatus = EXIT_SUCCESS;
+ DownloadResult::RESULT exitStatus = DownloadResult::FINISHED;
try {
Logger* logger = LogFactory::getInstance();
logger->info("<<--- --- --- ---");
@@ -191,13 +191,12 @@ int main(int argc, char* argv[])
#ifdef SIGPIPE
Util::setGlobalSignalHandler(SIGPIPE, SIG_IGN, 0);
#endif
- int32_t returnValue = 0;
std::deque<SharedHandle<RequestGroup> > requestGroups;
#ifdef ENABLE_BITTORRENT
if(!op->blank(PREF_TORRENT_FILE)) {
if(op->get(PREF_SHOW_FILES) == V_TRUE) {
showTorrentFile(op->get(PREF_TORRENT_FILE));
- return EXIT_SUCCESS;
+ return exitStatus;
} else {
createRequestGroupForBitTorrent(requestGroups, op, args);
}
@@ -208,7 +207,7 @@ int main(int argc, char* argv[])
if(!op->blank(PREF_METALINK_FILE)) {
if(op->get(PREF_SHOW_FILES) == V_TRUE) {
showMetalinkFile(op->get(PREF_METALINK_FILE), op);
- return EXIT_SUCCESS;
+ return exitStatus;
} else {
createRequestGroupForMetalink(requestGroups, op);
}
@@ -228,15 +227,12 @@ int main(int argc, char* argv[])
if(requestGroups.empty()) {
std::cout << MSG_NO_FILES_TO_DOWNLOAD << std::endl;
} else {
- returnValue = MultiUrlRequestInfo(requestGroups, op, getStatCalc(op),
- getSummaryOut(op)).execute();
- }
- if(returnValue == 1) {
- exitStatus = EXIT_FAILURE;
+ exitStatus = MultiUrlRequestInfo(requestGroups, op, getStatCalc(op),
+ getSummaryOut(op)).execute();
}
} catch(Exception& ex) {
std::cerr << EX_EXCEPTION_CAUGHT << "\n" << ex.stackTrace() << std::endl;
- exitStatus = EXIT_FAILURE;
+ exitStatus = DownloadResult::UNKNOWN_ERROR;
}
delete op;
LogFactory::release();
@@ -248,7 +244,7 @@ int main(int argc, char* argv[])
int main(int argc, char* argv[]) {
aria2::Platform platform;
- int r = aria2::main(argc, argv);
+ aria2::DownloadResult::RESULT r = aria2::main(argc, argv);
return r;
}
diff --git a/src/option_processing.cc b/src/option_processing.cc
index 035cf1db..bc8d33d4 100644
--- a/src/option_processing.cc
+++ b/src/option_processing.cc
@@ -53,6 +53,7 @@
#include "File.h"
#include "StringFormat.h"
#include "OptionHandlerException.h"
+#include "DownloadResult.h"
extern char* optarg;
extern int optind, opterr, optopt;
@@ -107,7 +108,7 @@ Option* option_processing(int argc, char* const argv[])
oparser.parseDefaultValues(op);
} catch(Exception& e) {
std::cerr << e.stackTrace();
- exit(EXIT_FAILURE);
+ exit(DownloadResult::UNKNOWN_ERROR);
}
while(1) {
@@ -254,12 +255,12 @@ Option* option_processing(int argc, char* const argv[])
std::cout << "--http-proxy-user was deprecated. See --http-proxy,"
<< " --https-proxy, --ftp-proxy, --all-proxy options."
<< std::endl;
- exit(EXIT_FAILURE);
+ exit(DownloadResult::UNKNOWN_ERROR);
case 5:
std::cout << "--http-proxy-passwd was deprecated. See --http-proxy,"
<< " --https-proxy, --ftp-proxy, --all-proxy options."
<< std::endl;
- exit(EXIT_FAILURE);
+ exit(DownloadResult::UNKNOWN_ERROR);
case 6:
cmdstream << PREF_HTTP_AUTH_SCHEME << "=" << optarg << "\n";
break;
@@ -282,12 +283,12 @@ Option* option_processing(int argc, char* const argv[])
std::cout << "--ftp-via-http-proxy was deprecated."
<< " Use --http-proxy-method option instead."
<< std::endl;
- exit(EXIT_FAILURE);
+ exit(DownloadResult::UNKNOWN_ERROR);
case 14:
std::cout << "--http-proxy-method was deprecated."
<< " Use --proxy-method option instead."
<< std::endl;
- exit(EXIT_FAILURE);
+ exit(DownloadResult::UNKNOWN_ERROR);
case 15:
cmdstream << PREF_LISTEN_PORT << "=" << optarg << "\n";
break;
@@ -553,7 +554,7 @@ Option* option_processing(int argc, char* const argv[])
break;
case 'v':
showVersion();
- exit(EXIT_SUCCESS);
+ exit(DownloadResult::FINISHED);
case 'h':
{
std::string category;
@@ -563,11 +564,11 @@ Option* option_processing(int argc, char* const argv[])
category = optarg;
}
showUsage(category, oparser);
- exit(EXIT_SUCCESS);
+ exit(DownloadResult::FINISHED);
}
default:
showUsage(TAG_HELP, oparser);
- exit(EXIT_FAILURE);
+ exit(DownloadResult::UNKNOWN_ERROR);
}
}
@@ -588,18 +589,18 @@ Option* option_processing(int argc, char* const argv[])
<< "Usage:" << "\n"
<< oparser.findByName(e.getOptionName())->getDescription()
<< std::endl;
- exit(EXIT_FAILURE);
+ exit(DownloadResult::UNKNOWN_ERROR);
} catch(Exception& e) {
std::cerr << "Parse error in " << cfname << "\n"
<< e.stackTrace() << std::endl;
- exit(EXIT_FAILURE);
+ exit(DownloadResult::UNKNOWN_ERROR);
}
} else if(!ucfname.empty()) {
std::cerr << StringFormat("Configuration file %s is not found.",
cfname.c_str())
<< "\n";
showUsage(TAG_HELP, oparser);
- exit(EXIT_FAILURE);
+ exit(DownloadResult::UNKNOWN_ERROR);
}
}
// Override configuration with environment variables.
@@ -616,11 +617,11 @@ Option* option_processing(int argc, char* const argv[])
<< "Usage:" << "\n"
<< oparser.findByName(e.getOptionName())->getDescription()
<< std::endl;
- exit(EXIT_FAILURE);
+ exit(DownloadResult::UNKNOWN_ERROR);
} catch(Exception& e) {
std::cerr << e.stackTrace() << std::endl;
showUsage(TAG_HELP, oparser);
- exit(EXIT_FAILURE);
+ exit(DownloadResult::UNKNOWN_ERROR);
}
}
if(
@@ -634,14 +635,14 @@ Option* option_processing(int argc, char* const argv[])
if(optind == argc) {
std::cerr << MSG_URI_REQUIRED << std::endl;
showUsage(TAG_HELP, oparser);
- exit(EXIT_FAILURE);
+ exit(DownloadResult::UNKNOWN_ERROR);
}
}
#ifdef HAVE_DAEMON
if(op->getAsBool(PREF_DAEMON)) {
if(daemon(1, 1) < 0) {
perror(MSG_DAEMON_FAILED);
- exit(EXIT_FAILURE);
+ exit(DownloadResult::UNKNOWN_ERROR);
}
}
#endif // HAVE_DAEMON