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

Don't connect server before checking file integrity at startup, 
if
	filesize and output file path are known.
	* src/AbstractCommand.cc
	* src/StreamFileAllocationEntry.cc
	* src/Metalink2RequestGroup.cc
	* src/RequestGroup.{h, cc}
	* src/HttpResponseCommand.cc
	* src/FtpNegotiationCommand.cc

	Added DownloadFailureException. If it is thrown, RequestGroup 
should
	halt.
	* src/AbstractCommand.cc
	* src/DownloadFailureException.h
	* src/RequestGroup.cc

	Catch RecoverableException, instead of DlAbortEx.
	* src/RequestGroupMan.cc
	* src/FillRequestGroupCommand.cc
	* src/MetaFileUtil.cc
	* src/IteratableChunkChecksumValidator.cc

	Now first parameter of MSG_DOWNLOAD_ABORTED is 
gid(RequestGroup::
	getGID())
	* src/CheckIntegrityCommand.cc
	* src/message.h
	
	Print gid instead of idx.
	* src/RequestGroupMan.cc

	Removed exception throwers declaration.
	* src/DirectDiskAdaptor.{h, cc}
	* src/SocketCore.{h, cc}
	* src/MultiDiskAdaptor.{h, cc}
	* src/HttpConnection.{h, cc}
	* src/HttpResponse.{h, cc}
	* src/DiskAdaptor.{h, cc}
	* src/CopyDiskAdaptor.{h, cc}
	* src/MultiDiskAdaptor.{h, cc}
	* src/HttpHeaderProcessor.{h, cc}
	* src/AbstractSingleDiskAdaptor.{h, cc}
	* src/Util.{h, cc}
	* test/UtilTest.cc
	* src/DefaultDiskWriter.{h, cc}
	* src/FtpConnection.{h, cc}
	* src/AbstractDiskWriter.{h, cc}

	Removed duplicate code.
	* src/StreamCheckIntegrityEntry.cc

	Removed unnecessary include.
	* src/DiskWriter.h

	Included Exception.h
	* src/option_processing.cc

	Included 2 files and added doc
	* src/TrackerWatcherCommand.cc

	* src/SocketCore.cc (writeData): Fixed send error with GnuTLS.
pull/1/head
Tatsuhiro Tsujikawa 2007-11-09 18:01:12 +00:00
parent 76b9093d09
commit b5ad009809
48 changed files with 451 additions and 386 deletions

View File

@ -1,3 +1,65 @@
2007-11-10 Tatsuhiro Tsujikawa <tujikawa at rednoah dot com>
Don't connect server before checking file integrity at startup, if
filesize and output file path are known.
* src/AbstractCommand.cc
* src/StreamFileAllocationEntry.cc
* src/Metalink2RequestGroup.cc
* src/RequestGroup.{h, cc}
* src/HttpResponseCommand.cc
* src/FtpNegotiationCommand.cc
Added DownloadFailureException. If it is thrown, RequestGroup should
halt.
* src/AbstractCommand.cc
* src/DownloadFailureException.h
* src/RequestGroup.cc
Catch RecoverableException, instead of DlAbortEx.
* src/RequestGroupMan.cc
* src/FillRequestGroupCommand.cc
* src/MetaFileUtil.cc
* src/IteratableChunkChecksumValidator.cc
Now first parameter of MSG_DOWNLOAD_ABORTED is gid(RequestGroup::
getGID())
* src/CheckIntegrityCommand.cc
* src/message.h
Print gid instead of idx.
* src/RequestGroupMan.cc
Removed exception throwers declaration.
* src/DirectDiskAdaptor.{h, cc}
* src/SocketCore.{h, cc}
* src/MultiDiskAdaptor.{h, cc}
* src/HttpConnection.{h, cc}
* src/HttpResponse.{h, cc}
* src/DiskAdaptor.{h, cc}
* src/CopyDiskAdaptor.{h, cc}
* src/MultiDiskAdaptor.{h, cc}
* src/HttpHeaderProcessor.{h, cc}
* src/AbstractSingleDiskAdaptor.{h, cc}
* src/Util.{h, cc}
* test/UtilTest.cc
* src/DefaultDiskWriter.{h, cc}
* src/FtpConnection.{h, cc}
* src/AbstractDiskWriter.{h, cc}
Removed duplicate code.
* src/StreamCheckIntegrityEntry.cc
Removed unnecessary include.
* src/DiskWriter.h
Included Exception.h
* src/option_processing.cc
Included 2 files and added doc
* src/TrackerWatcherCommand.cc
* src/SocketCore.cc (writeData): Fixed send error with GnuTLS.
2007-11-08 Tatsuhiro Tsujikawa <tujikawa at rednoah dot com>
Changed CheckIntegrityEntry interface so that it can define

9
TODO
View File

@ -48,10 +48,15 @@
* Implement the feature to treat http/ftp as auxuality download method for BitTorrent
* http-seeding(single and multi-file torrent)
* Use content-type for PostDownloadHandler
* Rewrite exception usage:
RecoverableException
DlRetryEx .... Retry using same connection/url. Should be renamed to TemporaryFailureException
DlAbortEx .... Abort download with the connection/url. Should be renamed to PermanentFailureException
DownloadFailureException .... RequestGroup should halt.
FatalException .... Program should abort.
-- remaining features to be implemented for 0.12.0 release
* Reimplement ChecksumCommand(validation using 1 checksum for 1 file)
* Implement duplicate download checking in Bt
* improve --metalink-location field
* Do not connect a server when before checking file integrity.
* If size and filename is provided(for example, metalink), "HEAD" like behavior is unnecessary.
* Piece length conversion when loading file

View File

