mirror of https://github.com/aria2/aria2
* Request.h: Added AFTER_COMPLETED event.
* TorrentDownloadEngine.cc: Prints "Download complete" message instead of downloaded size and progress(%) after download completes. * PeerInteractionCommand.cc: After download completes, sends unchoke message to the peer if it is interested in what localhost has downloaded. * TorrentMan.cc: In single-file mode, copy temporary file to the final destination instead of just renaming it. * TorrentMan.cc: Added deleteTempFile(). * PeerAbstractCommand.cc: do not stop execution after download completes. This makes localhost a seeder. * Util.{h,cc}: Added fileCopy(). * PeerListenCommand.cc: do not stop execution after download completes. This makes localhost a seeder. * main.cc: Do not call TorrentMan::fixFilename() in torrentHandler. Added TorrentMan::deleteTempFile() to torrentHandler. Initialized the variable dir as ".". * TorrentMan.h: Changed DEFAULT_ANNOUNCE_INTERVAL to 120 seconds. Deleted renameSingleFile(). Added copySingleFile(), deleteTempFile(). * DownloadEngine.h: Added virtual function afterEachIteration(). * TorrentDownloadEngine.cc: Move a call to TorrentMan::fixFilename() in onEndOfRun() to afterEachIteration(). In onEndOfRun(), changed if condition to check whether filenameFixed is true. * Util.cc: Implemented fileCopy() using rangedFileCopy(). In rangedFileCopy(), added try-catch block to properly close file descriptors. * TorrentDownloadEngine.cc: Added a member variable filenameFixed. Added afterEachIteration(), isFilenameFixed(). * Peer.cc: Changed choking strategy. * PreAllocationDiskWriter.cc: Drop O_DIRECT flag. * TrackerInitCommand.cc: Send completed event only once. * DownloadEngine.cc: Added a call to afterEachIteration(). * TrackerUpdateCommand.cc: Do not stop execution after download completes. * TorrentMan.h: Defined MAX_PEER_UPDATE as 15. aria2 attempts to connect the peers at most MAX_PEER_UPDATE when a peer list is received from a tracker. * TrackerUpdateCommand.cc: Implemented above mentioned behavior. Decreased the number of failure peers to delete to 0(just comment out the line). * Release 0.3.1pull/1/head
parent
be44f3a736
commit
2065b049ab
49
ChangeLog
49
ChangeLog
|
@ -1,3 +1,49 @@
|
|||
2006-03-24 Tatsuhiro Tsujikawa <tujikawa at rednoah dot com>
|
||||
|
||||
* Request.h: Added AFTER_COMPLETED event.
|
||||
* TorrentDownloadEngine.cc: Prints "Download complete" message
|
||||
instead of downloaded size and progress(%) after download completes.
|
||||
* PeerInteractionCommand.cc: After download completes, sends unchoke
|
||||
message to the peer if it is interested in what localhost has
|
||||
downloaded.
|
||||
* TorrentMan.cc: In single-file mode, copy temporary file to the final
|
||||
destination instead of just renaming it.
|
||||
* TorrentMan.cc: Added deleteTempFile().
|
||||
* PeerAbstractCommand.cc: do not stop execution after download
|
||||
completes. This makes localhost a seeder.
|
||||
* Util.{h,cc}: Added fileCopy().
|
||||
* PeerListenCommand.cc: do not stop execution after download completes.
|
||||
This makes localhost a seeder.
|
||||
* main.cc: Do not call TorrentMan::fixFilename() in torrentHandler.
|
||||
Added TorrentMan::deleteTempFile() to torrentHandler.
|
||||
Initialized the variable dir as ".".
|
||||
* TorrentMan.h: Changed DEFAULT_ANNOUNCE_INTERVAL to 120 seconds.
|
||||
Deleted renameSingleFile().
|
||||
Added copySingleFile(), deleteTempFile().
|
||||
* DownloadEngine.h: Added virtual function afterEachIteration().
|
||||
* TorrentDownloadEngine.cc: Move a call to TorrentMan::fixFilename()
|
||||
in onEndOfRun() to afterEachIteration().
|
||||
In onEndOfRun(), changed if condition to check whether filenameFixed is
|
||||
true.
|
||||
* Util.cc: Implemented fileCopy() using rangedFileCopy().
|
||||
In rangedFileCopy(), added try-catch block to properly close file
|
||||
descriptors.
|
||||
* TorrentDownloadEngine.cc: Added a member variable filenameFixed.
|
||||
Added afterEachIteration(), isFilenameFixed().
|
||||
* Peer.cc: Changed choking strategy.
|
||||
* PreAllocationDiskWriter.cc: Drop O_DIRECT flag.
|
||||
* TrackerInitCommand.cc: Send completed event only once.
|
||||
* DownloadEngine.cc: Added a call to afterEachIteration().
|
||||
* TrackerUpdateCommand.cc: Do not stop execution after download
|
||||
completes.
|
||||
* TorrentMan.h: Defined MAX_PEER_UPDATE as 15. aria2 attempts to
|
||||
connect the peers at most MAX_PEER_UPDATE when a peer list is
|
||||
received from a tracker.
|
||||
* TrackerUpdateCommand.cc: Implemented above mentioned behavior.
|
||||
Decreased the number of failure peers to delete to 0(just comment out
|
||||
the line).
|
||||
* Release 0.3.1
|
||||
|
||||
2006-03-23 Tatsuhiro Tsujikawa <tujikawa at rednoah dot com>
|
||||
|
||||
* PeerInteractionCommand.cc: added a call to
|
||||
|
@ -34,7 +80,8 @@
|
|||
2006-03-22 Tatsuhiro Tsujikawa <tujikawa at rednoah dot com>
|
||||
|
||||
* BitTorrent protocol support added.
|
||||
|
||||
* Release 0.3.0
|
||||
|
||||
2006-03-17 Tatsuhiro Tsujikawa <tujikawa at rednoah dot com>
|
||||
|
||||
* SocketCore.cc: remove the assignment of addrinfo.ai_addr.
|
||||
|
|
3
README
3
README
|
@ -50,6 +50,9 @@ multi-file mode:
|
|||
The directory to store the top directory of downloaded files can be
|
||||
specified by -d option.
|
||||
|
||||
In both mode, aria2 needs at least 2 times more disk space than the file size
|
||||
itself because it creates complete temporary file.
|
||||
|
||||
Note:
|
||||
* -o option is used to change the filename of downloaded .torrent file.
|
||||
* This version only supports compact peers list format.
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
#! /bin/sh
|
||||
# Guess values for system-dependent variables and create Makefiles.
|
||||
# Generated by GNU Autoconf 2.59 for aria2c 0.3.0.
|
||||
# Generated by GNU Autoconf 2.59 for aria2c 0.3.1.
|
||||
#
|
||||
# Report bugs to <tujikawa@rednoah.com>.
|
||||
#
|
||||
|
@ -269,8 +269,8 @@ SHELL=${CONFIG_SHELL-/bin/sh}
|
|||
# Identity of this package.
|
||||
PACKAGE_NAME='aria2c'
|
||||
PACKAGE_TARNAME='aria2c'
|
||||
PACKAGE_VERSION='0.3.0'
|
||||
PACKAGE_STRING='aria2c 0.3.0'
|
||||
PACKAGE_VERSION='0.3.1'
|
||||
PACKAGE_STRING='aria2c 0.3.1'
|
||||
PACKAGE_BUGREPORT='tujikawa@rednoah.com'
|
||||
|
||||
ac_unique_file="src/Socket.h"
|
||||
|
@ -788,7 +788,7 @@ if test "$ac_init_help" = "long"; then
|
|||
# Omit some internal or obsolete options to make the list less imposing.
|
||||
# This message is too long to be a string in the A/UX 3.1 sh.
|
||||
cat <<_ACEOF
|
||||
\`configure' configures aria2c 0.3.0 to adapt to many kinds of systems.
|
||||
\`configure' configures aria2c 0.3.1 to adapt to many kinds of systems.
|
||||
|
||||
Usage: $0 [OPTION]... [VAR=VALUE]...
|
||||
|
||||
|
@ -854,7 +854,7 @@ fi
|
|||
|
||||
if test -n "$ac_init_help"; then
|
||||
case $ac_init_help in
|
||||
short | recursive ) echo "Configuration of aria2c 0.3.0:";;
|
||||
short | recursive ) echo "Configuration of aria2c 0.3.1:";;
|
||||
esac
|
||||
cat <<\_ACEOF
|
||||
|
||||
|
@ -989,7 +989,7 @@ fi
|
|||
test -n "$ac_init_help" && exit 0
|
||||
if $ac_init_version; then
|
||||
cat <<\_ACEOF
|
||||
aria2c configure 0.3.0
|
||||
aria2c configure 0.3.1
|
||||
generated by GNU Autoconf 2.59
|
||||
|
||||
Copyright (C) 2003 Free Software Foundation, Inc.
|
||||
|
@ -1003,7 +1003,7 @@ cat >&5 <<_ACEOF
|
|||
This file contains any messages produced by compilers while
|
||||
running configure, to aid debugging if configure makes a mistake.
|
||||
|
||||
It was created by aria2c $as_me 0.3.0, which was
|
||||
It was created by aria2c $as_me 0.3.1, which was
|
||||
generated by GNU Autoconf 2.59. Invocation command line was
|
||||
|
||||
$ $0 $@
|
||||
|
@ -1646,7 +1646,7 @@ fi
|
|||
|
||||
# Define the identity of the package.
|
||||
PACKAGE='aria2c'
|
||||
VERSION='0.3.0'
|
||||
VERSION='0.3.1'
|
||||
|
||||
|
||||
cat >>confdefs.h <<_ACEOF
|
||||
|
@ -10971,7 +10971,7 @@ _ASBOX
|
|||
} >&5
|
||||
cat >&5 <<_CSEOF
|
||||
|
||||
This file was extended by aria2c $as_me 0.3.0, which was
|
||||
This file was extended by aria2c $as_me 0.3.1, which was
|
||||
generated by GNU Autoconf 2.59. Invocation command line was
|
||||
|
||||
CONFIG_FILES = $CONFIG_FILES
|
||||
|
@ -11034,7 +11034,7 @@ _ACEOF
|
|||
|
||||
cat >>$CONFIG_STATUS <<_ACEOF
|
||||
ac_cs_version="\\
|
||||
aria2c config.status 0.3.0
|
||||
aria2c config.status 0.3.1
|
||||
configured by $0, generated by GNU Autoconf 2.59,
|
||||
with options \\"`echo "$ac_configure_args" | sed 's/[\\""\`\$]/\\\\&/g'`\\"
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
# Process this file with autoconf to produce a configure script.
|
||||
#
|
||||
AC_PREREQ(2.59)
|
||||
AC_INIT(aria2c, 0.3.0, tujikawa@rednoah.com)
|
||||
AC_INIT(aria2c, 0.3.1, tujikawa@rednoah.com)
|
||||
AM_INIT_AUTOMAKE()
|
||||
AM_PATH_CPPUNIT(1.10.2)
|
||||
AC_CONFIG_SRCDIR([src/Socket.h])
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
# General Public License and is *not* in the public domain.
|
||||
|
||||
PACKAGE = aria2c
|
||||
VERSION = 0.3.0
|
||||
VERSION = 0.3.1
|
||||
|
||||
SHELL = /bin/sh
|
||||
|
||||
|
|
|
@ -47,6 +47,7 @@ void DownloadEngine::run() {
|
|||
delete(com);
|
||||
}
|
||||
}
|
||||
afterEachIteration();
|
||||
shortSleep();
|
||||
if(!noWait && !commands.empty()) {
|
||||
waitData();
|
||||
|
|
|
@ -51,6 +51,7 @@ protected:
|
|||
virtual void initStatistics() = 0;
|
||||
virtual void calculateStatistics() = 0;
|
||||
virtual void onEndOfRun() = 0;
|
||||
virtual void afterEachIteration() {}
|
||||
public:
|
||||
bool noWait;
|
||||
Commands commands;
|
||||
|
|
|
@ -34,16 +34,16 @@ void Peer::updateBitfield(int index, int operation) {
|
|||
#define THRESHOLD 1024*1024*2
|
||||
|
||||
bool Peer::shouldChoke() const {
|
||||
if(bitfield->countBlock()*0.8 < bitfield->countMissingBlock()) {
|
||||
if(bitfield->countBlock()*0.7 < bitfield->countMissingBlock()) {
|
||||
return false;
|
||||
}
|
||||
if(peerDownload < pieceLength*4 && peerUpload < pieceLength*4) {
|
||||
if(peerDownload <= pieceLength*10) {
|
||||
return false;
|
||||
}
|
||||
if(amChocking) {
|
||||
return !(peerDownload+pieceLength*4 < peerUpload);
|
||||
return !(peerDownload+pieceLength*5 < peerUpload);
|
||||
} else {
|
||||
return peerDownload >= peerUpload+pieceLength*4;
|
||||
return peerDownload >= peerUpload+pieceLength*5;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -73,9 +73,6 @@ bool PeerAbstractCommand::isTimeoutDetected() {
|
|||
|
||||
bool PeerAbstractCommand::execute() {
|
||||
try {
|
||||
if(e->torrentMan->downloadComplete()) {
|
||||
return true;
|
||||
}
|
||||
beforeSocketCheck();
|
||||
if(checkSocketIsReadable && !readCheckTarget->isReadable(0)
|
||||
|| checkSocketIsWritable && !writeCheckTarget->isWritable(0)) {
|
||||
|
|
|
@ -124,6 +124,13 @@ void PeerInteractionCommand::syncPiece() {
|
|||
}
|
||||
|
||||
void PeerInteractionCommand::decideChoking() {
|
||||
if(e->torrentMan->downloadComplete()) {
|
||||
if(peer->amChocking && peer->peerInterested) {
|
||||
PendingMessage pendingMessage(PeerMessage::UNCHOKE, peerConnection);
|
||||
pendingMessages.push_back(pendingMessage);
|
||||
}
|
||||
return;
|
||||
}
|
||||
if(peer->shouldChoke()) {
|
||||
if(!peer->amChocking) {
|
||||
PendingMessage pendingMessage(PeerMessage::CHOKE, peerConnection);
|
||||
|
|
|
@ -52,9 +52,6 @@ int PeerListenCommand::bindPort(int portRangeStart, int portRangeEnd) {
|
|||
}
|
||||
|
||||
bool PeerListenCommand::execute() {
|
||||
if(e->torrentMan->downloadComplete()) {
|
||||
return true;
|
||||
}
|
||||
for(int i = 0; i < 3 && socket->isReadable(0); i++) {
|
||||
Socket* peerSocket = NULL;
|
||||
try {
|
||||
|
|
|
@ -34,35 +34,23 @@ PreAllocationDiskWriter::PreAllocationDiskWriter(long long int totalLength)
|
|||
PreAllocationDiskWriter::~PreAllocationDiskWriter() {}
|
||||
|
||||
void PreAllocationDiskWriter::initAndOpenFile(string filename) {
|
||||
createFile(filename, O_DIRECT);
|
||||
createFile(filename);
|
||||
|
||||
int pageSize = getpagesize();
|
||||
int bufSize = pageSize*4;
|
||||
char* buf;
|
||||
int rt = posix_memalign((void**)&buf, pageSize, bufSize);
|
||||
if(rt != 0) {
|
||||
throw new DlAbortEx(strerror(rt));
|
||||
int bufSize = 4096;
|
||||
char buf[4096];
|
||||
|
||||
memset(buf, 0, bufSize);
|
||||
long long int x = totalLength/bufSize;
|
||||
int r = totalLength%bufSize;
|
||||
for(long long int i = 0; i < x; i++) {
|
||||
if(write(fd, buf, bufSize) < 0) {
|
||||
throw new DlAbortEx(strerror(errno));
|
||||
}
|
||||
}
|
||||
try {
|
||||
memset(buf, 0, bufSize);
|
||||
long long int x = totalLength/bufSize;
|
||||
int r = totalLength%bufSize;
|
||||
for(long long int i = 0; i < x; i++) {
|
||||
if(write(fd, buf, bufSize) < 0) {
|
||||
if(r > 0) {
|
||||
seek(totalLength-r);
|
||||
if(write(fd, buf, r) < 0) {
|
||||
throw new DlAbortEx(strerror(errno));
|
||||
}
|
||||
}
|
||||
closeFile();
|
||||
openExistingFile(filename);
|
||||
if(r > 0) {
|
||||
seek(totalLength-r);
|
||||
if(write(fd, buf, r) < 0) {
|
||||
throw new DlAbortEx(strerror(errno));
|
||||
}
|
||||
}
|
||||
free(buf);
|
||||
} catch(Exception* ex) {
|
||||
free(buf);
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -97,7 +97,8 @@ public:
|
|||
AUTO,
|
||||
STARTED,
|
||||
STOPPED,
|
||||
COMPLETED
|
||||
COMPLETED,
|
||||
AFTER_COMPLETED
|
||||
};
|
||||
|
||||
};
|
||||
|
|
|
@ -27,14 +27,19 @@ TorrentConsoleDownloadEngine::TorrentConsoleDownloadEngine() {}
|
|||
TorrentConsoleDownloadEngine::~TorrentConsoleDownloadEngine() {}
|
||||
|
||||
void TorrentConsoleDownloadEngine::printStatistics() {
|
||||
printf("\r ");
|
||||
printf("\r ");
|
||||
printf("\r");
|
||||
printf("%s/%sB %d%% DW:%.2f UP:%.2f(%s) %dpeers",
|
||||
Util::llitos(torrentMan->getDownloadedSize(), true).c_str(),
|
||||
Util::llitos(torrentMan->totalSize, true).c_str(),
|
||||
(torrentMan->totalSize == 0 ?
|
||||
0 : (int)((torrentMan->getDownloadedSize()*100)/torrentMan->totalSize)),
|
||||
downloadSpeed/1000.0,
|
||||
if(torrentMan->downloadComplete()) {
|
||||
printf("Download Completed ");
|
||||
} else {
|
||||
printf("%s/%sB %d%% DW:%.2f",
|
||||
Util::llitos(torrentMan->getDownloadedSize(), true).c_str(),
|
||||
Util::llitos(torrentMan->totalSize, true).c_str(),
|
||||
(torrentMan->totalSize == 0 ?
|
||||
0 : (int)((torrentMan->getDownloadedSize()*100)/torrentMan->totalSize)),
|
||||
downloadSpeed/1000.0);
|
||||
}
|
||||
printf(" UP:%.2f(%s) %dpeers",
|
||||
uploadSpeed/1000.0,
|
||||
Util::llitos(torrentMan->getUploadedSize(), true).c_str(),
|
||||
torrentMan->connections);
|
||||
|
@ -42,15 +47,8 @@ void TorrentConsoleDownloadEngine::printStatistics() {
|
|||
}
|
||||
|
||||
void TorrentConsoleDownloadEngine::initStatistics() {
|
||||
/*
|
||||
gettimeofday(&cp, NULL);
|
||||
*/
|
||||
downloadSpeed = 0;
|
||||
uploadSpeed = 0;
|
||||
/*
|
||||
sessionDownloadSize = 0;
|
||||
sessionUploadSize = 0;
|
||||
*/
|
||||
lastElapsed = 0;
|
||||
gettimeofday(&cp[0], NULL);
|
||||
gettimeofday(&cp[1], NULL);
|
||||
|
@ -61,34 +59,12 @@ void TorrentConsoleDownloadEngine::initStatistics() {
|
|||
currentCp = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
int TorrentConsoleDownloadEngine::calculateSpeed(int deltaSize, long long int elapsed, int prevSpeed) {
|
||||
int nowSpeed = (int)(deltaSize/(elapsed/1000000.0));
|
||||
return (nowSpeed+prevSpeed)/2;
|
||||
}
|
||||
*/
|
||||
int TorrentConsoleDownloadEngine::calculateSpeed(long long int sessionSize, long long int elapsed) {
|
||||
int nowSpeed = (int)(sessionSize/(elapsed/1000000.0));
|
||||
return nowSpeed;
|
||||
}
|
||||
|
||||
void TorrentConsoleDownloadEngine::calculateStatistics() {
|
||||
/*
|
||||
struct timeval now;
|
||||
gettimeofday(&now, NULL);
|
||||
long long int elapsed = Util::difftv(now, cp);
|
||||
sessionDownloadSize += torrentMan->getDeltaDownload();
|
||||
sessionUploadSize += torrentMan->getDeltaUpload();
|
||||
|
||||
downloadSpeed = calculateSpeed(sessionDownloadSize, elapsed);
|
||||
uploadSpeed = calculateSpeed(sessionUploadSize, elapsed);
|
||||
torrentMan->resetDeltaDownload();
|
||||
torrentMan->resetDeltaUpload();
|
||||
if(elapsed-lastElapsed >= 1000000) {
|
||||
printStatistics();
|
||||
lastElapsed = elapsed;
|
||||
}
|
||||
*/
|
||||
struct timeval now;
|
||||
gettimeofday(&now, NULL);
|
||||
long long int elapsed = Util::difftv(now, cp[currentCp]);
|
||||
|
@ -116,17 +92,4 @@ void TorrentConsoleDownloadEngine::calculateStatistics() {
|
|||
lastElapsed = 0;
|
||||
currentCp = currentCp ? 0 : 1;
|
||||
}
|
||||
|
||||
/*
|
||||
if(elapsed >= 1000000) {
|
||||
downloadSpeed = calculateSpeed(torrentMan->getDeltaDownload(),
|
||||
elapsed, downloadSpeed);
|
||||
uploadSpeed = calculateSpeed(torrentMan->getDeltaUpload(),
|
||||
elapsed, uploadSpeed);
|
||||
torrentMan->resetDeltaDownload();
|
||||
torrentMan->resetDeltaUpload();
|
||||
cp = now;
|
||||
printStatistics();
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
|
|
@ -23,10 +23,19 @@
|
|||
|
||||
void TorrentDownloadEngine::onEndOfRun() {
|
||||
torrentMan->diskWriter->closeFile();
|
||||
if(torrentMan->downloadComplete()) {
|
||||
if(filenameFixed && torrentMan->downloadComplete()) {
|
||||
torrentMan->remove();
|
||||
torrentMan->fixFilename();
|
||||
} else {
|
||||
torrentMan->save();
|
||||
}
|
||||
}
|
||||
|
||||
void TorrentDownloadEngine::afterEachIteration() {
|
||||
if(!filenameFixed && torrentMan->downloadComplete()) {
|
||||
torrentMan->diskWriter->closeFile();
|
||||
torrentMan->save();
|
||||
torrentMan->fixFilename();
|
||||
filenameFixed = true;
|
||||
torrentMan->diskWriter->openExistingFile(torrentMan->getTempFilePath());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -26,13 +26,18 @@
|
|||
#include "TorrentMan.h"
|
||||
|
||||
class TorrentDownloadEngine : public DownloadEngine {
|
||||
private:
|
||||
bool filenameFixed;
|
||||
protected:
|
||||
void onEndOfRun();
|
||||
void afterEachIteration();
|
||||
public:
|
||||
TorrentDownloadEngine() {}
|
||||
TorrentDownloadEngine():filenameFixed(false) {}
|
||||
virtual ~TorrentDownloadEngine() {}
|
||||
|
||||
TorrentMan* torrentMan;
|
||||
|
||||
bool isFilenameFixed() const { return filenameFixed; }
|
||||
};
|
||||
|
||||
#endif // _D_TORRENT_DOWNLOAD_ENGINE_H_
|
||||
|
|
|
@ -336,7 +336,6 @@ void TorrentMan::setup(string metaInfoFile) {
|
|||
itr++) {
|
||||
Dictionary* fileDic = (Dictionary*)(*itr);
|
||||
Data* lengthData = (Data*)fileDic->get("length");
|
||||
//length += strtoll(data->toString().c_str(), NULL, 10);
|
||||
length += lengthData->toLLInt();
|
||||
List* path = (List*)fileDic->get("path");
|
||||
const MetaList& paths = path->getList();
|
||||
|
@ -490,25 +489,30 @@ void TorrentMan::remove() const {
|
|||
|
||||
void TorrentMan::fixFilename() const {
|
||||
if(fileMode == SINGLE) {
|
||||
renameSingleFile();
|
||||
copySingleFile();
|
||||
} else {
|
||||
splitMultiFile();
|
||||
}
|
||||
}
|
||||
|
||||
void TorrentMan::renameSingleFile() const {
|
||||
rename(getTempFilePath().c_str(), getFilePath().c_str());
|
||||
void TorrentMan::copySingleFile() const {
|
||||
logger->info("writing file %s", getFilePath().c_str());
|
||||
Util::fileCopy(getFilePath(), getTempFilePath());
|
||||
}
|
||||
|
||||
void TorrentMan::splitMultiFile() const {
|
||||
logger->info("creating directories");
|
||||
multiFileTopDir->createDir(storeDir, true);
|
||||
long long int offset = 0;
|
||||
logger->info("splitting file");
|
||||
for(MultiFileEntries::const_iterator itr = multiFileEntries.begin();
|
||||
itr != multiFileEntries.end(); itr++) {
|
||||
Util::rangedFileCopy(storeDir+"/"+itr->path, getTempFilePath(), offset, itr->length);
|
||||
string dest = storeDir+"/"+itr->path;
|
||||
logger->info("writing file %s", dest.c_str());
|
||||
Util::rangedFileCopy(dest, getTempFilePath(), offset, itr->length);
|
||||
offset += itr->length;
|
||||
}
|
||||
}
|
||||
|
||||
void TorrentMan::deleteTempFile() const {
|
||||
unlink(getTempFilePath().c_str());
|
||||
}
|
||||
|
|
|
@ -42,9 +42,11 @@ using namespace std;
|
|||
|
||||
#define IS_NULL_PIECE(X) (X.index == 0 && X.length == 0)
|
||||
|
||||
#define DEFAULT_ANNOUNCE_INTERVAL 1800
|
||||
#define DEFAULT_ANNOUNCE_INTERVAL 120
|
||||
#define DEFAULT_ANNOUNCE_MIN_INTERVAL 120
|
||||
#define MAX_PEERS 55
|
||||
#define MAX_PEER_UPDATE 15
|
||||
|
||||
#define MAX_PEER_LIST_SIZE 250
|
||||
#define END_GAME_PIECE_NUM 20
|
||||
|
||||
|
@ -203,9 +205,10 @@ public:
|
|||
void save() const;
|
||||
void remove() const;
|
||||
|
||||
void renameSingleFile() const;
|
||||
void copySingleFile() const;
|
||||
void splitMultiFile() const;
|
||||
void fixFilename() const;
|
||||
void deleteTempFile() const;
|
||||
|
||||
void setPort(int port) { this->port = port; }
|
||||
int getPort() const { return port; }
|
||||
|
|
|
@ -31,7 +31,11 @@ TrackerInitCommand::~TrackerInitCommand() {}
|
|||
|
||||
bool TrackerInitCommand::execute() {
|
||||
if(e->torrentMan->downloadComplete()) {
|
||||
req->setTrackerEvent(Request::COMPLETED);
|
||||
if(req->getTrackerEvent() == Request::COMPLETED) {
|
||||
req->setTrackerEvent(Request::AFTER_COMPLETED);
|
||||
} else {
|
||||
req->setTrackerEvent(Request::COMPLETED);
|
||||
}
|
||||
}
|
||||
string event;
|
||||
switch(req->getTrackerEvent()) {
|
||||
|
|
|
@ -40,10 +40,7 @@ TrackerUpdateCommand::~TrackerUpdateCommand() {
|
|||
}
|
||||
|
||||
bool TrackerUpdateCommand::execute() {
|
||||
if(req->getTrackerEvent() == Request::COMPLETED) {
|
||||
return true;
|
||||
}
|
||||
e->torrentMan->deleteOldErrorPeers(25);
|
||||
//e->torrentMan->deleteOldErrorPeers(25);
|
||||
|
||||
Dictionary* response = (Dictionary*)trackerResponse;
|
||||
Data* failureReason = (Data*)response->get("failure reason");
|
||||
|
@ -110,7 +107,7 @@ bool TrackerUpdateCommand::execute() {
|
|||
}
|
||||
*/
|
||||
while(e->torrentMan->isPeerAvailable() &&
|
||||
e->torrentMan->connections < MAX_PEERS) {
|
||||
e->torrentMan->connections < MAX_PEER_UPDATE) {
|
||||
Peer* peer = e->torrentMan->getPeer();
|
||||
int newCuid = e->torrentMan->getNewCuid();
|
||||
peer->cuid = newCuid;
|
||||
|
|
90
src/Util.cc
90
src/Util.cc
|
@ -21,6 +21,7 @@
|
|||
/* copyright --> */
|
||||
#include "Util.h"
|
||||
#include "DlAbortEx.h"
|
||||
#include "File.h"
|
||||
#include <errno.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
|
@ -190,41 +191,58 @@ FILE* Util::openFile(string filename, string mode) {
|
|||
return file;
|
||||
}
|
||||
|
||||
void Util::rangedFileCopy(string dest, string src, long long int srcOffset, long long int length) {
|
||||
int destFd;
|
||||
if((destFd = open(dest.c_str(), O_CREAT|O_WRONLY|O_TRUNC, S_IRUSR|S_IWUSR)) < 0) {
|
||||
throw new DlAbortEx(strerror(errno));
|
||||
}
|
||||
int srcFd;
|
||||
if((srcFd = open(src.c_str(), O_RDONLY, S_IRUSR|S_IWUSR)) < 0) {
|
||||
throw new DlAbortEx(strerror(errno));
|
||||
}
|
||||
if(lseek(srcFd, srcOffset, SEEK_SET) != srcOffset) {
|
||||
throw new DlAbortEx(strerror(errno));
|
||||
}
|
||||
int BUF_SIZE = 16*1024;
|
||||
char buf[BUF_SIZE];
|
||||
int x = length/BUF_SIZE;
|
||||
int r = length%BUF_SIZE;
|
||||
for(int i = 0; i < x; i++) {
|
||||
int readLength;
|
||||
if((readLength = read(srcFd, buf, BUF_SIZE)) == -1 || readLength != BUF_SIZE) {
|
||||
throw new DlAbortEx(strerror(errno));
|
||||
}
|
||||
if(write(destFd, buf, readLength) == -1) {
|
||||
throw new DlAbortEx(strerror(errno));
|
||||
}
|
||||
}
|
||||
if(r > 0) {
|
||||
int readLength;
|
||||
if((readLength = read(srcFd, buf, r)) == -1 || readLength != r) {
|
||||
throw new DlAbortEx(strerror(errno));
|
||||
}
|
||||
if(write(destFd, buf, readLength) == -1) {
|
||||
throw new DlAbortEx(strerror(errno));
|
||||
}
|
||||
}
|
||||
close(srcFd);
|
||||
close(destFd);
|
||||
void Util::fileCopy(string dest, string src) {
|
||||
File file(src);
|
||||
rangedFileCopy(dest, src, 0, file.size());
|
||||
}
|
||||
|
||||
void Util::rangedFileCopy(string dest, string src, long long int srcOffset, long long int length) {
|
||||
int bufSize = 4096;
|
||||
char buf[bufSize];
|
||||
int destFd = -1;
|
||||
int srcFd = -1;
|
||||
try {
|
||||
if((destFd = open(dest.c_str(), O_CREAT|O_WRONLY|O_TRUNC, S_IRUSR|S_IWUSR)) == -1) {
|
||||
throw new DlAbortEx(strerror(errno));
|
||||
}
|
||||
if((srcFd = open(src.c_str(), O_RDONLY, S_IRUSR|S_IWUSR)) == -1) {
|
||||
throw new DlAbortEx(strerror(errno));
|
||||
}
|
||||
if(lseek(srcFd, srcOffset, SEEK_SET) != srcOffset) {
|
||||
throw new DlAbortEx(strerror(errno));
|
||||
}
|
||||
int x = length/bufSize;
|
||||
int r = length%bufSize;
|
||||
for(int i = 0; i < x; i++) {
|
||||
int readLength;
|
||||
if((readLength = read(srcFd, buf, bufSize)) == -1 || readLength != bufSize) {
|
||||
throw new DlAbortEx(strerror(errno));
|
||||
}
|
||||
if(write(destFd, buf, readLength) == -1) {
|
||||
throw new DlAbortEx(strerror(errno));
|
||||
}
|
||||
}
|
||||
if(r > 0) {
|
||||
int readLength;
|
||||
if((readLength = read(srcFd, buf, r)) == -1 || readLength != r) {
|
||||
throw new DlAbortEx(strerror(errno));
|
||||
}
|
||||
if(write(destFd, buf, r) == -1) {
|
||||
throw new DlAbortEx(strerror(errno));
|
||||
}
|
||||
}
|
||||
close(srcFd);
|
||||
close(destFd);
|
||||
srcFd = -1;
|
||||
destFd = -1;
|
||||
} catch(Exception* e) {
|
||||
if(srcFd != -1) {
|
||||
close(srcFd);
|
||||
}
|
||||
if(destFd != -1) {
|
||||
close(destFd);
|
||||
}
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -63,6 +63,8 @@ public:
|
|||
|
||||
static FILE* openFile(string filename, string mode);
|
||||
|
||||
static void fileCopy(string destFile, string src);
|
||||
|
||||
static void rangedFileCopy(string destFile, string src, long long int srcOffset, long long int length);
|
||||
|
||||
};
|
||||
|
|
|
@ -85,9 +85,9 @@ void torrentHandler(int signal) {
|
|||
if(te->torrentMan->diskWriter != NULL) {
|
||||
te->torrentMan->diskWriter->closeFile();
|
||||
}
|
||||
if(te->torrentMan->downloadComplete()) {
|
||||
if(te->torrentMan->downloadComplete() && te->isFilenameFixed()) {
|
||||
te->torrentMan->remove();
|
||||
te->torrentMan->fixFilename();
|
||||
te->torrentMan->deleteTempFile();
|
||||
printDownloadCompeleteMessage(te->torrentMan->getFilePath());
|
||||
} else {
|
||||
te->torrentMan->save();
|
||||
|
@ -223,7 +223,7 @@ int main(int argc, char* argv[]) {
|
|||
#endif // ENABLE_NLS
|
||||
bool stdoutLog = false;
|
||||
string logfile;
|
||||
string dir;
|
||||
string dir = ".";
|
||||
string ufilename;
|
||||
int split = 1;
|
||||
bool daemonMode = false;
|
||||
|
@ -575,7 +575,7 @@ int main(int argc, char* argv[]) {
|
|||
new PeerListenCommand(te->torrentMan->getNewCuid(), te);
|
||||
int port = listenCommand->bindPort(6881, 6999);
|
||||
if(port == -1) {
|
||||
printf("an error occurred while binding port.\n");
|
||||
printf("Errors occurred while binding port.\n");
|
||||
exit(1);
|
||||
}
|
||||
te->torrentMan->setPort(port);
|
||||
|
|
Loading…
Reference in New Issue