2007-01-11 Tatsuhiro Tsujikawa <tujikawa at rednoah dot com>

To add RecoverableException, FatalException:
	
	* src/AbstractCommand.cc
	(onAbort): Exception -> RecoverableException
	* src/PeerAbstractCommand.h
	(RecoverableException.h): New include.
	(onAbort): Exception -> RecoverableException.
	* src/PeerInteractionCommand.cc
	(onAbort): Exception -> RecoverableException.
	* src/PeerAbstractCommand.cc
	(execute): Exception -> RecoverableException.
	(onAbort): Exception -> RecoverableException.
	* src/TorrentRequestInfo.cc
	(execute): Exception -> RecoverableException.
	* src/MetalinkRequestInfo.cc
	(execute): Exception -> RecoverableException.
	* src/MetaFileUtil.cc: RecoverableException.
	* src/AbstractCommand.h
	(onAbort): Exception -> RecoverableException.
	* src/DlRetryEx.h: Exception -> RecoverableException.
	* src/DlAbortEx.h: Exception -> RecoverableException.
	* src/PeerListenCommand.cc: Exception -> RecoverableException.
	* src/Util.cc: Exception -> RecoverableException.
	* src/DefauldDiskWriter.cc: Exception -> RecoverableException.
	* src/TrackerUpdateCommand.cc: Exception -> 
RecoverableException.
	* src/UrlRequestInfo.cc: Exception -> RecoverableException.
	
	To make ID static const int

	* src/BtInterestedMessage.h
	(ID_t): Removed.
	(ID): New variable.
	(getId): Made non-const.
	* src/BtPieceMessage.h
	(ID_t): Removed.
	(ID): New variable.
	(getId): Made non-const.
	* src/BtChokeMessage.h
	(ID_t): Removed.
	(ID): New variable.
	(getId): Made non-const.
	* src/BtHaveAllMessage.h
	(ID_t): Removed.
	(ID): New variable.
	(getId): Made non-const.
	* src/BtKeepAliveMessage.h
	(ID_t): Removed.
	(ID): New variable.
	(getId): Made non-const.
	* src/BtHandshakeMessage.h
	(ID): New variable.
	(getId): Made non-const.
	* src/BtSuggestPieceMessage.h
	(ID_t): Removed.
	(ID): New variable.
	(getId): Made non-const.
	* src/BtPortMessage.h
	(ID_t): Removed.
	(ID): New variable.
	(getId): Made non-const.
	* src/AbstractBtMessage.h
	(id): Removed.
	(AbstractBtMessage): Removed id.
	(getId): Removed.
	* src/BtHaveMessage.h
	(ID_t): Removed.
	(ID): New variable.
	(getId): Made non-const.
	* src/BtAllowedFastMessage.h
	(ID_t): Removed.
	(ID): New variable.
	(getId): Made non-const.
	* src/BtCancelMessage.h
	(ID_t): Removed.
	(ID): New variable.
	(getId): Made non-const.
	* src/BtNotInterestedMessage.h
	(ID_t): Removed.
	(ID): New variable.
	(getId): Made non-const.
	* src/BtChokeMessage.h
	(ID_t): Removed.
	(ID): New variable.
	(getId): Made non-const.
	* src/BtRejectMessage.h
	(ID_t): Removed.
	(ID): New variable.
	(getId): Made non-const.
	* src/BtBitfieldMessage.h
	(ID_t): Removed.
	(ID): New variable.
	(getId): Made non-const.
	* src/BtUnchokeMessage.h
	(ID_t): Removed.
	(ID): New variable.
	(getId): Made non-const.
	* src/BtRequestMessage.h
	(ID_t): Removed.
	(ID): New variable.
	(getId): Made non-const.
	* src/BtHaveMessage.h
	(ID_t): Removed.
	(ID): New variable.
	(getId): Made non-const.

	To add --force-truncate command-line option and a check whether
	the file already exists:
	
	* src/DirectDiskAdaptor.h
	(getFilePath): Made virtual public.
	* src/MultiDiskAdaptor.h
	(File.h): New include.
	(DiskWriterEntry::fileEntry): Made private.
	(DiskWriterEntry::fileExists): New function.
	(DiskWriterEntry::getFileEntry): New function.
	(fileExists): New function.
	(getFilePath): New function.
	* src/TorrentRequestInfo.cc
	(FatalException.h): New include.
	(message.h): New include.
	(RecoverableException.h): New include.
	(execute): Added a check whether file is already exists or not.
	* src/DiskAdaptor.h
	(fileExists): New function.
	(getFilePath): New function.
	* src/main.cc
	(showUsage): Added an explanation of --force-truncate 
command-line
	option.
	(main): Added --force-truncate command-line option.
	* src/Exception.h
	(setMsg): buf[256] -> buf[1024]
	* src/CopyDiskWriter.h
	(getFilePath): Made public virtual.
	* src/MultiDiskAdaptor.cc: fileEntry -> getFileEntry()
	(fileExists): New function.
	* src/DownloadEngineFactory.cc
	(newTorrentConsoleEngine): Don't open file here.
	* src/message.h
	(EX_FILE_ALREADY_EXISTS): New definition.
	* src/prefs.h
	(PREF_FOECE_TRUNCATE): New definition.
	* src/HttpResponseCommand.cc
	(handleDefaultEncoding): Added a check whether the file already 
exists.
	* src/SegmentMan.h
	(fileExists): New function.
	(shouldCancelDownloadForSafety): New function.
	* src/FtpNegotiateCommand.cc
	(recvSize): Added a check whether the file already exists.
	* src/AbstractSingleDiskAdaptor.cc
	(File.h): New include.
	(fileExists): New function.
	* src/AbstractSingleDiskAdaptor.h
	(getFilePath): Removed.
	(fileExists): New function.
	* src/SegmentMan.cc
	(fileExists): New function.
	(shouldCancelDownloadForSafety): New function.

	To fix regression bug in torrent downloading:
	
	* src/DefaultBtRequestFactory.cc
	(doChokedAction): New function.
	* src/DefaultBtRequestFactory.h
	(doChokedAction): New function.
	* src/DefaultBtMessageDispatcher.cc
	(doChokedAction): Do not delete request if its target is in 
allowed
	fast set.
	* src/DefaultBtInteractive.cc
	(doPostHandshakeProcessing): Added a call to 
sendPendingMessage().
	(sendKeepAlive): Send keep alive message even if the outgoing 
message
	queue is not empty.
	(decideInterest): Simplified the code.
	(fillPiece): Remove a call to dispatcher->doChokedAction() 
because
	it is already called when BtChokeMessage is received from a 
peer.
	* src/BtRequestFactory.h
	(doChokedAction): New function.

	To clean up code:
	
	* src/PeerInteractionCommand.h
	(executeInternal): Added virtual keyword explicitly.
	(prepareForRetry): Added virtual keyword explicitly.
	(prepareForNextPeer): Added virtual keyword explicitly.
	(onAbort): Added virtual keyword explicitly.

	* src/RequestSlot.cc
	(isTimeout): Use Time::elapsed() instead of 
differenceInMillis().

	* src/BtPieceMessage.cc
	(doReceivedAction): Added a debug log of piece's bitfield.
	* src/Piece.h
	(getBitfieldLength): New function.

	* src/ByteArrayDiskWriter.cc
	(clear): Added buf = 0 to avoid double free corruption.

	* src/FileAllocator.cc
	(allocate): Fixed an assignment of 
fileAllocationMonitor->currentValue.
	Added cp.reset().

	* src/BitfieldMan.h
	(operator=): Rewritten.
	* src/BitfieldMan.cc
	(BitfieldMan): Initialized bitfield, useBitfield.
	
	* src/PeerConnection.cc
	(receiveMessage): Added a call to socket->readable() after 
getting
	message length to avoid possible EOF.

	* src/Util.cc
	(torrentUrlencode): Fixed an encodeing bug. BUG#1629912
pull/1/head
Tatsuhiro Tsujikawa 2007-01-11 16:32:31 +00:00
parent e8034f2fd4
commit d28e6aca15
71 changed files with 605 additions and 377 deletions

214
ChangeLog
View File

