* 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
pull/1/head
Tatsuhiro Tsujikawa 2006-03-24 11:59:18 +00:00
parent be44f3a736
commit 2065b049ab
23 changed files with 203 additions and 156 deletions

View File

@ -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
View File

@ -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.

20
configure vendored
View File

@ -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'`\\"

View File

@ -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])

View File

@ -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

View File

@ -47,6 +47,7 @@ void DownloadEngine::run() {
delete(com);
}
}
afterEachIteration();
shortSleep();
if(!noWait && !commands.empty()) {
waitData();

View File

@ -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;

View File

@ -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;
}
}

View File

@ -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)) {

View File

@ -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);

View File

@ -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 {

View File

@ -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;
}
}

View File

@ -97,7 +97,8 @@ public:
AUTO,
STARTED,
STOPPED,
COMPLETED
COMPLETED,
AFTER_COMPLETED
};
};

View File

@ -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();
}
*/
}

View File

@ -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());
}
}

View File

@ -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_

View File

@ -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());
}

View File

@ -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; }

View File

@ -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()) {

View File

@ -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;

View File

@ -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;
}
}

View File

@ -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);
};

View File

@ -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);