mirror of
https://github.com/RetroShare/RetroShare.git
synced 2024-10-01 02:35:48 -04:00
Addition of next stage of new FileTransfer Code:
* Completed rough ftExtraList class (with Test Case) * Added data flow interface (ftData.h) * Added ftDataMultiplex (server + client modules). * Finished parts of ftcontroller / ftserver. * Minor Tweaks to ftTransferModules interface for compilation. Related Changes in other parts of the code: * Added new Job/Queue Thread Class. * Added more user-friendly directory functions. * Added FileInfo print operator. git-svn-id: http://svn.code.sf.net/p/retroshare/code/trunk@650 b45a01b8-16f6-495d-af2f-9b41ad6348cc
This commit is contained in:
parent
a9bda83565
commit
79727897dd
@ -7,19 +7,23 @@ RS_TOP_DIR = ..
|
||||
include $(RS_TOP_DIR)/scripts/config.mk
|
||||
###############################################################
|
||||
|
||||
RSOBJ = ftfileprovider.o ftfilecreator.o
|
||||
RSOBJ = ftfileprovider.o ftfilecreator.o ftextralist.o ftdatamultiplex.o
|
||||
#ftservermodule.o
|
||||
|
||||
TESTOBJ = ftfileprovidertest.o ftfilecreatortest.o
|
||||
TESTOBJ = ftfileprovidertest.o ftfilecreatortest.o ftextralisttest.o
|
||||
|
||||
TESTS = ftfileprovidertest ftfilecreatortest
|
||||
TESTS = ftfileprovidertest ftfilecreatortest ftextralisttest
|
||||
|
||||
all: librs tests
|
||||
|
||||
ftfilecreatortest : ftfilecreatortest.o $(RSOBJ)
|
||||
$(CC) $(CFLAGS) -o ftfilecreatortest ftfilecreatortest.o $(RSOBJ) $(LIBS)
|
||||
ftfilecreatortest : ftfilecreatortest.o
|
||||
$(CC) $(CFLAGS) -o ftfilecreatortest ftfilecreatortest.o $(LIBS)
|
||||
|
||||
ftfileprovidertest : ftfileprovidertest.o $(RSOBJ)
|
||||
$(CC) $(CFLAGS) -o ftfileprovidertest ftfileprovidertest.o $(RSOBJ) $(LIBS)
|
||||
ftfileprovidertest : ftfileprovidertest.o
|
||||
$(CC) $(CFLAGS) -o ftfileprovidertest ftfileprovidertest.o $(LIBS)
|
||||
|
||||
ftextralisttest : ftextralisttest.o
|
||||
$(CC) $(CFLAGS) -o ftextralisttest ftextralisttest.o $(LIBS)
|
||||
|
||||
###############################################################
|
||||
include $(RS_TOP_DIR)/scripts/rules.mk
|
||||
|
364
libretroshare/src/ft/ftcontroller.cc
Normal file
364
libretroshare/src/ft/ftcontroller.cc
Normal file
@ -0,0 +1,364 @@
|
||||
/*
|
||||
* libretroshare/src/ft: ftcontroller.cc
|
||||
*
|
||||
* File Transfer for RetroShare.
|
||||
*
|
||||
* Copyright 2008 by Robert Fernie.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License Version 2 as published by the Free Software Foundation.
|
||||
*
|
||||
* This library 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
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
||||
* USA.
|
||||
*
|
||||
* Please report all bugs and problems to "retroshare@lunamutt.com".
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef FT_CONTROLLER_HEADER
|
||||
#define FT_CONTROLLER_HEADER
|
||||
|
||||
/*
|
||||
* ftController
|
||||
*
|
||||
* Top level download controller.
|
||||
*
|
||||
* inherits configuration (save downloading files)
|
||||
* inherits pqiMonitor (knows which peers are online).
|
||||
* inherits CacheTransfer (transfers cache files too)
|
||||
* inherits RsThread (to control transfers)
|
||||
*
|
||||
*/
|
||||
|
||||
class ftController: public CacheTransfer, public RsThread, public pqiMonitor, public p3Config
|
||||
{
|
||||
public:
|
||||
|
||||
/* Setup */
|
||||
ftController::ftController(std::string configDir);
|
||||
|
||||
void ftController::setFtSearch(ftSearch *search)
|
||||
{
|
||||
mSearch = search;
|
||||
}
|
||||
|
||||
|
||||
virtual void ftController::run()
|
||||
{
|
||||
/* check the queues */
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Called every 10 seconds or so */
|
||||
void ftController::checkDownloadQueue()
|
||||
{
|
||||
/* */
|
||||
|
||||
|
||||
}
|
||||
|
||||
bool ftController::completeFile(std::string hash)
|
||||
{
|
||||
RsStackMutex stack(ctrlMutex); /******* LOCKED ********/
|
||||
|
||||
std::map<std::string, ftFileControl>::iterator it;
|
||||
it = mDownloads.find(hash);
|
||||
if (it == mDownloads.end())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/* check if finished */
|
||||
if (!(it->second).mCreator->finished())
|
||||
{
|
||||
/* not done! */
|
||||
return false;
|
||||
}
|
||||
|
||||
ftFileControl *fc = &(it->second);
|
||||
|
||||
/* done - cleanup */
|
||||
fc->mTransfer->done();
|
||||
mClientModule->removeTransferModule(fc->mTransfer);
|
||||
mServerModule->removeFileCreator(fc->mCreator);
|
||||
|
||||
delete fc->mTransfer;
|
||||
fc->mTransfer = NULL;
|
||||
|
||||
delete fc->mCreator;
|
||||
fc->mCreator = NULL;
|
||||
|
||||
fc->state = COMPLETE;
|
||||
|
||||
/* switch map */
|
||||
mCompleted[fc->hash] = *fc;
|
||||
mDownloads.erase(it);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/***************************************************************/
|
||||
/********************** Controller Access **********************/
|
||||
/***************************************************************/
|
||||
|
||||
bool ftController::FileRequest(std::string fname, std::string hash,
|
||||
uint64_t size, std::string dest, uint32_t flags,
|
||||
std::list<std::string> srcIds)
|
||||
{
|
||||
/* check if we have the file */
|
||||
|
||||
if (ftSearch->findFile(LOCAL))
|
||||
{
|
||||
/* have it already */
|
||||
/* add in as completed transfer */
|
||||
return true;
|
||||
}
|
||||
|
||||
/* do a source search - for any extra sources */
|
||||
if (ftSearch->findFile(REMOTE))
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
std::map<std::string, ftTransferModule *> mTransfers;
|
||||
std::map<std::string, ftFileCreator *> mFileCreators;
|
||||
|
||||
/* add in new item for download */
|
||||
std::string savepath = mDownloadPath + "/" + fname;
|
||||
std::string chunker = "";
|
||||
ftFileCreator *fc = new ftFileCreator(savepath, size, hash, chunker);
|
||||
ftTransferModule = *tm = new ftTransferModule(fc, mClientModule);
|
||||
|
||||
/* add into maps */
|
||||
ftFileControl ftfc(fname, size, hash, flags, fc, tm);
|
||||
|
||||
/* add to ClientModule */
|
||||
mClientModule->addTransferModule(tm);
|
||||
|
||||
/* now add source peers (and their current state) */
|
||||
tm->setFileSources(srcIds);
|
||||
|
||||
/* get current state for transfer module */
|
||||
for(it = srcIds.begin(); it != srcIds.end(); it++)
|
||||
{
|
||||
if (mConnMgr->isOnline(*it))
|
||||
{
|
||||
tm->setPeer(*it, TRICKLE | ONLINE);
|
||||
}
|
||||
else
|
||||
{
|
||||
tm->setPeer(*it, OFFLINE);
|
||||
}
|
||||
}
|
||||
|
||||
/* only need to lock before to fiddle with own variables */
|
||||
RsStackMutex stack(ctrlMutex); /******* LOCKED ********/
|
||||
mDownloads[hash] = ftfc;
|
||||
mSlowQueue.push_back(hash);
|
||||
|
||||
}
|
||||
|
||||
|
||||
bool ftController::FileCancel(std::string hash);
|
||||
bool ftController::FileControl(std::string hash, uint32_t flags);
|
||||
bool ftController::FileClearCompleted();
|
||||
|
||||
/* get Details of File Transfers */
|
||||
bool ftController::FileDownloads(std::list<std::string> &hashs)
|
||||
{
|
||||
RsStackMutex stack(ctrlMutex); /******* LOCKED ********/
|
||||
|
||||
std::map<std::string, ftFileControl>::iterator it;
|
||||
for(it = mDownloads.begin(); it != mDownloads.end(); it++)
|
||||
{
|
||||
hashes.push_back(it->second.hash);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/* Directory Handling */
|
||||
bool ftController::setDownloadDirectory(std::string path)
|
||||
{
|
||||
/* check if it exists */
|
||||
if (RsDirUtil::checkCreateDirectory(path))
|
||||
{
|
||||
RsStackMutex stack(ctrlMutex); /******* LOCKED ********/
|
||||
|
||||
mDownloadPath = path;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ftController::setPartialsDirectory(std::string path);
|
||||
{
|
||||
/* check it is not a subdir of download / shared directories (BAD) - TODO */
|
||||
|
||||
/* check if it exists */
|
||||
|
||||
if (RsDirUtil::checkCreateDirectory(path))
|
||||
{
|
||||
RsStackMutex stack(ctrlMutex); /******* LOCKED ********/
|
||||
|
||||
mPartialPath = path;
|
||||
|
||||
/* move all existing files! */
|
||||
std::map<std::string, ftFileControl>::iterator it;
|
||||
for(it = mDownloads.begin(); it != mDownloads.end(); it++)
|
||||
{
|
||||
(it->second).mCreator->changePartialDirectory(mPartialPath);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string ftController::getDownloadDirectory()
|
||||
{
|
||||
RsStackMutex stack(ctrlMutex); /******* LOCKED ********/
|
||||
|
||||
return mDownloadPath;
|
||||
}
|
||||
|
||||
std::string ftController::getPartialsDirectory()
|
||||
{
|
||||
RsStackMutex stack(ctrlMutex); /******* LOCKED ********/
|
||||
|
||||
return mPartialPath;
|
||||
}
|
||||
|
||||
bool ftController::FileDetails(std::string hash, FileInfo &info)
|
||||
{
|
||||
RsStackMutex stack(ctrlMutex); /******* LOCKED ********/
|
||||
|
||||
std::map<std::string, ftFileControl>::iterator it;
|
||||
it = mDownloads.find(hash);
|
||||
if (it == mDownloads.end())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/* extract details */
|
||||
|
||||
return true;
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************/
|
||||
/********************** Controller Access **********************/
|
||||
/***************************************************************/
|
||||
|
||||
/* pqiMonitor callback:
|
||||
* Used to tell TransferModules new available peers
|
||||
*/
|
||||
void ftController::statusChange(const std::list<pqipeer> &plist)
|
||||
{
|
||||
RsStackMutex stack(ctrlMutex); /******* LOCKED ********/
|
||||
|
||||
/* add online to all downloads */
|
||||
std::map<std::string, ftFileControl>::iterator it;
|
||||
std::list<pqipeer>::const_iterator pit;
|
||||
|
||||
for(it = mDownloads.begin(); it != mDownloads.end(); it++)
|
||||
{
|
||||
for(pit = plist.begin(); pit != plist.end(); pit++)
|
||||
{
|
||||
if (pit->actions | RS_PEER_CONNECTED)
|
||||
{
|
||||
((it->second).tm)->setPeer(ONLINE | TRICKLE);
|
||||
}
|
||||
else if (pit->actions | RS_PEER_DISCONNECTED)
|
||||
{
|
||||
((it->second).tm)->setPeer(OFFLINE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* modify my list of peers */
|
||||
for(pit = plist.begin(); pit != plist.end(); pit++)
|
||||
{
|
||||
if (pit->actions | RS_PEER_CONNECTED)
|
||||
{
|
||||
/* add in */
|
||||
|
||||
((it->second).tm)->setPeer(ONLINE | TRICKLE);
|
||||
}
|
||||
else if (pit->actions | RS_PEER_DISCONNECTED)
|
||||
{
|
||||
((it->second).tm)->setPeer(OFFLINE);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* p3Config Interface */
|
||||
protected:
|
||||
virtual RsSerialiser *setupSerialiser();
|
||||
virtual std::list<RsItem *> saveList(bool &cleanup);
|
||||
virtual bool loadList(std::list<RsItem *> load);
|
||||
|
||||
private:
|
||||
|
||||
/* RunTime Functions */
|
||||
|
||||
/* pointers to other components */
|
||||
|
||||
ftSearch *mSearch;
|
||||
|
||||
RsMutex ctrlMutex;
|
||||
|
||||
std::list<FileDetails> incomingQueue;
|
||||
std::map<std::string, FileDetails> mCompleted;
|
||||
|
||||
class ftFileControl
|
||||
{
|
||||
public:
|
||||
|
||||
ftFileControl(std::string fname, uint64_t size, std::string hash,
|
||||
uint32_t flags, ftFileCreator *fc, ftTransferModule *tm);
|
||||
|
||||
std::string mName,
|
||||
uint64_t mSize;
|
||||
std::string mHash,
|
||||
uint32_t mFlags;
|
||||
ftFileCreator *mCreator;
|
||||
ftTransferModule *mTransfer;
|
||||
};
|
||||
|
||||
class ftPeerControl
|
||||
{
|
||||
std::string peerId;
|
||||
std::map<std::string, uint32_t> priority;
|
||||
uint32_t currentBandwidth;
|
||||
uint32_t maxBandwidth;
|
||||
};
|
||||
|
||||
std::map<std::string, ftFileControl> mDownloads;
|
||||
|
||||
/* A Bunch of Queues */
|
||||
std::map<std::string, std::string> mStreamQueue;
|
||||
std::map<std::string, std::string> mFastQueue;
|
||||
std::list<std::string> mSlowQueue;
|
||||
std::list<std::string> mTrickleQueue;
|
||||
|
||||
std::string mConfigPath;
|
||||
std::string mDownloadPath;
|
||||
std::string mPartialPath;
|
||||
};
|
||||
|
||||
#endif
|
@ -54,7 +54,8 @@ virtual void run();
|
||||
/***************************************************************/
|
||||
|
||||
bool FileRequest(std::string fname, std::string hash,
|
||||
uint32_t size, std::string dest, uint32_t flags);
|
||||
uint64_t size, std::string dest, uint32_t flags,
|
||||
std::list<std::string> sourceIds);
|
||||
|
||||
bool FileCancel(std::string hash);
|
||||
bool FileControl(std::string hash, uint32_t flags);
|
||||
@ -64,8 +65,8 @@ bool FileClearCompleted();
|
||||
bool FileDownloads(std::list<std::string> &hashs);
|
||||
|
||||
/* Directory Handling */
|
||||
void setDownloadDirectory(std::string path);
|
||||
void setPartialsDirectory(std::string path);
|
||||
bool setDownloadDirectory(std::string path);
|
||||
bool setPartialsDirectory(std::string path);
|
||||
std::string getDownloadDirectory();
|
||||
std::string getPartialsDirectory();
|
||||
bool FileDetails(std::string hash, FileInfo &info);
|
||||
|
79
libretroshare/src/ft/ftdata.h
Normal file
79
libretroshare/src/ft/ftdata.h
Normal file
@ -0,0 +1,79 @@
|
||||
/*
|
||||
* libretroshare/src/ft: ftdata.h
|
||||
*
|
||||
* File Transfer for RetroShare.
|
||||
*
|
||||
* Copyright 2008 by Robert Fernie.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License Version 2 as published by the Free Software Foundation.
|
||||
*
|
||||
* This library 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
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
||||
* USA.
|
||||
*
|
||||
* Please report all bugs and problems to "retroshare@lunamutt.com".
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef FT_DATA_INTERFACE_HEADER
|
||||
#define FT_DATA_INTERFACE_HEADER
|
||||
|
||||
/*
|
||||
* ftData.
|
||||
*
|
||||
* Internal Interfaces for sending and receiving data.
|
||||
* Most likely to be implemented by ftServer.
|
||||
* Provided as an independent interface for testing purposes.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <string>
|
||||
#include <inttypes.h>
|
||||
|
||||
/*************** SEND INTERFACE *******************/
|
||||
|
||||
class ftDataSend
|
||||
{
|
||||
public:
|
||||
virtual ~ftDataSend() { return; }
|
||||
|
||||
/* Client Send */
|
||||
virtual bool sendDataRequest(std::string peerId, std::string hash,
|
||||
uint64_t offset, uint32_t size) = 0;
|
||||
|
||||
/* Server Send */
|
||||
virtual bool sendData(std::string peerId, std::string hash,
|
||||
uint64_t offset, uint32_t size, void *data) = 0;
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
/*************** RECV INTERFACE *******************/
|
||||
|
||||
class ftDataRecv
|
||||
{
|
||||
public:
|
||||
|
||||
virtual ~ftDataRecv() { return; }
|
||||
|
||||
/* Client Recv */
|
||||
virtual bool recvData(std::string peerId, std::string hash,
|
||||
uint64_t offset, uint32_t size, void *data) = 0;
|
||||
|
||||
/* Server Recv */
|
||||
virtual bool recvDataRequest(std::string peerId, std::string hash,
|
||||
uint64_t offset, uint32_t size) = 0;
|
||||
|
||||
|
||||
};
|
||||
|
||||
#endif
|
247
libretroshare/src/ft/ftdatamultiplex.cc
Normal file
247
libretroshare/src/ft/ftdatamultiplex.cc
Normal file
@ -0,0 +1,247 @@
|
||||
/*
|
||||
* libretroshare/src/ft: ftdatamultiplex.h
|
||||
*
|
||||
* File Transfer for RetroShare.
|
||||
*
|
||||
* Copyright 2008 by Robert Fernie.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License Version 2 as published by the Free Software Foundation.
|
||||
*
|
||||
* This library 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
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
||||
* USA.
|
||||
*
|
||||
* Please report all bugs and problems to "retroshare@lunamutt.com".
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* ftDataMultiplexModule.
|
||||
*
|
||||
* This multiplexes the data from PQInterface to the ftTransferModules.
|
||||
*/
|
||||
|
||||
#include "ft/ftdatamultiplex.h"
|
||||
#include "ft/fttransfermodule.h"
|
||||
#include "ft/ftfilecreator.h"
|
||||
#include "ft/ftfileprovider.h"
|
||||
#include "ft/ftsearch.h"
|
||||
|
||||
ftClient::ftClient(ftTransferModule *module, ftFileCreator *creator)
|
||||
:mModule(module), mCreator(creator)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
const uint32_t FT_DATA = 0x0001;
|
||||
const uint32_t FT_DATA_REQ = 0x0002;
|
||||
|
||||
ftRequest::ftRequest(uint32_t type, std::string peerId, std::string hash, uint64_t offset, uint32_t chunk, void *data)
|
||||
:mType(type), mPeerId(peerId), mHash(hash),
|
||||
mOffset(offset), mChunk(chunk), mData(data)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
ftDataMultiplex::ftDataMultiplex(ftDataSend *server, ftSearch *search)
|
||||
:mDataSend(server), mSearch(search)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
bool ftDataMultiplex::addTransferModule(ftTransferModule *mod, ftFileCreator *f)
|
||||
{
|
||||
RsStackMutex stack(dataMtx); /******* LOCK MUTEX ******/
|
||||
std::map<std::string, ftClient>::iterator it;
|
||||
if (mClients.end() != (it = mClients.find(mod->hash())))
|
||||
{
|
||||
/* error */
|
||||
return false;
|
||||
}
|
||||
mClients[mod->hash()] = ftClient(mod, f);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ftDataMultiplex::removeTransferModule(ftTransferModule *mod, ftFileCreator *f)
|
||||
{
|
||||
RsStackMutex stack(dataMtx); /******* LOCK MUTEX ******/
|
||||
std::map<std::string, ftClient>::iterator it;
|
||||
if (mClients.end() == (it = mClients.find(mod->hash())))
|
||||
{
|
||||
/* error */
|
||||
return false;
|
||||
}
|
||||
mClients.erase(it);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/* data interface */
|
||||
|
||||
/*************** SEND INTERFACE (calls ftDataSend) *******************/
|
||||
|
||||
/* Client Send */
|
||||
bool ftDataMultiplex::sendDataRequest(std::string peerId, std::string hash, uint64_t offset, uint32_t size)
|
||||
{
|
||||
return mDataSend->sendDataRequest(peerId, hash, offset, size);
|
||||
}
|
||||
|
||||
/* Server Send */
|
||||
bool ftDataMultiplex::sendData(std::string peerId, std::string hash, uint64_t offset, uint32_t size, void *data)
|
||||
{
|
||||
return mDataSend->sendData(peerId, hash, offset, size, data);
|
||||
}
|
||||
|
||||
|
||||
/*************** RECV INTERFACE (provides ftDataRecv) ****************/
|
||||
|
||||
/* Client Recv */
|
||||
bool ftDataMultiplex::recvData(std::string peerId, std::string hash, uint64_t offset, uint32_t size, void *data)
|
||||
{
|
||||
/* Store in Queue */
|
||||
RsStackMutex stack(dataMtx); /******* LOCK MUTEX ******/
|
||||
mRequestQueue.push_back(
|
||||
ftRequest(FT_DATA, peerId, hash, offset, size, data));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/* Server Recv */
|
||||
bool ftDataMultiplex::recvDataRequest(std::string peerId, std::string hash, uint64_t offset, uint32_t size)
|
||||
{
|
||||
/* Store in Queue */
|
||||
RsStackMutex stack(dataMtx); /******* LOCK MUTEX ******/
|
||||
mRequestQueue.push_back(
|
||||
ftRequest(FT_DATA_REQ, peerId, hash, offset, size, NULL));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/*********** BACKGROUND THREAD OPERATIONS ***********/
|
||||
|
||||
|
||||
bool ftDataMultiplex::handleRecvData(std::string peerId,
|
||||
std::string hash, uint64_t offset, uint32_t size, void *data)
|
||||
{
|
||||
RsStackMutex stack(dataMtx); /******* LOCK MUTEX ******/
|
||||
std::map<std::string, ftClient>::iterator it;
|
||||
if (mClients.end() == (it = mClients.find(hash)))
|
||||
{
|
||||
/* error */
|
||||
return false;
|
||||
}
|
||||
|
||||
(it->second).mModule->recvFileData(peerId, offset, size, data);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/* called by ftTransferModule */
|
||||
bool ftDataMultiplex::handleRecvDataRequest(std::string peerId,
|
||||
std::string hash, uint64_t offset, uint32_t size)
|
||||
{
|
||||
/**** Find Files *****/
|
||||
|
||||
RsStackMutex stack(dataMtx); /******* LOCK MUTEX ******/
|
||||
std::map<std::string, ftClient>::iterator cit;
|
||||
if (mClients.end() != (cit = mClients.find(hash)))
|
||||
{
|
||||
locked_handleServerRequest((cit->second).mCreator,
|
||||
peerId, hash, offset, size);
|
||||
return true;
|
||||
}
|
||||
|
||||
std::map<std::string, ftFileProvider *>::iterator sit;
|
||||
if (mServers.end() != (sit = mServers.find(hash)))
|
||||
{
|
||||
locked_handleServerRequest(sit->second,
|
||||
peerId, hash, offset, size);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/* Add to Search Queue */
|
||||
mSearchQueue.push_back(
|
||||
ftRequest(FT_DATA_REQ, peerId, hash, offset, size, NULL));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ftDataMultiplex::locked_handleServerRequest(ftFileProvider *provider,
|
||||
std::string peerId, std::string hash, uint64_t offset, uint32_t size)
|
||||
{
|
||||
void *data = malloc(size);
|
||||
if (provider->getFileData(offset, size, data))
|
||||
{
|
||||
/* send data out */
|
||||
sendData(peerId, hash, offset, size, data);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool ftDataMultiplex::handleSearchRequest(std::string peerId,
|
||||
std::string hash, uint64_t offset, uint32_t size)
|
||||
{
|
||||
|
||||
{
|
||||
RsStackMutex stack(dataMtx); /******* LOCK MUTEX ******/
|
||||
|
||||
/* Check for bad requests */
|
||||
std::map<std::string, time_t>::iterator bit;
|
||||
if (mUnknownHashs.end() != (bit = mUnknownHashs.find(hash)))
|
||||
{
|
||||
/* We've previously rejected this one, so ignore */
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Do Actual search
|
||||
* Could be Cache File, Local or Extra
|
||||
* (anywhere but remote really)
|
||||
*/
|
||||
|
||||
FileInfo info;
|
||||
uint32_t hintflags = (RS_FILE_HINTS_CACHE |
|
||||
RS_FILE_HINTS_EXTRA |
|
||||
RS_FILE_HINTS_LOCAL |
|
||||
RS_FILE_HINTS_SPEC_ONLY);
|
||||
|
||||
if (mSearch->search(hash, size, hintflags, info))
|
||||
{
|
||||
|
||||
/* setup a new provider */
|
||||
RsStackMutex stack(dataMtx); /******* LOCK MUTEX ******/
|
||||
|
||||
ftFileProvider *provider =
|
||||
new ftFileProvider(info.path, size, hash);
|
||||
|
||||
mServers[hash] = provider;
|
||||
|
||||
/* handle request finally */
|
||||
locked_handleServerRequest(provider,
|
||||
peerId, hash, offset, size);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
136
libretroshare/src/ft/ftdatamultiplex.h
Normal file
136
libretroshare/src/ft/ftdatamultiplex.h
Normal file
@ -0,0 +1,136 @@
|
||||
/*
|
||||
* libretroshare/src/ft: ftdatamultiplex.h
|
||||
*
|
||||
* File Transfer for RetroShare.
|
||||
*
|
||||
* Copyright 2008 by Robert Fernie.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License Version 2 as published by the Free Software Foundation.
|
||||
*
|
||||
* This library 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
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
||||
* USA.
|
||||
*
|
||||
* Please report all bugs and problems to "retroshare@lunamutt.com".
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef FT_DATA_MULTIPLEX_HEADER
|
||||
#define FT_DATA_MULTIPLEX_HEADER
|
||||
|
||||
/*
|
||||
* ftDataMultiplexModule.
|
||||
*
|
||||
* This multiplexes the data from PQInterface to the ftTransferModules.
|
||||
*/
|
||||
|
||||
class ftTransferModule;
|
||||
class ftFileProvider;
|
||||
class ftFileCreator;
|
||||
class ftSearch;
|
||||
|
||||
#include <string>
|
||||
#include <list>
|
||||
#include <map>
|
||||
#include <inttypes.h>
|
||||
|
||||
#include "util/rsthreads.h"
|
||||
|
||||
#include "ft/ftdata.h"
|
||||
|
||||
class ftClient
|
||||
{
|
||||
public:
|
||||
|
||||
ftClient() :mModule(NULL), mCreator(NULL) { return; }
|
||||
ftClient(ftTransferModule *module, ftFileCreator *creator);
|
||||
|
||||
ftTransferModule *mModule;
|
||||
ftFileCreator *mCreator;
|
||||
};
|
||||
|
||||
class ftRequest
|
||||
{
|
||||
public:
|
||||
|
||||
ftRequest(uint32_t type, std::string peerId, std::string hash, uint64_t offset, uint32_t chunk, void *data);
|
||||
|
||||
uint32_t mType;
|
||||
std::string mPeerId;
|
||||
std::string mHash;
|
||||
uint64_t mOffset;
|
||||
uint32_t mChunk;
|
||||
void *mData;
|
||||
};
|
||||
|
||||
|
||||
|
||||
class ftDataMultiplex: public ftDataRecv
|
||||
{
|
||||
|
||||
public:
|
||||
|
||||
ftDataMultiplex(ftDataSend *server, ftSearch *search);
|
||||
|
||||
/* ftController Interface */
|
||||
bool addTransferModule(ftTransferModule *mod, ftFileCreator *f);
|
||||
bool removeTransferModule(ftTransferModule *mod, ftFileCreator *f);
|
||||
|
||||
/* data interface */
|
||||
|
||||
/*************** SEND INTERFACE (calls ftDataSend) *******************/
|
||||
|
||||
/* Client Send */
|
||||
bool sendDataRequest(std::string peerId, std::string hash, uint64_t offset, uint32_t size);
|
||||
|
||||
/* Server Send */
|
||||
bool sendData(std::string peerId, std::string hash, uint64_t offset, uint32_t size, void *data);
|
||||
|
||||
|
||||
/*************** RECV INTERFACE (provides ftDataRecv) ****************/
|
||||
|
||||
/* Client Recv */
|
||||
virtual bool recvData(std::string peerId, std::string hash, uint64_t offset, uint32_t size, void *data);
|
||||
|
||||
/* Server Recv */
|
||||
virtual bool recvDataRequest(std::string peerId, std::string hash, uint64_t offset, uint32_t size);
|
||||
|
||||
|
||||
private:
|
||||
|
||||
/* Handling Job Queues */
|
||||
bool handleRecvData(std::string peerId,
|
||||
std::string hash, uint64_t offset, uint32_t size, void *data);
|
||||
|
||||
bool handleRecvDataRequest(std::string peerId,
|
||||
std::string hash, uint64_t offset, uint32_t size);
|
||||
|
||||
bool handleSearchRequest(std::string peerId,
|
||||
std::string hash, uint64_t offset, uint32_t size);
|
||||
|
||||
/* We end up doing the actual server job here */
|
||||
bool locked_handleServerRequest(ftFileProvider *provider,
|
||||
std::string peerId, std::string hash, uint64_t offset, uint32_t size);
|
||||
|
||||
RsMutex dataMtx;
|
||||
|
||||
std::map<std::string, ftClient> mClients;
|
||||
std::map<std::string, ftFileProvider *> mServers;
|
||||
|
||||
std::list<ftRequest> mRequestQueue;
|
||||
std::list<ftRequest> mSearchQueue;
|
||||
std::map<std::string, time_t> mUnknownHashs;
|
||||
|
||||
ftDataSend *mDataSend;
|
||||
ftSearch *mSearch;
|
||||
};
|
||||
|
||||
#endif
|
@ -23,59 +23,8 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef FT_FILE_EXTRA_LIST_HEADER
|
||||
#define FT_FILE_EXTRA_LIST_HEADER
|
||||
|
||||
/*
|
||||
* ftFileExtraList
|
||||
*
|
||||
* This maintains a list of 'Extra Files' to share with peers.
|
||||
*
|
||||
* Files are added via:
|
||||
* 1) For Files which have been hashed already:
|
||||
* addExtraFile(std::string path, std::string hash, uint64_t size, uint32_t period, uint32_t flags);
|
||||
*
|
||||
* 2) For Files to be hashed:
|
||||
* hashExtraFile(std::string path, uint32_t period, uint32_t flags);
|
||||
*
|
||||
* Results of Hashing can be retrieved via:
|
||||
* hashExtraFileDone(std::string path, std::string &hash, uint64_t &size);
|
||||
*
|
||||
* Files can be searched for via:
|
||||
* searchExtraFiles(std::string hash, ftFileDetail file);
|
||||
*
|
||||
* This Class is Mutexed protected, and has a thread in it which checks the files periodically.
|
||||
* If a file is found to have changed... It is discarded from the list - and not updated.
|
||||
*
|
||||
* this thread is also used to hash added files.
|
||||
*
|
||||
* The list of extra files is stored using the configuration system.
|
||||
*
|
||||
*/
|
||||
|
||||
class FileDetails
|
||||
{
|
||||
public:
|
||||
|
||||
std::list<std::string> sources;
|
||||
std::string path;
|
||||
std::string fname;
|
||||
std::string hash;
|
||||
uint64_t size;
|
||||
|
||||
uint32_t start;
|
||||
uint32_t period;
|
||||
uint32_t flags;
|
||||
};
|
||||
|
||||
const uint32_t FT_DETAILS_CLEANUP = 0x0100; /* remove when it expires */
|
||||
const uint32_t FT_DETAILS_LOCAL = 0x0001;
|
||||
const uint32_t FT_DETAILS_REMOTE = 0x0002;
|
||||
|
||||
class ftExtraList: public p3Config
|
||||
{
|
||||
|
||||
public:
|
||||
#include "ft/ftextralist.h"
|
||||
#include "util/rsdir.h"
|
||||
|
||||
ftExtraList::ftExtraList()
|
||||
:p3Config(CONFIG_FT_EXTRA_LIST)
|
||||
@ -128,26 +77,32 @@ void ftExtraList::run()
|
||||
void ftExtraList::hashAFile()
|
||||
{
|
||||
/* extract entry from the queue */
|
||||
std::string path;
|
||||
FileDetails details;
|
||||
|
||||
{
|
||||
RsStackMutex stack(extMutex);
|
||||
path = mToHash.front();
|
||||
details = mToHash.front();
|
||||
mToHash.pop_front();
|
||||
}
|
||||
|
||||
/* hash it! */
|
||||
if (hashFile(path, details))
|
||||
std::string name, hash;
|
||||
uint64_t size;
|
||||
if (RsDirUtil::hashFile(details.info.path, details.info.fname,
|
||||
details.info.hash, details.info.size))
|
||||
{
|
||||
RsStackMutex stack(extMutex);
|
||||
|
||||
details.start = time(NULL);
|
||||
|
||||
/* stick it in the available queue */
|
||||
addExtraFile(path, hash, size, period, flags);
|
||||
mFiles[details.info.hash] = details;
|
||||
|
||||
/* add to the path->hash map */
|
||||
addNewlyHashed(path, details);
|
||||
mHashedList[details.info.path] = details.info.hash;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/***
|
||||
* If the File is alreay Hashed, then just add it in.
|
||||
**/
|
||||
@ -157,6 +112,19 @@ bool ftExtraList::addExtraFile(std::string path, std::string hash,
|
||||
{
|
||||
RsStackMutex stack(extMutex);
|
||||
|
||||
FileDetails details;
|
||||
|
||||
details.info.path = path;
|
||||
details.info.fname = RsDirUtil::getTopDir(path);
|
||||
details.info.hash = hash;
|
||||
details.info.size = size;
|
||||
|
||||
details.start = time(NULL);
|
||||
details.flags = flags;
|
||||
details.period = period;
|
||||
|
||||
/* stick it in the available queue */
|
||||
mFiles[details.info.hash] = details;
|
||||
|
||||
}
|
||||
|
||||
@ -165,6 +133,8 @@ bool ftExtraList::cleanupOldFiles()
|
||||
{
|
||||
RsStackMutex stack(extMutex);
|
||||
|
||||
time_t now = time(NULL);
|
||||
|
||||
std::list<std::string> toRemove;
|
||||
std::list<std::string>::iterator rit;
|
||||
|
||||
@ -172,7 +142,7 @@ bool ftExtraList::cleanupOldFiles()
|
||||
for(it = mFiles.begin(); it != mFiles.end(); it++)
|
||||
{
|
||||
/* check timestamps */
|
||||
if (it->
|
||||
if (it->second.start + it->second.period < now)
|
||||
{
|
||||
toRemove.push_back(it->first);
|
||||
}
|
||||
@ -208,7 +178,7 @@ bool ftExtraList::hashExtraFile(std::string path, uint32_t period, uint32_t fla
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ftExtraList::hashExtraFileDone(std::string path, FileDetails &details)
|
||||
bool ftExtraList::hashExtraFileDone(std::string path, FileInfo &info)
|
||||
{
|
||||
std::string hash;
|
||||
{
|
||||
@ -222,14 +192,14 @@ bool ftExtraList::hashExtraFileDone(std::string path, FileDetails &details)
|
||||
}
|
||||
hash = it->second;
|
||||
}
|
||||
return searchExtraFiles(hash, details);
|
||||
return searchExtraFiles(hash, info);
|
||||
}
|
||||
|
||||
/***
|
||||
* Search Function - used by File Transfer
|
||||
*
|
||||
**/
|
||||
bool ftExtraList::searchExtraFiles(std::string hash, FileDetails &details)
|
||||
bool ftExtraList::searchExtraFiles(std::string hash, FileInfo &info)
|
||||
{
|
||||
RsStackMutex stack(extMutex);
|
||||
|
||||
@ -240,7 +210,7 @@ bool ftExtraList::searchExtraFiles(std::string hash, FileDetails &details)
|
||||
return false;
|
||||
}
|
||||
|
||||
details = fit->second;
|
||||
info = fit->second.info;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -53,15 +53,45 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include <list>
|
||||
#include <map>
|
||||
#include <string>
|
||||
|
||||
#include "util/rsthreads.h"
|
||||
#include "rsiface/rsfiles.h"
|
||||
#include "pqi/p3cfgmgr.h"
|
||||
|
||||
class FileDetails
|
||||
{
|
||||
public:
|
||||
FileDetails()
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
FileDetails(std::string path, uint32_t p, uint32_t f)
|
||||
{
|
||||
info.path = path;
|
||||
period = p;
|
||||
flags = f;
|
||||
}
|
||||
|
||||
FileDetails(FileInfo &i, uint32_t p, uint32_t f)
|
||||
{
|
||||
info = i;
|
||||
period = p;
|
||||
flags = f;
|
||||
}
|
||||
|
||||
FileInfo info;
|
||||
|
||||
#if 0 /*** WHAT IS NEEDED ***/
|
||||
std::list<std::string> sources;
|
||||
std::string path;
|
||||
std::string fname;
|
||||
std::string hash;
|
||||
uint64_t size;
|
||||
#endif
|
||||
|
||||
uint32_t start;
|
||||
uint32_t period;
|
||||
@ -72,7 +102,13 @@ const uint32_t FT_DETAILS_CLEANUP = 0x0100; /* remove when it expires */
|
||||
const uint32_t FT_DETAILS_LOCAL = 0x0001;
|
||||
const uint32_t FT_DETAILS_REMOTE = 0x0002;
|
||||
|
||||
class ftExtraList: public p3Config
|
||||
#warning CONFIG_FT_EXTRA_LIST Not defined in p3cfgmgr.h
|
||||
|
||||
const uint32_t CONFIG_FT_EXTRA_LIST = 1;
|
||||
const uint32_t CLEANUP_PERIOD = 600; /* 10 minutes */
|
||||
|
||||
|
||||
class ftExtraList: public RsThread, public p3Config
|
||||
{
|
||||
|
||||
public:
|
||||
@ -100,6 +136,11 @@ bool hashExtraFileDone(std::string path, FileInfo &info);
|
||||
**/
|
||||
bool searchExtraFiles(std::string hash, FileInfo &info);
|
||||
|
||||
/***
|
||||
* Thread Main Loop
|
||||
**/
|
||||
virtual void run();
|
||||
|
||||
/***
|
||||
* Configuration - store extra files.
|
||||
*
|
||||
@ -111,12 +152,19 @@ virtual bool loadList(std::list<RsItem *> load);
|
||||
|
||||
private:
|
||||
|
||||
/* Worker Functions */
|
||||
void hashAFile();
|
||||
bool cleanupOldFiles();
|
||||
|
||||
RsMutex extMutex;
|
||||
|
||||
std::map<std::string, std::string> hashedList; /* path -> hash ( not saved ) */
|
||||
std::map<std::string, FileInfo> files;
|
||||
std::list<FileDetails> mToHash;
|
||||
|
||||
std::map<std::string, std::string> mHashedList; /* path -> hash ( not saved ) */
|
||||
std::map<std::string, FileDetails> mFiles;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
|
160
libretroshare/src/ft/ftextralisttest.cc
Normal file
160
libretroshare/src/ft/ftextralisttest.cc
Normal file
@ -0,0 +1,160 @@
|
||||
/*
|
||||
* libretroshare/src/ft: ftextralisttest.cc
|
||||
*
|
||||
* File Transfer for RetroShare.
|
||||
*
|
||||
* Copyright 2008 by Robert Fernie.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License Version 2 as published by the Free Software Foundation.
|
||||
*
|
||||
* This library 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
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
||||
* USA.
|
||||
*
|
||||
* Please report all bugs and problems to "retroshare@lunamutt.com".
|
||||
*
|
||||
*/
|
||||
|
||||
#include "ft/ftextralist.h"
|
||||
|
||||
extern "C" void* runExtraList(void* p)
|
||||
{
|
||||
ftExtraList *eList = (ftExtraList *) p;
|
||||
if (!eList)
|
||||
{
|
||||
pthread_exit(NULL);
|
||||
}
|
||||
|
||||
while (1)
|
||||
{
|
||||
//eList->tick();
|
||||
sleep(1);
|
||||
}
|
||||
|
||||
delete eList;
|
||||
|
||||
pthread_exit(NULL);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void displayExtraListDetails(ftExtraList *eList, std::list<std::string> toHash, std::list<std::string> hashed);
|
||||
|
||||
|
||||
void usage(char *name)
|
||||
{
|
||||
std::cerr << "Usage: " << name << " -h <path> -p <period> -d <dperiod>";
|
||||
std::cerr << std::endl;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int c;
|
||||
uint32_t period = 1;
|
||||
uint32_t dPeriod = 600; /* default 10 minutes */
|
||||
|
||||
std::list<std::string> hashList;
|
||||
|
||||
while(-1 != (c = getopt(argc, argv, "h:p:d:")))
|
||||
{
|
||||
switch (c)
|
||||
{
|
||||
case 'h':
|
||||
hashList.push_back(std::string(optarg));
|
||||
break;
|
||||
case 'p':
|
||||
period = atoi(optarg);
|
||||
break;
|
||||
case 'd':
|
||||
dPeriod = atoi(optarg);
|
||||
break;
|
||||
default:
|
||||
usage(argv[0]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
ftExtraList *eList = new ftExtraList();
|
||||
|
||||
/* now startup background thread to keep it reunning */
|
||||
eList->start();
|
||||
|
||||
|
||||
|
||||
/* now work the thread */
|
||||
std::list<std::string> toHash;
|
||||
std::list<std::string> hashed;
|
||||
std::list<std::string>::iterator it;
|
||||
|
||||
uint32_t flags = 0;
|
||||
for(it = hashList.begin(); it != hashList.end(); it++)
|
||||
{
|
||||
sleep(period);
|
||||
|
||||
/* load up file */
|
||||
//eList->addExtraFile(*it);
|
||||
eList->hashExtraFile(*it, dPeriod, flags);
|
||||
|
||||
toHash.push_back(*it);
|
||||
|
||||
displayExtraListDetails(eList, toHash, hashed);
|
||||
}
|
||||
|
||||
while(1)
|
||||
{
|
||||
sleep(period);
|
||||
displayExtraListDetails(eList, toHash, hashed);
|
||||
}
|
||||
}
|
||||
|
||||
void displayExtraListDetails(ftExtraList *eList, std::list<std::string> toHash, std::list<std::string> hashed)
|
||||
{
|
||||
std::cerr << "displayExtraListDetails()";
|
||||
std::cerr << std::endl;
|
||||
|
||||
std::list<std::string>::iterator it;
|
||||
for(it = toHash.begin(); it != toHash.end(); it++)
|
||||
{
|
||||
FileInfo info;
|
||||
if (eList->hashExtraFileDone(*it, info))
|
||||
{
|
||||
std::cerr << "displayExtraListDetails() Hash Completed for: " << *it;
|
||||
std::cerr << std::endl;
|
||||
std::cerr << info << std::endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cerr << "displayExtraListDetails() Hash Not Done for: " << *it;
|
||||
std::cerr << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
for(it = hashed.begin(); it != hashed.end(); it++)
|
||||
{
|
||||
FileInfo info;
|
||||
if (eList->searchExtraFiles(*it, info))
|
||||
{
|
||||
std::cerr << "displayExtraListDetails() Found Hash: " << *it;
|
||||
std::cerr << std::endl;
|
||||
std::cerr << info << std::endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cerr << "displayExtraListDetails() Hash Not Found: " << *it;
|
||||
std::cerr << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -34,7 +34,7 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include "rsiface/rstypes.h"
|
||||
#include "rsiface/rsfiles.h" // includes rsiface/rstypes.h too!
|
||||
|
||||
class ftSearch
|
||||
{
|
||||
@ -42,10 +42,21 @@ class ftSearch
|
||||
public:
|
||||
|
||||
ftSearch() { return; }
|
||||
virtual bool search(std::string hash, uint64_t size, uint32_t hintflags, FileInfo &info);
|
||||
virtual ~ftSearch() { return; }
|
||||
virtual bool search(std::string hash, uint64_t size, uint32_t hintflags, FileInfo &info) = 0;
|
||||
|
||||
};
|
||||
|
||||
|
||||
class ftSearchDummy
|
||||
{
|
||||
ftSearchDummy() { return; }
|
||||
virtual ~ftSearchDummy() { return; }
|
||||
virtual bool search(std::string hash, uint64_t size, uint32_t hintflags, FileInfo &info)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -39,27 +39,25 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include "pqi/pqi.h"
|
||||
#include "pqi/pqiindic.h"
|
||||
#include "serialiser/rsconfigitems.h"
|
||||
#include <map>
|
||||
#include <deque>
|
||||
#include <list>
|
||||
#include <map>
|
||||
#include <iostream>
|
||||
|
||||
#include "rsiface/rsiface.h"
|
||||
#include "rsiface/rsfiles.h"
|
||||
#include "dbase/cachestrapper.h"
|
||||
|
||||
#include "pqi/p3cfgmgr.h"
|
||||
|
||||
|
||||
class p3ConnectMgr;
|
||||
class p3AuthMgr;
|
||||
|
||||
class CacheStrapper;
|
||||
class ftfiler;
|
||||
class FileIndexStore;
|
||||
class FileIndexMonitor;
|
||||
|
||||
class ftController;
|
||||
class ftExtraList;
|
||||
|
||||
class ftServer: public RsFiles
|
||||
{
|
||||
@ -104,7 +102,7 @@ virtual bool FileDetails(std::string hash, uint32_t hintflags, FileInfo &info);
|
||||
/* Access ftExtraList - Details */
|
||||
virtual bool ExtraFileAdd(std::string fname, std::string hash, uint32_t size,
|
||||
uint32_t period, uint32_t flags);
|
||||
virtual bool ExtraFileRemove(std::string hash, uin32_t flags);
|
||||
virtual bool ExtraFileRemove(std::string hash, uint32_t flags);
|
||||
virtual bool ExtraFileHash(std::string localpath, uint32_t period, uint32_t flags);
|
||||
virtual bool ExtraFileStatus(std::string localpath, FileInfo &info);
|
||||
|
||||
@ -131,23 +129,20 @@ virtual bool getSharedDirectories(std::list<std::string> &dirs);
|
||||
virtual bool addSharedDirectory(std::string dir);
|
||||
virtual bool removeSharedDirectory(std::string dir);
|
||||
|
||||
|
||||
virtual int reScanDirs();
|
||||
virtual int check_dBUpdate();
|
||||
|
||||
std::string getSaveDir();
|
||||
void setSaveDir(std::string d);
|
||||
void setEmergencySaveDir(std::string s);
|
||||
|
||||
void setConfigDir(std::string d) { config_dir = d; }
|
||||
bool getSaveIncSearch();
|
||||
void setSaveIncSearch(bool v);
|
||||
|
||||
|
||||
/***************************************************************/
|
||||
/*************** Control Interface *****************************/
|
||||
/***************************************************************/
|
||||
|
||||
/***************************************************************/
|
||||
/*************** Data Transfer Interface ***********************/
|
||||
/***************************************************************/
|
||||
|
||||
bool requestData(std::string peerId, std::string hash,
|
||||
uint64_t offset, uint32_t size);
|
||||
|
||||
/******************* p3 Config Overload ************************/
|
||||
protected:
|
||||
/* Key Functions to be overloaded for Full Configuration */
|
||||
|
@ -37,7 +37,7 @@
|
||||
|
||||
#include <map>
|
||||
#include <list>
|
||||
#include <ftFileCreator.h>
|
||||
#include "ft/ftfilecreator.h"
|
||||
|
||||
class Request
|
||||
{
|
||||
@ -47,7 +47,7 @@ class Request
|
||||
|
||||
class peerInfo
|
||||
{
|
||||
std:string peerId;
|
||||
std::string peerId;
|
||||
uint16_t state;
|
||||
uint32_t desiredRate;
|
||||
Request lastRequest;
|
||||
@ -71,21 +71,26 @@ public:
|
||||
bool completeFileTransfer();
|
||||
|
||||
//interface to client module
|
||||
bool recvFileData(uint64_t offset, uint32_t chunk_size, void *data);
|
||||
void requestData(std::hash, uint64_t offset, uint32_t chunk_size);
|
||||
bool recvFileData(std::string peerId, uint64_t offset,
|
||||
uint32_t chunk_size, void *data);
|
||||
void requestData(std::string hash, uint64_t offset, uint32_t chunk_size);
|
||||
|
||||
//interface to file creator
|
||||
bool getChunk(uint64_t &offset, uint32_t &chunk_size);
|
||||
bool storeData(uint64_t offset, uint32_t chunk_size);
|
||||
|
||||
void tick();
|
||||
|
||||
|
||||
/* add by DrBob for interfaces */
|
||||
std::string hash() { return mHash; }
|
||||
uint64_t size() { return mSize; }
|
||||
|
||||
public:
|
||||
ftFileCreator* fc;
|
||||
|
||||
private:
|
||||
std::string hash;
|
||||
uint64_t size;
|
||||
std::string mHash;
|
||||
uint64_t mSize;
|
||||
uint32_t dataRate; //data transfer rate for current file
|
||||
uint16_t state; //file transfer state
|
||||
std::list<std::string> onlinePeerList;
|
||||
|
@ -105,6 +105,10 @@ class FileTransferInfo: public FileInfo
|
||||
FileTransferInfo() { return; }
|
||||
};
|
||||
|
||||
|
||||
std::ostream &operator<<(std::ostream &out, const FileInfo &info);
|
||||
|
||||
|
||||
/* matched to the uPnP states */
|
||||
#define UPNP_STATE_UNINITIALISED 0
|
||||
#define UPNP_STATE_UNAVAILABILE 1
|
||||
|
@ -19,9 +19,9 @@ RSOBJ = p3peers.o \
|
||||
p3face-msgs.o \
|
||||
rsiface.o \
|
||||
p3files.o \
|
||||
rstypes.o
|
||||
|
||||
# p3face-file.o \
|
||||
# rstypes.o \
|
||||
# pqistrings.o \
|
||||
# p3face-people.o
|
||||
# p3face-network.o \
|
||||
|
@ -45,3 +45,16 @@
|
||||
*
|
||||
**********************************************************************/
|
||||
|
||||
|
||||
std::ostream &operator<<(std::ostream &out, const FileInfo &info)
|
||||
{
|
||||
out << "FileInfo: path: " << info.path;
|
||||
out << std::endl;
|
||||
out << "File: " << info.fname;
|
||||
out << " Size: " << info.size;
|
||||
out << std::endl;
|
||||
out << "Hash: " << info.hash;
|
||||
return out;
|
||||
}
|
||||
|
||||
|
||||
|
@ -196,6 +196,31 @@ int RsDirUtil::breakupDirList(std::string path,
|
||||
|
||||
|
||||
|
||||
bool RsDirUtil::checkDirectory(std::string dir)
|
||||
{
|
||||
struct stat buf;
|
||||
int val = stat(dir.c_str(), &buf);
|
||||
if (val == -1)
|
||||
{
|
||||
#ifdef RSDIR_DEBUG
|
||||
std::cerr << "RsDirUtil::checkDirectory() ";
|
||||
std::cerr << dir << " doesn't exist" << std::endl;
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
else if (!S_ISDIR(buf.st_mode))
|
||||
{
|
||||
// Some other type - error.
|
||||
#ifdef RSDIR_DEBUG
|
||||
std::cerr << "RsDirUtil::checkDirectory() ";
|
||||
std::cerr << dir << " is not Directory" << std::endl;
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool RsDirUtil::checkCreateDirectory(std::string dir)
|
||||
{
|
||||
struct stat buf;
|
||||
@ -289,11 +314,24 @@ bool RsDirUtil::cleanupDirectory(std::string cleandir, std::list<std::string> k
|
||||
return true;
|
||||
}
|
||||
|
||||
/* slightly nicer helper function */
|
||||
bool RsDirUtil::hashFile(std::string filepath,
|
||||
std::string &name, std::string &hash, uint64_t &size)
|
||||
{
|
||||
if (getFileHash(filepath, hash, size))
|
||||
{
|
||||
/* extract file name */
|
||||
name = RsDirUtil::getTopDir(filepath);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
#include <openssl/sha.h>
|
||||
#include <sstream>
|
||||
#include <iomanip>
|
||||
|
||||
|
||||
/* Function to hash, and get details of a file */
|
||||
bool RsDirUtil::getFileHash(std::string filepath,
|
||||
std::string &hash, uint64_t &size)
|
||||
|
@ -43,9 +43,13 @@ std::string removeRootDirs(std::string path, std::string root);
|
||||
int breakupDirList(std::string path,
|
||||
std::list<std::string> &subdirs);
|
||||
|
||||
bool checkDirectory(std::string dir);
|
||||
bool checkCreateDirectory(std::string dir);
|
||||
bool cleanupDirectory(std::string dir, std::list<std::string> keepFiles);
|
||||
|
||||
bool hashFile(std::string filepath,
|
||||
std::string &name, std::string &hash, uint64_t &size);
|
||||
|
||||
bool getFileHash(std::string filepath,
|
||||
std::string &hash, uint64_t &size);
|
||||
|
||||
|
@ -26,6 +26,7 @@
|
||||
|
||||
|
||||
#include "rsthreads.h"
|
||||
#include <unistd.h> /* for usleep() */
|
||||
|
||||
extern "C" void* rsthread_init(void* p)
|
||||
{
|
||||
@ -56,4 +57,43 @@ pthread_t createThread(RsThread &thread)
|
||||
}
|
||||
|
||||
|
||||
RsQueueThread::RsQueueThread(uint32_t min, uint32_t max, double relaxFactor )
|
||||
:mMinSleep(min), mMaxSleep(max), mRelaxFactor(relaxFactor)
|
||||
{
|
||||
|
||||
|
||||
}
|
||||
|
||||
void RsQueueThread::run()
|
||||
{
|
||||
while(1)
|
||||
{
|
||||
bool doneWork = false;
|
||||
while(workQueued() && doWork())
|
||||
{
|
||||
doneWork = true;
|
||||
}
|
||||
time_t now = time(NULL);
|
||||
if (doneWork)
|
||||
{
|
||||
mLastWork = now;
|
||||
mLastSleep = (uint32_t)
|
||||
(mMinSleep + (mLastSleep - mMinSleep) / 2.0);
|
||||
}
|
||||
else
|
||||
{
|
||||
uint32_t deltaT = now - mLastWork;
|
||||
double frac = deltaT / mRelaxFactor;
|
||||
|
||||
mLastSleep += (uint32_t)
|
||||
((mMaxSleep-mMinSleep) * (frac + 0.05));
|
||||
if (mLastSleep > mMaxSleep)
|
||||
{
|
||||
mLastSleep = mMaxSleep;
|
||||
}
|
||||
}
|
||||
|
||||
usleep(1000 * mLastSleep);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -28,6 +28,7 @@
|
||||
|
||||
|
||||
#include <pthread.h>
|
||||
#include <inttypes.h>
|
||||
|
||||
/* RsIface Thread Wrappers */
|
||||
|
||||
@ -75,4 +76,23 @@ virtual void run() = 0; /* called once the thread is started */
|
||||
};
|
||||
|
||||
|
||||
class RsQueueThread
|
||||
{
|
||||
RsQueueThread(uint32_t min, uint32_t max, double relaxFactor );
|
||||
virtual ~RsQueueThread() { return; }
|
||||
|
||||
virtual void run();
|
||||
|
||||
virtual bool workQueued() = 0;
|
||||
virtual bool doWork() = 0;
|
||||
|
||||
private:
|
||||
uint32_t mMinSleep; /* ms */
|
||||
uint32_t mMaxSleep; /* ms */
|
||||
uint32_t mLastSleep; /* ms */
|
||||
time_t mLastWork; /* secs */
|
||||
float mRelaxFactor;
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user