|
From: <arn...@us...> - 2006-10-06 21:19:07
|
Revision: 663
http://svn.sourceforge.net/dcplusplus/?rev=663&view=rev
Author: arnetheduck
Date: 2006-10-06 14:18:32 -0700 (Fri, 06 Oct 2006)
Log Message:
-----------
Janitory
Modified Paths:
--------------
dcplusplus/trunk/Compile.txt
dcplusplus/trunk/Example.xml
dcplusplus/trunk/changelog.txt
dcplusplus/trunk/client/DownloadManager.cpp
dcplusplus/trunk/client/DownloadManager.h
dcplusplus/trunk/client/FinishedManager.cpp
dcplusplus/trunk/client/QueueManager.cpp
dcplusplus/trunk/client/QueueManager.h
dcplusplus/trunk/client/SettingsManager.cpp
dcplusplus/trunk/client/ShareManager.cpp
dcplusplus/trunk/client/ShareManager.h
dcplusplus/trunk/client/StringDefs.cpp
dcplusplus/trunk/client/StringDefs.h
dcplusplus/trunk/client/UploadManager.cpp
dcplusplus/trunk/client/UploadManager.h
dcplusplus/trunk/client/UserConnection.cpp
dcplusplus/trunk/client/UserConnection.h
dcplusplus/trunk/help/changelog.html
dcplusplus/trunk/windows/TransferView.cpp
Modified: dcplusplus/trunk/Compile.txt
===================================================================
--- dcplusplus/trunk/Compile.txt 2006-09-29 16:24:13 UTC (rev 662)
+++ dcplusplus/trunk/Compile.txt 2006-10-06 21:18:32 UTC (rev 663)
@@ -43,7 +43,7 @@
Linux / Unix:
I've made some rudimentary autoconf/automake scripts now, so you can compile the client part into a library
without too much hassle (I don't check if it compiles very often though...). You'll need the latest versions
-of automake and autoconf, and after getting the source (from CVS is easiest), do
+of automake and autoconf, and after getting the source (from SVN is easiest), do
"aclocal && automake && autoconf && configure && make" and you'll have the client part nicely compiled.
When / if I test it I do it on a Gentoo AMD64 box with the latest gcc in 64-bit mode, so I don't have a clue
if the 32-bit compile works...
@@ -56,7 +56,7 @@
ugly code, abusable features, feature that I don't like that bloat the application and incompatibility with other
modifications I've already done.
To increase the chances of your patch being accepted, post them in the DC++ bugzilla as diffs against the latest
-code you can find (in the cvs repository on sourceforge most probably). You can find a lot of
+code you can find (in the SVN repository on sourceforge most probably). You can find a lot of
information about diff and patch by googling for it. I like unified format (diff -u). When diffing, apply diff to
the folders of the two versions, so that the paths will be included in the diff.
By submitting a patch, you agree to that I get copyright of it. This to avoid stupid situations later on where
Modified: dcplusplus/trunk/Example.xml
===================================================================
--- dcplusplus/trunk/Example.xml 2006-09-29 16:24:13 UTC (rev 662)
+++ dcplusplus/trunk/Example.xml 2006-10-06 21:18:32 UTC (rev 663)
@@ -581,6 +581,7 @@
<String Name="UnableToCreateThread">Unable to create thread</String>
<String Name="UnableToOpenFilelist">Unable to open filelist: </String>
<String Name="UnableToRename">Unable to rename </String>
+ <String Name="UnableToSendFile">Unable to send file </String>
<String Name="Unknown">Unknown</String>
<String Name="UnknownAddress">Unknown address</String>
<String Name="UnknownCommand">Unknown command: </String>
Modified: dcplusplus/trunk/changelog.txt
===================================================================
--- dcplusplus/trunk/changelog.txt 2006-09-29 16:24:13 UTC (rev 662)
+++ dcplusplus/trunk/changelog.txt 2006-10-06 21:18:32 UTC (rev 663)
@@ -1,7 +1,10 @@
-- --
* [bug 1065] Code cleanup (thanks steven sheehy)
+* Fixed readme.txt (thanks ullner)
+* More code cleanup
+* Fixed trusted/untrusted upload view
+* Fixed crash on invalid remote command during upload
-
-- 0.697 2006-09-29 --
* [ADC] Fixed a few protocol issues
* Some code cleanup
Modified: dcplusplus/trunk/client/DownloadManager.cpp
===================================================================
--- dcplusplus/trunk/client/DownloadManager.cpp 2006-09-29 16:24:13 UTC (rev 662)
+++ dcplusplus/trunk/client/DownloadManager.cpp 2006-10-06 21:18:32 UTC (rev 663)
@@ -45,23 +45,27 @@
static const string DOWNLOAD_AREA = "Downloads";
const string Download::ANTI_FRAG_EXT = ".antifrag";
-const string DownloadManager::USER_LIST_NAME = "files.xml";
-const string DownloadManager::USER_LIST_NAME_BZ = "files.xml.bz2";
-
-Download::Download() throw() : file(NULL),
+Download::Download(UserConnection& conn) throw() : Transfer(conn), file(0),
crcCalc(NULL), treeValid(false) {
+ conn.setDownload(this);
}
-Download::Download(QueueItem* qi) throw() :
- target(qi->getTarget()), tempTarget(qi->getTempTarget()), file(NULL),
- crcCalc(NULL), tth(qi->getTTH()), treeValid(false) {
-
- setSize(qi->getSize());
- if(qi->isSet(QueueItem::FLAG_USER_LIST))
+Download::Download(UserConnection& conn, QueueItem& qi) throw() : Transfer(conn),
+ target(qi.getTarget()), tempTarget(qi.getTempTarget()), file(0),
+ crcCalc(NULL), treeValid(false)
+{
+ conn.setDownload(this);
+
+ setTTH(qi.getTTH());
+ setSize(qi.getSize());
+ if(qi.isSet(QueueItem::FLAG_USER_LIST))
setFlag(Download::FLAG_USER_LIST);
- if(qi->isSet(QueueItem::FLAG_RESUME))
+ if(qi.isSet(QueueItem::FLAG_RESUME))
setFlag(Download::FLAG_RESUME);
}
+Download::~Download() {
+ getUserConnection().setDownload(0);
+}
AdcCommand Download::getCommand(bool zlib) {
AdcCommand cmd(AdcCommand::CMD_GET);
@@ -126,7 +130,7 @@
if((u_int32_t)(aTick / 1000) % SETTING(AUTODROP_INTERVAL) == 0) {
for(Download::Iter i = downloads.begin(); i != downloads.end(); ++i) {
u_int32_t timeElapsed = GET_TICK() - (*i)->getStart();
- u_int32_t timeInactive = GET_TICK() - (*i)->getUserConnection()->getLastActivity();
+ u_int32_t timeInactive = GET_TICK() - (*i)->getUserConnection().getLastActivity();
u_int64_t bytesDownloaded = (*i)->getTotal();
bool timeElapsedOk = timeElapsed >= (u_int32_t)SETTING(AUTODROP_ELAPSED) * 1000;
bool timeInactiveOk = timeInactive <= (u_int32_t)SETTING(AUTODROP_INACTIVITY) * 1000;
@@ -139,9 +143,9 @@
(filesizeOk && BOOLSETTING(AUTODROP_ALL));
if(speedTooLow && onlineSourcesOk && dropIt) {
if(BOOLSETTING(AUTODROP_DISCONNECT) && !((*i)->isSet(Download::FLAG_USER_LIST))) {
- (*i)->getUserConnection()->disconnect();
+ (*i)->getUserConnection().disconnect();
} else {
- dropTargets.push_back(make_pair((*i)->getTarget(), (*i)->getUserConnection()->getUser()));
+ dropTargets.push_back(make_pair((*i)->getTarget(), (*i)->getUser()));
}
}
}
@@ -271,7 +275,7 @@
}
}
- Download* d = QueueManager::getInstance()->getDownload(aConn->getUser(), aConn->isSet(UserConnection::FLAG_SUPPORTS_TTHL));
+ Download* d = QueueManager::getInstance()->getDownload(*aConn, aConn->isSet(UserConnection::FLAG_SUPPORTS_TTHL));
if(!d) {
Lock l(cs);
@@ -279,9 +283,6 @@
return;
}
- d->setUserConnection(aConn);
- aConn->setDownload(d);
-
aConn->setState(UserConnection::STATE_FILELENGTH);
if(d->isSet(Download::FLAG_RESUME)) {
@@ -323,9 +324,9 @@
if(d->isSet(Download::FLAG_USER_LIST)) {
if(aConn->isSet(UserConnection::FLAG_SUPPORTS_XML_BZLIST)) {
- d->setSource(USER_LIST_NAME_BZ);
+ d->setSource(Transfer::USER_LIST_NAME_BZ);
} else {
- d->setSource(USER_LIST_NAME);
+ d->setSource(Transfer::USER_LIST_NAME);
}
}
@@ -482,7 +483,6 @@
}
if(d->getPos() >= d->getSize()) {
// Already finished?
- aSource->setDownload(NULL);
removeDownload(d);
QueueManager::getInstance()->putDownload(d, true);
removeConnection(aSource);
@@ -561,7 +561,7 @@
dcassert(d->getPos() != -1);
d->setStart(GET_TICK());
- aSource->setState(UserConnection::STATE_DONE);
+ aSource->setState(UserConnection::STATE_RUNNING);
fire(DownloadManagerListener::Starting(), d);
@@ -598,7 +598,7 @@
/** Download finished! */
void DownloadManager::handleEndData(UserConnection* aSource) {
- dcassert(aSource->getState() == UserConnection::STATE_DONE);
+ dcassert(aSource->getState() == UserConnection::STATE_RUNNING);
Download* d = aSource->getDownload();
dcassert(d != NULL);
@@ -620,7 +620,6 @@
QueueManager::getInstance()->removeSource(d->getTarget(), aSource->getUser(), QueueItem::Source::FLAG_BAD_TREE, false);
- aSource->setDownload(NULL);
QueueManager::getInstance()->putDownload(d, false);
checkDownloads(aSource);
@@ -680,7 +679,6 @@
removeDownload(d);
fire(DownloadManagerListener::Complete(), d);
- aSource->setDownload(NULL);
QueueManager::getInstance()->putDownload(d, true);
checkDownloads(aSource);
}
@@ -720,7 +718,6 @@
fire(DownloadManagerListener::Failed(), d, STRING(SFV_INCONSISTENCY));
QueueManager::getInstance()->removeSource(d->getTarget(), aSource->getUser(), QueueItem::Source::FLAG_CRC_WARN, false);
- aSource->setDownload(NULL);
QueueManager::getInstance()->putDownload(d, false);
checkDownloads(aSource);
@@ -734,29 +731,15 @@
return true;
}
+void Download::getParams(const UserConnection& aSource, StringMap& params) {
+ Transfer::getParams(aSource, params);
+ params["target"] = getTarget();
+ params["sfv"] = Util::toString(isSet(Download::FLAG_CRC32_OK) ? 1 : 0);
+}
+
void DownloadManager::logDownload(UserConnection* aSource, Download* d) {
StringMap params;
- params["target"] = d->getTarget();
- params["userNI"] = Util::toString(ClientManager::getInstance()->getNicks(aSource->getUser()->getCID()));
- params["userI4"] = aSource->getRemoteIp();
- StringList hubNames = ClientManager::getInstance()->getHubNames(aSource->getUser()->getCID());
- if(hubNames.empty())
- hubNames.push_back(STRING(OFFLINE));
- params["hub"] = Util::toString(hubNames);
- StringList hubs = ClientManager::getInstance()->getHubs(aSource->getUser()->getCID());
- if(hubs.empty())
- hubs.push_back(STRING(OFFLINE));
- params["hubURL"] = Util::toString(hubs);
- params["fileSI"] = Util::toString(d->getSize());
- params["fileSIshort"] = Util::formatBytes(d->getSize());
- params["fileSIchunk"] = Util::toString(d->getTotal());
- params["fileSIchunkshort"] = Util::formatBytes(d->getTotal());
- params["fileSIactual"] = Util::toString(d->getActual());
- params["fileSIactualshort"] = Util::formatBytes(d->getActual());
- params["speed"] = Util::formatBytes(d->getAverageSpeed()) + "/s";
- params["time"] = Util::formatSeconds((GET_TICK() - d->getStart()) / 1000);
- params["sfv"] = Util::toString(d->isSet(Download::FLAG_CRC32_OK) ? 1 : 0);
- params["fileTR"] = d->getTTH().toBase32();
+ d->getParams(*aSource, params);
LOG(LogManager::DOWNLOAD, params);
}
@@ -798,6 +781,10 @@
failDownload(aSource, STRING(NO_SLOTS_AVAILABLE));
}
+void DownloadManager::on(UserConnectionListener::Error, UserConnection* aSource, const string& aError) throw() {
+ failDownload(aSource, aError);
+}
+
void DownloadManager::on(UserConnectionListener::Failed, UserConnection* aSource, const string& aError) throw() {
failDownload(aSource, aError);
}
@@ -809,7 +796,6 @@
removeDownload(d);
fire(DownloadManagerListener::Failed(), d, reason);
- aSource->setDownload(0);
QueueManager::getInstance()->putDownload(d, false);
}
removeConnection(aSource);
@@ -893,8 +879,6 @@
removeDownload(d);
fire(DownloadManagerListener::Failed(), d, d->getTargetFileName() + ": " + STRING(FILE_NOT_AVAILABLE));
- aSource->setDownload(NULL);
-
QueueManager::getInstance()->removeSource(d->getTarget(), aSource->getUser(), d->isSet(Download::FLAG_TREE_DOWNLOAD) ? QueueItem::Source::FLAG_NO_TREE : QueueItem::Source::FLAG_FILE_NOT_AVAILABLE, false);
QueueManager::getInstance()->putDownload(d, false);
Modified: dcplusplus/trunk/client/DownloadManager.h
===================================================================
--- dcplusplus/trunk/client/DownloadManager.h 2006-09-29 16:24:13 UTC (rev 662)
+++ dcplusplus/trunk/client/DownloadManager.h 2006-10-06 21:18:32 UTC (rev 663)
@@ -60,11 +60,13 @@
FLAG_TTH_CHECK = 0x800
};
- Download() throw();
- Download(QueueItem* qi) throw();
+ Download(UserConnection& conn) throw();
+ Download(UserConnection& conn, QueueItem& qi) throw();
- virtual ~Download() { }
+ virtual void getParams(const UserConnection& aSource, StringMap& params);
+ virtual ~Download();
+
/**
* @remarks This function is only used from DownloadManager but its
* functionality could be useful in TransferView.
@@ -72,12 +74,7 @@
* @return Target filename without path.
*/
string getTargetFileName() {
- string::size_type i = getTarget().rfind('\\');
- if(i != string::npos) {
- return getTarget().substr(i + 1);
- } else {
- return getTarget();
- }
+ return Util::getFileName(getTarget());
}
/** @internal */
@@ -98,7 +95,6 @@
GETSET(string, tempTarget, TempTarget);
GETSET(OutputStream*, file, File);
GETSET(CrcOS*, crcCalc, CrcCalc);
- GETSET(TTHValue, tth, TTH);
GETSET(bool, treeValid, TreeValid);
private:
@@ -198,8 +194,6 @@
return downloads.size();
}
- static const string USER_LIST_NAME;
- static const string USER_LIST_NAME_BZ;
private:
enum { MOVER_LIMIT = 10*1024*1024 };
class FileMover : public Thread {
@@ -248,6 +242,7 @@
// UserConnectionListener
virtual void on(Data, UserConnection*, const u_int8_t*, size_t) throw();
+ virtual void on(Error, UserConnection*, const string&) throw();
virtual void on(Failed, UserConnection*, const string&) throw();
virtual void on(Sending, UserConnection*, int64_t) throw();
virtual void on(FileLength, UserConnection*, int64_t) throw();
Modified: dcplusplus/trunk/client/FinishedManager.cpp
===================================================================
--- dcplusplus/trunk/client/FinishedManager.cpp 2006-09-29 16:24:13 UTC (rev 662)
+++ dcplusplus/trunk/client/FinishedManager.cpp 2006-10-06 21:18:32 UTC (rev 663)
@@ -66,8 +66,8 @@
{
if(!d->isSet(Download::FLAG_TREE_DOWNLOAD) && (!d->isSet(Download::FLAG_USER_LIST) || BOOLSETTING(LOG_FILELIST_TRANSFERS))) {
FinishedItem *item = new FinishedItem(
- d->getTarget(), Util::toString(ClientManager::getInstance()->getNicks(d->getUserConnection()->getUser()->getCID())),
- Util::toString(ClientManager::getInstance()->getHubNames(d->getUserConnection()->getUser()->getCID())),
+ d->getTarget(), Util::toString(ClientManager::getInstance()->getNicks(d->getUser()->getCID())),
+ Util::toString(ClientManager::getInstance()->getHubNames(d->getUser()->getCID())),
d->getSize(), d->getTotal(), (GET_TICK() - d->getStart()), GET_TIME(), d->isSet(Download::FLAG_CRC32_OK));
{
Lock l(cs);
@@ -82,8 +82,8 @@
{
if(!u->isSet(Upload::FLAG_TTH_LEAVES) && (!u->isSet(Upload::FLAG_USER_LIST) || BOOLSETTING(LOG_FILELIST_TRANSFERS))) {
FinishedItem *item = new FinishedItem(
- u->getLocalFileName(), Util::toString(ClientManager::getInstance()->getNicks(u->getUserConnection()->getUser()->getCID())),
- Util::toString(ClientManager::getInstance()->getHubNames(u->getUserConnection()->getUser()->getCID())),
+ u->getSourceFile(), Util::toString(ClientManager::getInstance()->getNicks(u->getUser()->getCID())),
+ Util::toString(ClientManager::getInstance()->getHubNames(u->getUser()->getCID())),
u->getSize(), u->getTotal(), (GET_TICK() - u->getStart()), GET_TIME());
{
Lock l(cs);
Modified: dcplusplus/trunk/client/QueueManager.cpp
===================================================================
--- dcplusplus/trunk/client/QueueManager.cpp 2006-09-29 16:24:13 UTC (rev 662)
+++ dcplusplus/trunk/client/QueueManager.cpp 2006-10-06 21:18:32 UTC (rev 663)
@@ -724,13 +724,14 @@
}
}
-Download* QueueManager::getDownload(User::Ptr& aUser, bool supportsTrees) throw() {
+Download* QueueManager::getDownload(UserConnection& aSource, bool supportsTrees) throw() {
Lock l(cs);
+ User::Ptr& aUser = aSource.getUser();
// First check PFS's...
PfsIter pi = pfsQueue.find(aUser->getCID());
if(pi != pfsQueue.end()) {
- Download* d = new Download();
+ Download* d = new Download(aSource);
d->setFlag(Download::FLAG_PARTIAL_LIST);
d->setSource(pi->second);
return d;
@@ -743,7 +744,7 @@
userQueue.setRunning(q, aUser);
- Download* d = new Download(q);
+ Download* d = new Download(aSource, *q);
q->setCurrentDownload(d);
@@ -783,18 +784,18 @@
Lock l(cs);
if(aDownload->isSet(Download::FLAG_PARTIAL_LIST)) {
- pair<PfsIter, PfsIter> range = pfsQueue.equal_range(aDownload->getUserConnection()->getUser()->getCID());
+ pair<PfsIter, PfsIter> range = pfsQueue.equal_range(aDownload->getUser()->getCID());
PfsIter i = find_if(range.first, range.second, CompareSecond<CID, string>(aDownload->getSource()));
if(i != range.second) {
pfsQueue.erase(i);
- fire(QueueManagerListener::PartialList(), aDownload->getUserConnection()->getUser(), aDownload->getPFS());
+ fire(QueueManagerListener::PartialList(), aDownload->getUser(), aDownload->getPFS());
}
} else {
QueueItem* q = fileQueue.find(aDownload->getTarget());
if(q) {
if(aDownload->isSet(Download::FLAG_USER_LIST)) {
- if(aDownload->getSource() == DownloadManager::USER_LIST_NAME_BZ) {
+ if(aDownload->getSource() == Transfer::USER_LIST_NAME_BZ) {
q->setFlag(QueueItem::FLAG_XML_BZLIST);
} else {
q->unsetFlag(QueueItem::FLAG_XML_BZLIST);
@@ -861,7 +862,6 @@
}
}
}
- aDownload->setUserConnection(0);
delete aDownload;
}
Modified: dcplusplus/trunk/client/QueueManager.h
===================================================================
--- dcplusplus/trunk/client/QueueManager.h 2006-09-29 16:24:13 UTC (rev 662)
+++ dcplusplus/trunk/client/QueueManager.h 2006-10-06 21:18:32 UTC (rev 663)
@@ -103,7 +103,7 @@
QueueItem::StringMap& lockQueue() throw() { cs.enter(); return fileQueue.getQueue(); } ;
void unlockQueue() throw() { cs.leave(); }
- Download* getDownload(User::Ptr& aUser, bool supportsTrees) throw();
+ Download* getDownload(UserConnection& aSource, bool supportsTrees) throw();
void putDownload(Download* aDownload, bool finished) throw();
bool hasDownload(const User::Ptr& aUser, QueueItem::Priority minPrio = QueueItem::LOWEST) throw() {
Modified: dcplusplus/trunk/client/SettingsManager.cpp
===================================================================
--- dcplusplus/trunk/client/SettingsManager.cpp 2006-09-29 16:24:13 UTC (rev 662)
+++ dcplusplus/trunk/client/SettingsManager.cpp 2006-10-06 21:18:32 UTC (rev 663)
@@ -152,8 +152,8 @@
setDefault(USE_OEM_MONOFONT, false);
setDefault(POPUP_PMS, true);
setDefault(MIN_UPLOAD_SPEED, 0);
- setDefault(LOG_FORMAT_POST_DOWNLOAD, "%Y-%m-%d %H:%M: %[target]" + STRING(DOWNLOADED_FROM) + "%[userNI] (%[userCID]), %[fileSI] (%[fileSIchunk]), %[speed], %[time]");
- setDefault(LOG_FORMAT_POST_UPLOAD, "%Y-%m-%d %H:%M: %[source]" + STRING(UPLOADED_TO) + "%[userNI] (%[userCID]), %[fileSI] (%[fileSIchunk]), %[speed], %[time]");
+ setDefault(LOG_FORMAT_POST_DOWNLOAD, "%Y-%m-%d %H:%M: %[target]" + STRING(DOWNLOADED_FROM) + "%[userNI] (%[userCID]), %[fileSI] (%[fileSIchunk]), %[speed], %[time], %[fileTR]");
+ setDefault(LOG_FORMAT_POST_UPLOAD, "%Y-%m-%d %H:%M: %[source]" + STRING(UPLOADED_TO) + "%[userNI] (%[userCID]), %[fileSI] (%[fileSIchunk]), %[speed], %[time], %[fileTR]");
setDefault(LOG_FORMAT_MAIN_CHAT, "[%Y-%m-%d %H:%M] %[message]");
setDefault(LOG_FORMAT_PRIVATE_CHAT, "[%Y-%m-%d %H:%M] %[message]");
setDefault(LOG_FORMAT_STATUS, "[%Y-%m-%d %H:%M] %[message]");
Modified: dcplusplus/trunk/client/ShareManager.cpp
===================================================================
--- dcplusplus/trunk/client/ShareManager.cpp 2006-09-29 16:24:13 UTC (rev 662)
+++ dcplusplus/trunk/client/ShareManager.cpp 2006-10-06 21:18:32 UTC (rev 663)
@@ -82,9 +82,8 @@
}
}
-string ShareManager::translateTTH(const string& TTH) throw(ShareException) {
- TTHValue v(TTH);
- HashFileIter i = tthIndex.find(v);
+string ShareManager::translateTTH(const TTHValue& tth) throw(ShareException) {
+ HashFileIter i = tthIndex.find(tth);
if(i != tthIndex.end()) {
return i->second->getADCPath();
} else {
@@ -92,67 +91,64 @@
}
}
-string ShareManager::translateFileName(const string& aFile) throw(ShareException) {
- if(aFile == "MyList.DcLst") {
+string ShareManager::translateFileName(const string& virtualFile) throw(ShareException) {
+ if(virtualFile == "MyList.DcLst") {
throw ShareException("NMDC-style lists no longer supported, please upgrade your client");
- } else if(aFile == DownloadManager::USER_LIST_NAME || aFile == DownloadManager::USER_LIST_NAME_BZ) {
+ } else if(virtualFile == Transfer::USER_LIST_NAME_BZ || virtualFile == Transfer::USER_LIST_NAME) {
generateXmlList();
return getBZXmlFile();
} else {
- if(aFile.length() < 3)
- throw ShareException(UserConnection::FILE_NOT_AVAILABLE);
-
- string file;
-
+ string realFile;
Lock l(cs);
- // Check for tth root identifier
- if(aFile.compare(0, 4, "TTH/") == 0) {
- file = translateTTH(aFile.substr(4));
- } else if(aFile[0] != '/') {
+ Directory::File::Iter it;
+ if(!checkFile(virtualFile, realFile, it)) {
throw ShareException(UserConnection::FILE_NOT_AVAILABLE);
- } else {
- file = aFile;
}
+ return realFile;
+ }
+}
- string::size_type i = file.find('/', 1);
- if(i == string::npos)
- throw ShareException(UserConnection::FILE_NOT_AVAILABLE);
+TTHValue ShareManager::getTTH(const string& virtualName) throw(ShareException) {
+ Lock l(cs);
+ string realName;
+ Directory::File::Iter it;
+ if(!checkFile(virtualName, realName, it))
+ throw ShareException();
+ return it->getTTH();
+}
- StringPairIter j = lookupVirtual(file.substr(1, i-1));
- if(j == virtualMap.end()) {
- throw ShareException(UserConnection::FILE_NOT_AVAILABLE);
+MemoryInputStream* ShareManager::getTree(const string& aFile) {
+ TigerTree tree;
+ if(aFile.compare(0, 4, "TTH/") == 0) {
+ if(!HashManager::getInstance()->getTree(TTHValue(aFile.substr(4)), tree))
+ return 0;
+ } else {
+ try {
+ TTHValue tth = getTTH(aFile);
+ HashManager::getInstance()->getTree(tth, tree);
+ } catch(const Exception&) {
+ return 0;
}
-
- file = file.substr(i + 1);
- Directory::File::Iter it;
- if(!checkFile(j->second, file, it)) {
- throw ShareException(UserConnection::FILE_NOT_AVAILABLE);
- }
-
-#ifdef _WIN32
- for(i = 0; i < file.length(); ++i) {
- if(file[i] == '/')
- file[i] = '\\';
- }
-#endif
- return j->second + file;
}
+
+ vector<u_int8_t> buf = tree.getLeafData();
+ return new MemoryInputStream(&buf[0], buf.size());
}
AdcCommand ShareManager::getFileInfo(const string& aFile) throw(ShareException) {
- if(aFile == DownloadManager::USER_LIST_NAME) {
+ if(aFile == Transfer::USER_LIST_NAME) {
generateXmlList();
/** todo fix size... */
AdcCommand cmd(AdcCommand::CMD_RES);
- cmd.addParam("FN", DownloadManager::USER_LIST_NAME);
+ cmd.addParam("FN", aFile);
cmd.addParam("TR", xmlRoot.toBase32());
return cmd;
- } else if(aFile == DownloadManager::USER_LIST_NAME_BZ) {
+ } else if(aFile == Transfer::USER_LIST_NAME_BZ) {
generateXmlList();
AdcCommand cmd(AdcCommand::CMD_RES);
- cmd.addParam("FN", DownloadManager::USER_LIST_NAME_BZ);
+ cmd.addParam("FN", aFile);
cmd.addParam("SI", Util::toString(File::getSize(getBZXmlFile())));
cmd.addParam("TR", xmlbzRoot.toBase32());
return cmd;
@@ -176,42 +172,68 @@
return cmd;
}
-StringPairIter ShareManager::findVirtual(const string& name) {
+StringPairIter ShareManager::findVirtual(const string& realName) {
for(StringPairIter i = virtualMap.begin(); i != virtualMap. end(); ++i) {
- if(Util::stricmp(name, i->second) == 0)
+ if(Util::stricmp(realName, i->second) == 0)
return i;
}
return virtualMap.end();
}
-StringPairIter ShareManager::lookupVirtual(const string& name) {
+StringPairIter ShareManager::findReal(const string& virtualName) {
for(StringPairIter i = virtualMap.begin(); i != virtualMap. end(); ++i) {
- if(Util::stricmp(name, i->first) == 0)
+ if(Util::stricmp(virtualName, i->first) == 0)
return i;
}
return virtualMap.end();
}
-bool ShareManager::checkFile(const string& dir, const string& aFile, Directory::File::Iter& it) {
- Directory::MapIter mi = directories.find(dir);
+bool ShareManager::checkFile(const string& virtualFile, string& realFile, Directory::File::Iter& it) {
+ string file;
+ if(virtualFile.compare(0, 4, "TTH/") == 0) {
+ file = translateTTH(TTHValue(virtualFile.substr(4)));
+ } else if(virtualFile.empty() || virtualFile[0] != '/') {
+ return false;
+ } else {
+ file = virtualFile;
+ }
+
+ string::size_type i = file.find('/', 1);
+ if(i == string::npos || i == 1) {
+ return false;
+ }
+
+ StringPairIter k = findReal(file.substr(1, i-1));
+ if(k == virtualMap.end()) {
+ return false;
+ }
+
+ file = file.substr(i + 1);
+
+ Directory::MapIter mi = directories.find(k->second);
if(mi == directories.end())
return false;
Directory* d = mi->second;
- string::size_type i;
string::size_type j = 0;
- while( (i = aFile.find('/', j)) != string::npos) {
- mi = d->directories.find(aFile.substr(j, i-j));
+ while( (i = file.find('/', j)) != string::npos) {
+ mi = d->directories.find(file.substr(j, i-j));
j = i + 1;
if(mi == d->directories.end())
return false;
d = mi->second;
}
- it = find_if(d->files.begin(), d->files.end(), Directory::File::StringComp(aFile.substr(j)));
+ it = find_if(d->files.begin(), d->files.end(), Directory::File::StringComp(file.substr(j)));
if(it == d->files.end())
return false;
+
+#ifdef _WIN32
+ replace_if(file.begin(), file.end(), bind2nd(equal_to<char>(), '/'), '\\');
+#endif
+
+ realFile = k->second + file;
return true;
}
@@ -249,7 +271,7 @@
newVirt = validateVirtual(newVirt);
// add only unique directories
- if(lookupVirtual(newVirt) == virtualMap.end()) {
+ if(findReal(newVirt) == virtualMap.end()) {
Directory* dp = new Directory(newVirt);
directories[d] = dp;
virtualMap.push_back(make_pair(newVirt, d));
@@ -381,7 +403,7 @@
}
}
- if(lookupVirtual(vName) != virtualMap.end()) {
+ if(findReal(vName) != virtualMap.end()) {
throw ShareException(STRING(VIRTUAL_NAME_EXISTS));
}
}
@@ -427,13 +449,12 @@
}
void ShareManager::renameDirectory(const string& oName, const string& nName) throw(ShareException) {
- StringPairIter i;
Lock l(cs);
//Find the virtual name
- i = lookupVirtual(oName);
- if (lookupVirtual(nName) != virtualMap.end()) {
+ if (findReal(nName) != virtualMap.end()) {
throw ShareException(STRING(VIRTUAL_NAME_EXISTS));
} else {
+ StringPairIter i = findReal(oName);
// Valid newName, lets rename
i->first = nName;
@@ -886,7 +907,7 @@
if(first) {
first = false;
- StringPairIter k = lookupVirtual(dir.substr(j, i-j));
+ StringPairIter k = findReal(dir.substr(j, i-j));
if(k == virtualMap.end())
return NULL;
it = directories.find(k->second);
@@ -911,47 +932,6 @@
return new MemoryInputStream(xml);
}
-bool ShareManager::getTTH(const string& aFile, TTHValue& tth) throw() {
- if(aFile.length() < 3 || aFile[0] != '/')
- return false;
-
- string::size_type i = aFile.find('/', 1);
- if(i == string::npos)
- return false;
-
- Lock l(cs);
- StringPairIter j = lookupVirtual(aFile.substr(1, i-1));
- if(j == virtualMap.end()) {
- return false;
- }
-
- Directory::File::Iter it;
- if(!checkFile(j->second, aFile.substr(i + 1), it))
- return false;
-
- tth = it->getTTH();
- return true;
-}
-
-MemoryInputStream* ShareManager::getTree(const string& aFile) {
- TigerTree tree;
- if(aFile.compare(0, 4, "TTH/") == 0) {
- if(!HashManager::getInstance()->getTree(TTHValue(aFile.substr(4)), tree))
- return NULL;
- } else {
- try {
- TTHValue tth;
- if(getTTH(aFile, tth))
- HashManager::getInstance()->getTree(tth, tree);
- } catch(const Exception&) {
- return NULL;
- }
- }
-
- vector<u_int8_t> buf = tree.getLeafData();
- return new MemoryInputStream(&buf[0], buf.size());
-}
-
static const string& escaper(const string& n, string& tmp) {
if(SimpleXML::needsEscape(n, true, false)) {
tmp.clear();
Modified: dcplusplus/trunk/client/ShareManager.h
===================================================================
--- dcplusplus/trunk/client/ShareManager.h 2006-09-29 16:24:13 UTC (rev 662)
+++ dcplusplus/trunk/client/ShareManager.h 2006-10-06 21:18:32 UTC (rev 663)
@@ -57,9 +57,10 @@
void addDirectory(const string& aDirectory, const string & aName) throw(ShareException);
void removeDirectory(const string& aName, bool duringRefresh = false);
void renameDirectory(const string& oName, const string& nName) throw(ShareException);
- string translateTTH(const string& TTH) throw(ShareException);
+ string translateTTH(const TTHValue& tth) throw(ShareException);
string translateFileName(const string& aFile) throw(ShareException);
- bool getTTH(const string& aFile, TTHValue& tth) throw();
+ TTHValue getTTH(const string& aFile) throw(ShareException);
+
void refresh(bool dirs = false, bool aUpdate = true, bool block = false) throw(ThreadException, ShareException);
void setDirty() { xmlDirty = true; }
@@ -283,11 +284,11 @@
BloomFilter<5> bloom;
/** Find virtual name from real name */
- StringPairIter findVirtual(const string& name);
+ StringPairIter findVirtual(const string& realName);
/** Find real name from virtual name */
- StringPairIter lookupVirtual(const string& name);
+ StringPairIter findReal(const string& virtualName);
- bool checkFile(const string& aDir, const string& aFile, Directory::File::Iter& it);
+ bool checkFile(const string& virtualFile, string& realFile, Directory::File::Iter& it);
Directory* buildTree(const string& aName, Directory* aParent);
void addTree(Directory* aDirectory);
Modified: dcplusplus/trunk/client/StringDefs.cpp
===================================================================
--- dcplusplus/trunk/client/StringDefs.cpp 2006-09-29 16:24:13 UTC (rev 662)
+++ dcplusplus/trunk/client/StringDefs.cpp 2006-10-06 21:18:32 UTC (rev 663)
@@ -582,6 +582,7 @@
"Unable to create thread",
"Unable to open filelist: ",
"Unable to rename ",
+"Unable to send file ",
"Unknown",
"Unknown address",
"Unknown command: ",
@@ -1210,6 +1211,7 @@
"UnableToCreateThread",
"UnableToOpenFilelist",
"UnableToRename",
+"UnableToSendFile",
"Unknown",
"UnknownAddress",
"UnknownCommand",
Modified: dcplusplus/trunk/client/StringDefs.h
===================================================================
--- dcplusplus/trunk/client/StringDefs.h 2006-09-29 16:24:13 UTC (rev 662)
+++ dcplusplus/trunk/client/StringDefs.h 2006-10-06 21:18:32 UTC (rev 663)
@@ -585,6 +585,7 @@
UNABLE_TO_CREATE_THREAD, // "Unable to create thread"
UNABLE_TO_OPEN_FILELIST, // "Unable to open filelist: "
UNABLE_TO_RENAME, // "Unable to rename "
+ UNABLE_TO_SEND_FILE, // "Unable to send file "
UNKNOWN, // "Unknown"
UNKNOWN_ADDRESS, // "Unknown address"
UNKNOWN_COMMAND, // "Unknown command: "
Modified: dcplusplus/trunk/client/UploadManager.cpp
===================================================================
--- dcplusplus/trunk/client/UploadManager.cpp 2006-09-29 16:24:13 UTC (rev 662)
+++ dcplusplus/trunk/client/UploadManager.cpp 2006-10-06 21:18:32 UTC (rev 663)
@@ -37,6 +37,20 @@
static const string UPLOAD_AREA = "Uploads";
+Upload::Upload(UserConnection& conn) : Transfer(conn), stream(0) {
+ conn.setUpload(this);
+}
+
+Upload::~Upload() {
+ getUserConnection().setUpload(0);
+ delete stream;
+}
+
+void Upload::getParams(const UserConnection& aSource, StringMap& params) {
+ Transfer::getParams(aSource, params);
+ params["source"] = getSourceFile();
+}
+
UploadManager::UploadManager() throw() : running(0), extra(0), lastGrant(0) {
ClientManager::getInstance()->addListener(this);
TimerManager::getInstance()->addListener(this);
@@ -55,153 +69,143 @@
}
}
-bool UploadManager::prepareFile(UserConnection* aSource, const string& aType, const string& aFile, int64_t aStartPos, int64_t aBytes, bool listRecursive) {
- if(aSource->getState() != UserConnection::STATE_GET) {
- dcdebug("UM:prepFile Wrong state, ignoring\n");
+bool UploadManager::prepareFile(UserConnection& aSource, const string& aType, const string& aFile, int64_t aStartPos, int64_t aBytes, bool listRecursive) {
+ if(aFile.empty() || aStartPos < 0 || aBytes < -1 || aBytes == 0) {
+ aSource.fileNotAvail("Invalid request");
return false;
}
- dcassert(aFile.size() > 0);
-
- InputStream* is = NULL;
+ InputStream* is = 0;
+ int64_t start = 0;
+ int64_t bytesLeft = 0;
int64_t size = 0;
- bool userlist = false;
- bool free = false;
+ bool userlist = (aFile == Transfer::USER_LIST_NAME_BZ || aFile == Transfer::USER_LIST_NAME);
+ bool free = userlist;
bool leaves = false;
bool partList = false;
- string file;
+ string sourceFile;
try {
- if(aType == "file") {
- file = ShareManager::getInstance()->translateFileName(aFile);
- userlist = (aFile == DownloadManager::USER_LIST_NAME_BZ || aFile == DownloadManager::USER_LIST_NAME);
+ if(aType == Transfer::TYPE_FILE) {
+ sourceFile = ShareManager::getInstance()->translateFileName(aFile);
- try {
- if(aFile == DownloadManager::USER_LIST_NAME) {
- // Unpack before sending...
- string bz2 = File(file, File::READ, File::OPEN).read();
- string xml;
- CryptoManager::getInstance()->decodeBZ2(reinterpret_cast<const u_int8_t*>(bz2.data()), bz2.size(), xml);
- // Clear to save some memory...
- bz2 = string();
- is = new MemoryInputStream(xml);
- aBytes = size = xml.size();
- aStartPos = 0;
- free = true;
-
- } else {
- File* f = new File(file, File::READ, File::OPEN);
+ if(aFile == Transfer::USER_LIST_NAME) {
+ // Unpack before sending...
+ string bz2 = File(sourceFile, File::READ, File::OPEN).read();
+ string xml;
+ CryptoManager::getInstance()->decodeBZ2(reinterpret_cast<const u_int8_t*>(bz2.data()), bz2.size(), xml);
+ // Clear to save some memory...
+ string().swap(bz2);
+ is = new MemoryInputStream(xml);
+ start = 0;
+ bytesLeft = size = xml.size();
+ } else {
+ File* f = new File(sourceFile, File::READ, File::OPEN);
- size = f->getSize();
+ start = aStartPos;
+ size = f->getSize();
+ bytesLeft = (aBytes == -1) ? size : aBytes;
- free = userlist || (size <= (int64_t)(SETTING(SET_MINISLOT_SIZE) * 1024) );
+ if(size < (start + bytesLeft)) {
+ aSource.fileNotAvail();
+ delete f;
+ return false;
+ }
- if(aBytes == -1) {
- aBytes = size - aStartPos;
- }
+ free = (size <= (int64_t)(SETTING(SET_MINISLOT_SIZE) * 1024) );
- if((aBytes < 0) || ((aStartPos + aBytes) > size)) {
- aSource->fileNotAvail();
- delete f;
- return false;
- }
+ f->setPos(start);
- f->setPos(aStartPos);
-
- is = f;
-
- if((aStartPos + aBytes) < size) {
- is = new LimitedInputStream<true>(is, aBytes);
- }
+ is = f;
+ if((start + bytesLeft) < size) {
+ is = new LimitedInputStream<true>(is, aBytes);
}
- } catch(const Exception&) {
- aSource->fileNotAvail();
- return false;
}
-
- } else if(aType == "tthl") {
- // TTH Leaves...
+ } else if(aType == Transfer::TYPE_TTHL) {
+ sourceFile = ShareManager::getInstance()->translateFileName(aFile);
MemoryInputStream* mis = ShareManager::getInstance()->getTree(aFile);
- file = ShareManager::getInstance()->translateFileName(aFile);
- if(mis == NULL) {
- aSource->fileNotAvail();
+ if(!mis) {
+ aSource.fileNotAvail();
return false;
}
- size = mis->getSize();
- aStartPos = 0;
+ start = 0;
+ bytesLeft = size = mis->getSize();
is = mis;
leaves = true;
free = true;
- } else if(aType == "list") {
+ } else if(aType == Transfer::TYPE_LIST) {
// Partial file list
MemoryInputStream* mis = ShareManager::getInstance()->generatePartialList(aFile, listRecursive);
if(mis == NULL) {
- aSource->fileNotAvail();
+ aSource.fileNotAvail();
return false;
}
// Some old dc++ clients err here...
aBytes = -1;
- size = mis->getSize();
- aStartPos = 0;
+ start = 0;
+ bytesLeft = size = mis->getSize();
+
is = mis;
free = true;
partList = true;
} else {
- aSource->fileNotAvail();
+ aSource.fileNotAvail("Unknown file type");
return false;
}
} catch(const ShareException& e) {
- aSource->fileNotAvail(e.getError());
+ aSource.fileNotAvail(e.getError());
return false;
+ } catch(const Exception& e) {
+ LogManager::getInstance()->message(STRING(UNABLE_TO_SEND_FILE) + sourceFile + ": " + e.getError());
+ aSource.fileNotAvail();
+ return false;
}
Lock l(cs);
bool extraSlot = false;
- if(!aSource->isSet(UserConnection::FLAG_HASSLOT)) {
- bool hasReserved = (reservedSlots.find(aSource->getUser()) != reservedSlots.end());
- bool isFavorite = FavoriteManager::getInstance()->hasSlot(aSource->getUser());
+ if(!aSource.isSet(UserConnection::FLAG_HASSLOT)) {
+ bool hasReserved = (reservedSlots.find(aSource.getUser()) != reservedSlots.end());
+ bool isFavorite = FavoriteManager::getInstance()->hasSlot(aSource.getUser());
if(!(hasReserved || isFavorite || getFreeSlots() > 0 || getAutoSlot())) {
- bool supportsFree = aSource->isSet(UserConnection::FLAG_SUPPORTS_MINISLOTS);
- bool allowedFree = aSource->isSet(UserConnection::FLAG_HASEXTRASLOT) || aSource->isSet(UserConnection::FLAG_OP) || getFreeExtraSlots() > 0;
+ bool supportsFree = aSource.isSet(UserConnection::FLAG_SUPPORTS_MINISLOTS);
+ bool allowedFree = aSource.isSet(UserConnection::FLAG_HASEXTRASLOT) || aSource.isSet(UserConnection::FLAG_OP) || getFreeExtraSlots() > 0;
if(free && supportsFree && allowedFree) {
extraSlot = true;
} else {
delete is;
- aSource->maxedOut();
+ aSource.maxedOut();
// Check for tth root identifier
string tFile = aFile;
if (tFile.compare(0, 4, "TTH/") == 0)
- tFile = ShareManager::getInstance()->translateTTH(aFile.substr(4));
+ tFile = ShareManager::getInstance()->translateTTH(TTHValue(aFile.substr(4)));
addFailedUpload(aSource, tFile +
- " (" + Util::toString((aStartPos*1000/(File::getSize(file)+10))/10.0)+"% of " + Util::formatBytes(File::getSize(file)) + " done)");
- aSource->disconnect();
+ " (" + Util::toString((aStartPos*1000/(size+10))/10.0)+"% of " + Util::formatBytes(size) + " done)");
+ aSource.disconnect();
return false;
}
} else {
- clearUserFiles(aSource->getUser()); // this user is using a full slot, nix them.
+ clearUserFiles(aSource.getUser()); // this user is using a full slot, nix them.
}
setLastGrant(GET_TICK());
}
- Upload* u = new Upload();
- u->setUserConnection(aSource);
- u->setFile(is);
+ Upload* u = new Upload(aSource);
+ u->setStream(is);
if(aBytes == -1)
u->setSize(size);
else
- u->setSize(aStartPos + aBytes);
+ u->setSize(start + bytesLeft);
- u->setStartPos(aStartPos);
- u->setFileName(file);
- u->setLocalFileName(file);
+ u->setStartPos(start);
+ u->setSourceFile(sourceFile);
if(userlist)
u->setFlag(Upload::FLAG_USER_LIST);
@@ -210,36 +214,45 @@
if(partList)
u->setFlag(Upload::FLAG_PARTIAL_LIST);
- dcassert(aSource->getUpload() == NULL);
- aSource->setUpload(u);
+ dcassert(aSource.getUpload() == NULL);
uploads.push_back(u);
- if(!aSource->isSet(UserConnection::FLAG_HASSLOT)) {
+ if(!aSource.isSet(UserConnection::FLAG_HASSLOT)) {
if(extraSlot) {
- if(!aSource->isSet(UserConnection::FLAG_HASEXTRASLOT)) {
- aSource->setFlag(UserConnection::FLAG_HASEXTRASLOT);
+ if(!aSource.isSet(UserConnection::FLAG_HASEXTRASLOT)) {
+ aSource.setFlag(UserConnection::FLAG_HASEXTRASLOT);
extra++;
}
} else {
- if(aSource->isSet(UserConnection::FLAG_HASEXTRASLOT)) {
- aSource->unsetFlag(UserConnection::FLAG_HASEXTRASLOT);
+ if(aSource.isSet(UserConnection::FLAG_HASEXTRASLOT)) {
+ aSource.unsetFlag(UserConnection::FLAG_HASEXTRASLOT);
extra--;
}
- aSource->setFlag(UserConnection::FLAG_HASSLOT);
+ aSource.setFlag(UserConnection::FLAG_HASSLOT);
running++;
}
- reservedSlots.erase(aSource->getUser());
+ reservedSlots.erase(aSource.getUser());
}
return true;
}
+bool UploadManager::getAutoSlot() {
+ /** A 0 in settings means disable */
+ if(SETTING(MIN_UPLOAD_SPEED) == 0)
+ return false;
+ /** Only grant one slot per 30 sec */
+ if(GET_TICK() < getLastGrant() + 30*1000)
+ return false;
+ /** Grant if upload speed is less than the threshold speed */
+ return getAverageSpeed() < (SETTING(MIN_UPLOAD_SPEED)*1024);
+}
+
void UploadManager::removeUpload(Upload* aUpload) {
Lock l(cs);
dcassert(find(uploads.begin(), uploads.end(), aUpload) != uploads.end());
uploads.erase(remove(uploads.begin(), uploads.end(), aUpload), uploads.end());
- aUpload->setUserConnection(NULL);
delete aUpload;
}
@@ -253,7 +266,12 @@
}
void UploadManager::on(UserConnectionListener::Get, UserConnection* aSource, const string& aFile, int64_t aResume) throw() {
- if(prepareFile(aSource, "file", Util::toAdcFile(aFile), aResume, -1)) {
+ if(aSource->getState() != UserConnection::STATE_GET) {
+ dcdebug("UM::onGet Bad state, ignoring\n");
+ return;
+ }
+
+ if(prepareFile(*aSource, Transfer::TYPE_FILE, Util::toAdcFile(aFile), aResume, -1)) {
aSource->setState(UserConnection::STATE_SEND);
aSource->fileLength(Util::toString(aSource->getUpload()->getSize()));
}
@@ -269,13 +287,43 @@
dcassert(u != NULL);
u->setStart(GET_TICK());
- aSource->setState(UserConnection::STATE_DONE);
- aSource->transmitFile(u->getFile());
+ aSource->setState(UserConnection::STATE_RUNNING);
+ aSource->transmitFile(u->getStream());
fire(UploadManagerListener::Starting(), u);
}
+void UploadManager::on(AdcCommand::GET, UserConnection* aSource, const AdcCommand& c) throw() {
+ int64_t aBytes = Util::toInt64(c.getParam(3));
+ int64_t aStartPos = Util::toInt64(c.getParam(2));
+ const string& fname = c.getParam(1);
+ const string& type = c.getParam(0);
+
+ if(prepareFile(*aSource, type, fname, aStartPos, aBytes, c.hasFlag("RE", 4))) {
+ Upload* u = aSource->getUpload();
+ dcassert(u != NULL);
+
+ AdcCommand cmd(AdcCommand::CMD_SND);
+ cmd.addParam(type).addParam(fname)
+ .addParam(Util::toString(u->getPos()))
+ .addParam(Util::toString(u->getSize() - u->getPos()));
+
+ if(c.hasFlag("ZL", 4)) {
+ u->setStream(new FilteredInputStream<ZFilter, true>(u->getStream()));
+ u->setFlag(Upload::FLAG_ZUPLOAD);
+ cmd.addParam("ZL1");
+ }
+
+ aSource->send(cmd);
+
+ u->setStart(GET_TICK());
+ aSource->setState(UserConnection::STATE_RUNNING);
+ aSource->transmitFile(u->getStream());
+ fire(UploadManagerListener::Starting(), u);
+ }
+}
+
void UploadManager::on(UserConnectionListener::BytesSent, UserConnection* aSource, size_t aBytes, size_t aActual) throw() {
- dcassert(aSource->getState() == UserConnection::STATE_DONE);
+ dcassert(aSource->getState() == UserConnection::STATE_RUNNING);
Upload* u = aSource->getUpload();
dcassert(u != NULL);
u->addPos(aBytes, aActual);
@@ -285,7 +333,6 @@
Upload* u = aSource->getUpload();
if(u) {
- aSource->setUpload(NULL);
fire(UploadManagerListener::Failed(), u, aError);
dcdebug("UM::onFailed: Removing upload\n");
@@ -296,35 +343,15 @@
}
void UploadManager::on(UserConnectionListener::TransmitDone, UserConnection* aSource) throw() {
- dcassert(aSource->getState() == UserConnection::STATE_DONE);
+ dcassert(aSource->getState() == UserConnection::STATE_RUNNING);
Upload* u = aSource->getUpload();
dcassert(u != NULL);
- aSource->setUpload(NULL);
aSource->setState(UserConnection::STATE_GET);
if(BOOLSETTING(LOG_UPLOADS) && !u->isSet(Upload::FLAG_TTH_LEAVES) && (BOOLSETTING(LOG_FILELIST_TRANSFERS) || !u->isSet(Upload::FLAG_USER_LIST))) {
StringMap params;
- params["source"] = u->getFileName();
- params["userNI"] = Util::toString(ClientManager::getInstance()->getNicks(aSource->getUser()->getCID()));
- params["userI4"] = aSource->getRemoteIp();
- StringList hubNames = ClientManager::getInstance()->getHubNames(aSource->getUser()->getCID());
- if(hubNames.empty())
- hubNames.push_back(STRING(OFFLINE));
- params["hub"] = Util::toString(hubNames);
- StringList hubs = ClientManager::getInstance()->getHubs(aSource->getUser()->getCID());
- if(hubs.empty())
- hubs.push_back(STRING(OFFLINE));
- params["hubURL"] = Util::toString(hubs);
- params["fileSI"] = Util::toString(u->getSize());
- params["fileSIshort"] = Util::formatBytes(u->getSize());
- params["fileSIchunk"] = Util::toString(u->getTotal());
- params["fileSIchunkshort"] = Util::formatBytes(u->getTotal());
- params["fileSIactual"] = Util::toString(u->getActual());
- params["fileSIactualshort"] = Util::formatBytes(u->getActual());
- params["speed"] = Util::formatBytes(u->getAverageSpeed()) + "/s";
- params["time"] = Util::formatSeconds((GET_TICK() - u->getStart()) / 1000);
- params["tth"] = u->getTTH().toBase32();
+ u->getParams(*aSource, params);
LOG(LogManager::UPLOAD, params);
}
@@ -332,15 +359,15 @@
removeUpload(u);
}
-void UploadManager::addFailedUpload(UserConnection::Ptr source, string filename) {
+void UploadManager::addFailedUpload(const UserConnection& source, string filename) {
{
Lock l(cs);
- if (!count_if(waitingUsers.begin(), waitingUsers.end(), UserMatch(source->getUser())))
- waitingUsers.push_back(WaitingUser(source->getUser(), GET_TICK()));
- waitingFiles[source->getUser()].insert(filename); //files for which user's asked
+ if (!count_if(waitingUsers.begin(), waitingUsers.end(), UserMatch(source.getUser())))
+ waitingUsers.push_back(WaitingUser(source.getUser(), GET_TICK()));
+ waitingFiles[source.getUser()].insert(filename); //files for which user's asked
}
- fire(UploadManagerListener::WaitingAddFile(), source->getUser(), filename);
+ fire(UploadManagerListener::WaitingAddFile(), source.getUser(), filename);
}
void UploadManager::clearUserFiles(const User::Ptr& source) {
@@ -368,94 +395,65 @@
return waitingFiles.find(u)->second;
}
-void UploadManager::removeConnection(UserConnection::Ptr aConn) {
- dcassert(aConn->getUpload() == NULL);
- aConn->removeListener(this);
- if(aConn->isSet(UserConnection::FLAG_HASSLOT)) {
+void UploadManager::removeConnection(UserConnection* aSource) {
+ dcassert(aSource->getUpload() == NULL);
+ aSource->removeListener(this);
+ if(aSource->isSet(UserConnection::FLAG_HASSLOT)) {
running--;
- aConn->unsetFlag(UserConnection::FLAG_HASSLOT);
+ aSource->unsetFlag(UserConnection::FLAG_HASSLOT);
}
- if(aConn->isSet(UserConnection::FLAG_HASEXTRASLOT)) {
+ if(aSource->isSet(UserConnection::FLAG_HASEXTRASLOT)) {
extra--;
- aConn->unsetFlag(UserConnection::FLAG_HASEXTRASLOT);
+ aSource->unsetFlag(UserConnection::FLAG_HASEXTRASLOT);
}
}
void UploadManager::on(TimerManagerListener::Minute, u_int32_t /* aTick */) throw() {
- Lock l(cs);
+ User::List disconnects;
+ {
+ Lock l(cs);
- UserList::iterator i = stable_partition(waitingUsers.begin(), waitingUsers.end(), WaitingUserFresh());
- for (UserList::iterator j = i; j != waitingUsers.end(); ++j) {
- FilesMap::iterator fit = waitingFiles.find(j->first);
- if (fit != waitingFiles.end()) waitingFiles.erase(fit);
- fire(UploadManagerListener::WaitingRemoveUser(), j->first);
- }
+ UserList::iterator i = stable_partition(waitingUsers.begin(), waitingUsers.end(), WaitingUserFresh());
+ for (UserList::iterator j = i; j != waitingUsers.end(); ++j) {
+ FilesMap::iterator fit = waitingFiles.find(j->first);
+ if (fit != waitingFiles.end()) waitingFiles.erase(fit);
+ fire(UploadManagerListener::WaitingRemoveUser(), j->first);
+ }
- waitingUsers.erase(i, waitingUsers.end());
+ waitingUsers.erase(i, waitingUsers.end());
- if( BOOLSETTING(AUTO_KICK) ) {
- for(Upload::Iter i = uploads.begin(); i != uploads.end(); ++i) {
- Upload* u = *i;
- if(u->getUser()->isOnline()) {
- u->unsetFlag(Upload::FLAG_PENDING_KICK);
- continue;
- }
+ if( BOOLSETTING(AUTO_KICK) ) {
+ for(Upload::Iter i = uploads.begin(); i != uploads.end(); ++i) {
+ Upload* u = *i;
+ if(u->getUser()->isOnline()) {
+ u->unsetFlag(Upload::FLAG_PENDING_KICK);
+ continue;
+ }
- if(u->isSet(Upload::FLAG_PENDING_KICK)) {
- u->getUserConnection()->disconnect(true);
- LogManager::getInstance()->message(STRING(DISCONNECTED_USER) + Util::toString(ClientManager::getInstance()->getNicks(u->getUser()->getCID())));
- }
+ if(u->isSet(Upload::FLAG_PENDING_KICK)) {
+ disconnects.push_back(u->getUser());
+ continue;
+ }
- if(BOOLSETTING(AUTO_KICK_NO_FAVS) && FavoriteManager::getInstance()->isFavoriteUser(u->getUser())) {
- continue;
- }
+ if(BOOLSETTING(AUTO_KICK_NO_FAVS) && FavoriteManager::getInstance()->isFavoriteUser(u->getUser())) {
+ continue;
+ }
- u->setFlag(Upload::FLAG_PENDING_KICK);
+ u->setFlag(Upload::FLAG_PENDING_KICK);
+ }
}
}
+ for(User::Iter i = disconnects.begin(); i != disconnects.end(); ++i) {
+ LogManager::getInstance()->message(STRING(DISCONNECTED_USER) + Util::toString(ClientManager::getInstance()->getNicks((*i)->getCID())));
+ ConnectionManager::getInstance()->disconnect(*i, false);
+ }
}
void UploadManager::on(GetListLength, UserConnection* conn) throw() {
conn->listLen("42");
}
-void UploadManager::on(AdcCommand::GET, UserConnection* aSource, const AdcCommand& c) throw() {
- int64_t aBytes = Util::toInt64(c.getParam(3));
- int64_t aStartPos = Util::toInt64(c.getParam(2));
- const string& fname = c.getParam(1);
- const string& type = c.getParam(0);
- string tmp;
-
- if(prepareFile(aSource, type, fname, aStartPos, aBytes, c.hasFlag("RE", 4))) {
- Upload* u = aSource->getUpload();
- dcassert(u != NULL);
- if(aBytes == -1)
- aBytes = u->getSize() - aStartPos;
-
- dcassert(aBytes >= 0);
-
- u->setStart(GET_TICK());
-
- AdcCommand cmd(AdcCommand::CMD_SND);
- cmd.addParam(c.getParam(0));
- cmd.addParam(c.getParam(1));
- cmd.addParam(Util::toString(u->getPos()));
- cmd.addParam(Util::toString(u->getSize() - u->getPos()));
-
- if(c.hasFlag("ZL", 4)) {
- u->setFile(new FilteredInputStream<ZFilter, true>(u->getFile()));
- u->setFlag(Upload::FLAG_ZUPLOAD);
- cmd.addParam("ZL1");
- }
-
- aSource->send(cmd);
- aSource->setState(UserConnection::STATE_DONE);
- aSource->transmitFile(u->getFile());
- fire(UploadManagerListener::Starting(), u);
- }
-}
-
void UploadManager::on(AdcCommand::GFI, UserConnection* aSource, const AdcCommand& c) throw() {
if(c.getParameters().size() < 2) {
aSource->send(AdcCommand(AdcCommand::SEV_RECOVERABLE, AdcCommand::ERROR_PROTOCOL_GENERIC, "Missing parameters"));
@@ -465,22 +463,20 @@
const string& type = c.getParam(0);
const string& ident = c.getParam(1);
- if(type == "file") {
- SearchResult::List l;
- StringList sl;
-
- if(ident.compare(0, 4, "TTH/") != 0) {
- aSource->send(AdcCommand(AdcCommand::SEV_RECOVERABLE, AdcCommand::ERROR_PROTOCOL_GENERIC, "Invalid identifier"));
- return;
+ if(type == Transfer::TYPE_FILE) {
+ try {
+ string realFile = ShareManager::getInstance()->translateFileName(ident);
+ TTHValue tth = ShareManager::getInstance()->getTTH(ident);
+ string virtualFile = ShareManager::getInstance()->translateTTH(tth);
+ int64_t size = File::getSize(realFile);
+ SearchResult* sr = new SearchResult(SearchResult::TYPE_FILE, size, virtualFile, tth);
+ aSource->send(sr->toRES(AdcCommand::TYPE_CLIENT));
+ sr->decRef();
+ } catch(const ShareException&) {
+ aSource->fileNotAvail();
}
- sl.push_back("TH" + ident.substr(4));
- ShareManager::getInstance()->search(l, sl, 1);
- if(l.empty()) {
- aSource->send(AdcCommand(AdcCommand::SEV_RECOVERABLE, AdcCommand::ERROR_FILE_NOT_AVAILABLE, "Not found"));
- } else {
- aSource->send(l[0]->toRES(AdcCommand::TYPE_CLIENT));
- l[0]->decRef();
- }
+ } else {
+ aSource->fileNotAvail();
}
}
Modified: dcplusplus/trunk/client/UploadManager.h
===================================================================
--- dcplusplus/trunk/client/UploadManager.h 2006-09-29 16:24:13 UTC (rev 662)
+++ dcplusplus/trunk/client/UploadManager.h 2006-10-06 21:18:32 UTC (rev 663)
@@ -27,9 +27,10 @@
#include "Singleton.h"
#include "ClientManagerListener.h"
-#include "File.h"
#include "MerkleTree.h"
+class InputStream;
+
class Upload : public Transfer, public Flags {
public:
enum Flags {
@@ -44,17 +45,13 @@
typedef vector<Ptr> List;
typedef List::iterator Iter;
- Upload() : file(0) { }
- virtual ~Upload() {
- delete file;
- }
+ Upload(UserConnection& conn);
+ virtual ~Upload();
- User::Ptr& getUser() { dcassert(getUserConnection() != NULL); return getUserConnection()->getUser(); }
+ virtual void getParams(const UserConnection& aSource, StringMap& params);
- GETSET(string, fileName, FileName);
- GETSET(string, localFileName, LocalFileName);
- GETSET(TTHValue, tth, TTH);
- GETSET(InputStream*, file, File);
+ GETSET(string, sourceFile, SourceFile);
+ GETSET(InputStream*, stream, Stream);
};
class UploadManagerListener {
@@ -105,18 +102,6 @@
int getFreeSlots() { return max((SETTING(SLOTS) - running), 0); }
/** @internal */
- bool getAutoSlot() {
- /** A 0 in settings means disable */
- if(SETTING(MIN_UPLOAD_SPEED) == 0)
- return false;
- /** Only grant one slot per 30 sec */
- if(GET_TICK() < getLastGrant() + 30*1000)
- return false;
- /** Grant if upload speed is less than the threshold speed */
- return getAverageSpeed() < (SETTING(MIN_UPLOAD_SPEED)*1024);
- }
-
- /** @internal */
int getFreeExtraSlots() { return max(3 - getExtra(), 0); }
/** @param aUser Reserve an upload slot for this user and connect. */
@@ -163,13 +148,14 @@
//functions for manipulating waitingFiles and waitingUsers
UserList waitingUsers; //this one merely lists the users waiting for slots
FilesMap waitingFiles; //set of files which this user has asked for
- void addFailedUpload(UserConnection::Ptr source, string filename);
+ void addFailedUpload(const UserConnection& source, string filename);
friend class Singleton<UploadManager>;
UploadManager() throw();
virtual ~UploadManager() throw();
- void removeConnection(UserConnection::Ptr aConn);
+ bool getAutoSlot();
+ void removeConnection(UserConnection* aConn);
void removeUpload(Upload* aUpload);
// ClientManagerListener
@@ -190,7 +176,7 @@
virtual void on(AdcCommand::GET, UserConnection*, const AdcCommand&) throw();
virtual void on(AdcCommand::GFI, UserConnection*, const AdcCommand&) throw();
- bool prepareFile(UserConnection* aSource, const string& aType, const string& aFile, int64_t aResume, int64_t aBytes, bool listRecursive = false);
+ bool prepareFile(UserConnection& aSource, const string& aType, const string& aFile, int64_t aResume, int64_t aBytes, bool listRecursive = false);
};
#endif // !defined(UPLOAD_MANAGER_H)
Modified: dcplusplus/trunk/client/UserConnection.cpp
===================================================================
--- dcplusplus/trunk/client/UserConnection.cpp 2006-09-29 16:24:13 UTC (rev 662)
+++ dcplusplus/trunk/client/UserConnection.cpp 2006-10-06 21:18:32 UTC (rev 663)
@@ -21,6 +21,7 @@
#include "UserConnection.h"
#include "ClientManager.h"
+#include "ResourceManager.h"
#include "StringTokenizer.h"
#include "AdcCommand.h"
@@ -37,9 +38,19 @@
const string UserConnection::FILE_NOT_AVAILABLE = "File Not Available";
+const string Transfer::TYPE_FILE = "file";
+const string Transfer::TYPE_LIST = "list";
+const string Transfer::TYPE_TTHL = "tthl";
+
+const string Transfer::USER_LIST_NAME = "files.xml";
+const string Transfer::USER_LIST_NAME_BZ = "files.xml.bz2";
+
const string UserConnection::UPLOAD = "Upload";
const string UserConnection::DOWNLOAD = "Download";
+Transfer::Transfer(UserConnection& conn) : start(0), lastTick(GET_TICK()), runningAverage(0),
+last(0), actual(0), pos(0), startPos(0), size(-1), userConnection(conn) { }
+
void Transfer::updateRunningAverage() {
u_int32_t tick = GET_TICK();
if(tick > lastTick) {
@@ -64,6 +75,32 @@
lastTick = tick;
}
+void Transfer::getParams(const UserConnection& aSource, StringMap& params) {
+ params["userNI"] = Util::toString(ClientManager::getInstance()->getNicks(aSource.getUser()->getCID()));
+ params["userI4"] = aSource.getRemoteIp();
+ StringList hubNames = ClientManager::getInstance()->getHubNames(aSource.getUser()->getCID());
+ if(hubNames.empty())
+ hubNames.push_back(STRING(OFFLINE));
+ params["hub"] = Util::toString(hubNames);
+ StringList hubs = ClientManager::getInstance()->getHubs(aSource.getUser()->getCID());
+ if(hubs.empty())
+ hubs.push_back(STRING(OFFLINE));
+ params["hubURL"] = Util::toString(hubs);
+ params["fileSI"] = Util::toString(getSize());
+ params["fileSIshort"] = Util::formatBytes(getSize());
+ params["fileSIchunk"] = Util::toString(getTotal());
+ params["fileSIchunkshort"] = Util::formatBytes(getTotal());
+ params["fileSIactual"] = Util::toString(getActual());
+ params["fileSIactualshort"] = Util::formatBytes(getActual());
+ params["speed"] = Util::formatBytes(getAverageSpeed()) + "/s";
+ params["time"] = Util::formatSeconds((GET_TICK() - getStart()) / 1000);
+ params["fileTR"] = getTTH().toBase32();
+}
+
+User::Ptr Transfer::getUser() {
+ return getUserConnection().getUser();
+}
+
void UserConnection::on(BufferedSocketListener::Line, const string& aLine) throw () {
if(aLine.length() < 2)
Modified: dcplusplus/trunk/client/UserConnection.h
===================================================================
--- dcplusplus/trunk/client/UserConnection.h 2006-09-29 16:24:13 UTC (rev 662)
+++ dcplusplus/trunk/client/UserConnection.h 2006-10-06 21:18:32 UTC (rev 663)
@@ -30,6 +30,7 @@
#include "File.h"
#include "User.h"
#include "AdcCommand.h"
+#include "MerkleTree.h"
class UserConnection;
@@ -46,6 +47,7 @@
typedef X<5> Key;
typedef X<6> Direction;
typedef X<7> Get;
+ typedef X<8> Error;
typedef X<10> Sending;
typedef X<11> FileLength;
typedef X<12> Send;
@@ -63,6 +65,7 @@
virtual void on(BytesSent, UserConnection*, size_t, size_t) throw() { }
virtual void on(Connected, UserConnection*) throw() { }
virtual void on(Data, UserConnection*, const u_int8_t*, size_t) throw() { }
+ virtual void on(Error, UserConnection*, const string&) throw() { }
virtual void on(Failed, UserConnection*, const string&) throw() { }
virtual void on(CLock, UserConnection*, const string&, const string&) throw() { }
virtual void on(Key, UserConnection*, const string&) throw() { }
@@ -92,10 +95,16 @@
class Transfer {
public:
- Transfer() : userConnection(NULL), start(0), lastTick(GET_TICK()), runningAverage(0),
- last(0), actual(0), pos(0), startPos(0), size(-1) { }
- virtual ~Transfer() { }
+ static const string TYPE_FILE; ///< File transfer
+ static const string TYPE_LIST; ///< Partial file list
+ static const string TYPE_TTHL; ///< TTH Leaves
+ static const string USER_LIST_NAME;
+ static const string USER_LIST_NAME_BZ;
+
+ Transfer(UserConnection& conn);
+ virtual ~Transfer() { };
+
int64_t getPos() const { return pos; }
void setPos(int64_t aPos) { pos = aPos; }
@@ -113,7 +122,6 @@
int64_t getSize() const { return size; }
void setSize(int64_t aSize) { size = aSize; }
- void setSize(const string& aSize) { setSize(Util::toInt64(aSize)); }
int64_t getAverageSpeed() const {
int64_t diff = (int64_t)(GET_TICK() - getStart());
@@ -130,10 +138,17 @@
return getSize() - getPos();
}
- GETSET(UserConnection*, userConnection, UserConnection);
+ virtual void getParams(const UserConnection& aSource, StringMap& params);
+
+ User::Ptr getUser();
+
+ UserConnection& getUserConnection() { return userConnection; }
+ const UserConnection& getUserConnection() const { return userConnection; }
+
GETSET(u_int32_t, start, Start);
GETSET(u_int32_t, lastTick, LastTick);
GETSET(int64_t, runningAverage, RunningAverage);
+ GETSET(TTHValue, tth, TTH);
private:
Transfer(const Transfer&);
Transfer& operator=(const Transfer&);
@@ -149,6 +164,7 @@
/** Target size of this transfer */
int64_t size;
+ UserConnection& userConnection;
};
class ServerSocket;
@@ -214,9 +230,10 @@
STATE_KEY,
// UploadManager
- STATE_GET,
- STATE_SEND,
- STATE_DONE,
+ STATE_GET, // Waiting for GET
+ STATE_SEND, // Waiting for $Send
+ STATE_RUNNING, // Transmitting data
+
// DownloadManager
STATE_FILELENGTH,
STATE_TREE
@@ -273,6 +290,7 @@
return isSet(FLAG_UPLOAD) ? UPLOAD : DOWNLOAD;
}
+ const User::Ptr& getUser() const { return user...
[truncated message content] |