@ -1,3 +1,217 @@
2007-01-11 Tatsuhiro Tsujikawa <tujikawa at rednoah dot com>
To add RecoverableException, FatalException:
* src/AbstractCommand.cc
(onAbort): Exception -> RecoverableException
* src/PeerAbstractCommand.h
(RecoverableException.h): New include.
(onAbort): Exception -> RecoverableException.
* src/PeerInteractionCommand.cc
(onAbort): Exception -> RecoverableException.
* src/PeerAbstractCommand.cc
(execute): Exception -> RecoverableException.
(onAbort): Exception -> RecoverableException.
* src/TorrentRequestInfo.cc
(execute): Exception -> RecoverableException.
* src/MetalinkRequestInfo.cc
(execute): Exception -> RecoverableException.
* src/MetaFileUtil.cc: RecoverableException.
* src/AbstractCommand.h
(onAbort): Exception -> RecoverableException.
* src/DlRetryEx.h: Exception -> RecoverableException.
* src/DlAbortEx.h: Exception -> RecoverableException.
* src/PeerListenCommand.cc: Exception -> RecoverableException.
* src/Util.cc: Exception -> RecoverableException.
* src/DefauldDiskWriter.cc: Exception -> RecoverableException.
* src/TrackerUpdateCommand.cc: Exception -> RecoverableException.
* src/UrlRequestInfo.cc: Exception -> RecoverableException.
To make ID static const int
* src/BtInterestedMessage.h
(ID_t): Removed.
(ID): New variable.
(getId): Made non-const.
* src/BtPieceMessage.h
(ID_t): Removed.
(ID): New variable.
(getId): Made non-const.
* src/BtChokeMessage.h
(ID_t): Removed.
(ID): New variable.
(getId): Made non-const.
* src/BtHaveAllMessage.h
(ID_t): Removed.
(ID): New variable.
(getId): Made non-const.
* src/BtKeepAliveMessage.h
(ID_t): Removed.
(ID): New variable.
(getId): Made non-const.
* src/BtHandshakeMessage.h
(ID): New variable.
(getId): Made non-const.
* src/BtSuggestPieceMessage.h
(ID_t): Removed.
(ID): New variable.
(getId): Made non-const.
* src/BtPortMessage.h
(ID_t): Removed.
(ID): New variable.
(getId): Made non-const.
* src/AbstractBtMessage.h
(id): Removed.
(AbstractBtMessage): Removed id.
(getId): Removed.
* src/BtHaveMessage.h
(ID_t): Removed.
(ID): New variable.
(getId): Made non-const.
* src/BtAllowedFastMessage.h
(ID_t): Removed.
(ID): New variable.
(getId): Made non-const.
* src/BtCancelMessage.h
(ID_t): Removed.
(ID): New variable.
(getId): Made non-const.
* src/BtNotInterestedMessage.h
(ID_t): Removed.
(ID): New variable.
(getId): Made non-const.
* src/BtChokeMessage.h
(ID_t): Removed.
(ID): New variable.
(getId): Made non-const.
* src/BtRejectMessage.h
(ID_t): Removed.
(ID): New variable.
(getId): Made non-const.
* src/BtBitfieldMessage.h
(ID_t): Removed.
(ID): New variable.
(getId): Made non-const.
* src/BtUnchokeMessage.h
(ID_t): Removed.
(ID): New variable.
(getId): Made non-const.
* src/BtRequestMessage.h
(ID_t): Removed.
(ID): New variable.
(getId): Made non-const.
* src/BtHaveMessage.h
(ID_t): Removed.
(ID): New variable.
(getId): Made non-const.
To add --force-truncate command-line option and a check whether
the file already exists:
* src/DirectDiskAdaptor.h
(getFilePath): Made virtual public.
* src/MultiDiskAdaptor.h
(File.h): New include.
(DiskWriterEntry::fileEntry): Made private.
(DiskWriterEntry::fileExists): New function.
(DiskWriterEntry::getFileEntry): New function.
(fileExists): New function.
(getFilePath): New function.
* src/TorrentRequestInfo.cc
(FatalException.h): New include.
(message.h): New include.
(RecoverableException.h): New include.
(execute): Added a check whether file is already exists or not.
* src/DiskAdaptor.h
(fileExists): New function.
(getFilePath): New function.
* src/main.cc
(showUsage): Added an explanation of --force-truncate command-line
option.
(main): Added --force-truncate command-line option.
* src/Exception.h
(setMsg): buf[256] -> buf[1024]
* src/CopyDiskWriter.h
(getFilePath): Made public virtual.
* src/MultiDiskAdaptor.cc: fileEntry -> getFileEntry()
(fileExists): New function.
* src/DownloadEngineFactory.cc
(newTorrentConsoleEngine): Don't open file here.
* src/message.h
(EX_FILE_ALREADY_EXISTS): New definition.
* src/prefs.h
(PREF_FOECE_TRUNCATE): New definition.
* src/HttpResponseCommand.cc
(handleDefaultEncoding): Added a check whether the file already exists.
* src/SegmentMan.h
(fileExists): New function.
(shouldCancelDownloadForSafety): New function.
* src/FtpNegotiateCommand.cc
(recvSize): Added a check whether the file already exists.
* src/AbstractSingleDiskAdaptor.cc
(File.h): New include.
(fileExists): New function.
* src/AbstractSingleDiskAdaptor.h
(getFilePath): Removed.
(fileExists): New function.
* src/SegmentMan.cc
(fileExists): New function.
(shouldCancelDownloadForSafety): New function.
To fix regression bug in torrent downloading:
* src/DefaultBtRequestFactory.cc
(doChokedAction): New function.
* src/DefaultBtRequestFactory.h
(doChokedAction): New function.
* src/DefaultBtMessageDispatcher.cc
(doChokedAction): Do not delete request if its target is in allowed
fast set.
* src/DefaultBtInteractive.cc
(doPostHandshakeProcessing): Added a call to sendPendingMessage().
(sendKeepAlive): Send keep alive message even if the outgoing message
queue is not empty.
(decideInterest): Simplified the code.
(fillPiece): Remove a call to dispatcher->doChokedAction() because
it is already called when BtChokeMessage is received from a peer.
* src/BtRequestFactory.h
(doChokedAction): New function.
To clean up code:
* src/PeerInteractionCommand.h
(executeInternal): Added virtual keyword explicitly.
(prepareForRetry): Added virtual keyword explicitly.
(prepareForNextPeer): Added virtual keyword explicitly.
(onAbort): Added virtual keyword explicitly.
* src/RequestSlot.cc
(isTimeout): Use Time::elapsed() instead of differenceInMillis().
* src/BtPieceMessage.cc
(doReceivedAction): Added a debug log of piece's bitfield.
* src/Piece.h
(getBitfieldLength): New function.
* src/ByteArrayDiskWriter.cc
(clear): Added buf = 0 to avoid double free corruption.
* src/FileAllocator.cc
(allocate): Fixed an assignment of fileAllocationMonitor->currentValue.
Added cp.reset().
* src/BitfieldMan.h
(operator=): Rewritten.
* src/BitfieldMan.cc
(BitfieldMan): Initialized bitfield, useBitfield.
* src/PeerConnection.cc
(receiveMessage): Added a call to socket->readable() after getting
message length to avoid possible EOF.
* src/Util.cc
(torrentUrlencode): Fixed an encodeing bug. BUG#1629912
2007-01-08 Tatsuhiro Tsujikawa <tujikawa at rednoah dot com> 2007-01-08 Tatsuhiro Tsujikawa <tujikawa at rednoah dot com>
To add an ability to pre-allocate file space: To add an ability to pre-allocate file space:

8
TODO
View File

@ -21,9 +21,7 @@
* Add the message like "you can resume the transfer by invoking aria2 again" when the download stops. * Add the message like "you can resume the transfer by invoking aria2 again" when the download stops.
* Add --bt-timeout command line option. * Add --bt-timeout command line option.
* Fix DefaultBtProgressInfoFile.cc: save(), load() * Fix DefaultBtProgressInfoFile.cc: save(), load()
* Add a feature that if any existing file is detected, then
do not start downloading and print some useful message to the user.
* Fix Segfaults in BitfieldMan.cc:71
https://sourceforge.net/tracker/index.php?func=detail&aid=1606060&group_id=159897&atid=813673
* int32_t
* remove blockIndex * remove blockIndex
* Add piece hash checking
* Stop download after selective download completes
* Add an ability of seeding

View File

@ -50,7 +50,6 @@ protected:
bool sendingInProgress; bool sendingInProgress;
bool invalidate; bool invalidate;
bool uploading; bool uploading;
int32_t id;
int32_t cuid; int32_t cuid;
BtContextHandle btContext; BtContextHandle btContext;
@ -66,7 +65,6 @@ public:
AbstractBtMessage():sendingInProgress(false), AbstractBtMessage():sendingInProgress(false),
invalidate(false), invalidate(false),
uploading(false), uploading(false),
id(0),
cuid(0), cuid(0),
btContext(0), btContext(0),
pieceStorage(0), pieceStorage(0),
@ -100,10 +98,6 @@ public:
this->uploading = uploading; this->uploading = uploading;
} }
virtual uint8_t getId() {
return id;
}
int32_t getCuid() const { int32_t getCuid() const {
return cuid; return cuid;
} }

View File