@ -38,25 +38,18 @@
#include "CUIDCounter.h"
#include "DlAbortEx.h"
#include "DlRetryEx.h"
#include "FatalException.h"
#include "DownloadFailureException.h"
#include "InitiateConnectionCommandFactory.h"
#include "Util.h"
#include "message.h"
#include "SleepCommand.h"
#include "prefs.h"
#include "DNSCache.h"
#include "SingleFileDownloadContext.h"
#include "DefaultPieceStorage.h"
#include "UnknownLengthPieceStorage.h"
#include "File.h"
#include "StreamCheckIntegrityEntry.h"
#include "BtProgressInfoFile.h"
#include "CheckIntegrityCommand.h"
#include "DiskAdaptor.h"
#include "PeerStat.h"
#include "Segment.h"
#include "DiskWriterFactory.h"
#include "Option.h"
#include "PieceStorage.h"
AbstractCommand::AbstractCommand(int32_t cuid,
const RequestHandle& req,
@ -158,7 +151,8 @@ bool AbstractCommand::execute() {
delete(err);
return prepareForRetry(e->option->getAsInt(PREF_RETRY_WAIT));
}
} catch(FatalException* err) {
} catch(DownloadFailureException* err) {
logger->error(EX_EXCEPTION_CAUGHT, err);
delete(err);
_requestGroup->setHaltRequested(true);
return true;
@ -300,131 +294,9 @@ bool AbstractCommand::nameResolveFinished() const {
}
#endif // ENABLE_ASYNC_DNS
void AbstractCommand::loadAndOpenFile(const BtProgressInfoFileHandle& progressInfoFile)
{
if(!_requestGroup->isPreLocalFileCheckEnabled()) {
_requestGroup->getPieceStorage()->getDiskAdaptor()->initAndOpenFile();
return;
}
//_requestGroup->setProgressInfoFile(new DefaultBtProgressInfoFile(_requestGroup->getDownloadContext(), _requestGroup->getPieceStorage(), e->option));
if(progressInfoFile->exists()) {
progressInfoFile->load();
_requestGroup->getPieceStorage()->getDiskAdaptor()->openExistingFile();
} else {
File outfile(_requestGroup->getFilePath());
if(outfile.exists() && e->option->get(PREF_CONTINUE) == V_TRUE) {
if(_requestGroup->getTotalLength() < outfile.size()) {
throw new FatalException(EX_FILE_LENGTH_MISMATCH_BETWEEN_LOCAL_AND_REMOTE,
_requestGroup->getFilePath().c_str(),
Util::llitos(outfile.size()).c_str(),
Util::llitos(_requestGroup->getTotalLength()).c_str());
}
_requestGroup->getPieceStorage()->getDiskAdaptor()->openExistingFile();
_requestGroup->getPieceStorage()->markPiecesDone(outfile.size());
} else {
#ifdef ENABLE_MESSAGE_DIGEST
if(outfile.exists() && e->option->get(PREF_CHECK_INTEGRITY) == V_TRUE) {
_requestGroup->getPieceStorage()->getDiskAdaptor()->openExistingFile();
} else {
shouldCancelDownloadForSafety();
_requestGroup->getPieceStorage()->getDiskAdaptor()->initAndOpenFile();
}
#else // ENABLE_MESSAGE_DIGEST
shouldCancelDownloadForSafety();
_requestGroup->getPieceStorage()->getDiskAdaptor()->initAndOpenFile();
#endif // ENABLE_MESSAGE_DIGEST
}
}
_requestGroup->setProgressInfoFile(progressInfoFile);
}
void AbstractCommand::shouldCancelDownloadForSafety()
{
File outfile(_requestGroup->getFilePath());
if(outfile.exists() && !_requestGroup->getProgressInfoFile()->exists()) {
if(e->option->get(PREF_AUTO_FILE_RENAMING) == V_TRUE) {
if(tryAutoFileRenaming()) {
logger->notice("File already exists. Renamed to %s.",
_requestGroup->getFilePath().c_str());
} else {
logger->notice("File renaming failed: %s",
_requestGroup->getFilePath().c_str());
throw new FatalException(EX_DOWNLOAD_ABORTED);
}
} else if(e->option->get(PREF_ALLOW_OVERWRITE) != V_TRUE) {
logger->notice(MSG_FILE_ALREADY_EXISTS,
_requestGroup->getFilePath().c_str(),
_requestGroup->getProgressInfoFile()->getFilename().c_str());
throw new FatalException(EX_DOWNLOAD_ABORTED);
}
}
}
bool AbstractCommand::tryAutoFileRenaming()
{
string filepath = _requestGroup->getFilePath();
if(filepath.empty()) {
return false;
}
for(int32_t i = 1; i < 10000; ++i) {
File newfile(filepath+"."+Util::itos(i));
if(!newfile.exists()) {
SingleFileDownloadContextHandle(_requestGroup->getDownloadContext())->setUFilename(newfile.getBasename());
return true;
}
}
return false;
}
void AbstractCommand::initPieceStorage()
{
if(_requestGroup->getDownloadContext()->getTotalLength() == 0) {
UnknownLengthPieceStorageHandle ps = new UnknownLengthPieceStorage(_requestGroup->getDownloadContext(), e->option);
if(!_requestGroup->getDiskWriterFactory().isNull()) {
ps->setDiskWriterFactory(_requestGroup->getDiskWriterFactory());
}
_requestGroup->setPieceStorage(ps);
} else {
DefaultPieceStorageHandle ps = new DefaultPieceStorage(_requestGroup->getDownloadContext(), e->option);
if(!_requestGroup->getDiskWriterFactory().isNull()) {
ps->setDiskWriterFactory(_requestGroup->getDiskWriterFactory());
}
_requestGroup->setPieceStorage(ps);
}
_requestGroup->getPieceStorage()->initStorage();
_requestGroup->initSegmentMan();
}
bool AbstractCommand::downloadFinishedByFileLength()
{
// TODO consider the case when the getFilePath() returns dir path.
File outfile(_requestGroup->getFilePath());
if(outfile.exists() &&
_requestGroup->getTotalLength() == outfile.size()) {
_requestGroup->getPieceStorage()->markAllPiecesDone();
return true;
} else {
return false;
}
}
void AbstractCommand::prepareForNextAction(Command* nextCommand)
{
CheckIntegrityEntryHandle entry =
new StreamCheckIntegrityEntry(req, _requestGroup, nextCommand);
#ifdef ENABLE_MESSAGE_DIGEST
if(File(_requestGroup->getFilePath()).size() > 0 &&
e->option->get(PREF_CHECK_INTEGRITY) == V_TRUE &&
entry->isValidationReady()) {
entry->initValidator();
logger->debug("Issuing CheckIntegrityCommand.");
CheckIntegrityCommand* command =
new CheckIntegrityCommand(CUIDCounterSingletonHolder::instance()->newID(), _requestGroup, e, entry);
e->commands.push_back(command);
} else
#endif // ENABLE_MESSAGE_DIGEST
{
e->addCommand(entry->onDownloadIncomplete(e));
}
e->addCommand(_requestGroup->processCheckIntegrityEntry(entry, e));
}

View File

@ -38,6 +38,7 @@
#include "message.h"
#include "LogFactory.h"
#include "a2io.h"
#include "DlAbortEx.h"
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
@ -55,7 +56,6 @@ AbstractDiskWriter::~AbstractDiskWriter()
}
void AbstractDiskWriter::openFile(const string& filename, int64_t totalLength)
throw(DlAbortEx*)
{
File f(filename);
if(f.exists()) {
@ -75,7 +75,6 @@ void AbstractDiskWriter::closeFile()
void AbstractDiskWriter::openExistingFile(const string& filename,
int64_t totalLength)
throw(DlAbortEx*)
{
this->filename = filename;
File f(filename);
@ -89,7 +88,6 @@ void AbstractDiskWriter::openExistingFile(const string& filename,
}
void AbstractDiskWriter::createFile(const string& filename, int32_t addFlags)
throw(DlAbortEx*)
{
this->filename = filename;
assert(filename.size());
@ -110,7 +108,6 @@ int32_t AbstractDiskWriter::readDataInternal(unsigned char* data, int32_t len)
}
void AbstractDiskWriter::seek(int64_t offset)
throw(DlAbortEx*)
{
if(offset != lseek(fd, offset, SEEK_SET)) {
throw new DlAbortEx(EX_FILE_SEEK, filename.c_str(), strerror(errno));
@ -118,7 +115,6 @@ void AbstractDiskWriter::seek(int64_t offset)
}
void AbstractDiskWriter::writeData(const unsigned char* data, int32_t len, int64_t offset)
throw(DlAbortEx*)
{
seek(offset);
if(writeDataInternal(data, len) < 0) {
@ -127,7 +123,6 @@ void AbstractDiskWriter::writeData(const unsigned char* data, int32_t len, int64
}
int32_t AbstractDiskWriter::readData(unsigned char* data, int32_t len, int64_t offset)
throw(DlAbortEx*)
{
int32_t ret;
seek(offset);
@ -138,7 +133,6 @@ int32_t AbstractDiskWriter::readData(unsigned char* data, int32_t len, int64_t o
}
void AbstractDiskWriter::truncate(int64_t length)
throw(DlAbortEx*)
{
if(fd == -1) {
throw new DlAbortEx("File not opened.");
@ -148,7 +142,6 @@ void AbstractDiskWriter::truncate(int64_t length)
// TODO the file descriptor fd must be opened before calling this function.
int64_t AbstractDiskWriter::size() const
throw(DlAbortEx*)
{
if(fd == -1) {
throw new DlAbortEx("File not opened.");

View File

@ -37,7 +37,6 @@
#include "DiskWriter.h"
#include "Logger.h"
#include "DlAbortEx.h"
class AbstractDiskWriter : public DiskWriter {
protected:
@ -45,31 +44,31 @@ protected:
int32_t fd;
const Logger* logger;
void createFile(const string& filename, int32_t addFlags = 0) throw(DlAbortEx*);
void createFile(const string& filename, int32_t addFlags = 0);
private:
int32_t writeDataInternal(const unsigned char* data, int32_t len);
int32_t readDataInternal(unsigned char* data, int32_t len);
void seek(int64_t offset) throw(DlAbortEx*);
void seek(int64_t offset);
public:
AbstractDiskWriter();
virtual ~AbstractDiskWriter();
virtual void openFile(const string& filename, int64_t totalLength = 0) throw(DlAbortEx*);
virtual void openFile(const string& filename, int64_t totalLength = 0);
virtual void closeFile();
virtual void openExistingFile(const string& filename, int64_t totalLength = 0) throw(DlAbortEx*);
virtual void openExistingFile(const string& filename, int64_t totalLength = 0);
virtual void writeData(const unsigned char* data, int32_t len, int64_t offset) throw(DlAbortEx*);
virtual void writeData(const unsigned char* data, int32_t len, int64_t offset);
virtual int32_t readData(unsigned char* data, int32_t len, int64_t offset) throw(DlAbortEx*);
virtual int32_t readData(unsigned char* data, int32_t len, int64_t offset);
virtual void truncate(int64_t length) throw(DlAbortEx*);
virtual void truncate(int64_t length);
virtual int64_t size() const throw(DlAbortEx*);
virtual int64_t size() const;
};
#endif // _D_ABSTRACT_DISK_WRITER_H_

View File

@ -37,13 +37,11 @@
#include "SingleFileAllocationIterator.h"
void AbstractSingleDiskAdaptor::initAndOpenFile()
throw(DlAbortEx*)
{
diskWriter->initAndOpenFile(getFilePath(), totalLength);
}
void AbstractSingleDiskAdaptor::openFile()
throw(DlAbortEx*)
{
diskWriter->openFile(getFilePath(), totalLength);
}
@ -54,19 +52,16 @@ void AbstractSingleDiskAdaptor::closeFile()
}
void AbstractSingleDiskAdaptor::openExistingFile()
throw(DlAbortEx*)
{
diskWriter->openExistingFile(getFilePath(), totalLength);
}
void AbstractSingleDiskAdaptor::writeData(const unsigned char* data, int32_t len, int64_t offset)
throw(DlAbortEx*)
{
diskWriter->writeData(data, len, offset);
}
int32_t AbstractSingleDiskAdaptor::readData(unsigned char* data, int32_t len, int64_t offset)
throw(DlAbortEx*)
{
return diskWriter->readData(data, len, offset);
}

View File

@ -37,7 +37,6 @@
#include "DiskAdaptor.h"
#include "DiskWriter.h"
#include "DlAbortEx.h"
class AbstractSingleDiskAdaptor : public DiskAdaptor {
protected:
@ -48,27 +47,27 @@ public:
virtual ~AbstractSingleDiskAdaptor() {}
virtual void initAndOpenFile() throw(DlAbortEx*);
virtual void initAndOpenFile();
virtual void openFile() throw(DlAbortEx*);
virtual void openFile();
virtual void closeFile();
virtual void openExistingFile() throw(DlAbortEx*);
virtual void openExistingFile();
virtual void writeData(const unsigned char* data, int32_t len,
int64_t offset) throw(DlAbortEx*);
int64_t offset);
virtual int32_t readData(unsigned char* data, int32_t len, int64_t offset) throw(DlAbortEx*);
virtual int32_t readData(unsigned char* data, int32_t len, int64_t offset);
virtual bool fileExists();
virtual int64_t size() const throw(DlAbortEx*)
virtual int64_t size() const
{
return diskWriter->size();
}
virtual void truncate(int64_t length) throw(DlAbortEx*)
virtual void truncate(int64_t length)
{
diskWriter->truncate(length);
}

View File

@ -64,7 +64,8 @@ bool CheckIntegrityCommand::executeInternal()
if(_entry->finished()) {
_entry->updatePieceStorage();
if(_requestGroup->downloadFinished()) {
logger->notice(MSG_DOWNLOAD_ALREADY_COMPLETED, cuid, _requestGroup->getFilePath().c_str());
logger->notice(MSG_DOWNLOAD_ALREADY_COMPLETED, _requestGroup->getGID(),
_requestGroup->getFilePath().c_str());
_e->addCommand(_entry->onDownloadFinished(_e));
} else {
_e->addCommand(_entry->onDownloadIncomplete(_e));

View File

@ -37,7 +37,6 @@
#include "message.h"
void CopyDiskAdaptor::onDownloadComplete()
throw(DlAbortEx*)
{
closeFile();
fixFilename();
@ -45,7 +44,6 @@ void CopyDiskAdaptor::onDownloadComplete()
}
void CopyDiskAdaptor::fixFilename()
throw(DlAbortEx*)
{
int64_t offset = 0;
for(FileEntries::iterator itr = fileEntries.begin();

View File

@ -36,14 +36,13 @@
#define _D_COPY_DISK_ADAPTOR_H_
#include "AbstractSingleDiskAdaptor.h"
#include "DlAbortEx.h"
class CopyDiskAdaptor : public AbstractSingleDiskAdaptor {
private:
string tempFilename;
string topDir;
void fixFilename() throw(DlAbortEx*);
void fixFilename();
public:
CopyDiskAdaptor() {}
@ -51,7 +50,7 @@ public:
virtual string getFilePath();
virtual void onDownloadComplete() throw(DlAbortEx*);
virtual void onDownloadComplete();
// tempFilename is relative to storeDir
void setTempFilename(const string& tempFilename) {

View File

@ -45,7 +45,6 @@ DefaultDiskWriter::~DefaultDiskWriter() {}
void DefaultDiskWriter::initAndOpenFile(const string& filename,
int64_t totalLength)
throw(DlAbortEx*)
{
createFile(filename);
}

View File

@ -37,7 +37,6 @@
#include "AbstractDiskWriter.h"
#include "Option.h"
#include "DlAbortEx.h"
class DefaultDiskWriter:public AbstractDiskWriter {
public:
@ -45,8 +44,7 @@ public:
virtual ~DefaultDiskWriter();
virtual void initAndOpenFile(const string& filename,
int64_t totalLength = 0) throw(DlAbortEx*);
virtual void initAndOpenFile(const string& filename, int64_t totalLength = 0);
};
typedef SharedHandle<DefaultDiskWriter> DefaultDiskWriterHandle;

View File

@ -40,7 +40,6 @@ string DirectDiskAdaptor::getFilePath()
}
void DirectDiskAdaptor::onDownloadComplete()
throw(DlAbortEx*)
{
closeFile();
openFile();

View File

@ -36,7 +36,6 @@
#define _D_DIRECT_DISK_ADAPTOR_H_
#include "AbstractSingleDiskAdaptor.h"
#include "DlAbortEx.h"
class DirectDiskAdaptor : public AbstractSingleDiskAdaptor {
public:
@ -45,7 +44,7 @@ public:
virtual string getFilePath();
virtual void onDownloadComplete() throw(DlAbortEx*);
virtual void onDownloadComplete();
};
typedef SharedHandle<DirectDiskAdaptor> DirectDiskAdaptorHandle;

View File

@ -35,13 +35,13 @@
#include "DiskAdaptor.h"
#include "LogFactory.h"
#include "message.h"
#include "DlAbortEx.h"
DiskAdaptor::DiskAdaptor():logger(LogFactory::getInstance()) {}
DiskAdaptor::~DiskAdaptor() {}
FileEntryHandle DiskAdaptor::getFileEntryFromPath(const string& fileEntryPath) const
throw(DlAbortEx*)
{
for(FileEntries::const_iterator itr = fileEntries.begin();
itr != fileEntries.end(); itr++) {

View File

@ -39,7 +39,6 @@
#include "FileEntry.h"
#include "Logger.h"
#include "FileAllocationIterator.h"
#include "DlAbortEx.h"
class DiskAdaptor:public BinaryStream {
protected:
@ -73,8 +72,7 @@ public:
this->fileEntries = fileEntries;
}
FileEntryHandle
getFileEntryFromPath(const string& fileEntryPath) const throw(DlAbortEx*);
FileEntryHandle getFileEntryFromPath(const string& fileEntryPath) const;
const FileEntries& getFileEntries() const { return fileEntries; }

View File

@ -36,7 +36,6 @@
#define _D_DISK_WRITER_H_
#include "BinaryStream.h"
#include "DlAbortEx.h"
/**
* Interface for writing to a binary stream of bytes.

View File

@ -0,0 +1,62 @@
/* <!-- 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_DOWNLOAD_FAILURE_EXCEPTION_H_
#define _D_DOWNLOAD_FAILURE_EXCEPTION_H_
#include "RecoverableException.h"
/**
* Throw this exception when a RequestGroup should aborted.
* FYI, DlAbortEx is the exception to abort 1 Request.
*/
class DownloadFailureException : public RecoverableException {
public:
DownloadFailureException(Exception* cause = 0):RecoverableException(cause) {}
DownloadFailureException(const char* msg, ...) {
va_list ap;
va_start(ap, msg);
setMsg(string(msg), ap);
va_end(ap);
}
DownloadFailureException(Exception* cause, const char* msg, ...):RecoverableException(cause) {
va_list ap;
va_start(ap, msg);
setMsg(string(msg), ap);
va_end(ap);
}
};
#endif // _D_DOWNLOAD_FAILURE_EXCEPTION_H_

View File

@ -36,7 +36,7 @@
#include "DownloadEngine.h"
#include "RequestGroupMan.h"
#include "RequestGroup.h"
#include "DlAbortEx.h"
#include "RecoverableException.h"
#include "message.h"
FillRequestGroupCommand::FillRequestGroupCommand(int32_t cuid,
@ -55,7 +55,7 @@ bool FillRequestGroupCommand::execute()
{
try {
_e->_requestGroupMan->fillRequestGroupFromReserver(_e);
} catch(DlAbortEx* ex) {
} catch(RecoverableException* ex) {
logger->error(EX_EXCEPTION_CAUGHT, ex);
delete ex;
}

View File

@ -39,6 +39,7 @@
#include "LogFactory.h"
#include "AuthConfigFactory.h"
#include "AuthConfig.h"
#include "DlRetryEx.h"
FtpConnection::FtpConnection(int32_t cuid, const SocketHandle& socket,
const RequestHandle req, const Option* op)
@ -49,7 +50,6 @@ FtpConnection::FtpConnection(int32_t cuid, const SocketHandle& socket,
FtpConnection::~FtpConnection() {}
void FtpConnection::sendUser() const
throw(DlRetryEx*)
{
string request = "USER "+AuthConfigFactorySingleton::instance()->createAuthConfig(req)->getUser()+"\r\n";
logger->info(MSG_SENDING_REQUEST, cuid, request.c_str());
@ -57,7 +57,6 @@ void FtpConnection::sendUser() const
}
void FtpConnection::sendPass() const
throw(DlRetryEx*)
{
string request = "PASS "+AuthConfigFactorySingleton::instance()->createAuthConfig(req)->getPassword()+"\r\n";
logger->info(MSG_SENDING_REQUEST, cuid, "PASS ********");
@ -65,7 +64,6 @@ void FtpConnection::sendPass() const
}
void FtpConnection::sendType() const
throw(DlRetryEx*)
{
string type;
if(option->get(PREF_FTP_TYPE) == V_ASCII) {
@ -79,7 +77,6 @@ void FtpConnection::sendType() const
}
void FtpConnection::sendCwd() const
throw(DlRetryEx*)
{
string request = "CWD "+Util::urldecode(req->getDir())+"\r\n";
logger->info(MSG_SENDING_REQUEST, cuid, request.c_str());
@ -87,7 +84,6 @@ void FtpConnection::sendCwd() const
}
void FtpConnection::sendSize() const
throw(DlRetryEx*)
{
string request = "SIZE "+Util::urldecode(req->getFile())+"\r\n";
logger->info(MSG_SENDING_REQUEST, cuid, request.c_str());
@ -95,7 +91,6 @@ void FtpConnection::sendSize() const
}
void FtpConnection::sendPasv() const
throw(DlRetryEx*)
{
string request = "PASV\r\n";
logger->info(MSG_SENDING_REQUEST, cuid, request.c_str());
@ -103,7 +98,6 @@ void FtpConnection::sendPasv() const
}
SocketHandle FtpConnection::sendPort() const
throw(DlAbortEx*, DlRetryEx*)
{
SocketHandle serverSocket;
serverSocket->beginListen();
@ -124,7 +118,6 @@ SocketHandle FtpConnection::sendPort() const
}
void FtpConnection::sendRest(const SegmentHandle& segment) const
throw(DlRetryEx*)
{
string request = "REST "+Util::llitos(segment->getPositionToWrite())+"\r\n";
logger->info(MSG_SENDING_REQUEST, cuid, request.c_str());
@ -132,7 +125,6 @@ void FtpConnection::sendRest(const SegmentHandle& segment) const
}
void FtpConnection::sendRetr() const
throw(DlRetryEx*)
{
string request = "RETR "+Util::urldecode(req->getFile())+"\r\n";
logger->info(MSG_SENDING_REQUEST, cuid, request.c_str());
@ -177,7 +169,6 @@ bool FtpConnection::isEndOfResponse(int32_t status, const string& response) cons
}
bool FtpConnection::bulkReceiveResponse(pair<int32_t, string>& response)
throw(DlRetryEx*)
{
char buf[1024];
while(socket->isReadable(0)) {
@ -211,7 +202,6 @@ bool FtpConnection::bulkReceiveResponse(pair<int32_t, string>& response)
}
int32_t FtpConnection::receiveResponse()
throw(DlRetryEx*)
{
pair<int32_t, string> response;
if(bulkReceiveResponse(response)) {
@ -222,7 +212,6 @@ int32_t FtpConnection::receiveResponse()
}
int32_t FtpConnection::receiveSizeResponse(int64_t& size)
throw(DlRetryEx*)
{
pair<int32_t, string> response;
if(bulkReceiveResponse(response)) {
@ -236,7 +225,6 @@ int32_t FtpConnection::receiveSizeResponse(int64_t& size)
}
int32_t FtpConnection::receivePasvResponse(pair<string, int32_t>& dest)
throw(DlRetryEx*)
{
pair<int32_t, string> response;
if(bulkReceiveResponse(response)) {

View File

@ -41,8 +41,6 @@
#include "Logger.h"
#include "Segment.h"
#include "Request.h"
#include "DlAbortEx.h"
#include "DlRetryEx.h"
#include <utility>
class FtpConnection {
@ -57,24 +55,24 @@ private:
int32_t getStatus(const string& response) const;
bool isEndOfResponse(int32_t status, const string& response) const;
bool bulkReceiveResponse(pair<int32_t, string>& response) throw(DlRetryEx*);
bool bulkReceiveResponse(pair<int32_t, string>& response);
public:
FtpConnection(int32_t cuid, const SocketHandle& socket,
const RequestHandle req, const Option* op);
~FtpConnection();
void sendUser() const throw(DlRetryEx*);
void sendPass() const throw(DlRetryEx*);
void sendType() const throw(DlRetryEx*);
void sendCwd() const throw(DlRetryEx*);
void sendSize() const throw(DlRetryEx*);
void sendPasv() const throw(DlRetryEx*);
SocketHandle sendPort() const throw(DlAbortEx*, DlRetryEx*);
void sendRest(const SegmentHandle& segment) const throw(DlRetryEx*);
void sendRetr() const throw(DlRetryEx*);
void sendUser() const;
void sendPass() const;
void sendType() const;
void sendCwd() const;
void sendSize() const;
void sendPasv() const;
SocketHandle sendPort() const;
void sendRest(const SegmentHandle& segment) const;
void sendRetr() const;
int32_t receiveResponse() throw(DlRetryEx*);
int32_t receiveSizeResponse(int64_t& size) throw(DlRetryEx*);
int32_t receivePasvResponse(pair<string, int32_t>& dest) throw(DlRetryEx*);
int32_t receiveResponse();
int32_t receiveSizeResponse(int64_t& size);
int32_t receivePasvResponse(pair<string, int32_t>& dest);
};
#endif // _D_FTP_CONNECTION_H_

View File

@ -195,29 +195,26 @@ bool FtpNegotiationCommand::recvSize() {
throw new DlAbortEx(EX_TOO_LARGE_FILE, Util::llitos(size, true).c_str());
}
if(_requestGroup->getPieceStorage().isNull()) {
SingleFileDownloadContextHandle(_requestGroup->getDownloadContext())->setTotalLength(size);
SingleFileDownloadContextHandle(_requestGroup->getDownloadContext())->setFilename(Util::urldecode(req->getFile()));
SingleFileDownloadContextHandle dctx = _requestGroup->getDownloadContext();
dctx->setTotalLength(size);
dctx->setFilename(Util::urldecode(req->getFile()));
initPieceStorage();
_requestGroup->initPieceStorage();
// TODO validate totalsize against hintTotalSize if it is provided.
// validate totalsize against hintTotalSize if it is provided.
_requestGroup->validateTotalLengthByHint(size);
// TODO Is this really necessary?
if(req->getMethod() == Request::METHOD_HEAD) {
// TODO because we don't want segment file to be saved.
sequence = SEQ_HEAD_OK;
return false;
}
BtProgressInfoFileHandle infoFile = new DefaultBtProgressInfoFile(_requestGroup->getDownloadContext(), _requestGroup->getPieceStorage(), e->option);
if(e->option->get(PREF_CHECK_INTEGRITY) != V_TRUE) {
if(!infoFile->exists() && downloadFinishedByFileLength()) {
logger->notice(MSG_DOWNLOAD_ALREADY_COMPLETED, cuid, _requestGroup->getFilePath().c_str());
sequence = SEQ_DOWNLOAD_ALREADY_COMPLETED;
return false;
}
if(!infoFile->exists() && _requestGroup->downloadFinishedByFileLength()) {
sequence = SEQ_DOWNLOAD_ALREADY_COMPLETED;
return false;
}
loadAndOpenFile(infoFile);
_requestGroup->loadAndOpenFile(infoFile);
prepareForNextAction();
sequence = SEQ_FILE_PREPARATION;

View File

@ -37,6 +37,8 @@
#include "message.h"
#include "prefs.h"
#include "LogFactory.h"
#include "DlRetryEx.h"
#include "DlAbortEx.h"
#include <sstream>
HttpConnection::HttpConnection(int32_t cuid,
@ -63,7 +65,6 @@ string HttpConnection::eraseConfidentialInfo(const string& request)
}
void HttpConnection::sendRequest(const HttpRequestHandle& httpRequest)
throw(DlRetryEx*)
{
string request = httpRequest->createRequest();
logger->info(MSG_SENDING_REQUEST, cuid, eraseConfidentialInfo(request).c_str());
@ -73,7 +74,6 @@ void HttpConnection::sendRequest(const HttpRequestHandle& httpRequest)
}
void HttpConnection::sendProxyRequest(const HttpRequestHandle& httpRequest)
throw(DlRetryEx*)
{
string request = httpRequest->createProxyRequest();
logger->info(MSG_SENDING_REQUEST, cuid, eraseConfidentialInfo(request).c_str());
@ -83,7 +83,6 @@ void HttpConnection::sendProxyRequest(const HttpRequestHandle& httpRequest)
}
HttpResponseHandle HttpConnection::receiveResponse()
throw(DlAbortEx*, DlRetryEx*)
{
if(outstandingHttpRequests.size() == 0) {
throw new DlAbortEx(EX_NO_HTTP_REQUEST_ENTRY_FOUND);

View File

@ -44,8 +44,6 @@
#include "Logger.h"
#include "HttpResponse.h"
#include "HttpHeaderProcessor.h"
#include "DlRetryEx.h"
#include "DlAbortEx.h"
class HttpRequestEntry {
private:
@ -95,12 +93,12 @@ public:
* HTTP proxy(GET method).
* @param segment indicates starting postion of the file for downloading
*/
void sendRequest(const HttpRequestHandle& httpRequest) throw(DlRetryEx*);
void sendRequest(const HttpRequestHandle& httpRequest);
/**
* Sends Http proxy request using CONNECT method.
*/
void sendProxyRequest(const HttpRequestHandle& httpRequest) throw(DlRetryEx*);
void sendProxyRequest(const HttpRequestHandle& httpRequest);
/**
* Receives HTTP response from the server and returns HttpResponseHandle
@ -113,7 +111,7 @@ public:
*
* @return HttpResponse or 0 if whole response header is not received
*/
HttpResponseHandle receiveResponse() throw(DlAbortEx*, DlRetryEx*);
HttpResponseHandle receiveResponse();
HttpRequestHandle getFirstHttpRequest() const
{

View File

@ -35,23 +35,22 @@
#include "HttpHeaderProcessor.h"
#include "message.h"
#include "Util.h"
#include "DlRetryEx.h"
#include "DlAbortEx.h"
void HttpHeaderProcessor::update(const char* data, int32_t length)
throw(DlAbortEx*)
{
checkHeaderLimit(length);
strm.write(data, length);
}
void HttpHeaderProcessor::update(const string& data)
throw(DlAbortEx*)
{
checkHeaderLimit(data.size());
strm << data;
}
void HttpHeaderProcessor::checkHeaderLimit(int32_t incomingLength)
throw(DlAbortEx*)
{
strm.seekg(0, ios::end);
if((int32_t)strm.tellg()+incomingLength > _limit) {
@ -88,7 +87,6 @@ void HttpHeaderProcessor::clear()
}
pair<string, HttpHeaderHandle> HttpHeaderProcessor::getHttpStatusHeader()
throw(DlRetryEx*)
{
strm.seekg(0, ios::beg);
string line;

View File

@ -37,8 +37,6 @@
#include "common.h"
#include "HttpHeader.h"
#include "DlRetryEx.h"
#include "DlAbortEx.h"
#include <utility>
#include <sstream>
@ -47,16 +45,16 @@ private:
stringstream strm;
int32_t _limit;
void checkHeaderLimit(int32_t incomingLength) throw(DlAbortEx*);
void checkHeaderLimit(int32_t incomingLength);
public:
HttpHeaderProcessor():_limit(4096) {}
~HttpHeaderProcessor() {}
void update(const char* data, int32_t length) throw(DlAbortEx*);
void update(const char* data, int32_t length);
void update(const string& data) throw(DlAbortEx*);
void update(const string& data);
/**
* Returns true if end of header is reached.
@ -68,7 +66,7 @@ public:
*/
int32_t getPutBackDataLength() const;
pair<string, HttpHeaderHandle> getHttpStatusHeader() throw(DlRetryEx*);
pair<string, HttpHeaderHandle> getHttpStatusHeader();
string getHeaderString() const;

View File

@ -36,9 +36,10 @@
#include "ChunkedEncoding.h"
#include "Util.h"
#include "message.h"
#include "DlAbortEx.h"
#include "DlRetryEx.h"
void HttpResponse::validateResponse() const
throw(DlAbortEx*, DlRetryEx*)
{
if(status == 401) {
throw new DlAbortEx(EX_AUTH_FAILED);

View File

@ -40,8 +40,6 @@
#include "HttpHeader.h"
#include "TransferEncoding.h"
#include "LogFactory.h"
#include "DlAbortEx.h"
#include "DlRetryEx.h"
class HttpResponse {
private:
@ -60,7 +58,7 @@ public:
~HttpResponse() {}
void validateResponse() const throw(DlAbortEx*, DlRetryEx*);
void validateResponse() const;
/**
* Returns filename.

View File

@ -84,35 +84,32 @@ bool HttpResponseCommand::executeInternal()
e->noWait = true;
return prepareForRetry(0);
}
if(!_requestGroup->getPieceStorage().isNull()) {
// validate totalsize
_requestGroup->validateTotalLength(httpResponse->getEntityLength());
e->commands.push_back(createHttpDownloadCommand(httpResponse));
return true;
} else {
if(_requestGroup->getPieceStorage().isNull()) {
// validate totalsize against hintTotalSize if it is provided.
_requestGroup->validateTotalLengthByHint(httpResponse->getEntityLength());
SingleFileDownloadContextHandle(_requestGroup->getDownloadContext())->setFilename(httpResponse->determinFilename());
if(httpResponse->isTransferEncodingSpecified()) {
int64_t totalLength = httpResponse->getEntityLength();
_requestGroup->validateTotalLengthByHint(totalLength);
SingleFileDownloadContextHandle dctx = _requestGroup->getDownloadContext();
dctx->setTotalLength(totalLength);
dctx->setFilename(httpResponse->determinFilename());
if(totalLength == 0 || httpResponse->isTransferEncodingSpecified()) {
// we ignore content-length when transfer-encoding is set
dctx->setTotalLength(0);
return handleOtherEncoding(httpResponse);
} else {
return handleDefaultEncoding(httpResponse);
}
} else {
// validate totalsize
_requestGroup->validateTotalLength(httpResponse->getEntityLength());
e->commands.push_back(createHttpDownloadCommand(httpResponse));
return true;
}
}
bool HttpResponseCommand::handleDefaultEncoding(const HttpResponseHandle& httpResponse)
{
HttpRequestHandle httpRequest = httpResponse->getHttpRequest();
int64_t size = httpResponse->getEntityLength();
if(size == INT64_MAX || size < 0) {
throw new DlAbortEx(EX_TOO_LARGE_FILE, Util::llitos(size, true).c_str());
}
SingleFileDownloadContextHandle(_requestGroup->getDownloadContext())->setTotalLength(size);
initPieceStorage();
_requestGroup->initPieceStorage();
// quick hack for method 'head',, is it necessary?
if(httpRequest->getMethod() == Request::METHOD_HEAD) {
@ -121,16 +118,13 @@ bool HttpResponseCommand::handleDefaultEncoding(const HttpResponseHandle& httpRe
}
BtProgressInfoFileHandle infoFile = new DefaultBtProgressInfoFile(_requestGroup->getDownloadContext(), _requestGroup->getPieceStorage(), e->option);
if(e->option->get(PREF_CHECK_INTEGRITY) != V_TRUE) {
if(!infoFile->exists() && downloadFinishedByFileLength()) {
logger->notice(MSG_DOWNLOAD_ALREADY_COMPLETED, cuid, _requestGroup->getFilePath().c_str());
return true;
}
if(!infoFile->exists() && _requestGroup->downloadFinishedByFileLength()) {
return true;
}
DownloadCommand* command = 0;
try {
loadAndOpenFile(infoFile);
_requestGroup->loadAndOpenFile(infoFile);
File file(_requestGroup->getFilePath());
if(_requestGroup->getRemainingUris().empty() && !file.exists()) {
command = createHttpDownloadCommand(httpResponse);
@ -145,7 +139,6 @@ bool HttpResponseCommand::handleDefaultEncoding(const HttpResponseHandle& httpRe
}
bool HttpResponseCommand::handleOtherEncoding(const HttpResponseHandle& httpResponse) {
// we ignore content-length when transfer-encoding is set
HttpRequestHandle httpRequest = httpResponse->getHttpRequest();
// quick hack for method 'head',, is it necessary?
if(httpRequest->getMethod() == Request::METHOD_HEAD) {
@ -153,11 +146,8 @@ bool HttpResponseCommand::handleOtherEncoding(const HttpResponseHandle& httpResp
}
// disable keep-alive
req->setKeepAlive(false);
initPieceStorage();
shouldCancelDownloadForSafety();
// TODO handle file-size unknown case
_requestGroup->initPieceStorage();
_requestGroup->shouldCancelDownloadForSafety();
_requestGroup->getPieceStorage()->getDiskAdaptor()->initAndOpenFile();
e->commands.push_back(createHttpDownloadCommand(httpResponse));
return true;

View File

@ -37,6 +37,7 @@
#include "message.h"
#include "MessageDigestHelper.h"
#include "DiskAdaptor.h"
#include "RecoverableException.h"
void IteratableChunkChecksumValidator::validateChunk()
{
@ -44,7 +45,7 @@ void IteratableChunkChecksumValidator::validateChunk()
string actualChecksum;
try {
actualChecksum = calculateActualChecksum();
} catch(DlAbortEx* ex) {
} catch(RecoverableException* ex) {
_logger->debug("Caught exception while validating piece index=%d. Some part of file may be missing. Continue operation.", ex, _currentIndex);
delete ex;
_bitfield->unsetBit(_currentIndex);

View File

@ -73,7 +73,7 @@ MetaEntry* MetaFileUtil::bdecoding(const char* buf, int32_t len) {
const char* end = buf+len;
entry = bdecodingR(&p, end);
return entry;
} catch(DlAbortEx* ex) {
} catch(RecoverableException* ex) {
if(entry != NULL) {
delete entry;
}

View File

@ -158,7 +158,7 @@ RequestGroups Metalink2RequestGroup::generate(const string& metalinkFile)
}
SingleFileDownloadContextHandle dctx =
new SingleFileDownloadContext(pieceLength,
0,
entry->getLength(),
"",
entry->file->getPath());
dctx->setDir(_option->get(PREF_DIR));

View File

@ -38,6 +38,7 @@
#include "Util.h"
#include "MultiFileAllocationIterator.h"
#include "DefaultDiskWriterFactory.h"
#include "DlAbortEx.h"
void MultiDiskAdaptor::resetDiskWriterEntries()
{
@ -60,7 +61,6 @@ string MultiDiskAdaptor::getTopDirPath() const
}
void MultiDiskAdaptor::mkdir() const
throw(DlAbortEx*)
{
for(FileEntries::const_iterator itr = fileEntries.begin();
itr != fileEntries.end(); itr++) {
@ -69,7 +69,6 @@ void MultiDiskAdaptor::mkdir() const
}
void MultiDiskAdaptor::openFile()
throw(DlAbortEx*)
{
mkdir();
resetDiskWriterEntries();
@ -80,7 +79,6 @@ void MultiDiskAdaptor::openFile()
}
void MultiDiskAdaptor::initAndOpenFile()
throw(DlAbortEx*)
{
mkdir();
resetDiskWriterEntries();
@ -91,7 +89,6 @@ void MultiDiskAdaptor::initAndOpenFile()
}
void MultiDiskAdaptor::openExistingFile()
throw(DlAbortEx*)
{
resetDiskWriterEntries();
for(DiskWriterEntries::iterator itr = diskWriterEntries.begin();
@ -109,7 +106,6 @@ void MultiDiskAdaptor::closeFile()
}
void MultiDiskAdaptor::onDownloadComplete()
throw(DlAbortEx*)
{
closeFile();
openFile();
@ -117,7 +113,6 @@ void MultiDiskAdaptor::onDownloadComplete()
void MultiDiskAdaptor::writeData(const unsigned char* data, int32_t len,
int64_t offset)
throw(DlAbortEx*)
{
int64_t fileOffset = offset;
bool writing = false;
@ -160,7 +155,6 @@ int32_t MultiDiskAdaptor::calculateLength(const DiskWriterEntryHandle entry,
}
int32_t MultiDiskAdaptor::readData(unsigned char* data, int32_t len, int64_t offset)
throw(DlAbortEx*)
{
int64_t fileOffset = offset;
bool reading = false;
@ -200,7 +194,6 @@ bool MultiDiskAdaptor::fileExists()
// TODO call DiskWriter::openFile() before calling this function.
int64_t MultiDiskAdaptor::size() const
throw(DlAbortEx*)
{
int64_t size = 0;
for(DiskWriterEntries::const_iterator itr = diskWriterEntries.begin();

View File

@ -39,7 +39,6 @@
#include "Option.h"
#include "DiskWriter.h"
#include "File.h"
#include "DlAbortEx.h"
class DiskWriterEntry {
private:
@ -58,19 +57,16 @@ public:
}
void initAndOpenFile(const string& topDir)
throw(DlAbortEx*)
{
diskWriter->initAndOpenFile(getFilePath(topDir), fileEntry->getLength());
}
void openFile(const string& topDir)
throw(DlAbortEx*)
{
diskWriter->openFile(getFilePath(topDir), fileEntry->getLength());
}
void openExistingFile(const string& topDir)
throw(DlAbortEx*)
{
diskWriter->openExistingFile(getFilePath(topDir), fileEntry->getLength());
}
@ -86,7 +82,6 @@ public:
}
int64_t size() const
throw(DlAbortEx*)
{
return diskWriter->size();
}
@ -117,7 +112,7 @@ private:
void resetDiskWriterEntries();
void mkdir() const throw(DlAbortEx*);
void mkdir() const;
bool isInRange(const DiskWriterEntryHandle entry, int64_t offset) const;
@ -133,20 +128,20 @@ public:
virtual ~MultiDiskAdaptor() {}
virtual void initAndOpenFile() throw(DlAbortEx*);
virtual void initAndOpenFile();
virtual void openFile() throw(DlAbortEx*);
virtual void openFile();
virtual void openExistingFile() throw(DlAbortEx*);
virtual void openExistingFile();
virtual void closeFile();
virtual void onDownloadComplete() throw(DlAbortEx*);
virtual void onDownloadComplete();
virtual void writeData(const unsigned char* data, int32_t len,
int64_t offset) throw(DlAbortEx*);
int64_t offset);
virtual int32_t readData(unsigned char* data, int32_t len, int64_t offset) throw(DlAbortEx*);
virtual int32_t readData(unsigned char* data, int32_t len, int64_t offset);
virtual bool fileExists();
@ -155,7 +150,7 @@ public:
return getTopDirPath();
}
virtual int64_t size() const throw(DlAbortEx*);
virtual int64_t size() const;
virtual FileAllocationIteratorHandle fileAllocationIterator();

View File

@ -41,7 +41,6 @@ bool RealtimeCommand::execute()
try {
return executeInternal();
} catch(Exception* e) {
//_requestGroup->getSegmentMan()->errors++;
bool r = handleException(e);
delete e;
return r;

View File

@ -49,6 +49,12 @@
#include "DiskAdaptor.h"
#include "DiskWriterFactory.h"
#include "RecoverableException.h"
#include "StreamCheckIntegrityEntry.h"
#include "CheckIntegrityCommand.h"
#include "UnknownLengthPieceStorage.h"
#include "SingleFileDownloadContext.h"
#include "DlAbortEx.h"
#include "DownloadFailureException.h"
#ifdef ENABLE_MESSAGE_DIGEST
# include "CheckIntegrityCommand.h"
#endif // ENABLE_MESSAGE_DIGEST
@ -149,10 +155,7 @@ Commands RequestGroup::createInitialCommand(DownloadEngine* e)
_logger->debug("Clearing http/ftp URIs because the current implementation does not allow integrating multi-file torrent and http/ftp.");
_uris.clear();
}
_pieceStorage = new DefaultPieceStorage(btContext, _option);
_pieceStorage->initStorage();
initSegmentMan();
initPieceStorage();
BtProgressInfoFileHandle progressInfoFile =
new DefaultBtProgressInfoFile(_downloadContext,
@ -201,26 +204,159 @@ Commands RequestGroup::createInitialCommand(DownloadEngine* e)
}
}
_progressInfoFile = progressInfoFile;
Commands commands;
CheckIntegrityEntryHandle entry = new BtCheckIntegrityEntry(this);
#ifdef ENABLE_MESSAGE_DIGEST
if(File(getFilePath()).size() > 0 &&
e->option->get(PREF_CHECK_INTEGRITY) == V_TRUE &&
entry->isValidationReady()) {
entry->initValidator();
CheckIntegrityCommand* command =
new CheckIntegrityCommand(CUIDCounterSingletonHolder::instance()->newID(), this, e, entry);
commands.push_back(command);
} else
#endif // ENABLE_MESSAGE_DIGEST
{
commands = entry->onDownloadIncomplete(e);
}
return commands;
return processCheckIntegrityEntry(entry, e);
}
}
#endif // ENABLE_BITTORRENT
return createNextCommand(e, 1);
// TODO I assume here when totallength is set to DownloadContext and it is
// not 0, then filepath is also set DownloadContext correctly....
if(_downloadContext->getTotalLength() == 0) {
return createNextCommand(e, 1);
}else {
initPieceStorage();
BtProgressInfoFileHandle infoFile =
new DefaultBtProgressInfoFile(_downloadContext, _pieceStorage, _option);
if(!infoFile->exists() && downloadFinishedByFileLength()) {
return Commands();
}
loadAndOpenFile(infoFile);
return processCheckIntegrityEntry(new StreamCheckIntegrityEntry(0, this), e);
}
}
Commands RequestGroup::processCheckIntegrityEntry(const CheckIntegrityEntryHandle& entry, DownloadEngine* e)
{
#ifdef ENABLE_MESSAGE_DIGEST
if(File(getFilePath()).size() > 0 &&
e->option->get(PREF_CHECK_INTEGRITY) == V_TRUE &&
entry->isValidationReady()) {
entry->initValidator();
CheckIntegrityCommand* command =
new CheckIntegrityCommand(CUIDCounterSingletonHolder::instance()->newID(), this, e, entry);
Commands commands;
commands.push_back(command);
return commands;
} else
#endif // ENABLE_MESSAGE_DIGEST
{
return entry->onDownloadIncomplete(e);
}
}
void RequestGroup::initPieceStorage()
{
if(_downloadContext->getTotalLength() == 0) {
UnknownLengthPieceStorageHandle ps = new UnknownLengthPieceStorage(_downloadContext, _option);
if(!_diskWriterFactory.isNull()) {
ps->setDiskWriterFactory(_diskWriterFactory);
}
_pieceStorage = ps;
} else {
DefaultPieceStorageHandle ps = new DefaultPieceStorage(_downloadContext, _option);
if(!_diskWriterFactory.isNull()) {
ps->setDiskWriterFactory(_diskWriterFactory);
}
_pieceStorage = ps;
}
_pieceStorage->initStorage();
initSegmentMan();
}
bool RequestGroup::downloadFinishedByFileLength()
{
if(_option->get(PREF_CHECK_INTEGRITY) == V_TRUE &&
!_downloadContext->getPieceHashes().empty()) {
return false;
}
// TODO consider the case when the getFilePath() returns dir path.
File outfile(getFilePath());
if(outfile.exists() && getTotalLength() == outfile.size()) {
_pieceStorage->markAllPiecesDone();
_logger->notice(MSG_DOWNLOAD_ALREADY_COMPLETED, _gid, getFilePath().c_str());
return true;
} else {
return false;
}
}
void RequestGroup::loadAndOpenFile(const BtProgressInfoFileHandle& progressInfoFile)
{
try {
if(!isPreLocalFileCheckEnabled()) {
_pieceStorage->getDiskAdaptor()->initAndOpenFile();
return;
}
if(progressInfoFile->exists()) {
progressInfoFile->load();
_pieceStorage->getDiskAdaptor()->openExistingFile();
} else {
File outfile(getFilePath());
if(outfile.exists() && _option->get(PREF_CONTINUE) == V_TRUE) {
if(getTotalLength() < outfile.size()) {
throw new DlAbortEx(EX_FILE_LENGTH_MISMATCH_BETWEEN_LOCAL_AND_REMOTE,
getFilePath().c_str(),
Util::llitos(outfile.size()).c_str(),
Util::llitos(getTotalLength()).c_str());
}
_pieceStorage->getDiskAdaptor()->openExistingFile();
_pieceStorage->markPiecesDone(outfile.size());
} else {
#ifdef ENABLE_MESSAGE_DIGEST
if(outfile.exists() && _option->get(PREF_CHECK_INTEGRITY) == V_TRUE) {
_pieceStorage->getDiskAdaptor()->openExistingFile();
} else {
shouldCancelDownloadForSafety();
_pieceStorage->getDiskAdaptor()->initAndOpenFile();
}
#else // ENABLE_MESSAGE_DIGEST
shouldCancelDownloadForSafety();
_pieceStorage->getDiskAdaptor()->initAndOpenFile();
#endif // ENABLE_MESSAGE_DIGEST
}
}
setProgressInfoFile(progressInfoFile);
} catch(RecoverableException* e) {
throw new DownloadFailureException(e, EX_DOWNLOAD_ABORTED);
}
}
void RequestGroup::shouldCancelDownloadForSafety()
{
File outfile(getFilePath());
if(outfile.exists() && !_progressInfoFile->exists()) {
if(_option->get(PREF_AUTO_FILE_RENAMING) == V_TRUE) {
if(tryAutoFileRenaming()) {
_logger->notice("File already exists. Renamed to %s.",
getFilePath().c_str());
} else {
_logger->notice("File renaming failed: %s", getFilePath().c_str());
throw new DownloadFailureException(EX_DOWNLOAD_ABORTED);
}
} else if(_option->get(PREF_ALLOW_OVERWRITE) != V_TRUE) {
_logger->notice(MSG_FILE_ALREADY_EXISTS,
getFilePath().c_str(),
_progressInfoFile->getFilename().c_str());
throw new DownloadFailureException(EX_DOWNLOAD_ABORTED);
}
}
}
bool RequestGroup::tryAutoFileRenaming()
{
string filepath = getFilePath();
if(filepath.empty()) {
return false;
}
for(int32_t i = 1; i < 10000; ++i) {
File newfile(filepath+"."+Util::itos(i));
if(!newfile.exists()) {
SingleFileDownloadContextHandle(_downloadContext)->setUFilename(newfile.getBasename());
return true;
}
}
return false;
}
Commands RequestGroup::createNextCommandWithAdj(DownloadEngine* e, int32_t numAdj)

View File

@ -61,10 +61,12 @@ class DiskWriterFactory;
extern typedef SharedHandle<DiskWriterFactory> DiskWriterFactoryHandle;
class Option;
class Logger;
class RequestGroup;
extern typedef SharedHandle<RequestGroup> RequestGroupHandle;
extern typedef deque<RequestGroupHandle> RequestGroups;
class CheckIntegrityEntry;
extern typedef SharedHandle<CheckIntegrityEntry> CheckIntegrityEntryHandle;
class RequestGroup {
private:
@ -124,6 +126,9 @@ private:
int64_t actualTotalLength) const;
void initializePostDownloadHandler();
bool tryAutoFileRenaming();
public:
RequestGroup(const Option* option, const Strings& uris);
@ -300,6 +305,16 @@ public:
void addPostDownloadHandler(const PostDownloadHandlerHandle& handler);
void clearPostDowloadHandler();
Commands processCheckIntegrityEntry(const CheckIntegrityEntryHandle& entry, DownloadEngine* e);
void initPieceStorage();
bool downloadFinishedByFileLength();
void loadAndOpenFile(const BtProgressInfoFileHandle& progressInfoFile);
void shouldCancelDownloadForSafety();
};
typedef SharedHandle<RequestGroup> RequestGroupHandle;

View File

@ -34,7 +34,7 @@
/* copyright --> */
#include "RequestGroupMan.h"
#include "BtProgressInfoFile.h"
#include "DlAbortEx.h"
#include "RecoverableException.h"
#include "RequestGroup.h"
#include "LogFactory.h"
#include "DownloadEngine.h"
@ -120,7 +120,7 @@ void RequestGroupMan::removeStoppedGroup()
} else {
try {
(*itr)->getProgressInfoFile()->save();
} catch(DlAbortEx* ex) {
} catch(RecoverableException* ex) {
_logger->error(EX_EXCEPTION_CAUGHT, ex);
delete ex;
}
@ -154,7 +154,7 @@ void RequestGroupMan::fillRequestGroupFromReserver(DownloadEngine* e)
Commands commands = groupToAdd->createInitialCommand(e);
++count;
e->addCommand(commands);
} catch(DlAbortEx* ex) {
} catch(RecoverableException* ex) {
_logger->error(EX_EXCEPTION_CAUGHT, ex);
delete ex;
}
@ -175,7 +175,7 @@ Commands RequestGroupMan::getInitialCommands(DownloadEngine* e)
Commands nextCommands = (*itr)->createInitialCommand(e);
copy(nextCommands.begin(), nextCommands.end(), back_inserter(commands));
++itr;
} catch(DlAbortEx* e) {
} catch(RecoverableException* e) {
_logger->error(EX_EXCEPTION_CAUGHT, e);
delete e;
}
@ -196,7 +196,7 @@ void RequestGroupMan::save()
} else {
try {
(*itr)->getProgressInfoFile()->save();
} catch(DlAbortEx* e) {
} catch(RecoverableException* e) {
_logger->error(EX_EXCEPTION_CAUGHT, e);
delete e;
}
@ -220,7 +220,7 @@ void RequestGroupMan::showDownloadResults(ostream& o) const
o << "\n"
<<_("Download Results:") << "\n"
<< " (OK):download completed.(ERR):error occurred.(INPR):download in-progress." << "\n"
<< "idx|stat|path/URI" << "\n"
<< "gid|stat|path/URI" << "\n"
<< "===+====+======================================================================" << "\n";
for(RequestGroups::const_iterator itr = _spentGroups.begin();
itr != _spentGroups.end(); ++itr) {

View File

@ -36,6 +36,8 @@
#include "message.h"
#include "a2netcompat.h"
#include "a2time.h"
#include "DlRetryEx.h"
#include "DlAbortEx.h"
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
@ -81,7 +83,6 @@ SocketCore::~SocketCore() {
}
void SocketCore::beginListen(int32_t port)
throw(DlAbortEx*)
{
closeConnection();
//sockfd = socket(AF_UNSPEC, SOCK_STREAM, PF_UNSPEC);
@ -118,7 +119,6 @@ void SocketCore::beginListen(int32_t port)
}
SocketCore* SocketCore::acceptConnection() const
throw(DlAbortEx*)
{
struct sockaddr_in sockaddr;
socklen_t len = sizeof(sockaddr);
@ -133,7 +133,6 @@ SocketCore* SocketCore::acceptConnection() const
}
void SocketCore::getAddrInfo(pair<string, int32_t>& addrinfo) const
throw(DlAbortEx*)
{
struct sockaddr_in listenaddr;
memset((char*)&listenaddr, 0, sizeof(listenaddr));
@ -146,7 +145,6 @@ void SocketCore::getAddrInfo(pair<string, int32_t>& addrinfo) const
}
void SocketCore::getPeerInfo(pair<string, int32_t>& peerinfo) const
throw(DlAbortEx*)
{
struct sockaddr_in peerin;
memset(&peerin, 0, sizeof(peerin));
@ -159,7 +157,6 @@ void SocketCore::getPeerInfo(pair<string, int32_t>& peerinfo) const
}
void SocketCore::establishConnection(const string& host, int32_t port)
throw(DlAbortEx*)
{
closeConnection();
sockfd = socket(AF_INET, SOCK_STREAM, 0);
@ -209,7 +206,6 @@ WSAEWOULDBLOCK
}
void SocketCore::setNonBlockingMode()
throw(DlAbortEx*)
{
#ifdef __MINGW32__
static u_long flag = 1;
@ -225,7 +221,6 @@ void SocketCore::setNonBlockingMode()
}
void SocketCore::setBlockingMode()
throw(DlAbortEx*)
{
#ifdef __MINGW32__
static u_long flag = 0;
@ -277,7 +272,6 @@ void SocketCore::closeConnection()
}
bool SocketCore::isWritable(int32_t timeout) const
throw(DlRetryEx*)
{
fd_set fds;
FD_ZERO(&fds);
@ -303,7 +297,6 @@ bool SocketCore::isWritable(int32_t timeout) const
}
bool SocketCore::isReadable(int32_t timeout) const
throw(DlRetryEx*)
{
#ifdef HAVE_LIBGNUTLS
if(secure && peekBufLength > 0) {
@ -334,7 +327,6 @@ bool SocketCore::isReadable(int32_t timeout) const
}
void SocketCore::writeData(const char* data, int32_t len)
throw(DlRetryEx*)
{
int32_t ret = 0;
@ -351,7 +343,7 @@ void SocketCore::writeData(const char* data, int32_t len)
}
#endif // HAVE_LIBSSL
#ifdef HAVE_LIBGNUTLS
if((ret = gnutls_record_send(sslSession, data, len)) == len) {
if((ret = gnutls_record_send(sslSession, data, len)) != len) {
throw new DlRetryEx(EX_SOCKET_SEND, gnutls_strerror(ret));
}
#endif // HAVE_LIBGNUTLS
@ -359,7 +351,6 @@ void SocketCore::writeData(const char* data, int32_t len)
}
void SocketCore::readData(char* data, int32_t& len)
throw(DlRetryEx*)
{
int32_t ret = 0;
@ -386,7 +377,6 @@ void SocketCore::readData(char* data, int32_t& len)
}
void SocketCore::peekData(char* data, int32_t& len)
throw(DlRetryEx*)
{
int32_t ret = 0;
@ -446,7 +436,6 @@ void SocketCore::addPeekData(char* data, int32_t len)
}
int32_t SocketCore::gnutlsRecv(char* data, int32_t len)
throw(DlRetryEx*)
{
int32_t plen = shiftPeekData(data, len);
if(plen < len) {
@ -461,7 +450,6 @@ int32_t SocketCore::gnutlsRecv(char* data, int32_t len)
}
int32_t SocketCore::gnutlsPeek(char* data, int32_t len)
throw(DlRetryEx*)
{
if(peekBufLength >= len) {
memcpy(data, peekBuf, len);
@ -479,7 +467,6 @@ int32_t SocketCore::gnutlsPeek(char* data, int32_t len)
#endif // HAVE_LIBGNUTLS
void SocketCore::initiateSecureConnection()
throw(DlAbortEx*)
{
#ifdef HAVE_LIBSSL
// for SSL

View File

@ -36,8 +36,6 @@
#define _D_SOCKET_CORE_H_
#include "common.h"
#include "DlRetryEx.h"
#include "DlAbortEx.h"
#include <string>
#include <utility>
@ -77,8 +75,8 @@ private:
int32_t shiftPeekData(char* data, int32_t len);
void addPeekData(char* data, int32_t len);
int32_t gnutlsRecv(char* data, int32_t len) throw(DlRetryEx*);
int32_t gnutlsPeek(char* data, int32_t len) throw(DlRetryEx*);
int32_t gnutlsRecv(char* data, int32_t len);
int32_t gnutlsPeek(char* data, int32_t len);
#endif // HAVE_LIBGNUTLS
void init();
@ -99,26 +97,26 @@ public:
* @param port port to listen. If 0 is specified, os automaticaly
* choose avaiable port.
*/
void beginListen(int32_t port = 0) throw(DlAbortEx*);
void beginListen(int32_t port = 0);
/**
* Stores host address and port of this socket to addrinfo.
* @param addrinfo placeholder to store host address and port.
*/
void getAddrInfo(pair<string, int32_t>& addrinfo) const throw(DlAbortEx*);
void getAddrInfo(pair<string, int32_t>& addrinfo) const;
/**
* Stores peer's address and port to peerinfo.
* @param peerinfo placeholder to store peer's address and port.
*/
void getPeerInfo(pair<string, int32_t>& peerinfo) const throw(DlAbortEx*);
void getPeerInfo(pair<string, int32_t>& peerinfo) const;
/**
* Accepts incoming connection on this socket.
* You must call beginListen() before calling this method.
* @return accepted socket. The caller must delete it after using it.
*/
SocketCore* acceptConnection() const throw(DlAbortEx*);
SocketCore* acceptConnection() const;
/**
* Connects to the server named host and the destination port is port.
@ -128,14 +126,14 @@ public:
* @param host hostname or ip address to connect to
* @param port service port number to connect to
*/
void establishConnection(const string& host, int32_t port) throw(DlAbortEx*);
void establishConnection(const string& host, int32_t port);
void setNonBlockingMode() throw(DlAbortEx*);
void setNonBlockingMode();
/**
* Makes this socket blocking mode.
*/
void setBlockingMode() throw(DlAbortEx*);
void setBlockingMode();
/**
* Closes the connection of this socket.
@ -149,7 +147,7 @@ public:
* @return true if the socket is available for writing,
* otherwise returns false.
*/
bool isWritable(int32_t timeout) const throw(DlRetryEx*);
bool isWritable(int32_t timeout) const;
/**
* Checks whether this socket is available for reading.
@ -158,7 +156,7 @@ public:
* @return true if the socket is available for reading,
* otherwise returns false.
*/
bool isReadable(int32_t timeout) const throw(DlRetryEx*);
bool isReadable(int32_t timeout) const;
/**
* Writes characters into this socket. data is a pointer pointing the first
@ -168,8 +166,8 @@ public:
* @param data data to write
* @param len length of data
*/
void writeData(const char* data, int32_t len) throw(DlRetryEx*);
void writeData(const string& msg) throw(DlRetryEx*)
void writeData(const char* data, int32_t len);
void writeData(const string& msg)
{
writeData(msg.c_str(), msg.size());
}
@ -186,7 +184,7 @@ public:
* @param len the maximum size data can store. This method assigns
* the number of bytes read to len.
*/
void readData(char* data, int32_t& len) throw(DlRetryEx*);
void readData(char* data, int32_t& len);
/**
* Reads up to len bytes from this socket, but bytes are not removed from
@ -197,14 +195,14 @@ public:
* @param len the maximum size data can store. This method assigns
* the number of bytes read to len.
*/
void peekData(char* data, int32_t& len) throw(DlRetryEx*);
void peekData(char* data, int32_t& len);
/**
* Makes this socket secure.
* If the system has not OpenSSL, then this method do nothing.
* connection must be established before calling this method.
*/
void initiateSecureConnection() throw(DlAbortEx*);
void initiateSecureConnection();
bool operator==(const SocketCore& s) {
return sockfd == s.sockfd;

View File

@ -54,22 +54,13 @@ StreamCheckIntegrityEntry::~StreamCheckIntegrityEntry() {}
Commands StreamCheckIntegrityEntry::onDownloadIncomplete(DownloadEngine* e)
{
Commands commands;
FileAllocationEntryHandle entry =
new StreamFileAllocationEntry(_currentRequest, _requestGroup,
popNextCommand());
if(_requestGroup->needsFileAllocation()) {
FileAllocationEntryHandle entry =
new StreamFileAllocationEntry(_currentRequest, _requestGroup,
popNextCommand());
e->_fileAllocationMan->pushFileAllocationEntry(entry);
} else {
if(_nextCommand) {
commands.push_back(popNextCommand());
} else {
Commands streamCommands = _requestGroup->createNextCommandWithAdj(e, -1);
Command* command = InitiateConnectionCommandFactory::createInitiateConnectionCommand(CUIDCounterSingletonHolder::instance()->newID(),
_currentRequest, _requestGroup, e);
commands.push_front(command);
copy(streamCommands.begin(), streamCommands.end(), back_inserter(commands));
}
commands = entry->prepareForNextAction(e);
}
return commands;
}

View File

@ -58,12 +58,16 @@ Commands StreamFileAllocationEntry::prepareForNextAction(DownloadEngine* e)
_nextCommand) {
commands.push_back(popNextCommand());
} else {
Commands streamCommands = _requestGroup->createNextCommandWithAdj(e, -1);
Command* command = InitiateConnectionCommandFactory::createInitiateConnectionCommand(CUIDCounterSingletonHolder::instance()->newID(),
_currentRequest, _requestGroup, e);
commands.push_back(command);
copy(streamCommands.begin(), streamCommands.end(), back_inserter(commands));
if(_currentRequest.isNull()) {
commands = _requestGroup->createNextCommandWithAdj(e, 0);
} else {
Commands streamCommands = _requestGroup->createNextCommandWithAdj(e, -1);
Command* command = InitiateConnectionCommandFactory::createInitiateConnectionCommand(CUIDCounterSingletonHolder::instance()->newID(),
_currentRequest, _requestGroup, e);
commands.push_back(command);
copy(streamCommands.begin(), streamCommands.end(), back_inserter(commands));
}
}
return commands;
}

View File

@ -45,6 +45,8 @@
#include "DiskAdaptor.h"
#include "RequestGroup.h"
#include "Option.h"
#include "DlRetryEx.h"
#include "DlAbortEx.h"
TrackerWatcherCommand::TrackerWatcherCommand(int32_t cuid,
RequestGroup* requestGroup,
@ -87,6 +89,7 @@ bool TrackerWatcherCommand::execute() {
btAnnounce->announceFailure();
btAnnounce->resetAnnounce();
} catch(DlRetryEx* ex) {
// TODO Can I remove this catch clause?
logger->error(EX_EXCEPTION_CAUGHT, ex);
delete ex;
btAnnounce->announceFailure();

View File

@ -38,6 +38,7 @@
#include "Randomizer.h"
#include "a2netcompat.h"
#include "a2time.h"
#include "DlAbortEx.h"
#include <ctype.h>
#include <errno.h>
#include <fcntl.h>
@ -331,7 +332,6 @@ void Util::fileCopy(const string& dest, const string& src) {
}
void Util::rangedFileCopy(const string& dest, const string& src, int64_t srcOffset, int64_t length)
throw(DlAbortEx*)
{
int32_t bufSize = 4096;
char buf[bufSize];

View File

@ -36,7 +36,6 @@
#define _D_UTIL_H_
#include "common.h"
#include "DlAbortEx.h"
#include "a2time.h"
#include "FileEntry.h"
#include <utility>
@ -100,7 +99,7 @@ public:
static void fileCopy(const string& destFile, const string& src);
static void rangedFileCopy(const string& destFile, const string& src, int64_t srcOffset, int64_t length) throw(DlAbortEx*);
static void rangedFileCopy(const string& destFile, const string& src, int64_t srcOffset, int64_t length);
static bool isPowerOf(int32_t num, int32_t base);

View File

@ -57,7 +57,7 @@
#define MSG_GOT_NEW_PIECE _("CUID#%d - we got new piece. index=%d")
#define MSG_GOT_WRONG_PIECE _("CUID#%d - we got wrong piece. index=%d")
#define MSG_DOWNLOAD_NOT_COMPLETE _("CUID#%d - Download not complete: %s")
#define MSG_DOWNLOAD_ALREADY_COMPLETED _("CUID#%d - Download has already completed: %s")
#define MSG_DOWNLOAD_ALREADY_COMPLETED _("#%d - Download has already completed: %s")
#define MSG_GOOD_CHECKSUM _("CUID#%d - Good checksum: %s")
#define MSG_BAD_CHECKSUM _("CUID#%d - Bad checksum: %s")
#define MSG_RESOLVING_HOSTNAME _("CUID#%d - Resolving hostname %s")

View File

@ -39,6 +39,7 @@
#include "OptionHandlerFactory.h"
#include "Util.h"
#include "message.h"
#include "Exception.h"
#include <fstream>
#include <sstream>

View File

@ -1,5 +1,6 @@
#include "Util.h"
#include "FixedNumberRandomizer.h"
#include "DlAbortEx.h"
#include <string>
#include <cppunit/extensions/HelperMacros.h>