summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/AbstractDiskWriter.cc8
-rw-r--r--src/AbstractDiskWriter.h2
-rw-r--r--src/BitfieldMan.cc22
-rw-r--r--src/BitfieldMan.h2
-rw-r--r--src/BtContext.h10
-rw-r--r--src/ByteArrayDiskWriter.h7
-rw-r--r--src/Checksum.h2
-rw-r--r--src/ChunkChecksumValidator.cc2
-rw-r--r--src/ChunkChecksumValidator.h4
-rw-r--r--src/DefaultBtAnnounce.cc4
-rw-r--r--src/DefaultBtContext.cc20
-rw-r--r--src/DefaultBtContext.h20
-rw-r--r--src/DefaultBtInteractive.cc4
-rw-r--r--src/DefaultBtMessageDispatcher.h9
-rw-r--r--src/DefaultPieceStorage.cc11
-rw-r--r--src/DefaultPieceStorage.h2
-rw-r--r--src/DiskAdaptor.h4
-rw-r--r--src/DiskWriter.h3
-rw-r--r--src/DownloadCommand.cc2
-rw-r--r--src/FtpNegotiationCommand.cc2
-rw-r--r--src/HttpResponseCommand.cc2
-rw-r--r--src/Makefile.am7
-rw-r--r--src/Makefile.in10
-rw-r--r--src/MetalinkChunkChecksum.h4
-rw-r--r--src/MetalinkEntry.cc8
-rw-r--r--src/MetalinkEntry.h5
-rw-r--r--src/MetalinkRequestInfo.cc8
-rw-r--r--src/PeerConnection.cc12
-rw-r--r--src/PieceStorage.h13
-rw-r--r--src/SegmentMan.cc22
-rw-r--r--src/SegmentMan.h5
-rw-r--r--src/ShareRatioSeedCriteria.h5
-rw-r--r--src/TorrentDownloadEngine.cc2
-rw-r--r--src/TorrentRequestInfo.cc6
-rw-r--r--src/UrlRequestInfo.cc26
-rw-r--r--src/UrlRequestInfo.h23
-rw-r--r--src/Xml2MetalinkProcessor.cc40
-rw-r--r--src/Xml2MetalinkProcessor.h4
-rw-r--r--src/common.h5
-rw-r--r--src/main.cc98
-rw-r--r--src/message.h2
-rw-r--r--src/prefs.h2
42 files changed, 302 insertions, 147 deletions
diff --git a/src/AbstractDiskWriter.cc b/src/AbstractDiskWriter.cc
index 0741aa7e..476ce676 100644
--- a/src/AbstractDiskWriter.cc
+++ b/src/AbstractDiskWriter.cc
@@ -103,17 +103,16 @@ int32_t AbstractDiskWriter::readDataInternal(char* data, int32_t len) {
return read(fd, data, len);
}
+#ifdef ENABLE_MESSAGE_DIGEST
string AbstractDiskWriter::messageDigest(int64_t offset, int64_t length,
const MessageDigestContext::DigestAlgo& algo)
{
-#ifdef ENABLE_MESSAGE_DIGEST
MessageDigestContext ctx(algo);
ctx.digestInit();
int32_t BUFSIZE = 16*1024;
char buf[BUFSIZE];
for(int64_t i = 0; i < length/BUFSIZE; i++) {
- int32_t rs = readData(buf, BUFSIZE, offset);
if(BUFSIZE != readData(buf, BUFSIZE, offset)) {
throw new DlAbortEx(EX_FILE_SHA1SUM, filename.c_str(), strerror(errno));
}
@@ -122,7 +121,6 @@ string AbstractDiskWriter::messageDigest(int64_t offset, int64_t length,
}
int32_t r = length%BUFSIZE;
if(r > 0) {
- int32_t rs = readData(buf, r, offset);
if(r != readData(buf, r, offset)) {
throw new DlAbortEx(EX_FILE_SHA1SUM, filename.c_str(), strerror(errno));
}
@@ -132,10 +130,8 @@ string AbstractDiskWriter::messageDigest(int64_t offset, int64_t length,
ctx.digestFinal(hashValue);
return Util::toHex(hashValue, 20);
-#else
- return "";
-#endif // ENABLE_MESSAGE_DIGEST
}
+#endif // ENABLE_MESSAGE_DIGEST
void AbstractDiskWriter::seek(int64_t offset) {
if(offset != lseek(fd, offset, SEEK_SET)) {
diff --git a/src/AbstractDiskWriter.h b/src/AbstractDiskWriter.h
index b7ab1bcd..b6807e46 100644
--- a/src/AbstractDiskWriter.h
+++ b/src/AbstractDiskWriter.h
@@ -64,8 +64,10 @@ public:
virtual void openExistingFile(const string& filename);
+#ifdef ENABLE_MESSAGE_DIGEST
virtual string messageDigest(int64_t offset, int64_t length,
const MessageDigestContext::DigestAlgo& algo);
+#endif // ENABLE_MESSAGE_DIGEST
virtual void writeData(const char* data, int32_t len, int64_t offset);
diff --git a/src/BitfieldMan.cc b/src/BitfieldMan.cc
index c91d3010..af8488a4 100644
--- a/src/BitfieldMan.cc
+++ b/src/BitfieldMan.cc
@@ -444,7 +444,7 @@ bool BitfieldMan::unsetBit(int32_t index) {
return b;
}
-bool BitfieldMan::isAllBitSet() const {
+bool BitfieldMan::isFilteredAllBitSet() const {
if(filterEnabled) {
for(int32_t i = 0; i < bitfieldLength; ++i) {
if((bitfield[i]&filterBitfield[i]) != filterBitfield[i]) {
@@ -453,17 +453,21 @@ bool BitfieldMan::isAllBitSet() const {
}
return true;
} else {
- for(int32_t i = 0; i < bitfieldLength-1; ++i) {
- if(bitfield[i] != 0xff) {
- return false;
- }
- }
- unsigned char b = ~((128 >> (blocks-1)%8)-1);
- if(bitfield[bitfieldLength-1] != b) {
+ return isAllBitSet();
+ }
+}
+
+bool BitfieldMan::isAllBitSet() const {
+ for(int32_t i = 0; i < bitfieldLength-1; ++i) {
+ if(bitfield[i] != 0xff) {
return false;
}
- return true;
}
+ unsigned char b = ~((128 >> (blocks-1)%8)-1);
+ if(bitfield[bitfieldLength-1] != b) {
+ return false;
+ }
+ return true;
}
bool BitfieldMan::isBitSetInternal(const unsigned char* bitfield, int32_t index) const {
diff --git a/src/BitfieldMan.h b/src/BitfieldMan.h
index d304a6e3..3ced8678 100644
--- a/src/BitfieldMan.h
+++ b/src/BitfieldMan.h
@@ -184,6 +184,8 @@ public:
/**
* affected by filter
*/
+ bool isFilteredAllBitSet() const;
+
bool isAllBitSet() const;
const unsigned char* getBitfield() const { return bitfield; }
diff --git a/src/BtContext.h b/src/BtContext.h
index c94088cc..5b4e832e 100644
--- a/src/BtContext.h
+++ b/src/BtContext.h
@@ -56,15 +56,15 @@ public:
virtual const unsigned char* getInfoHash() const = 0;
- virtual int getInfoHashLength() const = 0;
+ virtual int32_t getInfoHashLength() const = 0;
virtual string getInfoHashAsString() const = 0;
- virtual string getPieceHash(int index) const = 0;
+ virtual string getPieceHash(int32_t index) const = 0;
virtual const Strings& getPieceHashes() const = 0;
- virtual long long int getTotalLength() const = 0;
+ virtual int64_t getTotalLength() const = 0;
virtual FILE_MODE getFileMode() const = 0;
@@ -76,9 +76,9 @@ public:
virtual string getName() const = 0;
- virtual int getPieceLength() const = 0;
+ virtual int32_t getPieceLength() const = 0;
- virtual int getNumPieces() const = 0;
+ virtual int32_t getNumPieces() const = 0;
/**
* Returns the peer id of localhost, 20 byte length
diff --git a/src/ByteArrayDiskWriter.h b/src/ByteArrayDiskWriter.h
index e6e94c31..e11917ff 100644
--- a/src/ByteArrayDiskWriter.h
+++ b/src/ByteArrayDiskWriter.h
@@ -60,9 +60,14 @@ public:
// position is ignored
virtual void writeData(const char* data, int32_t len, int64_t position = 0);
virtual int readData(char* data, int32_t len, int64_t position);
+
// not implemented yet
+#ifdef ENABLE_MESSAGE_DIGEST
virtual string messageDigest(int64_t offset, int64_t length,
- const MessageDigestContext::DigestAlgo& algo) { return ""; }
+ const MessageDigestContext::DigestAlgo& algo) {
+ return "";
+ }
+#endif // ENABLE_MESSAGE_DIGEST
const char* getByteArray() const {
return buf;
diff --git a/src/Checksum.h b/src/Checksum.h
index 1bc16134..d4134510 100644
--- a/src/Checksum.h
+++ b/src/Checksum.h
@@ -36,9 +36,9 @@
#define _D_CHECKSUM_H_
#include "common.h"
+#ifdef ENABLE_MESSAGE_DIGEST
#include "messageDigest.h"
-#ifdef ENABLE_MESSAGE_DIGEST
class Checksum {
private:
string md;
diff --git a/src/ChunkChecksumValidator.cc b/src/ChunkChecksumValidator.cc
index b6d0e99b..4f15cdbc 100644
--- a/src/ChunkChecksumValidator.cc
+++ b/src/ChunkChecksumValidator.cc
@@ -38,6 +38,7 @@
#include "TimeA2.h"
#include "message.h"
+#ifdef ENABLE_MESSAGE_DIGEST
void ChunkChecksumValidator::validateSameLengthChecksum(BitfieldMan* bitfieldMan,
int32_t index,
const string& expectedChecksum,
@@ -118,3 +119,4 @@ void ChunkChecksumValidator::validate(BitfieldMan* bitfieldMan,
fileAllocationMonitor->setCurrentValue(bitfieldMan->getTotalLength());
fileAllocationMonitor->showProgress();
}
+#endif // ENABLE_MESSAGE_DIGEST
diff --git a/src/ChunkChecksumValidator.h b/src/ChunkChecksumValidator.h
index 084bbed3..89f7b22c 100644
--- a/src/ChunkChecksumValidator.h
+++ b/src/ChunkChecksumValidator.h
@@ -38,12 +38,15 @@
#include "common.h"
#include "DiskWriter.h"
#include "BitfieldMan.h"
+#ifdef ENABLE_MESSAGE_DIGEST
#include "messageDigest.h"
+#endif // ENABLE_MESSAGE_DIGEST
#include "LogFactory.h"
#include "FileAllocationMonitor.h"
#include "NullFileAllocationMonitor.h"
class ChunkChecksumValidator {
+#ifdef ENABLE_MESSAGE_DIGEST
private:
DiskWriterHandle diskWriter;
@@ -89,6 +92,7 @@ public:
void setFileAllocationMonitor(const FileAllocationMonitorHandle& monitor) {
this->fileAllocationMonitor = monitor;
}
+#endif // ENABLE_MESSAGE_DIGEST
};
#endif // _D_CHUNK_CHECKSUM_VALIDATOR_H_
diff --git a/src/DefaultBtAnnounce.cc b/src/DefaultBtAnnounce.cc
index ab9cad07..d7b4af86 100644
--- a/src/DefaultBtAnnounce.cc
+++ b/src/DefaultBtAnnounce.cc
@@ -84,7 +84,7 @@ bool DefaultBtAnnounce::isStoppedAnnounceReady() {
bool DefaultBtAnnounce::isCompletedAnnounceReady() {
return (trackers == 0 &&
- pieceStorage->downloadFinished() &&
+ pieceStorage->allDownloadFinished() &&
announceList.countCompletedAllowedTier());
}
@@ -106,7 +106,7 @@ string DefaultBtAnnounce::getAnnounceUrl() {
// If download completed before "started" event is sent to a tracker,
// we change the event to something else to prevent us from
// sending "completed" event.
- if(pieceStorage->downloadFinished() &&
+ if(pieceStorage->allDownloadFinished() &&
announceList.getEvent() == AnnounceTier::STARTED) {
announceList.setEvent(AnnounceTier::STARTED_AFTER_COMPLETION);
}
diff --git a/src/DefaultBtContext.cc b/src/DefaultBtContext.cc
index 8615af91..f841f1ce 100644
--- a/src/DefaultBtContext.cc
+++ b/src/DefaultBtContext.cc
@@ -56,7 +56,7 @@ const unsigned char* DefaultBtContext::getInfoHash() const {
return infoHash;
}
-int DefaultBtContext::getInfoHashLength() const {
+int32_t DefaultBtContext::getInfoHashLength() const {
return INFO_HASH_LENGTH;
}
@@ -78,14 +78,14 @@ void DefaultBtContext::clear() {
}
void DefaultBtContext::extractPieceHash(const unsigned char* hashData,
- int hashDataLength,
- int hashLength) {
+ int32_t hashDataLength,
+ int32_t hashLength) {
assert(hashDataLength > 0);
assert(hashLength > 0);
- int numPieces = hashDataLength/hashLength;
+ int32_t numPieces = hashDataLength/hashLength;
assert(numPieces > 0);
- for(int i = 0; i < numPieces; i++) {
+ for(int32_t i = 0; i < numPieces; i++) {
pieceHashes.push_back(Util::toHex(&hashData[i*hashLength],
hashLength));
}
@@ -180,7 +180,7 @@ void DefaultBtContext::load(const string& torrentFile) {
// retrieve infoHash
ShaVisitor v;
infoDic->accept(&v);
- int len;
+ int32_t len;
v.getHash(infoHash, len);
infoHashString = Util::toHex(infoHash, INFO_HASH_LENGTH);
// calculate the number of pieces
@@ -208,14 +208,14 @@ void DefaultBtContext::load(const string& torrentFile) {
}
}
-string DefaultBtContext::getPieceHash(int index) const {
+string DefaultBtContext::getPieceHash(int32_t index) const {
if(index < 0 || numPieces <= index) {
return "";
}
return pieceHashes.at(index);
}
-long long int DefaultBtContext::getTotalLength() const {
+int64_t DefaultBtContext::getTotalLength() const {
return totalLength;
}
@@ -235,10 +235,10 @@ string DefaultBtContext::getName() const {
return name;
}
-int DefaultBtContext::getPieceLength() const {
+int32_t DefaultBtContext::getPieceLength() const {
return pieceLength;
}
-int DefaultBtContext::getNumPieces() const {
+int32_t DefaultBtContext::getNumPieces() const {
return numPieces;
}
diff --git a/src/DefaultBtContext.h b/src/DefaultBtContext.h
index acec81f9..49ce7d9d 100644
--- a/src/DefaultBtContext.h
+++ b/src/DefaultBtContext.h
@@ -51,17 +51,17 @@ private:
PieceHashes pieceHashes;
FileEntries fileEntries;
FILE_MODE fileMode;
- long long int totalLength;
- int pieceLength;
+ int64_t totalLength;
+ int32_t pieceLength;
string name;
- int numPieces;
+ int32_t numPieces;
string peerId;
AnnounceTiers announceTiers;
void clear();
void extractPieceHash(const unsigned char* hashData,
- int hashDataLength,
- int hashLength);
+ int32_t hashDataLength,
+ int32_t hashLength);
void extractFileEntries(Dictionary* infoDic,
const string& defaultName);
void extractAnnounce(Data* announceData);
@@ -72,18 +72,18 @@ private:
virtual const unsigned char* getInfoHash() const;
- virtual int getInfoHashLength() const;
+ virtual int32_t getInfoHashLength() const;
virtual string getInfoHashAsString() const;
- virtual string getPieceHash(int index) const;
+ virtual string getPieceHash(int32_t index) const;
virtual const Strings& getPieceHashes() const
{
return pieceHashes;
}
- virtual long long int getTotalLength() const;
+ virtual int64_t getTotalLength() const;
virtual FILE_MODE getFileMode() const;
@@ -95,9 +95,9 @@ private:
virtual string getName() const;
- virtual int getPieceLength() const;
+ virtual int32_t getPieceLength() const;
- virtual int getNumPieces() const;
+ virtual int32_t getNumPieces() const;
virtual const unsigned char* getPeerId() {
if(peerId == "") {
diff --git a/src/DefaultBtInteractive.cc b/src/DefaultBtInteractive.cc
index 58f072e6..f22c2e49 100644
--- a/src/DefaultBtInteractive.cc
+++ b/src/DefaultBtInteractive.cc
@@ -78,7 +78,7 @@ void DefaultBtInteractive::doPostHandshakeProcessing() {
void DefaultBtInteractive::addBitfieldMessageToQueue() {
if(peer->isFastExtensionEnabled()) {
- if(pieceStorage->downloadFinished()) {
+ if(pieceStorage->allDownloadFinished()) {
dispatcher->addMessageToQueue(messageFactory->createHaveAllMessage());
} else if(pieceStorage->getCompletedLength() > 0) {
dispatcher->addMessageToQueue(messageFactory->createBitfieldMessage());
@@ -122,7 +122,7 @@ void DefaultBtInteractive::checkHave() {
pieceStorage->getAdvertisedPieceIndexes(cuid, haveCheckPoint);
haveCheckPoint.reset();
if(indexes.size() >= 20) {
- if(peer->isFastExtensionEnabled() && pieceStorage->downloadFinished()) {
+ if(peer->isFastExtensionEnabled() && pieceStorage->allDownloadFinished()) {
dispatcher->addMessageToQueue(messageFactory->createHaveAllMessage());
} else {
dispatcher->addMessageToQueue(messageFactory->createBitfieldMessage());
diff --git a/src/DefaultBtMessageDispatcher.h b/src/DefaultBtMessageDispatcher.h
index d94a3050..5a7e2ca3 100644
--- a/src/DefaultBtMessageDispatcher.h
+++ b/src/DefaultBtMessageDispatcher.h
@@ -68,9 +68,14 @@ public:
peer(0),
maxUploadSpeedLimit(0),
requestTimeout(0),
- logger(LogFactory::getInstance()) {}
+ logger(LogFactory::getInstance())
+ {
+ logger->debug("DefaultBtMessageDispatcher::instantiated");
+ }
- virtual ~DefaultBtMessageDispatcher() {}
+ virtual ~DefaultBtMessageDispatcher() {
+ logger->debug("DefaultBtMessageDispatcher::deleted");
+ }
virtual void addMessageToQueue(const BtMessageHandle& btMessage);
diff --git a/src/DefaultPieceStorage.cc b/src/DefaultPieceStorage.cc
index bb73552d..20e4ffe0 100644
--- a/src/DefaultPieceStorage.cc
+++ b/src/DefaultPieceStorage.cc
@@ -231,7 +231,7 @@ void DefaultPieceStorage::completePiece(const PieceHandle& piece) {
if(!isEndGame()) {
reduceUsedPieces(100);
}
- if(downloadFinished()) {
+ if(allDownloadFinished()) {
return;
}
bitfieldMan->setBit(piece->getIndex());
@@ -240,7 +240,9 @@ void DefaultPieceStorage::completePiece(const PieceHandle& piece) {
diskAdaptor->onDownloadComplete();
if(isSelectiveDownloadingMode()) {
logger->notice(_("Download of selected files was complete."));
- finishSelectiveDownloadingMode();
+ // following line was commented out in order to stop sending request
+ // message after user-specified files were downloaded.
+ //finishSelectiveDownloadingMode();
} else {
logger->info(_("The download was complete."));
}
@@ -326,6 +328,11 @@ void DefaultPieceStorage::clearFileFilter() {
// not unittested
bool DefaultPieceStorage::downloadFinished() {
+ return bitfieldMan->isFilteredAllBitSet();
+}
+
+// not unittested
+bool DefaultPieceStorage::allDownloadFinished() {
return bitfieldMan->isAllBitSet();
}
diff --git a/src/DefaultPieceStorage.h b/src/DefaultPieceStorage.h
index ac3657f9..33834b34 100644
--- a/src/DefaultPieceStorage.h
+++ b/src/DefaultPieceStorage.h
@@ -120,6 +120,8 @@ public:
virtual bool downloadFinished();
+ virtual bool allDownloadFinished();
+
virtual void setBitfield(const unsigned char* bitfield,
int bitfieldLength);
diff --git a/src/DiskAdaptor.h b/src/DiskAdaptor.h
index 4983fef8..32f93022 100644
--- a/src/DiskAdaptor.h
+++ b/src/DiskAdaptor.h
@@ -38,7 +38,9 @@
#include "common.h"
#include "FileEntry.h"
#include "Logger.h"
+#ifdef ENABLE_MESSAGE_DIGEST
#include "messageDigest.h"
+#endif // ENABLE_MESSAGE_DIGEST
class DiskAdaptor {
protected:
@@ -61,8 +63,10 @@ public:
virtual int32_t readData(unsigned char* data, int32_t len, int64_t offset) = 0;
+#ifdef ENABLE_MESSAGE_DIGEST
virtual string messageDigest(int64_t offset, int64_t length,
const MessageDigestContext::DigestAlgo& algo) = 0;
+#endif // ENABLE_MESSAGE_DIGEST
virtual void onDownloadComplete() = 0;
diff --git a/src/DiskWriter.h b/src/DiskWriter.h
index 0eb27723..e8c946c3 100644
--- a/src/DiskWriter.h
+++ b/src/DiskWriter.h
@@ -91,9 +91,10 @@ public:
virtual int readData(unsigned char* data, int32_t len, int64_t position) {
return readData((char*)data, len, position);
}
-
+#ifdef ENABLE_MESSAGE_DIGEST
virtual string messageDigest(int64_t offset, int64_t length,
const MessageDigestContext::DigestAlgo& algo) = 0;
+#endif // ENABLE_MESSAGE_DIGEST
};
typedef SharedHandle<DiskWriter> DiskWriterHandle;
diff --git a/src/DownloadCommand.cc b/src/DownloadCommand.cc
index 3b5b9570..33c54143 100644
--- a/src/DownloadCommand.cc
+++ b/src/DownloadCommand.cc
@@ -108,9 +108,11 @@ bool DownloadCommand::executeInternal(Segment& segment) {
if(te != NULL) te->end();
logger->info(MSG_DOWNLOAD_COMPLETED, cuid);
e->segmentMan->completeSegment(cuid, segment);
+#ifdef ENABLE_MESSAGE_DIGEST
if(e->option->get(PREF_REALTIME_CHUNK_CHECKSUM) == V_TRUE) {
e->segmentMan->tryChunkChecksumValidation(segment);
}
+#endif // ENABLE_MESSAGE_DIGEST
// this unit is going to download another segment.
return prepareForNextSegment(segment);
} else {
diff --git a/src/FtpNegotiationCommand.cc b/src/FtpNegotiationCommand.cc
index f7dc8c50..ad014069 100644
--- a/src/FtpNegotiationCommand.cc
+++ b/src/FtpNegotiationCommand.cc
@@ -182,7 +182,7 @@ bool FtpNegotiationCommand::recvSize() {
if(status != 213) {
throw new DlRetryEx(EX_BAD_STATUS, status);
}
- if(size == LONG_LONG_MAX || size < 0) {
+ if(size == INT64_MAX || size < 0) {
throw new DlAbortEx(EX_TOO_LARGE_FILE, size);
}
if(!e->segmentMan->downloadStarted) {
diff --git a/src/HttpResponseCommand.cc b/src/HttpResponseCommand.cc
index d0f75404..e478e9a1 100644
--- a/src/HttpResponseCommand.cc
+++ b/src/HttpResponseCommand.cc
@@ -148,7 +148,7 @@ bool HttpResponseCommand::handleDefaultEncoding(const HttpHeader& headers) {
}
long long int size = headers.getFirstAsLLInt("Content-Length");
- if(size == LONG_LONG_MAX || size < 0) {
+ if(size == INT64_MAX || size < 0) {
throw new DlAbortEx(EX_TOO_LARGE_FILE, size);
}
e->segmentMan->isSplittable = !(size == 0);
diff --git a/src/Makefile.am b/src/Makefile.am
index df0cdd22..1a88e859 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -182,7 +182,8 @@ SRCS += Metalinker.cc Metalinker.h\
MetalinkResource.cc MetalinkResource.h\
MetalinkProcessor.h\
Xml2MetalinkProcessor.cc Xml2MetalinkProcessor.h\
- MetalinkRequestInfo.cc MetalinkRequestInfo.h
+ MetalinkRequestInfo.cc MetalinkRequestInfo.h\
+ MetalinkChunkChecksum.h
endif # ENABLE_METALINK
noinst_LIBRARIES = libaria2c.a
@@ -190,9 +191,9 @@ libaria2c_a_SOURCES = $(SRCS)
aria2c_LDADD = libaria2c.a @LIBINTL@ @ALLOCA@ @LIBGNUTLS_LIBS@\
@LIBGCRYPT_LIBS@ @OPENSSL_LIBS@ @XML_LIBS@ @LIBARES_LIBS@\
@LIBCARES_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@\
@LIBARES_CPPFLAGS@ @LIBCARES_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 3a7f446d..e0372f03 100644
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -148,7 +148,8 @@ bin_PROGRAMS = aria2c$(EXEEXT)
@ENABLE_METALINK_TRUE@ MetalinkResource.cc MetalinkResource.h\
@ENABLE_METALINK_TRUE@ MetalinkProcessor.h\
@ENABLE_METALINK_TRUE@ Xml2MetalinkProcessor.cc Xml2MetalinkProcessor.h\
-@ENABLE_METALINK_TRUE@ MetalinkRequestInfo.cc MetalinkRequestInfo.h
+@ENABLE_METALINK_TRUE@ MetalinkRequestInfo.cc MetalinkRequestInfo.h\
+@ENABLE_METALINK_TRUE@ MetalinkChunkChecksum.h
subdir = src
DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in alloca.c
@@ -281,7 +282,8 @@ am__libaria2c_a_SOURCES_DIST = Socket.h SocketCore.cc SocketCore.h \
Metalinker.cc Metalinker.h MetalinkEntry.cc MetalinkEntry.h \
MetalinkResource.cc MetalinkResource.h MetalinkProcessor.h \
Xml2MetalinkProcessor.cc Xml2MetalinkProcessor.h \
- MetalinkRequestInfo.cc MetalinkRequestInfo.h
+ MetalinkRequestInfo.cc MetalinkRequestInfo.h \
+ MetalinkChunkChecksum.h
@ENABLE_ASYNC_DNS_TRUE@am__objects_1 = NameResolver.$(OBJEXT)
@ENABLE_BITTORRENT_TRUE@am__objects_2 = Data.$(OBJEXT) \
@ENABLE_BITTORRENT_TRUE@ Dictionary.$(OBJEXT) List.$(OBJEXT) \
@@ -592,12 +594,12 @@ aria2c_LDADD = libaria2c.a @LIBINTL@ @ALLOCA@ @LIBGNUTLS_LIBS@\
@LIBGCRYPT_LIBS@ @OPENSSL_LIBS@ @XML_LIBS@ @LIBARES_LIBS@\
@LIBCARES_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@\
@LIBARES_CPPFLAGS@ @LIBCARES_CPPFLAGS@\
- -D_FILE_OFFSET_BITS=64 -DLOCALEDIR=\"$(localedir)\" @DEFS@ -pg
+ -D_FILE_OFFSET_BITS=64 -DLOCALEDIR=\"$(localedir)\" @DEFS@# -pg
all: all-am
diff --git a/src/MetalinkChunkChecksum.h b/src/MetalinkChunkChecksum.h
index 077d5cc0..547ec164 100644
--- a/src/MetalinkChunkChecksum.h
+++ b/src/MetalinkChunkChecksum.h
@@ -36,15 +36,19 @@
#define _D_METALINK_CHUNK_CHECKSUM_H_
#include "common.h"
+#ifdef ENABLE_MESSAGE_DIGEST
#include "messageDigest.h"
+#endif // ENABLE_MESSAGE_DIGEST
class MetalinkChunkChecksum {
+#ifdef ENABLE_MESSAGE_DIGEST
public:
MessageDigestContext::DigestAlgo digestAlgo;
int32_t pieceLength;
Strings pieceHashes;
public:
MetalinkChunkChecksum():pieceLength(0) {}
+#endif // ENABLE_MESSAGE_DIGEST
};
typedef SharedHandle<MetalinkChunkChecksum> MetalinkChunkChecksumHandle;
diff --git a/src/MetalinkEntry.cc b/src/MetalinkEntry.cc
index 7e48aeb7..55d44407 100644
--- a/src/MetalinkEntry.cc
+++ b/src/MetalinkEntry.cc
@@ -36,7 +36,13 @@
#include "Util.h"
#include <algorithm>
-MetalinkEntry::MetalinkEntry():chunkChecksum(0) {}
+MetalinkEntry::MetalinkEntry():
+ size(0)
+#ifdef ENABLE_MESSAGE_DIGEST
+ ,
+ chunkChecksum(0)
+#endif // ENABLE_MESSAGE_DIGEST
+{}
MetalinkEntry::~MetalinkEntry() {}
diff --git a/src/MetalinkEntry.h b/src/MetalinkEntry.h
index 5b02ad40..71c9df31 100644
--- a/src/MetalinkEntry.h
+++ b/src/MetalinkEntry.h
@@ -51,7 +51,9 @@ public:
Checksum checksum;
public:
MetalinkResources resources;
+#ifdef ENABLE_MESSAGE_DIGEST
MetalinkChunkChecksumHandle chunkChecksum;
+#endif // ENABLE_MESSAGE_DIGEST
public:
MetalinkEntry();
~MetalinkEntry();
@@ -64,6 +66,9 @@ public:
this->os = metalinkEntry.os;
this->size = metalinkEntry.size;
this->checksum = metalinkEntry.checksum;
+#ifdef ENABLE_MESSAGE_DIGEST
+ this->chunkChecksum = metalinkEntry.chunkChecksum;
+#endif // ENABLE_MESSAGE_DIGEST
}
return *this;
}
diff --git a/src/MetalinkRequestInfo.cc b/src/MetalinkRequestInfo.cc
index f1e5578d..4cff522a 100644
--- a/src/MetalinkRequestInfo.cc
+++ b/src/MetalinkRequestInfo.cc
@@ -97,8 +97,8 @@ RequestInfos MetalinkRequestInfo::execute() {
if(entry->resources.size() == 0) {
continue;
}
- logger->notice("Metalink: Queueing %s for download.",
- entry->filename.c_str());
+ logger->info("Metalink: Queueing %s for download.",
+ entry->filename.c_str());
MetalinkResources::iterator itr =
find_if(entry->resources.begin(),
entry->resources.end(),
@@ -122,10 +122,14 @@ RequestInfos MetalinkRequestInfo::execute() {
urls.push_back((*itr)->url);
}
UrlRequestInfoHandle reqInfo = new UrlRequestInfo(urls, maxConnection, op);
+ reqInfo->setFilename(entry->filename);
+ reqInfo->setTotalLength(entry->size);
+#ifdef ENABLE_MESSAGE_DIGEST
reqInfo->setChecksum(checksum);
reqInfo->setDigestAlgo(entry->chunkChecksum->digestAlgo);
reqInfo->setChunkChecksumLength(entry->chunkChecksum->pieceLength);
reqInfo->setChunkChecksums(entry->chunkChecksum->pieceHashes);
+#endif // ENABLE_MESSAGE_DIGEST
nextReqInfos.push_front(reqInfo);
}
} catch(RecoverableException* ex) {
diff --git a/src/PeerConnection.cc b/src/PeerConnection.cc
index 06348d0a..ca68cd04 100644
--- a/src/PeerConnection.cc
+++ b/src/PeerConnection.cc
@@ -47,14 +47,18 @@ PeerConnection::PeerConnection(int32_t cuid,
:cuid(cuid),
socket(socket),
option(op),
- logger(logger),
+ logger(LogFactory::getInstance()),
resbufLength(0),
currentPayloadLength(0),
- lenbufLength(0) {
- logger = LogFactory::getInstance();
+ lenbufLength(0)
+{
+ logger->debug("PeerConnection::instantiated");
}
-PeerConnection::~PeerConnection() {}
+PeerConnection::~PeerConnection()
+{
+ logger->debug("PeerConnection::deleted");
+}
int32_t PeerConnection::sendMessage(const unsigned char* data, int32_t dataLength) {
int32_t writtenLength = 0;
diff --git a/src/PieceStorage.h b/src/PieceStorage.h
index f3c2d07e..b96d70bf 100644
--- a/src/PieceStorage.h
+++ b/src/PieceStorage.h
@@ -101,10 +101,21 @@ public:
virtual void setFileFilter(const Integers& fileIndexes) = 0;
virtual void clearFileFilter() = 0;
-
+
+ /**
+ * Returns true if download has completed.
+ * If file filter is enabled, then returns true if those files have
+ * downloaded.
+ */
virtual bool downloadFinished() = 0;
/**
+ * Returns true if all files have downloaded.
+ * The file filter is ignored.
+ */
+ virtual bool allDownloadFinished() = 0;
+
+ /**
* Initializes DiskAdaptor.
* TODO add better documentation here.
*/
diff --git a/src/SegmentMan.cc b/src/SegmentMan.cc
index 7259f007..1e93593c 100644
--- a/src/SegmentMan.cc
+++ b/src/SegmentMan.cc
@@ -40,24 +40,28 @@
#include "prefs.h"
#include "LogFactory.h"
#include "BitfieldManFactory.h"
+#ifdef ENABLE_MESSAGE_DIGEST
#include "ChunkChecksumValidator.h"
+#endif // ENABLE_MESSAGE_DIGEST
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <errno.h>
-SegmentMan::SegmentMan():bitfield(0),
+SegmentMan::SegmentMan():logger(LogFactory::getInstance()),
+ bitfield(0),
totalSize(0),
isSplittable(true),
downloadStarted(false),
dir("."),
errors(0),
- diskWriter(0),
+ diskWriter(0)
+#ifdef ENABLE_MESSAGE_DIGEST
+ ,
chunkHashLength(0),
digestAlgo(DIGEST_ALGO_SHA1)
-{
- logger = LogFactory::getInstance();
-}
+#endif // ENABLE_MESSAGE_DIGEST
+{}
SegmentMan::~SegmentMan() {
delete bitfield;
@@ -450,7 +454,7 @@ bool SegmentMan::fileExists() {
bool SegmentMan::shouldCancelDownloadForSafety() {
return fileExists() && !segmentFileExists() &&
- option->get(PREF_FORCE_TRUNCATE) != V_TRUE;
+ option->get(PREF_ALLOW_OVERWRITE) != V_TRUE;
}
void SegmentMan::markAllPiecesDone()
@@ -460,6 +464,7 @@ void SegmentMan::markAllPiecesDone()
}
}
+#ifdef ENABLE_MESSAGE_DIGEST
void SegmentMan::checkIntegrity()
{
logger->notice("Validating file %s",
@@ -470,12 +475,16 @@ void SegmentMan::checkIntegrity()
v.setFileAllocationMonitor(FileAllocationMonitorFactory::getFactory()->createNewMonitor());
v.validate(bitfield, pieceHashes, chunkHashLength);
}
+#endif // ENABLE_MESSAGE_DIGEST
+#ifdef ENABLE_MESSAGE_DIGEST
bool SegmentMan::isChunkChecksumValidationReady() const {
return bitfield &&
((int64_t)pieceHashes.size())*chunkHashLength == ((int64_t)bitfield->getBlockLength())*(bitfield->getMaxIndex()+1);
}
+#endif // ENABLE_MESSAGE_DIGEST
+#ifdef ENABLE_MESSAGE_DIGEST
void SegmentMan::tryChunkChecksumValidation(const Segment& segment)
{
if(!isChunkChecksumValidationReady()) {
@@ -527,3 +536,4 @@ void SegmentMan::tryChunkChecksumValidation(const Segment& segment)
}
}
}
+#endif // ENABLE_MESSAGE_DIGEST
diff --git a/src/SegmentMan.h b/src/SegmentMan.h
index 66958c64..9478f38d 100644
--- a/src/SegmentMan.h
+++ b/src/SegmentMan.h
@@ -157,9 +157,11 @@ public:
DiskWriterHandle diskWriter;
Requests reserved;
+#ifdef ENABLE_MESSAGE_DIGEST
Strings pieceHashes;
int32_t chunkHashLength;
MessageDigestContext::DigestAlgo digestAlgo;
+#endif // ENABLE_MESSAGE_DIGEST
SegmentMan();
~SegmentMan();
@@ -283,12 +285,13 @@ public:
void markAllPiecesDone();
+#ifdef ENABLE_MESSAGE_DIGEST
void checkIntegrity();
void tryChunkChecksumValidation(const Segment& segment);
bool isChunkChecksumValidationReady() const;
-
+#endif // ENABLE_MESSAGE_DIGEST
};
#endif // _D_SEGMENT_MAN_H_
diff --git a/src/ShareRatioSeedCriteria.h b/src/ShareRatioSeedCriteria.h
index 6ded3b02..8a7b9a27 100644
--- a/src/ShareRatioSeedCriteria.h
+++ b/src/ShareRatioSeedCriteria.h
@@ -38,6 +38,7 @@
#include "SeedCriteria.h"
#include "BtContext.h"
#include "PeerStorage.h"
+#include "PieceStorage.h"
#include "BtRuntime.h"
#include "BtRegistry.h"
@@ -46,12 +47,14 @@ private:
double ratio;
BtContextHandle btContext;
PeerStorageHandle peerStorage;
+ PieceStorageHandle pieceStorage;
BtRuntimeHandle btRuntime;
public:
ShareRatioSeedCriteria(double ratio, const BtContextHandle& btContext)
:ratio(ratio),
btContext(btContext),
peerStorage(PEER_STORAGE(btContext)),
+ pieceStorage(PIECE_STORAGE(btContext)),
btRuntime(BT_RUNTIME(btContext)) {}
virtual ~ShareRatioSeedCriteria() {}
@@ -66,7 +69,7 @@ public:
long long int allTimeUploadLength =
btRuntime->getUploadLengthAtStartup()+stat.getSessionUploadLength();
return ratio <=
- ((double)allTimeUploadLength)/btContext->getTotalLength();
+ ((double)allTimeUploadLength)/pieceStorage->getCompletedLength();
}
void setRatio(double ratio) {
diff --git a/src/TorrentDownloadEngine.cc b/src/TorrentDownloadEngine.cc
index 30a0587c..75491129 100644
--- a/src/TorrentDownloadEngine.cc
+++ b/src/TorrentDownloadEngine.cc
@@ -59,7 +59,7 @@ void TorrentDownloadEngine::setBtContext(const BtContextHandle& btContext) {
void TorrentDownloadEngine::onEndOfRun() {
pieceStorage->getDiskAdaptor()->closeFile();
- if(pieceStorage->downloadFinished()) {
+ if(pieceStorage->allDownloadFinished()) {
btProgressInfoFile->removeFile();
} else {
btProgressInfoFile->save();
diff --git a/src/TorrentRequestInfo.cc b/src/TorrentRequestInfo.cc
index dbf29c3e..48a5723b 100644
--- a/src/TorrentRequestInfo.cc
+++ b/src/TorrentRequestInfo.cc
@@ -67,21 +67,25 @@ RequestInfos TorrentRequestInfo::execute() {
// load .aria2 file if it exists.
BT_PROGRESS_INFO_FILE(btContext)->load();
PIECE_STORAGE(btContext)->getDiskAdaptor()->openExistingFile();
+#ifdef ENABLE_MESSAGE_DIGEST
if(op->get(PREF_CHECK_INTEGRITY) == V_TRUE) {
PIECE_STORAGE(btContext)->checkIntegrity();
}
+#endif // ENABLE_MESSAGE_DIGEST
} else {
if(PIECE_STORAGE(btContext)->getDiskAdaptor()->fileExists()) {
- if(op->get(PREF_FORCE_TRUNCATE) != V_TRUE) {
+ if(op->get(PREF_ALLOW_OVERWRITE) != V_TRUE) {
throw new FatalException(EX_FILE_ALREADY_EXISTS,
PIECE_STORAGE(btContext)->getDiskAdaptor()->getFilePath().c_str(),
BT_PROGRESS_INFO_FILE(btContext)->getFilename().c_str());
} else {
PIECE_STORAGE(btContext)->getDiskAdaptor()->openExistingFile();
+#ifdef ENABLE_MESSAGE_DIGEST
if(op->get(PREF_CHECK_INTEGRITY) == V_TRUE) {
PIECE_STORAGE(btContext)->markAllPiecesDone();
PIECE_STORAGE(btContext)->checkIntegrity();
}
+#endif // ENABLE_MESSAGE_DIGEST
}
} else {
PIECE_STORAGE(btContext)->getDiskAdaptor()->initAndOpenFile();
diff --git a/src/UrlRequestInfo.cc b/src/UrlRequestInfo.cc
index 620ceaca..0cd9643d 100644
--- a/src/UrlRequestInfo.cc
+++ b/src/UrlRequestInfo.cc
@@ -155,31 +155,39 @@ RequestInfos UrlRequestInfo::execute() {
op->get(PREF_REFERER),
op->getAsInt(PREF_SPLIT)));
- HeadResult hr = getHeadResult();
-
- if(fail) {
- return RequestInfos();
+ HeadResult hr;
+ if(filename.size() && totalLength > 0) {
+ hr.filename = filename;
+ hr.totalLength = totalLength;
+ } else {
+ hr = getHeadResult();
+ if(fail) {
+ return RequestInfos();
+ }
+
+ logger->info("Head result: filename=%s, total length=%s",
+ hr.filename.c_str(), Util::ullitos(hr.totalLength, true).c_str());
}
-
- logger->info("Head result: filename=%s, total length=%s",
- hr.filename.c_str(), Util::ullitos(hr.totalLength, true).c_str());
-
adjustRequestSize(requests, reserved, maxConnections);
SharedHandle<ConsoleDownloadEngine> e(DownloadEngineFactory::newConsoleEngine(op, requests, reserved));
e->segmentMan->filename = hr.filename;
e->segmentMan->totalSize = hr.totalLength;
e->segmentMan->downloadStarted = true;
+#ifdef ENABLE_MESSAGE_DIGEST
e->segmentMan->digestAlgo = digestAlgo;
e->segmentMan->chunkHashLength = chunkChecksumLength;
e->segmentMan->pieceHashes = chunkChecksums;
+#endif // ENABLE_MESSAGE_DIGEST
if(e->segmentMan->segmentFileExists()) {
e->segmentMan->load();
e->segmentMan->diskWriter->openExistingFile(e->segmentMan->getFilePath());
+#ifdef ENABLE_MESSAGE_DIGEST
if(e->option->get(PREF_CHECK_INTEGRITY) == V_TRUE) {
e->segmentMan->checkIntegrity();
}
+#endif // ENABLE_MESSAGE_DIGEST
} else {
if(e->segmentMan->shouldCancelDownloadForSafety()) {
throw new FatalException(EX_FILE_ALREADY_EXISTS,
@@ -190,8 +198,10 @@ RequestInfos UrlRequestInfo::execute() {
e->segmentMan->totalSize);
if(e->segmentMan->fileExists() && e->option->get(PREF_CHECK_INTEGRITY) == V_TRUE) {
e->segmentMan->diskWriter->openExistingFile(e->segmentMan->getFilePath());
+#ifdef ENABLE_MESSAGE_DIGEST
e->segmentMan->markAllPiecesDone();
e->segmentMan->checkIntegrity();
+#endif // ENABLE_MESSAGE_DIGEST
} else {
e->segmentMan->diskWriter->initAndOpenFile(e->segmentMan->getFilePath(),
e->segmentMan->totalSize);
diff --git a/src/UrlRequestInfo.h b/src/UrlRequestInfo.h
index dc81065a..bf7f0f26 100644
--- a/src/UrlRequestInfo.h
+++ b/src/UrlRequestInfo.h
@@ -50,9 +50,13 @@ class UrlRequestInfo : public RequestInfo {
private:
Strings urls;
int maxConnections;
+#ifdef ENABLE_MESSAGE_DIGEST
MessageDigestContext::DigestAlgo digestAlgo;
int32_t chunkChecksumLength;
Strings chunkChecksums;
+#endif // ENABLE_MESSAGE_DIGEST
+ string filename;
+ int64_t totalLength;
RequestInfo* createNextRequestInfo() const;
void adjustRequestSize(Requests& requests,
@@ -65,24 +69,41 @@ public:
RequestInfo(op),
urls(urls),
maxConnections(maxConnections),
+#ifdef ENABLE_MESSAGE_DIGEST
digestAlgo(DIGEST_ALGO_SHA1),
- chunkChecksumLength(0) {}
+ chunkChecksumLength(0),
+#endif // ENABLE_MESSAGE_DIGEST
+ totalLength(0) {}
virtual ~UrlRequestInfo() {}
virtual RequestInfos execute();
+#ifdef ENABLE_MESSAGE_DIGEST
void setDigestAlgo(const MessageDigestContext::DigestAlgo& algo) {
this->digestAlgo = algo;
}
+#endif // ENABLE_MESSAGE_DIGEST
+#ifdef ENABLE_MESSAGE_DIGEST
void setChunkChecksumLength(int32_t chunkChecksumLength) {
this->chunkChecksumLength = chunkChecksumLength;
}
+#endif // ENABLE_MESSAGE_DIGEST
+#ifdef ENABLE_MESSAGE_DIGEST
void setChunkChecksums(const Strings& chunkChecksums) {
this->chunkChecksums = chunkChecksums;
}
+#endif // ENABLE_MESSAGE_DIGEST
+
+ void setTotalLength(int64_t totalLength) {
+ this->totalLength = totalLength;
+ }
+
+ void setFilename(const string& filename) {
+ this->filename = filename;
+ }
};
typedef SharedHandle<UrlRequestInfo> UrlRequestInfoHandle;
diff --git a/src/Xml2MetalinkProcessor.cc b/src/Xml2MetalinkProcessor.cc
index ac25fb57..67925ddc 100644
--- a/src/Xml2MetalinkProcessor.cc
+++ b/src/Xml2MetalinkProcessor.cc
@@ -99,7 +99,12 @@ MetalinkEntryHandle Xml2MetalinkProcessor::getEntry(const string& xpath) {
MetalinkEntryHandle entry(new MetalinkEntry());
entry->filename = filename;
- entry->size = STRTOLL(xpathContent(xpath+"/m:size").c_str());
+ string sizeStr = Util::trim(xpathContent(xpath+"/m:size"));
+ if(sizeStr == "") {
+ entry->size = 0;
+ } else {
+ entry->size = STRTOLL(sizeStr.c_str());
+ }
entry->version = Util::trim(xpathContent(xpath+"/m:version"));
entry->language = Util::trim(xpathContent(xpath+"/m:language"));
entry->os = Util::trim(xpathContent(xpath+"/m:os"));
@@ -116,8 +121,14 @@ MetalinkEntryHandle Xml2MetalinkProcessor::getEntry(const string& xpath) {
entry->checksum.setDigestAlgo(DIGEST_ALGO_MD5);
}
}
- entry->chunkChecksum = getPieceHash(xpath+"/m:verification/m:pieces[@type=\"sha1\"]", entry->size);
-
+ string piecesPath = xpath+"/m:verification/m:pieces";
+ string sha1PiecesPath = piecesPath+"[@type=\"sha1\"]";
+ string md5PiecesPath = piecesPath+"[@type=\"md5\"]";
+ if(xpathExists(sha1PiecesPath)) {
+ entry->chunkChecksum = getPieceHash(sha1PiecesPath, entry->size);
+ } else if(xpathExists(md5PiecesPath)) {
+ entry->chunkChecksum = getPieceHash(md5PiecesPath, entry->size);
+ }
#endif // ENABLE_MESSAGE_DIGEST
for(int index = 1; 1; index++) {
MetalinkResourceHandle resource(getResource(xpath+"/m:resources/m:url["+Util::itos(index)+"]"));
@@ -130,11 +141,11 @@ MetalinkEntryHandle Xml2MetalinkProcessor::getEntry(const string& xpath) {
return entry;
}
+#ifdef ENABLE_MESSAGE_DIGEST
MetalinkChunkChecksumHandle Xml2MetalinkProcessor::getPieceHash(const string& xpath,
int64_t totalSize)
{
MetalinkChunkChecksumHandle chunkChecksum = new MetalinkChunkChecksum();
- chunkChecksum->digestAlgo = DIGEST_ALGO_SHA1;
xmlXPathObjectPtr result = xpathEvaluation(xpath);
if(!result) {
@@ -143,7 +154,17 @@ MetalinkChunkChecksumHandle Xml2MetalinkProcessor::getPieceHash(const string& xp
xmlNodeSetPtr nodeSet = result->nodesetval;
xmlNodePtr node = nodeSet->nodeTab[0];
chunkChecksum->pieceLength = STRTOLL(Util::trim(xmlAttribute(node, "length")).c_str());
+ string algo = Util::trim(xmlAttribute(node, "type"));
xmlXPathFreeObject(result);
+ if(algo == "sha1") {
+ chunkChecksum->digestAlgo = DIGEST_ALGO_SHA1;
+ } else if(algo == "md5") {
+ chunkChecksum->digestAlgo = DIGEST_ALGO_MD5;
+ } else {
+ // unknown checksum type
+ chunkChecksum->pieceLength = 0;
+ return chunkChecksum;
+ }
int64_t numPiece =
(totalSize+chunkChecksum->pieceLength-1)/chunkChecksum->pieceLength;
@@ -156,6 +177,7 @@ MetalinkChunkChecksumHandle Xml2MetalinkProcessor::getPieceHash(const string& xp
}
return chunkChecksum;
}
+#endif // ENABLE_MESSAGE_DIGEST
MetalinkResourceHandle Xml2MetalinkProcessor::getResource(const string& xpath) {
xmlXPathObjectPtr result = xpathEvaluation(xpath);
@@ -240,3 +262,13 @@ string Xml2MetalinkProcessor::xpathContent(const string& xpath) {
xmlXPathFreeObject(result);
return content;
}
+
+bool Xml2MetalinkProcessor::xpathExists(const string& xpath) {
+ xmlXPathObjectPtr result = xpathEvaluation(xpath);
+ bool retval = true;
+ if(!result) {
+ retval = false;
+ }
+ xmlXPathFreeObject(result);
+ return retval;
+}
diff --git a/src/Xml2MetalinkProcessor.h b/src/Xml2MetalinkProcessor.h
index df768141..aa855a7f 100644
--- a/src/Xml2MetalinkProcessor.h
+++ b/src/Xml2MetalinkProcessor.h
@@ -46,13 +46,17 @@ private:
MetalinkEntryHandle getEntry(const string& xpath);
MetalinkResourceHandle getResource(const string& xpath);
+
+#ifdef ENABLE_MESSAGE_DIGEST
MetalinkChunkChecksumHandle getPieceHash(const string& xpath,
int64_t totalSize);
+#endif // ENABLE_MESSAGE_DIGEST
xmlXPathObjectPtr xpathEvaluation(const string& xpath);
string xpathContent(const string& xpath);
string xmlAttribute(xmlNodePtr node, const string& attrName);
string xmlContent(xmlNodePtr node);
+ bool xpathExists(const string& xpath);
void release();
public:
diff --git a/src/common.h b/src/common.h
index 94e686cc..91049cb5 100644
--- a/src/common.h
+++ b/src/common.h
@@ -52,11 +52,6 @@
# define _(String) (String)
#endif
-#ifndef LONG_LONG_MAX
-# define LONG_LONG_MAX 9223372036854775807LL
-# define LONG_LONG_MIN (-LONG_LONG_MAX - 1LL)
-#endif // LONG_LONG_MAX
-
#define USER_AGENT "aria2"
#define BITFIELD_LEN_FROM_PIECES(X) ((X)/8+((X)%8? 1 : 0))
diff --git a/src/main.cc b/src/main.cc
index 2a241bef..31632f48 100644
--- a/src/main.cc
+++ b/src/main.cc
@@ -175,13 +175,24 @@ void showUsage() {
" pre-allocates file space before download begins.\n"
" This may take some time depending on the size of\n"
" file.\n"
- " Default: 'none'") << endl;
- cout << _(" --force-truncate=true|false If this option set to false, aria2 doesn't download\n"
- " file which already exists in file system but\n"
- " its corresponding .aria2 file doesn't exist.\n"
- " Set this option to true if you want to download\n"
- " file all over again.\n"
+ " Default: none") << endl;
+ cout << _(" --allow-overwrite=true|false If this option set to false, aria2 doesn't\n"
+ " download a file which already exists in the file\n"
+ " system but its corresponding .aria2 file doesn't\n"
+ " exist.\n"
" Default: false") << endl;
+ cout << _(" --check-integiry=true|false Check file integiry by validating piece hash.\n"
+ " This option makes effect in BitTorrent download\n"
+ " and Metalink with chunk checksums.\n"
+ " Use this option to redownload a damaged portion of\n"
+ " file.\n"
+ " You may need to specify --allow-overwrite=true\n"
+ " option if .aria2 file doesn't exist.\n"
+ " Default: false") << endl;
+ cout << _(" --realtime-chunk-checksum=true|false Validate chunk checksum while downloading\n"
+ " a file in Metalink mode. This option makes effect\n"
+ " in Metalink with chunk checksums.\n"
+ " Default: true") << 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"
@@ -343,9 +354,9 @@ int main(int argc, char* argv[]) {
op->put(PREF_STARTUP_IDLE_TIME, "10");
op->put(PREF_TRACKER_MAX_TRIES, "10");
op->put(PREF_FILE_ALLOCATION, V_NONE);
- op->put(PREF_FORCE_TRUNCATE, V_FALSE);
+ op->put(PREF_ALLOW_OVERWRITE, V_FALSE);
op->put(PREF_REALTIME_CHUNK_CHECKSUM, V_TRUE);
- op->put(PREF_CHECK_INTEGRITY, V_TRUE);
+ op->put(PREF_CHECK_INTEGRITY, V_FALSE);
while(1) {
int optIndex = 0;
int lopt;
@@ -375,7 +386,9 @@ int main(int argc, char* argv[]) {
{ "lowest-speed-limit", required_argument, &lopt, 200 },
{ "max-download-limit", required_argument, &lopt, 201 },
{ "file-allocation", required_argument, 0, 'a' },
- { "force-truncate", required_argument, &lopt, 202 },
+ { "allow-overwrite", required_argument, &lopt, 202 },
+ { "check-integrity", required_argument, &lopt, 203 },
+ {" realtime-chunk-checksum", required_argument, &lopt, 204 },
#ifdef ENABLE_BITTORRENT
{ "torrent-file", required_argument, NULL, 'T' },
{ "listen-port", required_argument, &lopt, 15 },
@@ -384,7 +397,7 @@ int main(int argc, char* argv[]) {
{ "no-preallocation", no_argument, &lopt, 18 },
{ "direct-file-mapping", required_argument, &lopt, 19 },
// TODO remove upload-limit.
- { "upload-limit", required_argument, &lopt, 20 },
+ //{ "upload-limit", required_argument, &lopt, 20 },
{ "select-file", required_argument, &lopt, 21 },
{ "seed-time", required_argument, &lopt, 22 },
{ "seed-ratio", required_argument, &lopt, 23 },
@@ -417,7 +430,6 @@ int main(int argc, char* argv[]) {
if(proxy.first.empty() || proxy.second.empty() ||
!(0 < port && port <= 65535)) {
cerr << _("unrecognized proxy format") << endl;
- showUsage();
exit(EXIT_FAILURE);
}
op->put(PREF_HTTP_PROXY_HOST, proxy.first);
@@ -453,7 +465,6 @@ int main(int argc, char* argv[]) {
int wait = (int)strtol(optarg, NULL, 10);
if(!(0 <= wait && wait <= 60)) {
cerr << _("retry-wait must be between 0 and 60.") << endl;
- showUsage();
exit(EXIT_FAILURE);
}
op->put(PREF_RETRY_WAIT, Util::itos(wait));
@@ -470,7 +481,6 @@ int main(int argc, char* argv[]) {
op->put(PREF_FTP_TYPE, optarg);
} else {
cerr << _("ftp-type must be either 'binary' or 'ascii'.") << endl;
- showUsage();
exit(EXIT_FAILURE);
}
break;
@@ -479,7 +489,6 @@ int main(int argc, char* argv[]) {
op->put(PREF_FTP_VIA_HTTP_PROXY, optarg);
} else {
cerr << _("ftp-via-http-proxy must be either 'get' or 'tunnel'.") << endl;
- showUsage();
exit(EXIT_FAILURE);
}
break;
@@ -487,7 +496,6 @@ int main(int argc, char* argv[]) {
long long int size = getRealSize(optarg);
if(size < 1024) {
cerr << _("min-segment-size invalid") << endl;
- showUsage();
exit(EXIT_FAILURE);
}
op->put(PREF_MIN_SEGMENT_SIZE, Util::llitos(size));
@@ -498,7 +506,6 @@ int main(int argc, char* argv[]) {
op->put(PREF_HTTP_PROXY_METHOD, optarg);
} else {
cerr << _("http-proxy-method must be either 'get' or 'tunnel'.") << endl;
- showUsage();
exit(EXIT_FAILURE);
}
break;
@@ -506,7 +513,6 @@ int main(int argc, char* argv[]) {
int listenPort = (int)strtol(optarg, NULL, 10);
if(!(1024 <= listenPort && listenPort <= 65535)) {
cerr << _("listen-port must be between 1024 and 65535.") << endl;
- showUsage();
exit(EXIT_FAILURE);
}
op->put(PREF_LISTEN_PORT, Util::itos(listenPort));
@@ -519,7 +525,6 @@ int main(int argc, char* argv[]) {
op->put(PREF_FOLLOW_TORRENT, V_FALSE);
} else {
cerr << _("follow-torrent must be either 'true' or 'false'.") << endl;
- showUsage();
exit(EXIT_FAILURE);
}
break;
@@ -533,23 +538,9 @@ int main(int argc, char* argv[]) {
op->put(PREF_DIRECT_FILE_MAPPING, V_FALSE);
} else {
cerr << _("direct-file-mapping must be either 'true' or 'false'.") << endl;
- showUsage();
- exit(EXIT_FAILURE);
- }
- break;
- case 20: {
- cerr << "Warning: upload-limit will be deprecated in the future release.\n"
- "Use max-upload-limit instead. Because there is a difference between them,\n"
- "take a look at the description of max-upload-limit option." << endl;
- int uploadSpeed = strtol(optarg, NULL, 10)*1024;
- if(0 > uploadSpeed) {
- cerr << _("upload-limit must be greater than or equal to 0.") << endl;
- showUsage();
exit(EXIT_FAILURE);
}
- op->put(PREF_MAX_UPLOAD_LIMIT, Util::itos(uploadSpeed));
break;
- }
case 21:
op->put(PREF_SELECT_FILE, optarg);
break;
@@ -557,7 +548,6 @@ int main(int argc, char* argv[]) {
int seedTime = (int)strtol(optarg, NULL, 10);
if(seedTime < 0) {
cerr << _("seed-time must be greater than or equal to 0.") << endl;
- showUsage();
exit(EXIT_FAILURE);
}
op->put(PREF_SEED_TIME, Util::itos(seedTime));
@@ -567,7 +557,6 @@ int main(int argc, char* argv[]) {
double ratio = (int)strtod(optarg, NULL);
if(ratio < 0.0) {
cerr << _("seed-ratio must be greater than or equal to 0.0.") << endl;
- showUsage();
exit(EXIT_FAILURE);
}
op->put(PREF_SEED_RATIO, optarg);
@@ -577,7 +566,6 @@ int main(int argc, char* argv[]) {
int limit = getRealSize(optarg);
if(limit < 0) {
cerr << _("max-upload-limit must be greater than or equal to 0") << endl;
- showUsage();
exit(EXIT_FAILURE);
}
op->put(PREF_MAX_UPLOAD_LIMIT, Util::itos(limit));
@@ -599,7 +587,6 @@ int main(int argc, char* argv[]) {
op->put(PREF_FOLLOW_METALINK, V_FALSE);
} else {
cerr << _("follow-metalink must be either 'true' or 'false'.") << endl;
- showUsage();
exit(EXIT_FAILURE);
}
break;
@@ -610,7 +597,6 @@ int main(int argc, char* argv[]) {
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));
@@ -620,7 +606,6 @@ int main(int argc, char* argv[]) {
int limit = getRealSize(optarg);
if(limit < 0) {
cerr << _("max-download-limit must be greater than or equal to 0") << endl;
- showUsage();
exit(EXIT_FAILURE);
}
op->put(PREF_MAX_DOWNLOAD_LIMIT, Util::itos(limit));
@@ -628,14 +613,36 @@ int main(int argc, char* argv[]) {
}
case 202: {
if(string(optarg) == "true") {
- op->put(PREF_FORCE_TRUNCATE, V_TRUE);
+ op->put(PREF_ALLOW_OVERWRITE, V_TRUE);
} else if(string(optarg) == "false") {
- op->put(PREF_FORCE_TRUNCATE, V_FALSE);
+ op->put(PREF_ALLOW_OVERWRITE, V_FALSE);
} else {
- cerr << _("force-true must be either 'true' or 'false'.") << endl;
- showUsage();
+ cerr << _("allow-overwrite must be either 'true' or 'false'.") << endl;
exit(EXIT_FAILURE);
}
+ break;
+ }
+ case 203: {
+ if(string(optarg) == "true") {
+ op->put(PREF_CHECK_INTEGRITY, V_TRUE);
+ } else if(string(optarg) == "false") {
+ op->put(PREF_CHECK_INTEGRITY, V_FALSE);
+ } else {
+ cerr << _("check-integrity must be be either 'true' or 'false'.") << endl;
+ exit(EXIT_FAILURE);
+ }
+ break;
+ }
+ case 204: {
+ if(string(optarg) == "true") {
+ op->put(PREF_REALTIME_CHUNK_CHECKSUM, V_TRUE);
+ } else if(string(optarg) == "false") {
+ op->put(PREF_REALTIME_CHUNK_CHECKSUM, V_FALSE);
+ } else {
+ cerr << _("realtime-chunk-checksum must be either 'true' or 'false'.") << endl;
+ exit(EXIT_FAILURE);
+ }
+ break;
}
}
break;
@@ -660,7 +667,6 @@ int main(int argc, char* argv[]) {
int split = (int)strtol(optarg, NULL, 10);
if(!(1 <= split && split <= 5)) {
cerr << _("split must be between 1 and 5.") << endl;
- showUsage();
exit(EXIT_FAILURE);
}
op->put(PREF_SPLIT, Util::itos(split));
@@ -672,7 +678,6 @@ int main(int argc, char* argv[]) {
op->put(PREF_TIMEOUT, Util::itos(timeout));
} else {
cerr << _("timeout must be between 1 and 600") << endl;
- showUsage();
exit(EXIT_FAILURE);
}
break;
@@ -681,7 +686,6 @@ int main(int argc, char* argv[]) {
int retries = (int)strtol(optarg, NULL, 10);
if(retries < 0) {
cerr << _("max-tries invalid") << endl;
- showUsage();
exit(EXIT_FAILURE);
}
op->put(PREF_MAX_TRIES, Util::itos(retries));
@@ -703,7 +707,6 @@ int main(int argc, char* argv[]) {
int metalinkServers = (int)strtol(optarg, NULL, 10);
if(metalinkServers <= 0) {
cerr << _("metalink-servers must be greater than 0.") << endl;
- showUsage();
exit(EXIT_FAILURE);
}
op->put(PREF_METALINK_SERVERS, Util::itos(metalinkServers));
@@ -715,7 +718,6 @@ int main(int argc, char* argv[]) {
op->put(PREF_FILE_ALLOCATION, value);
} else {
cerr << _("file-allocation must be either 'none' or 'prealloc'.") << endl;
- showUsage();
exit(EXIT_FAILURE);
}
break;
@@ -727,14 +729,12 @@ int main(int argc, char* argv[]) {
showUsage();
exit(EXIT_SUCCESS);
default:
- showUsage();
exit(EXIT_FAILURE);
}
}
if(!op->defined(PREF_TORRENT_FILE) && !op->defined(PREF_METALINK_FILE)) {
if(optind == argc) {
cerr << _("specify at least one URL") << endl;
- showUsage();
exit(EXIT_FAILURE);
}
}
diff --git a/src/message.h b/src/message.h
index b24584be..fc2d288e 100644
--- a/src/message.h
+++ b/src/message.h
@@ -111,7 +111,7 @@
#define EX_SOCKET_SEND _("Failed to send data, cause: %s")
#define EX_SOCKET_RECV _("Failed to receive data, cause: %s")
#define EX_SOCKET_PEEK _("Failed to peek data, cause: %s")
-#define EX_FILE_ALREADY_EXISTS _("File %s exists, but %s does not exist. The download was canceled in order to prevent your file from being truncated to 0. If you are sure to download file all over again, then delete it or add --force-truncate=true option and restart aria2.")
+#define EX_FILE_ALREADY_EXISTS _("File %s exists, but %s does not exist. The download was canceled in order to prevent your file from being truncated to 0. If you are sure to download file all over again, then delete it or add --allow-overwrite=true option and restart aria2.")
#define EX_INVALID_PAYLOAD_SIZE _("Invalid payload size for %s, size=%d. It should be %d.")
#define EX_INVALID_BT_MESSAGE_ID _("Invalid ID=%d for %s. It should be %d.")
#define EX_INVALID_CHUNK_CHECKSUM _("Chunk checksum validation failed. checksumIndex=%d, offset=%lld, length=%d, expectedHash=%s, actualHash=%s")
diff --git a/src/prefs.h b/src/prefs.h
index 8be227ca..95e8c312 100644
--- a/src/prefs.h
+++ b/src/prefs.h
@@ -85,7 +85,7 @@
#define PREF_FILE_ALLOCATION "file_allocation"
# define V_PREALLOC "prealloc"
// value: true | false
-#define PREF_FORCE_TRUNCATE "force_truncate"
+#define PREF_ALLOW_OVERWRITE "allow_overwrite"
// value: true | false
#define PREF_REALTIME_CHUNK_CHECKSUM "realtime_chunk_checksum"
// value: true | false