@ -146,7 +146,7 @@ bool AbstractCommand::prepareForRetry(int wait) {
return true; return true;
} }
void AbstractCommand::onAbort(Exception* ex) { void AbstractCommand::onAbort(RecoverableException* ex) {
logger->debug(MSG_UNREGISTER_CUID, cuid); logger->debug(MSG_UNREGISTER_CUID, cuid);
//e->segmentMan->unregisterId(cuid); //e->segmentMan->unregisterId(cuid);
e->segmentMan->cancelSegment(cuid); e->segmentMan->cancelSegment(cuid);

View File

@ -40,6 +40,7 @@
#include "DownloadEngine.h" #include "DownloadEngine.h"
#include "SegmentMan.h" #include "SegmentMan.h"
#include "TimeA2.h" #include "TimeA2.h"
#include "RecoverableException.h"
class AbstractCommand : public Command { class AbstractCommand : public Command {
private: private:
@ -52,7 +53,7 @@ protected:
void tryReserved(); void tryReserved();
virtual bool prepareForRetry(int wait); virtual bool prepareForRetry(int wait);
virtual void onAbort(Exception* ex); virtual void onAbort(RecoverableException* ex);
virtual bool executeInternal(Segment& segment) = 0; virtual bool executeInternal(Segment& segment) = 0;
void setReadCheckSocket(const SocketHandle& socket); void setReadCheckSocket(const SocketHandle& socket);

View File

@ -33,6 +33,7 @@
*/ */
/* copyright --> */ /* copyright --> */
#include "AbstractSingleDiskAdaptor.h" #include "AbstractSingleDiskAdaptor.h"
#include "File.h"
void AbstractSingleDiskAdaptor::initAndOpenFile() { void AbstractSingleDiskAdaptor::initAndOpenFile() {
diskWriter->initAndOpenFile(getFilePath(), totalLength); diskWriter->initAndOpenFile(getFilePath(), totalLength);
@ -61,3 +62,8 @@ int AbstractSingleDiskAdaptor::readData(unsigned char* data, uint32_t len, int64
string AbstractSingleDiskAdaptor::sha1Sum(int64_t offset, uint64_t length) { string AbstractSingleDiskAdaptor::sha1Sum(int64_t offset, uint64_t length) {
return diskWriter->sha1Sum(offset, length); return diskWriter->sha1Sum(offset, length);
} }
bool AbstractSingleDiskAdaptor::fileExists()
{
return File(getFilePath()).exists();
}

View File

@ -42,8 +42,6 @@ class AbstractSingleDiskAdaptor : public DiskAdaptor {
protected: protected:
DiskWriterHandle diskWriter; DiskWriterHandle diskWriter;
uint64_t totalLength; uint64_t totalLength;
virtual string getFilePath() = 0;
public: public:
AbstractSingleDiskAdaptor():diskWriter(0), totalLength(0) {} AbstractSingleDiskAdaptor():diskWriter(0), totalLength(0) {}
@ -63,7 +61,9 @@ public:
virtual int readData(unsigned char* data, uint32_t len, int64_t offset); virtual int readData(unsigned char* data, uint32_t len, int64_t offset);
virtual string sha1Sum(int64_t offset, uint64_t length); virtual string sha1Sum(int64_t offset, uint64_t length);
virtual bool fileExists();
void setDiskWriter(const DiskWriterHandle diskWriter) { void setDiskWriter(const DiskWriterHandle diskWriter) {
this->diskWriter = diskWriter; this->diskWriter = diskWriter;
} }

View File

@ -37,8 +37,14 @@
#include <string.h> #include <string.h>
BitfieldMan::BitfieldMan(uint32_t blockLength, uint64_t totalLength) BitfieldMan::BitfieldMan(uint32_t blockLength, uint64_t totalLength)
:blockLength(blockLength), totalLength(totalLength), filterBitfield(0), :blockLength(blockLength),
filterEnabled(false), randomizer(0) { totalLength(totalLength),
bitfield(0),
useBitfield(0),
filterBitfield(0),
filterEnabled(false),
randomizer(0)
{
if(blockLength > 0 && totalLength > 0) { if(blockLength > 0 && totalLength > 0) {
blocks = totalLength/blockLength+(totalLength%blockLength ? 1 : 0); blocks = totalLength/blockLength+(totalLength%blockLength ? 1 : 0);
bitfieldLength = blocks/8+(blocks%8 ? 1 : 0); bitfieldLength = blocks/8+(blocks%8 ? 1 : 0);
@ -49,7 +55,13 @@ BitfieldMan::BitfieldMan(uint32_t blockLength, uint64_t totalLength)
} }
} }
BitfieldMan::BitfieldMan(const BitfieldMan& bitfieldMan):randomizer(0) { BitfieldMan::BitfieldMan(const BitfieldMan& bitfieldMan)
:bitfield(0),
useBitfield(0),
filterBitfield(0),
filterEnabled(false),
randomizer(0)
{
blockLength = bitfieldMan.blockLength; blockLength = bitfieldMan.blockLength;
totalLength = bitfieldMan.totalLength; totalLength = bitfieldMan.totalLength;
blocks = bitfieldMan.blocks; blocks = bitfieldMan.blocks;
@ -59,7 +71,7 @@ BitfieldMan::BitfieldMan(const BitfieldMan& bitfieldMan):randomizer(0) {
memcpy(bitfield, bitfieldMan.bitfield, bitfieldLength); memcpy(bitfield, bitfieldMan.bitfield, bitfieldLength);
memcpy(useBitfield, bitfieldMan.useBitfield, bitfieldLength); memcpy(useBitfield, bitfieldMan.useBitfield, bitfieldLength);
filterEnabled = bitfieldMan.filterEnabled; filterEnabled = bitfieldMan.filterEnabled;
if(bitfieldMan.filterBitfield) { if(filterBitfield) {
filterBitfield = new unsigned char[bitfieldLength]; filterBitfield = new unsigned char[bitfieldLength];
memcpy(filterBitfield, bitfieldMan.filterBitfield, bitfieldLength); memcpy(filterBitfield, bitfieldMan.filterBitfield, bitfieldLength);
} else { } else {

View File

@ -73,26 +73,24 @@ public:
if(this != &bitfieldMan) { if(this != &bitfieldMan) {
blockLength = bitfieldMan.blockLength; blockLength = bitfieldMan.blockLength;
totalLength = bitfieldMan.totalLength; totalLength = bitfieldMan.totalLength;
if(bitfieldLength != bitfieldMan.bitfieldLength) {
delete [] bitfield;
delete [] useBitfield;
bitfield = new unsigned char[bitfieldMan.bitfieldLength];
useBitfield = new unsigned char[bitfieldMan.bitfieldLength];
}
blocks = bitfieldMan.blocks; blocks = bitfieldMan.blocks;
bitfieldLength = bitfieldMan.bitfieldLength; bitfieldLength = bitfieldMan.bitfieldLength;
memcpy(bitfield, bitfieldMan.bitfield, bitfieldLength);
memcpy(useBitfield, bitfieldMan.useBitfield, bitfieldLength);
filterEnabled = bitfieldMan.filterEnabled; filterEnabled = bitfieldMan.filterEnabled;
if(bitfieldLength != bitfieldMan.bitfieldLength) {
delete [] filterBitfield; delete [] bitfield;
filterBitfield = 0; bitfield = new unsigned char[bitfieldLength];
} memcpy(bitfield, bitfieldMan.bitfield, bitfieldLength);
if(bitfieldMan.filterBitfield) {
if(!filterBitfield) { delete [] useBitfield;
filterBitfield = new unsigned char[bitfieldLength]; useBitfield = new unsigned char[bitfieldLength];
} memcpy(useBitfield, bitfieldMan.useBitfield, bitfieldLength);
delete [] filterBitfield;
if(filterEnabled) {
filterBitfield = new unsigned char[bitfieldLength];
memcpy(filterBitfield, bitfieldMan.filterBitfield, bitfieldLength); memcpy(filterBitfield, bitfieldMan.filterBitfield, bitfieldLength);
} else {
filterBitfield = 0;
} }
} }
return *this; return *this;

View File

@ -57,9 +57,7 @@ public:
delete [] msg; delete [] msg;
} }
enum ID_t { static const uint8_t ID = 17;
ID = 17
};
void setIndex(int32_t index) { void setIndex(int32_t index) {
this->index = index; this->index = index;
@ -68,7 +66,7 @@ public:
static BtAllowedFastMessageHandle create(const unsigned char* data, uint32_t dataLength); static BtAllowedFastMessageHandle create(const unsigned char* data, uint32_t dataLength);
virtual uint8_t getId() const { return ID; } virtual uint8_t getId() { return ID; }
virtual void doReceivedAction(); virtual void doReceivedAction();

View File

@ -72,9 +72,7 @@ public:
delete [] msg; delete [] msg;
} }
enum ID_t { static const uint8_t ID = 5;
ID = 5
};
void setBitfield(const unsigned char* bitfield, uint32_t bitfieldLength); void setBitfield(const unsigned char* bitfield, uint32_t bitfieldLength);
@ -84,7 +82,7 @@ public:
static BtBitfieldMessageHandle create(const unsigned char* data, uint32_t dataLength); static BtBitfieldMessageHandle create(const unsigned char* data, uint32_t dataLength);
virtual uint8_t getId() const { return ID; } virtual uint8_t getId() { return ID; }
virtual void doReceivedAction(); virtual void doReceivedAction();

View File

@ -61,9 +61,7 @@ public:
delete [] msg; delete [] msg;
} }
enum ID_t { static const uint8_t ID = 8;
ID = 8
};
int32_t getIndex() const { return index; } int32_t getIndex() const { return index; }
@ -79,7 +77,7 @@ public:
static BtCancelMessageHandle create(const unsigned char* data, uint32_t dataLength); static BtCancelMessageHandle create(const unsigned char* data, uint32_t dataLength);
virtual uint8_t getId() const { return ID; } virtual uint8_t getId() { return ID; }
virtual void doReceivedAction(); virtual void doReceivedAction();

View File

@ -52,6 +52,7 @@ BtChokeMessageHandle BtChokeMessage::create(const unsigned char* data, uint32_t
void BtChokeMessage::doReceivedAction() { void BtChokeMessage::doReceivedAction() {
peer->peerChoking = true; peer->peerChoking = true;
BT_MESSAGE_DISPATCHER(btContext, peer)->doChokedAction(); BT_MESSAGE_DISPATCHER(btContext, peer)->doChokedAction();
BT_REQUEST_FACTORY(btContext, peer)->doChokedAction();
} }
bool BtChokeMessage::sendPredicate() const { bool BtChokeMessage::sendPredicate() const {

View File

@ -53,11 +53,9 @@ public:
delete [] msg; delete [] msg;
} }
enum ID_t { static const uint8_t ID = 0;
ID = 0
};
virtual uint8_t getId() const { return ID; } virtual uint8_t getId() { return ID; }
virtual void doReceivedAction(); virtual void doReceivedAction();

View File

@ -73,7 +73,9 @@ public:
delete [] peerId; delete [] peerId;
} }
virtual uint8_t getId() const { return UINT8_MAX; } static const uint8_t ID = UINT8_MAX;
virtual uint8_t getId() { return ID; }
virtual void doReceivedAction() {}; virtual void doReceivedAction() {};

View File

@ -53,13 +53,11 @@ public:
delete [] msg; delete [] msg;
} }
enum ID_t { static const uint8_t ID = 14;
ID = 14
};
static BtHaveAllMessageHandle create(const unsigned char* data, uint32_t dataLength); static BtHaveAllMessageHandle create(const unsigned char* data, uint32_t dataLength);
virtual uint8_t getId() const { return ID; } virtual uint8_t getId() { return ID; }
virtual void doReceivedAction(); virtual void doReceivedAction();

View File

@ -53,9 +53,7 @@ public:
delete [] msg; delete [] msg;
} }
enum ID_t { static const uint8_t ID = 4;
ID = 4
};
void setIndex(int32_t index) { void setIndex(int32_t index) {
this->index = index; this->index = index;
@ -65,7 +63,7 @@ public:
static BtHaveMessageHandle create(const unsigned char* data, uint32_t dataLength); static BtHaveMessageHandle create(const unsigned char* data, uint32_t dataLength);
virtual uint8_t getId() const { return ID; } virtual uint8_t getId() { return ID; }
virtual void doReceivedAction(); virtual void doReceivedAction();

View File

@ -53,13 +53,11 @@ public:
delete [] msg; delete [] msg;
} }
enum ID_t { static const uint8_t ID = 15;
ID = 15
};
static BtHaveNoneMessageHandle create(const unsigned char* data, uint32_t dataLength); static BtHaveNoneMessageHandle create(const unsigned char* data, uint32_t dataLength);
virtual uint8_t getId() const { return ID; } virtual uint8_t getId() { return ID; }
virtual void doReceivedAction(); virtual void doReceivedAction();

View File

@ -53,13 +53,11 @@ public:
delete [] msg; delete [] msg;
} }
enum ID_t { static const uint8_t ID = 2;
ID = 2
};
static BtInterestedMessageHandle create(const unsigned char* data, uint32_t dataLength); static BtInterestedMessageHandle create(const unsigned char* data, uint32_t dataLength);
virtual uint8_t getId() const { return ID; } virtual uint8_t getId() { return ID; }
virtual void doReceivedAction(); virtual void doReceivedAction();

View File

@ -53,11 +53,9 @@ public:
delete [] msg; delete [] msg;
} }
enum ID_t { static const uint8_t ID = 99;
ID = 99
};
virtual uint8_t getId() const { return ID; } virtual uint8_t getId() { return ID; }
virtual void doReceivedAction() {} virtual void doReceivedAction() {}

View File

@ -53,13 +53,11 @@ public:
delete [] msg; delete [] msg;
} }
enum ID_t { static const uint8_t ID = 3;
ID = 3
};
static BtNotInterestedMessageHandle create(const unsigned char* data, uint32_t dataLength); static BtNotInterestedMessageHandle create(const unsigned char* data, uint32_t dataLength);
virtual uint8_t getId() const { return ID; } virtual uint8_t getId() { return ID; }
virtual void doReceivedAction(); virtual void doReceivedAction();

View File

@ -81,6 +81,10 @@ void BtPieceMessage::doReceivedAction() {
blockLength, blockLength,
offset); offset);
piece->completeBlock(slot.getBlockIndex()); piece->completeBlock(slot.getBlockIndex());
logger->debug("CUID#%d - Piece bitfield %s",
cuid,
Util::toHex(piece->getBitfield(),
piece->getBitfieldLength()).c_str());
BT_MESSAGE_DISPATCHER(btContext, peer)->removeOutstandingRequest(slot); BT_MESSAGE_DISPATCHER(btContext, peer)->removeOutstandingRequest(slot);
if(piece->pieceComplete()) { if(piece->pieceComplete()) {
if(checkPieceHash(piece)) { if(checkPieceHash(piece)) {

View File

@ -112,9 +112,7 @@ public:
delete [] block; delete [] block;
} }
enum ID_t { static const uint8_t ID = 7;
ID = 7
};
int32_t getIndex() const { return index; } int32_t getIndex() const { return index; }
@ -134,7 +132,7 @@ public:
static BtPieceMessageHandle create(const unsigned char* data, uint32_t dataLength); static BtPieceMessageHandle create(const unsigned char* data, uint32_t dataLength);
virtual uint8_t getId() const { return ID; } virtual uint8_t getId() { return ID; }
virtual void doReceivedAction(); virtual void doReceivedAction();

View File

@ -49,15 +49,13 @@ public:
virtual ~BtPortMessage() {} virtual ~BtPortMessage() {}
enum ID_t { static const uint8_t ID = 9;
ID = 9
};
uint16_t getPort() const { return port; } uint16_t getPort() const { return port; }
void setPort(uint16_t port) { this->port = port; } void setPort(uint16_t port) { this->port = port; }
virtual uint8_t getId() const { return ID; } virtual uint8_t getId() { return ID; }
static BtPortMessageHandle create(const unsigned char* data, uint32_t dataLength); static BtPortMessageHandle create(const unsigned char* data, uint32_t dataLength);

View File

@ -59,9 +59,7 @@ public:
delete [] msg; delete [] msg;
} }
enum ID_t { static const uint8_t ID = 16;
ID = 16
};
int32_t getIndex() const { return index; } int32_t getIndex() const { return index; }
void setIndex(int32_t index) { this->index = index; } void setIndex(int32_t index) { this->index = index; }
@ -74,7 +72,7 @@ public:
static BtRejectMessageHandle create(const unsigned char* data, uint32_t dataLength); static BtRejectMessageHandle create(const unsigned char* data, uint32_t dataLength);
virtual uint8_t getId() const { return ID; } virtual uint8_t getId() { return ID; }
virtual void doReceivedAction(); virtual void doReceivedAction();

