summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTatsuhiro Tsujikawa <tatsuhiro.t@gmail.com>2007-08-28 15:46:49 +0000
committerTatsuhiro Tsujikawa <tatsuhiro.t@gmail.com>2007-08-28 15:46:49 +0000
commitf8aab322fc33194e8886eb630a01acda6c19e76b (patch)
treed17067aa7d3b30cb47ebd51091086a33d2eff914
parent7fb4336d5e6dbffe64fc39f84bbedd76a12237e6 (diff)
2007-08-28 Tatsuhiro Tsujikawa <tujikawa at rednoah dot com>
Added auto file renaming feature in http(s)/ftp download. * src/main.cc: Added --auto-file-renaming command-line option. * src/OptionHandlerFactory.cc * src/prefs.h: Added PREF_AUTO_FILE_RENAMING * src/RequestGroup.{h, cc} (shouldCancelDownloadForSafety): Rewritten (tryAutoFileRenaming): New function. * src/SegmentMan.{h, cc} (shouldCancelDownloadForSafety): Removed. * src/HttpResponseCommand.cc (executeInternal): Removed the call to RequestGroupMan:: isSameFileBeingDownloaded() * src/FtpNegotiateCommand.cc (recvSize): Removed the call to RequestGroupMan:: isSameFileBeingDownloaded() * test/RequestGroupTest.cc: New class.
-rw-r--r--ChangeLog16
-rw-r--r--src/FtpNegotiationCommand.cc5
-rw-r--r--src/HttpResponseCommand.cc4
-rw-r--r--src/OptionHandlerFactory.cc1
-rw-r--r--src/RequestGroup.cc41
-rw-r--r--src/RequestGroup.h2
-rw-r--r--src/SegmentMan.cc5
-rw-r--r--src/SegmentMan.h2
-rw-r--r--src/main.cc31
-rw-r--r--src/prefs.h2
-rw-r--r--test/Makefile.am1
-rw-r--r--test/Makefile.in27
12 files changed, 97 insertions, 40 deletions
diff --git a/ChangeLog b/ChangeLog
index 2c1cb9f2..cd5c7af2 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -30,6 +30,22 @@
Added '\n' after the error message
* src/RequestInfo.h (printDownloadAbortMessage)
+
+ Added auto file renaming feature in http(s)/ftp download.
+ * src/main.cc: Added --auto-file-renaming command-line option.
+ * src/OptionHandlerFactory.cc
+ * src/prefs.h: Added PREF_AUTO_FILE_RENAMING
+ * src/RequestGroup.{h, cc}
+ (shouldCancelDownloadForSafety): Rewritten
+ (tryAutoFileRenaming): New function.
+ * src/SegmentMan.{h, cc} (shouldCancelDownloadForSafety): Removed.
+ * src/HttpResponseCommand.cc
+ (executeInternal): Removed the call to RequestGroupMan::
+ isSameFileBeingDownloaded()
+ * src/FtpNegotiateCommand.cc
+ (recvSize): Removed the call to RequestGroupMan::
+ isSameFileBeingDownloaded()
+ * test/RequestGroupTest.cc: New class.
2007-08-26 Tatsuhiro Tsujikawa <tujikawa at rednoah dot com>
diff --git a/src/FtpNegotiationCommand.cc b/src/FtpNegotiationCommand.cc
index bd497228..4b5c3008 100644
--- a/src/FtpNegotiationCommand.cc
+++ b/src/FtpNegotiationCommand.cc
@@ -196,11 +196,6 @@ bool FtpNegotiationCommand::recvSize() {
// TODO validate filename and totalsize against hintFilename and hintTotalSize if these are provided.
_requestGroup->validateTotalLengthByHint(size);
-
- if(e->_requestGroupMan->isSameFileBeingDownloaded(_requestGroup)) {
- throw new FatalException(EX_DUPLICATE_FILE_DOWNLOAD, _requestGroup->getFilePath().c_str());
- }
-
if(req->getMethod() == Request::METHOD_HEAD) {
_requestGroup->getSegmentMan()->isSplittable = false; // TODO because we don't want segment file to be saved.
sequence = SEQ_HEAD_OK;
diff --git a/src/HttpResponseCommand.cc b/src/HttpResponseCommand.cc
index 3f5f5bcc..8a29619a 100644
--- a/src/HttpResponseCommand.cc
+++ b/src/HttpResponseCommand.cc
@@ -100,10 +100,6 @@ bool HttpResponseCommand::executeInternal()
_requestGroup->validateTotalLengthByHint(httpResponse->getEntityLength());
_requestGroup->getSegmentMan()->filename = httpResponse->determinFilename();
- if(e->_requestGroupMan->isSameFileBeingDownloaded(_requestGroup)) {
- throw new FatalException(EX_DUPLICATE_FILE_DOWNLOAD, _requestGroup->getFilePath().c_str());
- }
-
if(httpResponse->isTransferEncodingSpecified()) {
return handleOtherEncoding(httpResponse);
} else {
diff --git a/src/OptionHandlerFactory.cc b/src/OptionHandlerFactory.cc
index c3d466d5..527df1dd 100644
--- a/src/OptionHandlerFactory.cc
+++ b/src/OptionHandlerFactory.cc
@@ -95,6 +95,7 @@ OptionHandlers OptionHandlerFactory::createOptionHandlers()
handlers.push_back(new DefaultOptionHandler(PREF_LOAD_COOKIES));
handlers.push_back(new DefaultOptionHandler(PREF_PEER_ID_PREFIX));
handlers.push_back(new BooleanOptionHandler(PREF_FORCE_SEQUENTIAL));
+ handlers.push_back(new BooleanOptionHandler(PREF_AUTO_FILE_RENAMING));
return handlers;
}
diff --git a/src/RequestGroup.cc b/src/RequestGroup.cc
index ca4e850c..01e95a40 100644
--- a/src/RequestGroup.cc
+++ b/src/RequestGroup.cc
@@ -115,12 +115,22 @@ void RequestGroup::markPieceDone(int64_t length)
void RequestGroup::shouldCancelDownloadForSafety()
{
- if(_segmentMan->shouldCancelDownloadForSafety()) {
- logger->notice(MSG_FILE_ALREADY_EXISTS,
- _segmentMan->getFilePath().c_str(),
- _segmentMan->getSegmentFilePath().c_str());
-
- throw new FatalException(EX_DOWNLOAD_ABORTED);
+ if(fileExists() && !segmentFileExists()) {
+ if(_option->get(PREF_AUTO_FILE_RENAMING) == V_TRUE) {
+ if(tryAutoFileRenaming()) {
+ logger->notice("File already exists. Renamed to %s.",
+ getFilePath().c_str());
+ } else {
+ logger->notice("File renaming failed: %s",
+ _segmentMan->getFilePath().c_str());
+ throw new FatalException(EX_DOWNLOAD_ABORTED);
+ }
+ } else if(_option->get(PREF_ALLOW_OVERWRITE) != V_TRUE) {
+ logger->notice(MSG_FILE_ALREADY_EXISTS,
+ _segmentMan->getFilePath().c_str(),
+ _segmentMan->getSegmentFilePath().c_str());
+ throw new FatalException(EX_DOWNLOAD_ABORTED);
+ }
}
}
@@ -303,3 +313,22 @@ int64_t RequestGroup::getExistingFileLength() const
{
return File(getFilePath()).size();
}
+
+bool RequestGroup::tryAutoFileRenaming()
+{
+ string filepath = getFilePath();
+ if(filepath.empty()) {
+ return false;
+ }
+ for(int32_t i = 1; i < 10000; ++i) {
+ File newfile(filepath+"."+Util::itos(i));
+ if(!newfile.exists()) {
+ _ufilename = newfile.getBasename();
+ if(!_segmentMan.isNull()) {
+ _segmentMan->ufilename = _ufilename;
+ }
+ return true;
+ }
+ }
+ return false;
+}
diff --git a/src/RequestGroup.h b/src/RequestGroup.h
index ff7f31cc..83317786 100644
--- a/src/RequestGroup.h
+++ b/src/RequestGroup.h
@@ -312,6 +312,8 @@ public:
{
return _segmentMan->calculateDownloadSpeed();
}
+
+ bool tryAutoFileRenaming();
};
typedef SharedHandle<RequestGroup> RequestGroupHandle;
diff --git a/src/SegmentMan.cc b/src/SegmentMan.cc
index 7ad4f984..9b88585a 100644
--- a/src/SegmentMan.cc
+++ b/src/SegmentMan.cc
@@ -431,11 +431,6 @@ bool SegmentMan::fileExists() const {
return File(getFilePath()).exists();
}
-bool SegmentMan::shouldCancelDownloadForSafety() const {
- return fileExists() && !segmentFileExists() &&
- option->get(PREF_ALLOW_OVERWRITE) != V_TRUE;
-}
-
void SegmentMan::markAllPiecesDone()
{
if(bitfield) {
diff --git a/src/SegmentMan.h b/src/SegmentMan.h
index 7e877e6a..fc67214a 100644
--- a/src/SegmentMan.h
+++ b/src/SegmentMan.h
@@ -282,8 +282,6 @@ public:
bool fileExists() const;
- bool shouldCancelDownloadForSafety() const;
-
void markAllPiecesDone();
void markPieceDone(int64_t length);
diff --git a/src/main.cc b/src/main.cc
index 4b79ce2c..2838a2f6 100644
--- a/src/main.cc
+++ b/src/main.cc
@@ -196,10 +196,15 @@ void showUsage() {
" already exists but the corresponding .aria2 file\n"
" doesn't exist.\n"
" Default: false") << endl;
- cout << _(" -Z, --force-sequential Fetch URIs in the command-line sequentially and\n"
+ cout << _(" -Z, --force-sequential[=true|false] Fetch URIs in the command-line sequentially and\n"
" download each URI in a separate session, like\n"
- " the usual command-line download utilities.") << endl;
-
+ " the usual command-line download utilities.\n"
+ " Default: false") << endl;
+ cout << _(" --auto-file-renaming[=true|false] Rename file name if the same file already\n"
+ " exists. This option works only in http(s)/ftp\n"
+ " download.\n"
+ " The new file name has a dot and a number(1..9999)\n"
+ " appended. Default: true") << endl;
#ifdef ENABLE_MESSAGE_DIGEST
cout << _(" --check-integrity=true|false Check file integrity by validating piece hash.\n"
" This option only affects in BitTorrent downloads\n"
@@ -358,6 +363,17 @@ Strings unfoldURI(const Strings& args)
return nargs;
}
+string toBoolArg(const char* optarg)
+{
+ string arg;
+ if(!optarg || string(optarg) == "") {
+ arg = V_TRUE;
+ } else {
+ arg = optarg;
+ }
+ return arg;
+}
+
int main(int argc, char* argv[]) {
#ifdef HAVE_WINSOCK2_H
Platform platform;
@@ -425,6 +441,7 @@ int main(int argc, char* argv[]) {
op->put(PREF_MAX_CONCURRENT_DOWNLOADS, "5");
op->put(PREF_DIRECT_DOWNLOAD_TIMEOUT, "15");
op->put(PREF_FORCE_SEQUENTIAL, V_FALSE);
+ op->put(PREF_AUTO_FILE_RENAMING, V_TRUE);
while(1) {
int optIndex = 0;
int lopt;
@@ -457,7 +474,6 @@ int main(int argc, char* argv[]) {
{ "max-download-limit", required_argument, &lopt, 201 },
{ "file-allocation", required_argument, 0, 'a' },
{ "allow-overwrite", required_argument, &lopt, 202 },
- { "force-sequential", no_argument, 0, 'Z' },
#ifdef ENABLE_MESSAGE_DIGEST
{ "check-integrity", required_argument, &lopt, 203 },
{ "realtime-chunk-checksum", required_argument, &lopt, 204 },
@@ -468,6 +484,8 @@ int main(int argc, char* argv[]) {
{ "input-file", required_argument, 0, 'i' },
{ "max-concurrent-downloads", required_argument, 0, 'j' },
{ "load-cookies", required_argument, &lopt, 205 },
+ { "force-sequential", optional_argument, 0, 'Z' },
+ { "auto-file-renaming", optional_argument, &lopt, 206 },
#if defined ENABLE_BITTORRENT || ENABLE_METALINK
{ "show-files", no_argument, NULL, 'S' },
{ "select-file", required_argument, &lopt, 21 },
@@ -606,6 +624,9 @@ int main(int argc, char* argv[]) {
case 205:
cmdstream << PREF_LOAD_COOKIES << "=" << optarg << "\n";
break;
+ case 206:
+ cmdstream << PREF_AUTO_FILE_RENAMING << "=" << toBoolArg(optarg) << "\n";
+ break;
}
break;
}
@@ -666,7 +687,7 @@ int main(int argc, char* argv[]) {
cmdstream << PREF_MAX_CONCURRENT_DOWNLOADS << "=" << optarg << "\n";
break;
case 'Z':
- cmdstream << PREF_FORCE_SEQUENTIAL << "=" << V_TRUE << "\n";
+ cmdstream << PREF_FORCE_SEQUENTIAL << "=" << toBoolArg(optarg) << "\n";
break;
case 'v':
showVersion();
diff --git a/src/prefs.h b/src/prefs.h
index 4ad48643..68d4a983 100644
--- a/src/prefs.h
+++ b/src/prefs.h
@@ -109,6 +109,8 @@
#define PREF_DIRECT_DOWNLOAD_TIMEOUT "direct-download-timeout"
// value:
#define PREF_FORCE_SEQUENTIAL "force-sequential"
+// value:
+#define PREF_AUTO_FILE_RENAMING "auto-file-renaming"
/**
* FTP related preferences
diff --git a/test/Makefile.am b/test/Makefile.am
index 4d88f52c..16308915 100644
--- a/test/Makefile.am
+++ b/test/Makefile.am
@@ -1,6 +1,7 @@
TESTS = aria2c
check_PROGRAMS = $(TESTS)
aria2c_SOURCES = AllTest.cc\
+ RequestGroupTest.cc\
PStringBuildVisitorTest.cc\
ParameterizedStringParserTest.cc\
UtilTest.cc\
diff --git a/test/Makefile.in b/test/Makefile.in
index 84b59c80..4346d2f2 100644
--- a/test/Makefile.in
+++ b/test/Makefile.in
@@ -110,12 +110,12 @@ mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
CONFIG_HEADER = $(top_builddir)/config.h
CONFIG_CLEAN_FILES =
am__EXEEXT_1 = aria2c$(EXEEXT)
-am__aria2c_SOURCES_DIST = AllTest.cc PStringBuildVisitorTest.cc \
- ParameterizedStringParserTest.cc UtilTest.cc \
- AlphaNumberDecoratorTest.cc FileUriListParserTest.cc \
- StreamUriListParserTest.cc HttpHeaderProcessorTest.cc \
- CookieBoxTest.cc RequestTest.cc CookieParserTest.cc \
- HttpRequestTest.cc CookieBoxFactoryTest.cc \
+am__aria2c_SOURCES_DIST = AllTest.cc RequestGroupTest.cc \
+ PStringBuildVisitorTest.cc ParameterizedStringParserTest.cc \
+ UtilTest.cc AlphaNumberDecoratorTest.cc \
+ FileUriListParserTest.cc StreamUriListParserTest.cc \
+ HttpHeaderProcessorTest.cc CookieBoxTest.cc RequestTest.cc \
+ CookieParserTest.cc HttpRequestTest.cc CookieBoxFactoryTest.cc \
RequestGroupManTest.cc RequestFactoryTest.cc \
NetrcAuthResolverTest.cc DefaultAuthResolverTest.cc \
OptionHandlerTest.cc SegmentManTest.cc BitfieldManTest.cc \
@@ -195,7 +195,7 @@ am__aria2c_SOURCES_DIST = AllTest.cc PStringBuildVisitorTest.cc \
@ENABLE_METALINK_TRUE@am__objects_3 = MetalinkerTest.$(OBJEXT) \
@ENABLE_METALINK_TRUE@ MetalinkEntryTest.$(OBJEXT) \
@ENABLE_METALINK_TRUE@ Xml2MetalinkProcessorTest.$(OBJEXT)
-am_aria2c_OBJECTS = AllTest.$(OBJEXT) \
+am_aria2c_OBJECTS = AllTest.$(OBJEXT) RequestGroupTest.$(OBJEXT) \
PStringBuildVisitorTest.$(OBJEXT) \
ParameterizedStringParserTest.$(OBJEXT) UtilTest.$(OBJEXT) \
AlphaNumberDecoratorTest.$(OBJEXT) \
@@ -403,12 +403,12 @@ target_cpu = @target_cpu@
target_os = @target_os@
target_vendor = @target_vendor@
TESTS = aria2c
-aria2c_SOURCES = AllTest.cc PStringBuildVisitorTest.cc \
- ParameterizedStringParserTest.cc UtilTest.cc \
- AlphaNumberDecoratorTest.cc FileUriListParserTest.cc \
- StreamUriListParserTest.cc HttpHeaderProcessorTest.cc \
- CookieBoxTest.cc RequestTest.cc CookieParserTest.cc \
- HttpRequestTest.cc CookieBoxFactoryTest.cc \
+aria2c_SOURCES = AllTest.cc RequestGroupTest.cc \
+ PStringBuildVisitorTest.cc ParameterizedStringParserTest.cc \
+ UtilTest.cc AlphaNumberDecoratorTest.cc \
+ FileUriListParserTest.cc StreamUriListParserTest.cc \
+ HttpHeaderProcessorTest.cc CookieBoxTest.cc RequestTest.cc \
+ CookieParserTest.cc HttpRequestTest.cc CookieBoxFactoryTest.cc \
RequestGroupManTest.cc RequestFactoryTest.cc \
NetrcAuthResolverTest.cc DefaultAuthResolverTest.cc \
OptionHandlerTest.cc SegmentManTest.cc BitfieldManTest.cc \
@@ -548,6 +548,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/PeerTest.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/RequestFactoryTest.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/RequestGroupManTest.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/RequestGroupTest.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/RequestTest.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/SegmentManTest.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ShaVisitorTest.Po@am__quote@