View File

@ -53,6 +53,8 @@ public:
virtual void removeCompletedPiece() = 0; virtual void removeCompletedPiece() = 0;
virtual void doChokedAction() = 0;
/** /**
* Creates RequestMessage objects associated to the pieces added by * Creates RequestMessage objects associated to the pieces added by
* addTargetPiece() and returns them. * addTargetPiece() and returns them.

View File

@ -84,9 +84,7 @@ public:
delete [] msg; delete [] msg;
} }
enum ID_t { static const uint8_t ID = 6;
ID = 6
};
int32_t getIndex() const { return index; } int32_t getIndex() const { return index; }
void setIndex(int32_t index) { this->index = index; } void setIndex(int32_t index) { this->index = index; }
@ -102,7 +100,7 @@ public:
static BtRequestMessageHandle create(const unsigned char* data, uint32_t dataLength); static BtRequestMessageHandle create(const unsigned char* data, uint32_t dataLength);
virtual uint8_t getId() const { return ID; } virtual uint8_t getId() { return ID; }
virtual void doReceivedAction(); virtual void doReceivedAction();

View File

@ -53,9 +53,7 @@ public:
delete [] msg; delete [] msg;
} }
enum ID_t { static const uint8_t ID = 13;
ID = 13
};
void setIndex(int32_t index) { void setIndex(int32_t index) {
this->index = index; this->index = index;
@ -65,7 +63,7 @@ public:
static BtSuggestPieceMessageHandle create(const unsigned char* data, uint32_t dataLength); static BtSuggestPieceMessageHandle create(const unsigned char* data, uint32_t dataLength);
virtual uint8_t getId() const { return ID; } virtual uint8_t getId() { return ID; }
virtual void doReceivedAction() { virtual void doReceivedAction() {
// TODO Current implementation ignores this message. // TODO Current implementation ignores this message.

View File

@ -52,13 +52,11 @@ public:
delete [] msg; delete [] msg;
} }
enum ID_t { static const uint8_t ID = 1;
ID = 1
};
static BtUnchokeMessageHandle create(const unsigned char* data, uint32_t dataLength); static BtUnchokeMessageHandle create(const unsigned char* data, uint32_t dataLength);
virtual uint8_t getId() const { return ID; } virtual uint8_t getId() { return ID; }
virtual void doReceivedAction(); virtual void doReceivedAction();

View File

@ -44,6 +44,7 @@ ByteArrayDiskWriter::~ByteArrayDiskWriter() {
void ByteArrayDiskWriter::clear() { void ByteArrayDiskWriter::clear() {
delete [] buf; delete [] buf;
buf = 0;
} }
void ByteArrayDiskWriter::init() { void ByteArrayDiskWriter::init() {

View File

@ -1,149 +0,0 @@
/* <!-- 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 "CompactTrackerResponseProcessor.h"
#include "LogFactory.h"
#include "TorrentDownloadEngine.h"
#include "MetaFileUtil.h"
#include "DlAbortEx.h"
#include "message.h"
#include "PeerInitiateConnectionCommand.h"
#include <netinet/in.h>
CompactTrackerResponseProcessor::CompactTrackerResponseProcessor(ByteArrayDiskWriter* diskWriter, TorrentDownloadEngine* e, Request* req):
diskWriter(diskWriter),
e(e),
req(req) {
logger = LogFactory::getInstance();
}
CompactTrackerResponseProcessor::~CompactTrackerResponseProcessor() {}
void CompactTrackerResponseProcessor::resetTrackerResponse() {
if(e->segmentMan->finished()) {
diskWriter->reset();
e->segmentMan->init();
}
}
void CompactTrackerResponseProcessor::execute() {
MetaEntry* entry = NULL;
try {
entry = MetaFileUtil::bdecoding(diskWriter->getByteArray(),
diskWriter->getByteArrayLength());
Dictionary* response = (Dictionary*)entry;
Data* failureReason = (Data*)response->get("failure reason");
if(failureReason != NULL) {
throw new DlAbortEx("Tracker returned failure reason: %s", failureReason->toString().c_str());
}
Data* warningMessage = (Data*)response->get("warning message");
if(warningMessage != NULL) {
logger->warn(MSG_TRACKER_WARNING_MESSAGE, warningMessage->toString().c_str());
}
Data* trackerId = (Data*)response->get("tracker id");
if(trackerId != NULL) {
e->torrentMan->trackerId = trackerId->toString();
logger->debug("Tracker ID:%s", e->torrentMan->trackerId.c_str());
}
Data* interval = (Data*)response->get("interval");
if(interval != NULL) {
e->torrentMan->interval = interval->toInt();
logger->debug("interval:%d", e->torrentMan->interval);
}
Data* minInterval = (Data*)response->get("min interval");
if(minInterval != NULL) {
e->torrentMan->minInterval = minInterval->toInt();
logger->debug("min interval:%d", e->torrentMan->minInterval);
}
if(e->torrentMan->minInterval > e->torrentMan->interval) {
e->torrentMan->minInterval = e->torrentMan->interval;
}
Data* complete = (Data*)response->get("complete");
if(complete != NULL) {
e->torrentMan->complete = complete->toInt();
logger->debug("complete:%d", e->torrentMan->complete);
}
Data* incomplete = (Data*)response->get("incomplete");
if(incomplete != NULL) {
e->torrentMan->incomplete = incomplete->toInt();
logger->debug("incomplete:%d", e->torrentMan->incomplete);
}
Data* peers = (Data*)response->get("peers");
if(peers != NULL) {
for(int i = 0; i < peers->getLen(); i += 6) {
unsigned int ipaddr1 = (unsigned char)*(peers->getData()+i);
unsigned int ipaddr2 = (unsigned char)*(peers->getData()+i+1);
unsigned int ipaddr3 = (unsigned char)*(peers->getData()+i+2);
unsigned int ipaddr4 = (unsigned char)*(peers->getData()+i+3);
unsigned int port = ntohs(*(unsigned short int*)(peers->getData()+i+4));
char ipaddr[16];
snprintf(ipaddr, sizeof(ipaddr), "%d.%d.%d.%d",
ipaddr1, ipaddr2, ipaddr3, ipaddr4);
Peer* peer = new Peer(ipaddr, port, e->torrentMan->pieceLength,
e->torrentMan->getTotalLength());
if(e->torrentMan->addPeer(peer)) {
logger->debug("adding peer %s:%d", peer->ipaddr.c_str(), peer->port);
} else {
delete peer;
}
}
} else {
logger->info("no peer list received.");
}
while(e->torrentMan->isPeerAvailable() &&
e->torrentMan->connections < MAX_PEER_UPDATE) {
Peer* peer = e->torrentMan->getPeer();
int newCuid = e->torrentMan->getNewCuid();
peer->cuid = newCuid;
PeerInitiateConnectionCommand* command = new PeerInitiateConnectionCommand(newCuid, peer, e);
e->commands.push(command);
logger->debug("adding new command CUID#%d", newCuid);
}
if(req->getTrackerEvent() == Request::STARTED) {
req->setTrackerEvent(Request::AUTO);
}
} catch(Exception* err) {
logger->error("Error occurred while processing tracker response.", err);
delete(err);
}
if(entry != NULL) {
delete entry;
}
e->torrentMan->trackers = 0;
}
bool CompactTrackerResponseProcessor::isFeeded() const {
return e->segmentMan->finished();
}

View File

@ -43,13 +43,13 @@ private:
string topDir; string topDir;
void fixFilename(); void fixFilename();
protected:
virtual string getFilePath();
public: public:
CopyDiskAdaptor() {} CopyDiskAdaptor() {}
virtual ~CopyDiskAdaptor() {} virtual ~CopyDiskAdaptor() {}
virtual string getFilePath();
virtual void onDownloadComplete(); virtual void onDownloadComplete();
// tempFilename is relative to storeDir // tempFilename is relative to storeDir

View File

@ -75,6 +75,7 @@ void DefaultBtInteractive::doPostHandshakeProcessing() {
floodingCheckPoint.reset(); floodingCheckPoint.reset();
addBitfieldMessageToQueue(); addBitfieldMessageToQueue();
addAllowedFastMessageToQueue(); addAllowedFastMessageToQueue();
sendPendingMessage();
} }
void DefaultBtInteractive::addBitfieldMessageToQueue() { void DefaultBtInteractive::addBitfieldMessageToQueue() {
@ -142,10 +143,8 @@ void DefaultBtInteractive::checkHave() {
void DefaultBtInteractive::sendKeepAlive() { void DefaultBtInteractive::sendKeepAlive() {
if(keepAliveCheckPoint.elapsed(option->getAsInt(PREF_BT_KEEP_ALIVE_INTERVAL))) { if(keepAliveCheckPoint.elapsed(option->getAsInt(PREF_BT_KEEP_ALIVE_INTERVAL))) {
if(dispatcher->countMessageInQueue() == 0) { dispatcher->addMessageToQueue(BT_MESSAGE_FACTORY(btContext, peer)->createKeepAliveMessage());
dispatcher->addMessageToQueue(BT_MESSAGE_FACTORY(btContext, peer)->createKeepAliveMessage()); dispatcher->sendMessages();
dispatcher->sendMessages();
}
keepAliveCheckPoint.reset(); keepAliveCheckPoint.reset();
} }
} }
@ -187,27 +186,26 @@ void DefaultBtInteractive::receiveMessages() {
} }
void DefaultBtInteractive::decideInterest() { void DefaultBtInteractive::decideInterest() {
if(!pieceStorage->hasMissingPiece(peer)) { if(pieceStorage->hasMissingPiece(peer)) {
if(peer->amInterested) {
logger->debug("CUID#%d - Not interested in the peer", cuid);
dispatcher->
addMessageToQueue(BT_MESSAGE_FACTORY(btContext, peer)->
createNotInterestedMessage());
}
} else {
if(!peer->amInterested) { if(!peer->amInterested) {
logger->debug("CUID#%d - Interested in the peer", cuid); logger->debug("CUID#%d - Interested in the peer", cuid);
dispatcher-> dispatcher->
addMessageToQueue(BT_MESSAGE_FACTORY(btContext, peer)-> addMessageToQueue(BT_MESSAGE_FACTORY(btContext, peer)->
createInterestedMessage()); createInterestedMessage());
} }
} else {
if(peer->amInterested) {
logger->debug("CUID#%d - Not interested in the peer", cuid);
dispatcher->
addMessageToQueue(BT_MESSAGE_FACTORY(btContext, peer)->
createNotInterestedMessage());
}
} }
} }
void DefaultBtInteractive::fillPiece(int maxPieceNum) { void DefaultBtInteractive::fillPiece(int maxPieceNum) {
if(pieceStorage->hasMissingPiece(peer)) { if(pieceStorage->hasMissingPiece(peer)) {
if(peer->peerChoking) { if(peer->peerChoking) {
dispatcher->doChokedAction();
if(peer->isFastExtensionEnabled()) { if(peer->isFastExtensionEnabled()) {
while(btRequestFactory->countTargetPiece() < maxPieceNum) { while(btRequestFactory->countTargetPiece() < maxPieceNum) {
PieceHandle piece = pieceStorage->getMissingFastPiece(peer); PieceHandle piece = pieceStorage->getMissingFastPiece(peer);

View File

@ -129,14 +129,18 @@ void DefaultBtMessageDispatcher::doChokedAction()
for(RequestSlots::iterator itr = requestSlots.begin(); for(RequestSlots::iterator itr = requestSlots.begin();
itr != requestSlots.end();) { itr != requestSlots.end();) {
RequestSlot& slot = *itr; RequestSlot& slot = *itr;
logger->debug("CUID#%d - Deleting request slot index=%d, blockIndex=%d" if(peer->isInPeerAllowedIndexSet(slot.getIndex())) {
" because localhost got choked.", itr++;
cuid, } else {
slot.getIndex(), logger->debug("CUID#%d - Deleting request slot index=%d, blockIndex=%d"
slot.getBlockIndex()); " because localhost got choked.",
PieceHandle piece = pieceStorage->getPiece(slot.getIndex()); cuid,
piece->cancelBlock(slot.getBlockIndex()); slot.getIndex(),
itr = requestSlots.erase(itr); slot.getBlockIndex());
PieceHandle piece = pieceStorage->getPiece(slot.getIndex());
piece->cancelBlock(slot.getBlockIndex());
itr = requestSlots.erase(itr);
}
} }
BtChokedEventHandle event = new BtChokedEvent(); BtChokedEventHandle event = new BtChokedEvent();

View File

@ -54,6 +54,20 @@ void DefaultBtRequestFactory::removeTargetPiece(const PieceHandle& piece) {
pieceStorage->cancelPiece(piece); pieceStorage->cancelPiece(piece);
} }
void DefaultBtRequestFactory::doChokedAction()
{
Pieces temp;
for(Pieces::iterator itr = pieces.begin(); itr != pieces.end(); itr++) {
PieceHandle& piece = *itr;
if(peer->isInPeerAllowedIndexSet(piece->getIndex())) {
temp.push_back(piece);
} else {
pieceStorage->cancelPiece(*itr);
}
}
pieces = temp;
}
void DefaultBtRequestFactory::removeAllTargetPiece() { void DefaultBtRequestFactory::removeAllTargetPiece() {
for(Pieces::iterator itr = pieces.begin(); itr != pieces.end(); itr++) { for(Pieces::iterator itr = pieces.begin(); itr != pieces.end(); itr++) {
dispatcher->doAbortOutstandingRequestAction(*itr); dispatcher->doAbortOutstandingRequestAction(*itr);

View File

@ -82,6 +82,8 @@ public:
virtual void removeCompletedPiece(); virtual void removeCompletedPiece();
virtual void doChokedAction();
virtual BtMessages createRequestMessages(uint32_t max); virtual BtMessages createRequestMessages(uint32_t max);
virtual BtMessages createRequestMessagesOnEndGame(uint32_t max); virtual BtMessages createRequestMessagesOnEndGame(uint32_t max);

View File

@ -60,7 +60,7 @@ void DefaultDiskWriter::initAndOpenFile(const string& filename,
fileAllocator->allocate(fd, totalLength); fileAllocator->allocate(fd, totalLength);
} }
} }
} catch(Exception *e) { } catch(RecoverableException *e) {
throw new DlAbortEx(e, EX_FILE_WRITE, filename.c_str(), strerror(errno)); throw new DlAbortEx(e, EX_FILE_WRITE, filename.c_str(), strerror(errno));
} }
} }

View File

@ -38,12 +38,12 @@
#include "AbstractSingleDiskAdaptor.h" #include "AbstractSingleDiskAdaptor.h"
class DirectDiskAdaptor : public AbstractSingleDiskAdaptor { class DirectDiskAdaptor : public AbstractSingleDiskAdaptor {
protected:
virtual string getFilePath();
public: public:
DirectDiskAdaptor() {}; DirectDiskAdaptor() {};
virtual ~DirectDiskAdaptor() {}; virtual ~DirectDiskAdaptor() {};
virtual string getFilePath();
virtual void onDownloadComplete(); virtual void onDownloadComplete();
}; };

View File

@ -64,6 +64,10 @@ public:
virtual void onDownloadComplete() = 0; virtual void onDownloadComplete() = 0;
virtual bool fileExists() = 0;
virtual string getFilePath() = 0;
void setFileEntries(const FileEntries& fileEntries) { void setFileEntries(const FileEntries& fileEntries) {
this->fileEntries = fileEntries; this->fileEntries = fileEntries;
} }

View File

@ -34,20 +34,20 @@
/* copyright --> */ /* copyright --> */
#ifndef _D_DL_ABORT_EX_H_ #ifndef _D_DL_ABORT_EX_H_
#define _D_DL_ABORT_EX_H_ #define _D_DL_ABORT_EX_H_
#include "Exception.h" #include "RecoverableException.h"
class DlAbortEx:public Exception { class DlAbortEx : public RecoverableException {
public: public:
DlAbortEx(Exception* cause = 0):Exception(cause) {} DlAbortEx(Exception* cause = 0):RecoverableException(cause) {}
DlAbortEx(const char* msg, ...):Exception() { DlAbortEx(const char* msg, ...) {
va_list ap; va_list ap;
va_start(ap, msg); va_start(ap, msg);
setMsg(string(msg), ap); setMsg(string(msg), ap);
va_end(ap); va_end(ap);
} }
DlAbortEx(Exception* cause, const char* msg, ...):Exception(cause) { DlAbortEx(Exception* cause, const char* msg, ...):RecoverableException(cause) {
va_list ap; va_list ap;
va_start(ap, msg); va_start(ap, msg);
setMsg(string(msg), ap); setMsg(string(msg), ap);

View File

@ -34,20 +34,20 @@
/* copyright --> */ /* copyright --> */
#ifndef _D_DL_RETRY_EX_H_ #ifndef _D_DL_RETRY_EX_H_
#define _D_DL_RETRY_EX_H_ #define _D_DL_RETRY_EX_H_
#include "Exception.h" #include "RecoverableException.h"
class DlRetryEx:public Exception { class DlRetryEx : public RecoverableException {
public: public:
DlRetryEx(Exception* cause = 0):Exception(cause) {} DlRetryEx(Exception* cause = 0):RecoverableException(cause) {}
DlRetryEx(const char* msg, ...):Exception() { DlRetryEx(const char* msg, ...) {
va_list ap; va_list ap;
va_start(ap, msg); va_start(ap, msg);
setMsg(msg, ap); setMsg(msg, ap);
va_end(ap); va_end(ap);
} }
DlRetryEx(Exception* cause, const char* msg, ...):Exception(cause) { DlRetryEx(Exception* cause, const char* msg, ...):RecoverableException(cause) {
va_list ap; va_list ap;
va_start(ap, msg); va_start(ap, msg);
setMsg(msg, ap); setMsg(msg, ap);

View File

@ -130,13 +130,6 @@ DownloadEngineFactory::newTorrentConsoleEngine(const BtContextHandle& btContext,
te->setBtContext(btContext); te->setBtContext(btContext);
// initialize file storage // initialize file storage
pieceStorage->initStorage(); pieceStorage->initStorage();
if(btProgressInfoFile->exists()) {
// load .aria2 file if it exists.
btProgressInfoFile->load();
pieceStorage->getDiskAdaptor()->openExistingFile();
} else {
pieceStorage->getDiskAdaptor()->initAndOpenFile();
}
Integers selectIndexes; Integers selectIndexes;
Util::unfoldRange(op->get(PREF_SELECT_FILE), selectIndexes); Util::unfoldRange(op->get(PREF_SELECT_FILE), selectIndexes);

View File

@ -49,7 +49,7 @@ protected:
Exception* cause; Exception* cause;
void setMsg(const string& msgsrc, va_list ap) { void setMsg(const string& msgsrc, va_list ap) {
char buf[256]; char buf[1024];
vsnprintf(buf, sizeof(buf), msgsrc.c_str(), ap); vsnprintf(buf, sizeof(buf), msgsrc.c_str(), ap);
msg = buf; msg = buf;
} }

58
src/FatalException.h Normal file
View File

@ -0,0 +1,58 @@
/* <!-- 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_FATAL_EXCEPTION_H_
#define _D_FATAL_EXCEPTION_H_
#include "Exception.h"
class FatalException : public Exception {
public:
FatalException(Exception* cause = 0):Exception(cause) {}
FatalException(const char* msg, ...):Exception() {
va_list ap;
va_start(ap, msg);
setMsg(string(msg), ap);
va_end(ap);
}
FatalException(Exception* cause, const char* msg, ...):Exception(cause) {
va_list ap;
va_start(ap, msg);
setMsg(string(msg), ap);
va_end(ap);
}
};
#endif // _D_FATAL_EXCEPTION_EX_H_

View File

@ -59,8 +59,9 @@ void FileAllocator::allocate(int fd, uint64_t totalLength)
throw new DlAbortEx("Allocation failed: %s", strerror(errno)); throw new DlAbortEx("Allocation failed: %s", strerror(errno));
} }
if(cp.elapsedInMillis(500)) { if(cp.elapsedInMillis(500)) {
fileAllocationMonitor->setCurrentValue(x*bufSize); fileAllocationMonitor->setCurrentValue(i*bufSize);
fileAllocationMonitor->showProgress(); fileAllocationMonitor->showProgress();
cp.reset();
} }
} }
fileAllocationMonitor->setCurrentValue(totalLength); fileAllocationMonitor->setCurrentValue(totalLength);

View File

@ -39,6 +39,7 @@
#include "message.h" #include "message.h"
#include "prefs.h" #include "prefs.h"
#include "Util.h" #include "Util.h"
#include "FatalException.h"
FtpNegotiationCommand::FtpNegotiationCommand(int cuid, const RequestHandle req, FtpNegotiationCommand::FtpNegotiationCommand(int cuid, const RequestHandle req,
DownloadEngine* e, DownloadEngine* e,
@ -188,6 +189,11 @@ bool FtpNegotiationCommand::recvSize() {
e->segmentMan->totalSize); e->segmentMan->totalSize);
e->segmentMan->filename = Util::urldecode(req->getFile()); e->segmentMan->filename = Util::urldecode(req->getFile());
if(e->segmentMan->shouldCancelDownloadForSafety()) {
throw new FatalException(EX_FILE_ALREADY_EXISTS,
e->segmentMan->getFilePath().c_str(),
e->segmentMan->getSegmentFilePath().c_str());
}
bool segFileExists = e->segmentMan->segmentFileExists(); bool segFileExists = e->segmentMan->segmentFileExists();
if(segFileExists) { if(segFileExists) {
e->segmentMan->load(); e->segmentMan->load();

View File

@ -40,6 +40,8 @@
#include "message.h" #include "message.h"
#include "Util.h" #include "Util.h"
#include "prefs.h" #include "prefs.h"
#include "File.h"
#include "FatalException.h"
#include <sys/types.h> #include <sys/types.h>
#include <unistd.h> #include <unistd.h>
@ -159,6 +161,11 @@ bool HttpResponseCommand::handleDefaultEncoding(const HttpHeader& headers) {
// send request again to the server with Range header // send request again to the server with Range header
return prepareForRetry(0); return prepareForRetry(0);
} else { } else {
if(e->segmentMan->shouldCancelDownloadForSafety()) {
throw new FatalException(EX_FILE_ALREADY_EXISTS,
e->segmentMan->getFilePath().c_str(),
e->segmentMan->getSegmentFilePath().c_str());
}
e->segmentMan->totalSize = size; e->segmentMan->totalSize = size;
e->segmentMan->initBitfield(e->option->getAsInt(PREF_SEGMENT_SIZE), e->segmentMan->initBitfield(e->option->getAsInt(PREF_SEGMENT_SIZE),
e->segmentMan->totalSize); e->segmentMan->totalSize);

View File

@ -30,6 +30,8 @@ SRCS = Socket.h\
common.h\ common.h\
message.h\ message.h\
Exception.h\ Exception.h\
FatalException.h\
RecoverableException.h\
DlAbortEx.h\ DlAbortEx.h\
DlRetryEx.h\ DlRetryEx.h\
Logger.h\ Logger.h\
@ -187,9 +189,9 @@ libaria2c_a_SOURCES = $(SRCS)
aria2c_LDADD = libaria2c.a @LIBINTL@ @ALLOCA@ @LIBGNUTLS_LIBS@\ aria2c_LDADD = libaria2c.a @LIBINTL@ @ALLOCA@ @LIBGNUTLS_LIBS@\
@LIBGCRYPT_LIBS@ @OPENSSL_LIBS@ @XML_LIBS@ @LIBARES_LIBS@\ @LIBGCRYPT_LIBS@ @OPENSSL_LIBS@ @XML_LIBS@ @LIBARES_LIBS@\
@LIBCARES_LIBS@ @LIBCARES_LIBS@
#aria2c_LDFLAGS = -pg aria2c_LDFLAGS = -pg
AM_CPPFLAGS = -Wall\ AM_CPPFLAGS = -Wall\
-I../lib -I../intl -I$(top_srcdir)/intl\ -I../lib -I../intl -I$(top_srcdir)/intl\
@LIBGNUTLS_CFLAGS@ @LIBGCRYPT_CFLAGS@ @OPENSSL_CFLAGS@ @XML_CPPFLAGS@\ @LIBGNUTLS_CFLAGS@ @LIBGCRYPT_CFLAGS@ @OPENSSL_CFLAGS@ @XML_CPPFLAGS@\
@LIBARES_CPPFLAGS@ @LIBCARES_CPPFLAGS@\ @LIBARES_CPPFLAGS@ @LIBCARES_CPPFLAGS@\
-D_FILE_OFFSET_BITS=64 -DLOCALEDIR=\"$(localedir)\" @DEFS@ # -pg -D_FILE_OFFSET_BITS=64 -DLOCALEDIR=\"$(localedir)\" @DEFS@ -pg

View File

@ -196,18 +196,18 @@ am__libaria2c_a_SOURCES_DIST = Socket.h SocketCore.cc SocketCore.h \
DownloadEngine.cc DownloadEngine.h ConsoleDownloadEngine.cc \ DownloadEngine.cc DownloadEngine.h ConsoleDownloadEngine.cc \
ConsoleDownloadEngine.h Segment.cc Segment.h SegmentMan.cc \ ConsoleDownloadEngine.h Segment.cc Segment.h SegmentMan.cc \
SegmentMan.h Util.cc Util.h Request.cc Request.h common.h \ SegmentMan.h Util.cc Util.h Request.cc Request.h common.h \
message.h Exception.h DlAbortEx.h DlRetryEx.h Logger.h \ message.h Exception.h FatalException.h RecoverableException.h \
SimpleLogger.cc SimpleLogger.h TransferEncoding.h \ DlAbortEx.h DlRetryEx.h Logger.h SimpleLogger.cc \
ChunkedEncoding.cc ChunkedEncoding.h DiskWriter.h \ SimpleLogger.h TransferEncoding.h ChunkedEncoding.cc \
AbstractDiskWriter.cc AbstractDiskWriter.h \ ChunkedEncoding.h DiskWriter.h AbstractDiskWriter.cc \
DefaultDiskWriter.cc DefaultDiskWriter.h File.cc File.h \ AbstractDiskWriter.h DefaultDiskWriter.cc DefaultDiskWriter.h \
Option.cc Option.h Base64.cc Base64.h CookieBox.cc CookieBox.h \ File.cc File.h Option.cc Option.h Base64.cc Base64.h \
messageDigest.h LogFactory.cc LogFactory.h NullLogger.h \ CookieBox.cc CookieBox.h messageDigest.h LogFactory.cc \
TimeA2.cc TimeA2.h SharedHandle.h HandleRegistry.h \ LogFactory.h NullLogger.h TimeA2.cc TimeA2.h SharedHandle.h \
FeatureConfig.cc FeatureConfig.h DownloadEngineFactory.cc \ HandleRegistry.h FeatureConfig.cc FeatureConfig.h \
DownloadEngineFactory.h RequestInfo.h UrlRequestInfo.cc \ DownloadEngineFactory.cc DownloadEngineFactory.h RequestInfo.h \
UrlRequestInfo.h SpeedCalc.cc SpeedCalc.h PeerStat.h \ UrlRequestInfo.cc UrlRequestInfo.h SpeedCalc.cc SpeedCalc.h \
BitfieldMan.cc BitfieldMan.h BitfieldManFactory.cc \ PeerStat.h BitfieldMan.cc BitfieldMan.h BitfieldManFactory.cc \
BitfieldManFactory.h Randomizer.h SimpleRandomizer.cc \ BitfieldManFactory.h Randomizer.h SimpleRandomizer.cc \
SimpleRandomizer.h FileAllocator.cc FileAllocator.h \ SimpleRandomizer.h FileAllocator.cc FileAllocator.h \
FileAllocationMonitor.cc FileAllocationMonitor.h \ FileAllocationMonitor.cc FileAllocationMonitor.h \
@ -566,18 +566,18 @@ SRCS = Socket.h SocketCore.cc SocketCore.h Command.cc Command.h \
DownloadEngine.cc DownloadEngine.h ConsoleDownloadEngine.cc \ DownloadEngine.cc DownloadEngine.h ConsoleDownloadEngine.cc \
ConsoleDownloadEngine.h Segment.cc Segment.h SegmentMan.cc \ ConsoleDownloadEngine.h Segment.cc Segment.h SegmentMan.cc \
SegmentMan.h Util.cc Util.h Request.cc Request.h common.h \ SegmentMan.h Util.cc Util.h Request.cc Request.h common.h \
message.h Exception.h DlAbortEx.h DlRetryEx.h Logger.h \ message.h Exception.h FatalException.h RecoverableException.h \
SimpleLogger.cc SimpleLogger.h TransferEncoding.h \ DlAbortEx.h DlRetryEx.h Logger.h SimpleLogger.cc \
ChunkedEncoding.cc ChunkedEncoding.h DiskWriter.h \ SimpleLogger.h TransferEncoding.h ChunkedEncoding.cc \
AbstractDiskWriter.cc AbstractDiskWriter.h \ ChunkedEncoding.h DiskWriter.h AbstractDiskWriter.cc \
DefaultDiskWriter.cc DefaultDiskWriter.h File.cc File.h \ AbstractDiskWriter.h DefaultDiskWriter.cc DefaultDiskWriter.h \
Option.cc Option.h Base64.cc Base64.h CookieBox.cc CookieBox.h \ File.cc File.h Option.cc Option.h Base64.cc Base64.h \
messageDigest.h LogFactory.cc LogFactory.h NullLogger.h \ CookieBox.cc CookieBox.h messageDigest.h LogFactory.cc \
TimeA2.cc TimeA2.h SharedHandle.h HandleRegistry.h \ LogFactory.h NullLogger.h TimeA2.cc TimeA2.h SharedHandle.h \
FeatureConfig.cc FeatureConfig.h DownloadEngineFactory.cc \ HandleRegistry.h FeatureConfig.cc FeatureConfig.h \
DownloadEngineFactory.h RequestInfo.h UrlRequestInfo.cc \ DownloadEngineFactory.cc DownloadEngineFactory.h RequestInfo.h \
UrlRequestInfo.h SpeedCalc.cc SpeedCalc.h PeerStat.h \ UrlRequestInfo.cc UrlRequestInfo.h SpeedCalc.cc SpeedCalc.h \
BitfieldMan.cc BitfieldMan.h BitfieldManFactory.cc \ PeerStat.h BitfieldMan.cc BitfieldMan.h BitfieldManFactory.cc \
BitfieldManFactory.h Randomizer.h SimpleRandomizer.cc \ BitfieldManFactory.h Randomizer.h SimpleRandomizer.cc \
SimpleRandomizer.h FileAllocator.cc FileAllocator.h \ SimpleRandomizer.h FileAllocator.cc FileAllocator.h \
FileAllocationMonitor.cc FileAllocationMonitor.h \ FileAllocationMonitor.cc FileAllocationMonitor.h \
@ -589,12 +589,12 @@ aria2c_LDADD = libaria2c.a @LIBINTL@ @ALLOCA@ @LIBGNUTLS_LIBS@\
@LIBGCRYPT_LIBS@ @OPENSSL_LIBS@ @XML_LIBS@ @LIBARES_LIBS@\ @LIBGCRYPT_LIBS@ @OPENSSL_LIBS@ @XML_LIBS@ @LIBARES_LIBS@\
@LIBCARES_LIBS@ @LIBCARES_LIBS@
#aria2c_LDFLAGS = -pg aria2c_LDFLAGS = -pg
AM_CPPFLAGS = -Wall\ AM_CPPFLAGS = -Wall\
-I../lib -I../intl -I$(top_srcdir)/intl\ -I../lib -I../intl -I$(top_srcdir)/intl\
@LIBGNUTLS_CFLAGS@ @LIBGCRYPT_CFLAGS@ @OPENSSL_CFLAGS@ @XML_CPPFLAGS@\ @LIBGNUTLS_CFLAGS@ @LIBGCRYPT_CFLAGS@ @OPENSSL_CFLAGS@ @XML_CPPFLAGS@\
@LIBARES_CPPFLAGS@ @LIBCARES_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 all: all-am

View File

@ -57,7 +57,7 @@ MetaEntry* MetaFileUtil::parseMetaFile(const string& file) {
MetaEntry* entry = bdecoding(buf, len); MetaEntry* entry = bdecoding(buf, len);
delete [] buf; delete [] buf;
return entry; return entry;
} catch(Exception* ex) { } catch(RecoverableException* ex) {
delete [] buf; delete [] buf;
if(fp != NULL) { if(fp != NULL) {
fclose(fp); fclose(fp);
@ -121,7 +121,7 @@ Dictionary* MetaFileUtil::parseDictionaryTree(const char** pp, const char* end)
dic->put(name, e); dic->put(name, e);
} }
return dic; return dic;
} catch(Exception* ex) { } catch(RecoverableException* ex) {
delete dic; delete dic;
throw; throw;
} }
@ -142,7 +142,7 @@ List* MetaFileUtil::parseListTree(const char** pp, const char* end) {
lis->add(e); lis->add(e);
} }
return lis; return lis;
} catch(Exception* ex) { } catch(RecoverableException* ex) {
delete lis; delete lis;
throw; throw;
} }

View File

@ -125,7 +125,7 @@ RequestInfos MetalinkRequestInfo::execute() {
reqInfo->setChecksum(checksum); reqInfo->setChecksum(checksum);
nextReqInfos.push_front(reqInfo); nextReqInfos.push_front(reqInfo);
} }
} catch(Exception* ex) { } catch(RecoverableException* ex) {
logger->error("Exception caught", ex); logger->error("Exception caught", ex);
delete ex; delete ex;
fail = true; fail = true;

View File

@ -117,7 +117,7 @@ void MultiDiskAdaptor::writeData(const unsigned char* data, uint32_t len,
writing = true; writing = true;
fileOffset = 0; fileOffset = 0;
} else { } else {
fileOffset -= (*itr)->fileEntry->getLength(); fileOffset -= (*itr)->getFileEntry()->getLength();
} }
} }
if(!writing) { if(!writing) {
@ -128,8 +128,8 @@ void MultiDiskAdaptor::writeData(const unsigned char* data, uint32_t len,
bool MultiDiskAdaptor::isInRange(const DiskWriterEntryHandle entry, bool MultiDiskAdaptor::isInRange(const DiskWriterEntryHandle entry,
int64_t offset) const int64_t offset) const
{ {
return entry->fileEntry->getOffset() <= offset && return entry->getFileEntry()->getOffset() <= offset &&
offset < entry->fileEntry->getOffset()+entry->fileEntry->getLength(); offset < entry->getFileEntry()->getOffset()+entry->getFileEntry()->getLength();
} }
uint32_t MultiDiskAdaptor::calculateLength(const DiskWriterEntryHandle entry, uint32_t MultiDiskAdaptor::calculateLength(const DiskWriterEntryHandle entry,
@ -137,8 +137,8 @@ uint32_t MultiDiskAdaptor::calculateLength(const DiskWriterEntryHandle entry,
uint32_t rem) const uint32_t rem) const
{ {
uint32_t length; uint32_t length;
if(entry->fileEntry->getLength() < fileOffset+rem) { if(entry->getFileEntry()->getLength() < fileOffset+rem) {
length = entry->fileEntry->getLength()-fileOffset; length = entry->getFileEntry()->getLength()-fileOffset;
} else { } else {
length = rem; length = rem;
} }
@ -160,7 +160,7 @@ int MultiDiskAdaptor::readData(unsigned char* data, uint32_t len, int64_t offset
reading = true; reading = true;
fileOffset = 0; fileOffset = 0;
} else { } else {
fileOffset -= (*itr)->fileEntry->getLength(); fileOffset -= (*itr)->getFileEntry()->getLength();
} }
} }
if(!reading) { if(!reading) {
@ -205,7 +205,7 @@ string MultiDiskAdaptor::sha1Sum(int64_t offset, uint64_t length) {
reading = true; reading = true;
fileOffset = 0; fileOffset = 0;
} else { } else {
fileOffset -= (*itr)->fileEntry->getLength(); fileOffset -= (*itr)->getFileEntry()->getLength();
} }
} }
if(!reading) { if(!reading) {
@ -215,3 +215,14 @@ string MultiDiskAdaptor::sha1Sum(int64_t offset, uint64_t length) {
ctx.digestFinal(hashValue); ctx.digestFinal(hashValue);
return Util::toHex(hashValue, 20); return Util::toHex(hashValue, 20);
} }
bool MultiDiskAdaptor::fileExists()
{
for(DiskWriterEntries::iterator itr = diskWriterEntries.begin();
itr != diskWriterEntries.end(); itr++) {
if((*itr)->fileExists(getTopDirPath())) {
return true;
}
}
return false;
}

View File

@ -39,11 +39,11 @@
#include "Option.h" #include "Option.h"
#include "DiskWriter.h" #include "DiskWriter.h"
#include "messageDigest.h" #include "messageDigest.h"
#include "File.h"
class DiskWriterEntry { class DiskWriterEntry {
public:
FileEntryHandle fileEntry;
private: private:
FileEntryHandle fileEntry;
DiskWriterHandle diskWriter; DiskWriterHandle diskWriter;
public: public:
DiskWriterEntry(const FileEntryHandle& fileEntry): DiskWriterEntry(const FileEntryHandle& fileEntry):
@ -77,6 +77,15 @@ public:
diskWriter->closeFile(); diskWriter->closeFile();
} }
bool fileExists(const string& topDir)
{
return File(getFilePath(topDir)).exists();
}
FileEntryHandle getFileEntry() const {
return fileEntry;
}
void setDiskWriter(const DiskWriterHandle& diskWriter) { void setDiskWriter(const DiskWriterHandle& diskWriter) {
this->diskWriter = diskWriter; this->diskWriter = diskWriter;
} }
@ -139,6 +148,12 @@ public:
virtual string sha1Sum(int64_t offset, uint64_t length); virtual string sha1Sum(int64_t offset, uint64_t length);
virtual bool fileExists();
virtual string getFilePath() {
return getTopDirPath();
}
void setTopDir(const string& topDir) { void setTopDir(const string& topDir) {
this->topDir = topDir; this->topDir = topDir;
} }

View File

@ -77,7 +77,7 @@ bool PeerAbstractCommand::execute() {
throw new DlRetryEx(EX_TIME_OUT); throw new DlRetryEx(EX_TIME_OUT);
} }
return executeInternal(); return executeInternal();
} catch(Exception* err) { } catch(RecoverableException* err) {
logger->error(MSG_DOWNLOAD_ABORTED, err, cuid); logger->error(MSG_DOWNLOAD_ABORTED, err, cuid);
logger->debug("CUID#%d - Peer %s:%d banned.", logger->debug("CUID#%d - Peer %s:%d banned.",
cuid, peer->ipaddr.c_str(), peer->port); cuid, peer->ipaddr.c_str(), peer->port);
@ -96,7 +96,7 @@ bool PeerAbstractCommand::prepareForRetry(int wait) {
return true; return true;
} }
void PeerAbstractCommand::onAbort(Exception* ex) { void PeerAbstractCommand::onAbort(RecoverableException* ex) {
if(peer->isSeeder()) { if(peer->isSeeder()) {
peer->error++; peer->error++;
} else { } else {

View File

@ -39,6 +39,7 @@
#include "Request.h" #include "Request.h"
#include "TorrentDownloadEngine.h" #include "TorrentDownloadEngine.h"
#include "TimeA2.h" #include "TimeA2.h"
#include "RecoverableException.h"
class PeerAbstractCommand : public BtContextAwareCommand { class PeerAbstractCommand : public BtContextAwareCommand {
private: private:
@ -52,7 +53,7 @@ protected:
void setTimeout(int timeout) { this->timeout = timeout; } void setTimeout(int timeout) { this->timeout = timeout; }
virtual bool prepareForNextPeer(int wait); virtual bool prepareForNextPeer(int wait);
virtual bool prepareForRetry(int wait); virtual bool prepareForRetry(int wait);
virtual void onAbort(Exception* ex); virtual void onAbort(RecoverableException* ex);
virtual bool executeInternal() = 0; virtual bool executeInternal() = 0;
void setReadCheckSocket(const SocketHandle& socket); void setReadCheckSocket(const SocketHandle& socket);
void setWriteCheckSocket(const SocketHandle& socket); void setWriteCheckSocket(const SocketHandle& socket);

View File

@ -93,6 +93,9 @@ bool PeerConnection::receiveMessage(unsigned char* data, uint32_t& dataLength) {
} }
currentPayloadLength = payloadLength; currentPayloadLength = payloadLength;
} }
if(!socket->isReadable(0)) {
return false;
}
// we have currentPayloadLen-resbufLen bytes to read // we have currentPayloadLen-resbufLen bytes to read
uint32_t remaining = currentPayloadLength-resbufLength; uint32_t remaining = currentPayloadLength-resbufLength;
if(remaining > 0) { if(remaining > 0) {

View File

@ -204,7 +204,7 @@ bool PeerInteractionCommand::prepareForRetry(int wait) {
return false; return false;
} }
void PeerInteractionCommand::onAbort(Exception* ex) { void PeerInteractionCommand::onAbort(RecoverableException* ex) {
btInteractive->cancelAllPiece(); btInteractive->cancelAllPiece();
PeerAbstractCommand::onAbort(ex); PeerAbstractCommand::onAbort(ex);
} }

View File

@ -43,10 +43,10 @@ private:
int sequence; int sequence;
BtInteractiveHandle btInteractive; BtInteractiveHandle btInteractive;
protected: protected:
bool executeInternal(); virtual bool executeInternal();
bool prepareForRetry(int wait); virtual bool prepareForRetry(int wait);
bool prepareForNextPeer(int wait); virtual bool prepareForNextPeer(int wait);
void onAbort(Exception* ex); virtual void onAbort(RecoverableException* ex);
public: public:
PeerInteractionCommand(int cuid, PeerInteractionCommand(int cuid,
const PeerHandle& peer, const PeerHandle& peer,

View File

@ -53,7 +53,7 @@ int PeerListenCommand::bindPort(int portRangeStart, int portRangeEnd) {
logger->info("CUID#%d - using port %d for accepting new connections", logger->info("CUID#%d - using port %d for accepting new connections",
cuid, port); cuid, port);
return port; return port;
} catch(Exception* ex) { } catch(RecoverableException* ex) {
logger->error("CUID#%d - an error occurred while binding port=%d", logger->error("CUID#%d - an error occurred while binding port=%d",
ex, cuid, port); ex, cuid, port);
socket->closeConnection(); socket->closeConnection();
@ -92,7 +92,7 @@ bool PeerListenCommand::execute() {
logger->debug("CUID#%d - incoming connection, adding new command CUID#%d", cuid, newCuid); logger->debug("CUID#%d - incoming connection, adding new command CUID#%d", cuid, newCuid);
} }
} }
} catch(Exception* ex) { } catch(RecoverableException* ex) {
logger->error("CUID#%d - error in accepting connection", ex, cuid); logger->error("CUID#%d - error in accepting connection", ex, cuid);
delete ex; delete ex;
} }

View File

@ -105,6 +105,10 @@ public:
const unsigned char* getBitfield() const { return bitfield->getBitfield(); } const unsigned char* getBitfield() const { return bitfield->getBitfield(); }
void setBitfield(const unsigned char* bitfield, int len); void setBitfield(const unsigned char* bitfield, int len);
int getBitfieldLength() const {
return bitfield->getBitfieldLength();
}
void clearAllBlock(); void clearAllBlock();
void setAllBlock(); void setAllBlock();

View File

@ -32,31 +32,27 @@
* files in the program, then also delete it here. * files in the program, then also delete it here.
*/ */
/* copyright --> */ /* copyright --> */
#ifndef _D_COMPACT_TRACKER_RESPONSE_PROCESSOR_H_ #ifndef _D_RECOVERABLE_EXCEPTION_H_
#define _D_COMPACT_TRACKER_RESPONSE_PROCESSOR_H_ #define _D_RECOVERABLE_EXCEPTION_H_
#include "Exception.h"
#include "common.h" class RecoverableException : public Exception {
#include "ByteArrayDiskWriter.h"
#include "Request.h"
class TorrentDownloadEngine;
class Logger;
class CompactTrackerResponseProcessor {
private:
ByteArrayDiskWriter* diskWriter;
TorrentDownloadEngine* e;
Request* req;
const Logger* logger;
public: public:
CompactTrackerResponseProcessor(ByteArrayDiskWriter* diskWriter, RecoverableException(Exception* cause = 0):Exception(cause) {}
TorrentDownloadEngine* e,
Request* req);
~CompactTrackerResponseProcessor();
bool isFeeded() const; RecoverableException(const char* msg, ...):Exception() {
void execute(); va_list ap;
void resetTrackerResponse(); va_start(ap, msg);
setMsg(string(msg), ap);
va_end(ap);
}
RecoverableException(Exception* cause, const char* msg, ...):Exception(cause) {
va_list ap;
va_start(ap, msg);
setMsg(string(msg), ap);
va_end(ap);
}
}; };
#endif // _D_COMPACT_TRACKER_RESPONSE_PROCESSOR_H_ #endif // _D_RECOVERABLE_EXCEPTION_EX_H_

View File

@ -61,7 +61,7 @@ void RequestSlot::setDispatchedTime(time_t secFromEpoch) {
} }
bool RequestSlot::isTimeout(time_t timeoutSec) const { bool RequestSlot::isTimeout(time_t timeoutSec) const {
return dispatchedTime.differenceInMillis() > timeoutSec*1000; return dispatchedTime.elapsed(timeoutSec);
} }
int RequestSlot::getLatencyInMillis() const { int RequestSlot::getLatencyInMillis() const {

View File

@ -474,3 +474,12 @@ int SegmentMan::calculateDownloadSpeed() const {
} }
return speed; return speed;
} }
bool SegmentMan::fileExists() {
return File(getFilePath()).exists();
}
bool SegmentMan::shouldCancelDownloadForSafety() {
return fileExists() && !segmentFileExists() &&
option->get(PREF_FORCE_TRUNCATE) != V_TRUE;
}

View File

@ -255,6 +255,11 @@ public:
* Returns current download speed in bytes per sec. * Returns current download speed in bytes per sec.
*/ */
int calculateDownloadSpeed() const; int calculateDownloadSpeed() const;
bool fileExists();
bool shouldCancelDownloadForSafety();
}; };
#endif // _D_SEGMENT_MAN_H_ #endif // _D_SEGMENT_MAN_H_

View File

@ -38,6 +38,9 @@
#include "Util.h" #include "Util.h"
#include "BtRegistry.h" #include "BtRegistry.h"
#include "DefaultBtContext.h" #include "DefaultBtContext.h"
#include "FatalException.h"
#include "message.h"
#include "RecoverableException.h"
extern volatile sig_atomic_t btHaltRequested; extern volatile sig_atomic_t btHaltRequested;
@ -60,6 +63,21 @@ RequestInfos TorrentRequestInfo::execute() {
op, op,
targetFiles)); targetFiles));
if(BT_PROGRESS_INFO_FILE(btContext)->exists()) {
// load .aria2 file if it exists.
BT_PROGRESS_INFO_FILE(btContext)->load();
PIECE_STORAGE(btContext)->getDiskAdaptor()->openExistingFile();
} else {
if(PIECE_STORAGE(btContext)->getDiskAdaptor()->fileExists() &&
op->get(PREF_FORCE_TRUNCATE) != 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()->initAndOpenFile();
}
}
Util::setGlobalSignalHandler(SIGINT, torrentHandler, SA_RESETHAND); Util::setGlobalSignalHandler(SIGINT, torrentHandler, SA_RESETHAND);
Util::setGlobalSignalHandler(SIGTERM, torrentHandler, SA_RESETHAND); Util::setGlobalSignalHandler(SIGTERM, torrentHandler, SA_RESETHAND);
@ -68,7 +86,7 @@ RequestInfos TorrentRequestInfo::execute() {
if(PIECE_STORAGE(btContext)->downloadFinished()) { if(PIECE_STORAGE(btContext)->downloadFinished()) {
printDownloadCompeleteMessage(); printDownloadCompeleteMessage();
} }
} catch(Exception* ex) { } catch(RecoverableException* ex) {
logger->error("Exception caught", ex); logger->error("Exception caught", ex);
fail = true; fail = true;
delete ex; delete ex;

View File

@ -74,7 +74,7 @@ char* TrackerUpdateCommand::getTrackerResponse(size_t& trackerResponseLength) {
} }
trackerResponseLength = bufLength; trackerResponseLength = bufLength;
return buf; return buf;
} catch(Exception* e) { } catch(RecoverableException* e) {
delete [] buf; delete [] buf;
throw; throw;
} }
@ -113,7 +113,7 @@ bool TrackerUpdateCommand::execute() {
btAnnounce->announceSuccess(); btAnnounce->announceSuccess();
btAnnounce->resetAnnounce(); btAnnounce->resetAnnounce();
e->segmentMan->init(); e->segmentMan->init();
} catch(Exception* err) { } catch(RecoverableException* err) {
logger->error("CUID#%d - Error occurred while processing tracker response.", cuid, err); logger->error("CUID#%d - Error occurred while processing tracker response.", cuid, err);
e->segmentMan->errors++; e->segmentMan->errors++;
delete err; delete err;

View File

@ -37,6 +37,7 @@
#include "MetalinkRequestInfo.h" #include "MetalinkRequestInfo.h"
#include "prefs.h" #include "prefs.h"
#include "DownloadEngineFactory.h" #include "DownloadEngineFactory.h"
#include "RecoverableException.h"
extern volatile sig_atomic_t haltRequested; extern volatile sig_atomic_t haltRequested;
@ -140,7 +141,7 @@ RequestInfos UrlRequestInfo::execute() {
e->segmentMan->diskWriter->closeFile(); e->segmentMan->diskWriter->closeFile();
printDownloadAbortMessage(); printDownloadAbortMessage();
} }
} catch(Exception *ex) { } catch(RecoverableException *ex) {
logger->error("Exception caught", ex); logger->error("Exception caught", ex);
delete ex; delete ex;
fail = true; fail = true;

View File

@ -244,7 +244,9 @@ string Util::urlencode(const unsigned char* target, int len) {
string Util::torrentUrlencode(const unsigned char* target, int len) { string Util::torrentUrlencode(const unsigned char* target, int len) {
string dest; string dest;
for(int i = 0; i < len; i++) { for(int i = 0; i < len; i++) {
if(isalpha(target[i]) || isdigit(target[i])) { if('0' <= target[i] && target[i] <= '9' ||
'A' <= target[i] && target[i] <= 'Z' ||
'a' <= target[i] && target[i] <= 'z') {
dest += target[i]; dest += target[i];
} else { } else {
char temp[4]; char temp[4];
@ -339,7 +341,7 @@ void Util::rangedFileCopy(const string& dest, const string& src, long long int s
close(destFd); close(destFd);
srcFd = -1; srcFd = -1;
destFd = -1; destFd = -1;
} catch(Exception* e) { } catch(RecoverableException* e) {
if(srcFd != -1) { if(srcFd != -1) {
close(srcFd); close(srcFd);
} }

View File

@ -176,6 +176,12 @@ void showUsage() {
" This may take some time depending on the size of\n" " This may take some time depending on the size of\n"
" file.\n" " file.\n"
" Default: 'none'") << endl; " 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: false") << endl;
#ifdef ENABLE_BITTORRENT #ifdef ENABLE_BITTORRENT
cout << _(" -T, --torrent-file=TORRENT_FILE The file path to .torrent file.") << endl; 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" cout << _(" --follow-torrent=true|false Setting this option to false prevents aria2 to\n"
@ -337,6 +343,7 @@ int main(int argc, char* argv[]) {
op->put(PREF_STARTUP_IDLE_TIME, "10"); op->put(PREF_STARTUP_IDLE_TIME, "10");
op->put(PREF_TRACKER_MAX_TRIES, "10"); op->put(PREF_TRACKER_MAX_TRIES, "10");
op->put(PREF_FILE_ALLOCATION, V_NONE); op->put(PREF_FILE_ALLOCATION, V_NONE);
op->put(PREF_FORCE_TRUNCATE, V_FALSE);
while(1) { while(1) {
int optIndex = 0; int optIndex = 0;
int lopt; int lopt;
@ -366,6 +373,7 @@ int main(int argc, char* argv[]) {
{ "lowest-speed-limit", required_argument, &lopt, 200 }, { "lowest-speed-limit", required_argument, &lopt, 200 },
{ "max-download-limit", required_argument, &lopt, 201 }, { "max-download-limit", required_argument, &lopt, 201 },
{ "file-allocation", required_argument, 0, 'a' }, { "file-allocation", required_argument, 0, 'a' },
{ "force-truncate", required_argument, &lopt, 202 },
#ifdef ENABLE_BITTORRENT #ifdef ENABLE_BITTORRENT
{ "torrent-file", required_argument, NULL, 'T' }, { "torrent-file", required_argument, NULL, 'T' },
{ "listen-port", required_argument, &lopt, 15 }, { "listen-port", required_argument, &lopt, 15 },
@ -616,6 +624,17 @@ int main(int argc, char* argv[]) {
op->put(PREF_MAX_DOWNLOAD_LIMIT, Util::itos(limit)); op->put(PREF_MAX_DOWNLOAD_LIMIT, Util::itos(limit));
break; break;
} }
case 202: {
if(string(optarg) == "true") {
op->put(PREF_FORCE_TRUNCATE, V_TRUE);
} else if(string(optarg) == "false") {
op->put(PREF_FORCE_TRUNCATE, V_FALSE);
} else {
cerr << _("force-true must be either 'true' or 'false'.") << endl;
showUsage();
exit(EXIT_FAILURE);
}
}
} }
break; break;
} }

View File

@ -111,5 +111,6 @@
#define EX_SOCKET_SEND _("Failed to send data, cause: %s") #define EX_SOCKET_SEND _("Failed to send data, cause: %s")
#define EX_SOCKET_RECV _("Failed to receive 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_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.")
#endif // _D_MESSAGE_H_ #endif // _D_MESSAGE_H_

View File

@ -84,6 +84,8 @@
// value: prealloc | none // value: prealloc | none
#define PREF_FILE_ALLOCATION "file_allocation" #define PREF_FILE_ALLOCATION "file_allocation"
# define V_PREALLOC "prealloc" # define V_PREALLOC "prealloc"
// value: true | false
#define PREF_FORCE_TRUNCATE "force_truncate"
/** /**
* FTP related preferences * FTP related preferences