Created V0.3.x branch and moved the head into the trunk directory.

git-svn-id: http://svn.code.sf.net/p/retroshare/code/trunk@246 b45a01b8-16f6-495d-af2f-9b41ad6348cc
This commit is contained in:
drbob 2007-11-15 03:18:48 +00:00
commit 935745a08e
1318 changed files with 348809 additions and 0 deletions

11
libretroshare/src/BUGS Normal file
View File

@ -0,0 +1,11 @@
This is the list of known BUGS:
-------------------------------
* None!

6
libretroshare/src/FAQ Normal file
View File

@ -0,0 +1,6 @@
RetroShare FAQ
---------------
Ask a Question.

View File

@ -0,0 +1,39 @@
# FLTKGUI is not required for the Qt4,0 gui.
#
all:
make -C tcponudp
make -C pqi
make -C util
make -C dbase
make -C server
make -C dht
make -C upnp
make -C rsserver
make -C rsiface
# make -C fltkgui
clean:
make -C tcponudp clean
make -C pqi clean
make -C util clean
make -C dbase clean
make -C server clean
make -C dht clean
make -C upnp clean
make -C rsserver clean
make -C rsiface clean
# make -C fltkgui clean
clobber:
make -C tcponudp clobber
make -C pqi clobber
make -C util clobber
make -C dbase clobber
make -C server clobber
make -C dht clobber
make -C upnp clobber
make -C rsserver clobber
make -C rsiface clobber
# make -C fltkgui clobber

View File

@ -0,0 +1,150 @@
Compiling + Running RetroShare (V0.3.0)
-------------------------------------------------------------
Quick Requirements:
---------------------------------------------
Libraries/Tools:
C/C++ Compiler. (standard on Linux/cygwin)
OpenSSL-0.9.7g-xpgp
KadC Dht library
Qt-4.2 development libraries.
RetroShare Source Code: ( from sf.net/projects/retroshare)
Qt-GUI-XXX.tgz
retroshare-src-v0.3.XXX.tgz
Windows Requirements:
Cygwin (Windows Only)
Pthreads (Windows Only)
Zlib (Windows Only)
---------------------------------------------
OpenSSL-0.9.7g-xpgp is available at:
http://www.lunamutt.com/retroshare/openssl-0.9.7g-xpgp-0.1c.tgz
KadC (latest) is available from sourceforge.net
Download/Compile as per instructions...
---------------------------------------------
Compiling Linux
---------------------------------------------
(1) compile openSSL-0.9.7g-xpgp.
(2) compile KadC. (and correct the library)
(4) Modify ./make.opts
(4a) modify the Makefile so that: OS=Linux or OS=Win
(4c) Define SSL_DIR to point to openSSL-0.9.7g-xpgp.
(4c) Define KADC_DIR to point to KadC
(5) type: make
This builds ./lib/libretroshare.a,
and the various test programs.
There is server-only (no GUI) executable
compiled in ./rsiface/retroshare-nogui,
you can run this to check that its working.
---------------------------------------------
Compiling Linux (Alternative Instructions from Bharath)
---------------------------------------------
here's how to compiled retroshare on ubuntu linux:
compile openssl:
1. Get the patched version of openssl (openssl-0.9.7g-xpgp, from http://www.lunamutt.com)
2. run:
./config
make
make test
compile KadC:
1. Get KadC library from http://kadc.sourceforge.net/
2. run:
make
install packages needed for retroshare compile:
sudo apt-get install libxft-dev
sudo apt-get install libXinerama-dev
complile retroshare:
1. set directories in make.opt:
RS_DIR=/home/dev/rs-v0.3.0-pr8/src
SSL_DIR=/home/dev/openssl-0.9.7g-xpgp-0.1c
KADC_DIR=/home/dev/KadC
2. comment out the directory declarations uncer Cygwin since that will override your directory declarations from 1.
3. change RSLIBS = -L$(LIBDIR) -lretroshare -L$(SSL_DIR) -lssl -lcrypto -lpthread -lKadC
to
RSLIBS = -L$(LIBDIR) -lretroshare -L$(SSL_DIR) -lssl -lcrypto -lpthread -L$(KADC_DIR) -lKadC
4. run:
make
Hope this helps.
---------------------------------------------
Compiling the Qt GUI
_____________________________________________
(1) untar the Qt-GUI source package. run qmake,
tar -xvzf Qt-GUI-XXXX.tgz
cd Qt-Gui-XXX/src/
qmake-qt4 Retroshare.pro
(2) tweak the makefile: The default makefile
doesn't have the links to the retroshare
libraries. It should something like this:
RSLIBS = -L/home/dev/prog/devel/rs-v0.3.0XXX/src/lib -lretroshare -lKadC
SSLLIBS = -L/home/dev/prog/devel/openssl-0.9.7g-xpgp -lssl -lcrypto
LIBS = $(SUBLIBS) $(RSLIBS) $(SSLLIBS) -L/usr/lib -lQtXml -lQtGui -lQtNetwork -lQtCore -lpthread
This should build you an executable:
RetroShare.
------------------------------------------------
This has been compiled on the following platforms:
(a) Debian Linux (stable/testing/unstable)
(b) Suse Linux (9.X/10.X)
(c) WinXP
------------------------------------------------
WIN XP Compilation.
------------------------------------------------
This much harder, and more perilous than the
Linux compilation: It requires both the cygwin
and the mingw compilers...
Need:
Cygwin development environment
Qt4.2 opensource development kit + MinGw.
source code for all libraries.
In Brief:
UNDER Cygwin:
(1) Compile openssl-xpgp.
(2) Compile pthreads.
(3) Compile zlib.
(4) Compile KadC. (there are some tweaks,
needed to the code)
(5) Compile retroshare-v0.3.0
UNDER Mingw:
(6) Compile the Qt-Gui.
Email me if you're having trouble:
retroshare@lunamutt.com
---------------------------------------------

View File

@ -0,0 +1,54 @@
Compiling + Running RetroShare
-------------------------------------------------------------
Quick Requirements:
---------------------------------------------
Cygwin (Windows Only)
Fltk 1.1.6 (standard on Linux)
OpenSSL-0.9.7g-xpgp
C/C++ Compiler. (standard on Linux/cygwin)
---------------------------------------------
OpenSSL-0.9.7g-xpgp is available at:
http://www.lunamutt.com/retroshare/openssl-0.9.7g-xpgp-0.1c.tgz
Download/Compile as per instructions...
---------------------------------------------
Compiling.
---------------------------------------------
(1) Install openSSL-0.9.7g-xpgp.
(2) (WIN ONLY) Install fltk1.1.6.
(3) compile the tcponudp library.
(3a) cd ./tcponudp
(3b) modify the Makefile so that: OS=Linux or OS=Win
(3c) type: make
(3d) This should compile the libtou library, and the tests
(4) Modify ./make.opts
(4a) modify the Makefile so that: OS=Linux or OS=Win
(4b) Define RS_DIR to point to this directory.
(4c) Define SSL_DIR to point to openSSL-0.9.7g-xpgp.
(4d) (WIN ONLY) Define FLTK_DIR to point to FLTK.
(5) type: make
(6) run retroShare: ./fltkgui/RetroShare
---------------------------------------------
This has been compiled on the following platforms:
(a) Debian Linux (stable/testing/unstable)
(b) Suse Linux (9.X/10.X)
(c) WinXP
Let me know if something goes wrong:
retroshare@lunamutt.com
---------------------------------------------

7
libretroshare/src/TODO Normal file
View File

@ -0,0 +1,7 @@
TODO
---------------
Too much to list...

View File

@ -0,0 +1,53 @@
RS_TOP_DIR = ..
include ../make.opt
OBJ = filedex.o filelook.o \
findex.o fimonitor.o cachestrapper.o fistore.o \
rsexpr.o
EXEC = ftest looktest fitest2 fisavetest ficachetest searchtest
ifeq ($(OS),Linux)
EXEC += fimontest
endif
all : $(OBJ) librs $(EXEC)
librs: $(OBJ)
$(AR) r $(LIBRS) $(OBJ)
$(RANLIB) $(LIBRS)
ftest: $(OBJ) ftest.o
$(CC) $(CFLAGS) -o ftest $(OBJ) ftest.o $(RSLIBS)
looktest: $(OBJ) looktest.o
$(CC) $(CFLAGS) -o looktest $(OBJ) looktest.o $(RSLIBS)
fitest2 : fitest2.o $(OBJ)
$(CC) $(CFLAGS) -o fitest2 fitest2.o $(OBJ) $(RSLIBS)
fisavetest : fisavetest.o $(OBJ)
$(CC) $(CFLAGS) -o fisavetest fisavetest.o $(OBJ) $(RSLIBS)
fimontest : fimontest.o $(OBJ)
$(CC) $(CFLAGS) -o fimontest fimontest.o $(OBJ) $(RSLIBS)
ficachetest : ficachetest.o $(OBJ)
$(CC) $(CFLAGS) -o ficachetest ficachetest.o $(OBJ) $(RSLIBS)
searchtest : searchtest.o $(OBJ)
$(CC) $(CFLAGS) -o searchtest searchtest.o $(OBJ) $(RSLIBS)
.cc.o:
$(CC) $(CFLAGS) -c $<
clean:
-/bin/rm $(OBJ) ftest.o looktest.o
-/bin/rm fitest2.o fisavetest.o fimontest.o
-/bin/rm ficachetest.o searchtest.o
clobber: clean
-/bin/rm $(EXEC)

View File

@ -0,0 +1,721 @@
/*
* RetroShare FileCache Module: cachestrapper.cc
*
* Copyright 2004-2007 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 "dbase/cachestrapper.h"
#include <iostream>
#include <sstream>
#include <iomanip>
/**
* #define CS_DEBUG 1
*/
bool operator<(const CacheId &a, const CacheId &b)
{
if (a.type == b.type)
return (a.subid < b.subid);
return (a.type < b.type);
}
bool operator<(const CachePair &a, const CachePair &b)
{
return (a.id < b.id);
}
std::ostream &operator<<(std::ostream &out, const CacheData &d)
{
out << "[ p: " << d.pid << " id: <" << d.cid.type << "," << d.cid.subid;
out << "> #" << d.hash << " size: " << d.size;
out << " \"" << d.name << "\"@\"" << d.path;
out << "\" ]";
return out;
}
/********************************* Cache Store / Source **************************
* This is a generic interface which interacts with the FileTransfer Unit
* to collect Data to be Cached.
*
********************************* Cache Store / Source *************************/
CacheSource::CacheSource(uint16_t t, bool m, std::string cachedir)
:cacheType(t), multiCache(m), cacheDir(cachedir)
{
return;
}
/* Mutex Stuff -> to be done... */
void CacheSource::lockData()
{
#ifdef CS_DEBUG
std::cerr << "CacheSource::lockData()" << std::endl;
#endif
cMutex.lock();
}
void CacheSource::unlockData()
{
#ifdef CS_DEBUG
std::cerr << "CacheSource::unlockData()" << std::endl;
#endif
cMutex.unlock();
}
/* to be overloaded for inherited Classes */
bool CacheSource::loadCache(const CacheData &data)
{
return refreshCache(data);
}
/* control Caches available */
bool CacheSource::refreshCache(const CacheData &data)
{
lockData(); /* LOCK MUTEX */
bool ret = false;
if (data.cid.type == getCacheType())
{
if (isMultiCache())
{
caches[data.cid.subid] = data;
}
else
{
caches[0] = data;
}
ret = true;
}
unlockData(); /* UNLOCK MUTEX */
return ret;
}
bool CacheSource::clearCache(CacheId id)
{
lockData(); /* LOCK MUTEX */
bool ret = false;
if (id.type == getCacheType())
{
CacheSet::iterator it;
if (caches.end() != (it = caches.find(id.subid)))
{
caches.erase(it);
ret = true;
}
}
unlockData(); /* UNLOCK MUTEX */
return ret;
}
bool CacheSource::cachesAvailable(RsPeerId pid, std::map<CacheId, CacheData> &ids)
{
lockData(); /* LOCK MUTEX */
/* can overwrite for more control! */
CacheSet::iterator it;
for(it = caches.begin(); it != caches.end(); it++)
{
ids[(it->second).cid] = it->second;
}
bool ret = (caches.size() > 0);
unlockData(); /* UNLOCK MUTEX */
return ret;
}
bool CacheSource::findCache(std::string hash, CacheData &data)
{
lockData(); /* LOCK MUTEX */
bool found = false;
CacheSet::iterator it;
for(it = caches.begin(); it != caches.end(); it++)
{
if (hash == (it->second).hash)
{
data = it->second;
found = true;
break;
}
}
unlockData(); /* UNLOCK MUTEX */
return found;
}
void CacheSource::listCaches(std::ostream &out)
{
lockData(); /* LOCK MUTEX */
/* can overwrite for more control! */
CacheSet::iterator it;
out << "CacheSource::listCaches() [" << getCacheType();
out << "] Total: " << caches.size() << std::endl;
int i;
for(i = 0, it = caches.begin(); it != caches.end(); it++, i++)
{
out << "\tC[" << i << "] : " << it->second << std::endl;
}
unlockData(); /* UNLOCK MUTEX */
return;
}
CacheStore::CacheStore(uint16_t t, bool m, CacheTransfer *cft, std::string cachedir)
:cacheType(t), multiCache(m), cacheTransfer(cft), cacheDir(cachedir)
{
/* not much */
return;
}
/* Mutex Stuff -> to be done... */
void CacheStore::lockData()
{
#ifdef CS_DEBUG
std::cerr << "CacheStore::lockData()" << std::endl;
#endif
cMutex.lock();
}
void CacheStore::unlockData()
{
#ifdef CS_DEBUG
std::cerr << "CacheStore::unlockData()" << std::endl;
#endif
cMutex.unlock();
}
void CacheStore::listCaches(std::ostream &out)
{
lockData(); /* LOCK MUTEX */
/* can overwrite for more control! */
std::map<RsPeerId, CacheSet>::iterator pit;
out << "CacheStore::listCaches() [" << getCacheType();
out << "] Total People: " << caches.size();
out << std::endl;
for(pit = caches.begin(); pit != caches.end(); pit++)
{
CacheSet::iterator it;
out << "\tTotal for [" << pit->first << "] : " << (pit->second).size();
out << std::endl;
for(it = (pit->second).begin(); it != (pit->second).end(); it++)
{
out << "\t\t" << it->second;
out << std::endl;
}
}
unlockData(); /* UNLOCK MUTEX */
return;
}
/* look for stored data. using pic/cid in CacheData
*/
bool CacheStore::getStoredCache(CacheData &data)
{
lockData(); /* LOCK MUTEX */
bool ok = locked_getStoredCache(data);
unlockData(); /* UNLOCK MUTEX */
return ok;
}
bool CacheStore::locked_getStoredCache(CacheData &data)
{
if (data.cid.type != getCacheType())
{
return false;
}
std::map<RsPeerId, CacheSet>::iterator pit;
if (caches.end() == (pit = caches.find(data.pid)))
{
return false;
}
CacheSet::iterator cit;
if (isMultiCache())
{
/* look for subid */
if ((pit->second).end() ==
(cit = (pit->second).find(data.cid.subid)))
{
return false;
}
}
else
{
if ((pit->second).end() ==
(cit = (pit->second).find(0)))
{
return false;
}
}
/* we found it! (cit) */
data = cit->second;
return true;
}
/* input from CacheStrapper.
* check if we want to download it...
* determine the new name/path
* then request it.
*/
void CacheStore::availableCache(const CacheData &data)
{
std::cerr << "CacheStore::availableCache() :" << data << std::endl;
/* basic checks */
lockData(); /* LOCK MUTEX */
bool rightCache = (data.cid.type == getCacheType());
unlockData(); /* UNLOCK MUTEX */
if (!rightCache)
{
return; /* bad id */
}
/* These Functions lock the Mutex themselves
*/
if (!fetchCache(data))
{
return; /* ignore it */
}
CacheData rData = data;
/* get new name */
if (!nameCache(rData))
{
return; /* error naming */
}
/* request it */
cacheTransfer -> RequestCache(rData, this);
/* will get callback when it is complete */
return;
}
/* called when the download is completed ... updates internal data */
void CacheStore::downloadedCache(const CacheData &data)
{
std::cerr << "CacheStore::downloadedCache() :" << data << std::endl;
/* updates data */
if (!loadCache(data))
{
return;
}
}
/* called when the download is completed ... updates internal data */
void CacheStore::failedCache(const CacheData &data)
{
std::cerr << "CacheStore::failedCache() :" << data << std::endl;
return;
}
/* virtual function overloaded by cache implementor */
bool CacheStore::fetchCache(const CacheData &data)
{
/* should we fetch it? */
std::cerr << "CacheStore::fetchCache() tofetch?:" << data << std::endl;
CacheData incache = data;
lockData(); /* LOCK MUTEX */
bool haveCache = ((locked_getStoredCache(incache)) && (data.hash == incache.hash));
unlockData(); /* UNLOCK MUTEX */
if (haveCache)
{
std::cerr << "CacheStore::fetchCache() Already have it: false" << std::endl;
return false;
}
std::cerr << "CacheStore::fetchCache() Missing this cache: true" << std::endl;
return true;
}
int CacheStore::nameCache(CacheData &data)
{
/* name it... */
lockData(); /* LOCK MUTEX */
std::cerr << "CacheStore::nameCache() for:" << data << std::endl;
data.name = data.hash;
data.path = getCacheDir();
std::cerr << "CacheStore::nameCache() done:" << data << std::endl;
unlockData(); /* UNLOCK MUTEX */
return 1;
}
int CacheStore::loadCache(const CacheData &data)
{
/* attempt to load -> dummy function */
std::cerr << "CacheStore::loadCache() Dummy Load for:" << data << std::endl;
lockData(); /* LOCK MUTEX */
locked_storeCacheEntry(data);
unlockData(); /* UNLOCK MUTEX */
return 1;
}
/* This function is called to store Cache Entry in the CacheStore Table.
* it must be called from within a Mutex Lock....
*
* It doesn't lock itself -> to avoid race conditions
*/
void CacheStore::locked_storeCacheEntry(const CacheData &data)
{
/* store what we loaded - overwriting if necessary */
std::map<RsPeerId, CacheSet>::iterator pit;
if (caches.end() == (pit = caches.find(data.pid)))
{
/* add in a new CacheSet */
CacheSet emptySet;
caches[data.pid] = emptySet;
pit = caches.find(data.pid);
}
if (isMultiCache())
{
(pit->second)[data.cid.subid] = data;
}
else
{
(pit->second)[0] = data;
}
return;
}
/********************************* CacheStrapper *********************************
* This is the bit which handles queries
*
********************************* CacheStrapper ********************************/
CacheStrapper::CacheStrapper(RsPeerId id, time_t period)
:ownId(id), queryPeriod(period)
{
return;
}
void CacheStrapper::addCachePair(CachePair set)
{
caches[set.id.type] = set;
}
/* from pqimonclient */
void CacheStrapper::monUpdate(const std::list<pqipeer> &plist)
{
std::list<pqipeer>::const_iterator it;
std::map<RsPeerId, CacheTS>::iterator mit;
for(it = plist.begin(); it != plist.end(); it++)
{
if (status.end() == (mit = status.find(it->id)))
{
addPeerId(it->id);
}
}
}
void CacheStrapper::addPeerId(RsPeerId pid)
{
std::map<RsPeerId, CacheTS>::iterator it;
/* just reset it for the moment */
CacheTS ts;
ts.query = 0;
ts.answer = 0;
status[pid] = ts;
}
bool CacheStrapper::removePeerId(RsPeerId pid)
{
std::map<RsPeerId, CacheTS>::iterator it;
if (status.end() != (it = status.find(pid)))
{
status.erase(it);
return true;
}
return false;
}
/* pass to correct CacheSet */
void CacheStrapper::recvCacheResponse(CacheData &data, time_t ts)
{
/* update internal data first */
std::map<RsPeerId, CacheTS>::iterator it;
if (status.end() == status.find(data.pid))
{
/* add it in */
CacheTS d;
d.query = 0;
d.answer = 0;
status[data.pid] = d;
}
it = status.find(data.pid); /* will always succeed */
/* update status */
(it -> second).answer = ts;
/* find cache store */
std::map<uint16_t, CachePair>::iterator it2;
if (caches.end() == (it2 = caches.find(data.cid.type)))
{
/* error - don't have this type of cache */
return;
}
/* notify the CacheStore */
(it2 -> second).store -> availableCache(data);
}
/* generate periodically or at a change */
bool CacheStrapper::sendCacheQuery(std::list<RsPeerId> &id, time_t ts)
{
/* iterate through peers, and see who we haven't got an answer from recently */
std::map<RsPeerId, CacheTS>::iterator it;
for(it = status.begin(); it != status.end(); it++)
{
if ((ts - (it->second).query) > queryPeriod)
{
/* query this one */
id.push_back(it->first);
(it->second).query = ts;
}
}
return (id.size() > 0);
}
void CacheStrapper::handleCacheQuery(RsPeerId id, std::map<CacheId,CacheData> &hashs)
{
/* basic version just iterates through ....
* more complex could decide who gets what!
*
* or that can be handled on a cache by cache basis.
*/
std::map<uint16_t, CachePair>::iterator it;
for(it = caches.begin(); it != caches.end(); it++)
{
(it->second).source -> cachesAvailable(id, hashs);
}
return;
}
void CacheStrapper::listCaches(std::ostream &out)
{
/* can overwrite for more control! */
std::map<uint16_t, CachePair>::iterator it;
out << "CacheStrapper::listCaches() [" << ownId;
out << "] Total Peers: " << status.size() << " Total Caches: " << caches.size();
out << std::endl;
for(it = caches.begin(); it != caches.end(); it++)
{
out << "CacheType: " << it->first;
out << std::endl;
(it->second).source->listCaches(out);
(it->second).store->listCaches(out);
out << std::endl;
}
return;
}
void CacheStrapper::listPeerStatus(std::ostream &out)
{
std::map<RsPeerId, CacheTS>::iterator it;
out << "CacheStrapper::listPeerStatus() [" << ownId;
out << "] Total Peers: " << status.size() << " Total Caches: " << caches.size();
out << std::endl;
for(it = status.begin(); it != status.end(); it++)
{
out << "Peer: " << it->first;
out << " Query: " << (it->second).query;
out << " Answer: " << (it->second).answer;
out << std::endl;
}
return;
}
bool CacheStrapper::findCache(std::string hash, CacheData &data)
{
/* can overwrite for more control! */
std::map<uint16_t, CachePair>::iterator it;
for(it = caches.begin(); it != caches.end(); it++)
{
if ((it->second).source->findCache(hash, data))
{
return true;
}
}
return false;
}
/********************************* CacheStrapper *********************************
* This is the bit which handles queries
*
********************************* CacheStrapper ********************************/
/* request from CacheStore */
bool CacheTransfer::RequestCache(CacheData &data, CacheStore *cbStore)
{
/* store request */
cbData[data.hash] = data;
cbStores[data.hash] = cbStore;
/* request data */
RequestCacheFile(data.pid, data.path, data.hash, data.size);
/* wait for answer */
return true;
}
/* to be overloaded */
bool CacheTransfer::RequestCacheFile(RsPeerId id, std::string path, std::string hash, uint32_t size)
{
std::cerr << "CacheTransfer::RequestCacheFile() : from:" << id << " #";
std::cerr << hash << " size: " << size;
std::cerr << " savepath: " << path << std::endl;
std::cerr << "CacheTransfer::RequestCacheFile() Dummy... saying completed";
std::cerr << std::endl;
/* just tell them we've completed! */
CompletedCache(hash);
return true;
}
/* internal completion -> does cb */
bool CacheTransfer::CompletedCache(std::string hash)
{
std::map<std::string, CacheData>::iterator dit;
std::map<std::string, CacheStore *>::iterator sit;
/* find in store.... */
sit = cbStores.find(hash);
dit = cbData.find(hash);
if ((sit == cbStores.end()) || (dit == cbData.end()))
{
return false;
}
/* callback */
(sit -> second) -> downloadedCache(dit->second);
/* clean up store */
cbStores.erase(sit);
cbData.erase(dit);
return true;
}
/* internal completion -> does cb */
bool CacheTransfer::FailedCache(std::string hash)
{
std::map<std::string, CacheData>::iterator dit;
std::map<std::string, CacheStore *>::iterator sit;
/* find in store.... */
sit = cbStores.find(hash);
dit = cbData.find(hash);
if ((sit == cbStores.end()) || (dit == cbData.end()))
{
return false;
}
/* callback */
(sit -> second) -> failedCache(dit->second);
/* clean up store */
cbStores.erase(sit);
cbData.erase(dit);
return true;
}
bool CacheTransfer::FindCacheFile(std::string hash, std::string &path, uint32_t &size)
{
CacheData data;
if (strapper->findCache(hash, data))
{
path = data.path + "/" + data.name;
size = data.size;
return true;
}
return false;
}

View File

@ -0,0 +1,321 @@
/*
* RetroShare FileCache Module: cachestrapper.h
*
* Copyright 2004-2007 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 MRK_CACHE_STRAPPER_H
#define MRK_CACHE_STRAPPER_H
#include <list>
#include <map>
#include <string>
#include <iostream>
#include "util/rsthreads.h"
/******************* CacheStrapper and Related Classes *******************
* A generic Cache Update system.
*
* CacheStrapper: maintains a set of CacheSources, and CacheStores,
* queries and updates as new information arrives.
*
* CacheTransfer: Interface for FileTransfer Class to support.
*
* CacheSource: Base Class for cache data provider. eg. FileIndexMonitor.
* CacheStore: Base Class for data cache. eg. FileCache/Store.
*
* Still TODO:
* (1) Design and Implement the Upload side of CacheTransfer/CacheStrapper.
* (2) CacheStrapper:: Save / Load Cache lists....
* (3) Clean up lists, maps on shutdown etc.
* (4) Consider Mutexes for multithreaded operations.
* (5) Test the MultiSource/Store capabilities.
*
******************* CacheStrapper and Related Classes *******************/
class CacheTransfer; /* Interface for File Transfer */
class CacheSource; /* Interface for local File Index/Monitor */
class CacheStore; /* Interface for the actual Cache */
class CacheStrapper; /* Controlling Class */
/****
typedef uint32_t RsPeerId;
*****/
typedef std::string RsPeerId;
/******************************** CacheId ********************************/
class CacheId
{
public:
CacheId() :type(0), subid(0) { return; }
CacheId(uint16_t a, uint16_t b) :type(a), subid(b) { return; }
uint16_t type;
uint16_t subid;
};
bool operator<(const CacheId &a, const CacheId &b);
#define CACHE_TYPE_FILE_INDEX 1
#define CACHE_TYPE_WEB 2
#define CACHE_TYPE_OTHER 4
/* think of any others? */
class CacheData
{
public:
RsPeerId pid;
std::string pname; /* peer name (can be used by cachestore) */
CacheId cid;
std::string path;
std::string name;
std::string hash;
uint32_t size;
time_t recvd;
};
std::ostream &operator<<(std::ostream &out, const CacheData &d);
/***************************** CacheTransfer *****************************/
class CacheTransfer
{
public:
CacheTransfer(CacheStrapper *cs) :strapper(cs) { return; }
virtual ~CacheTransfer() {}
/* upload side of things .... searches through CacheStrapper. */
bool FindCacheFile(std::string hash, std::string &path, uint32_t &size);
/* At the download side RequestCache() => overloaded RequestCacheFile()
* the class should then call CompletedCache() or FailedCache()
*/
bool RequestCache(CacheData &data, CacheStore *cbStore); /* request from CacheStore */
protected:
/* to be overloaded */
virtual bool RequestCacheFile(RsPeerId id, std::string path, std::string hash, uint32_t size);
bool CompletedCache(std::string hash); /* internal completion -> does cb */
bool FailedCache(std::string hash); /* internal completion -> does cb */
private:
CacheStrapper *strapper;
std::map<std::string, CacheData> cbData;
std::map<std::string, CacheStore *> cbStores;
};
/************************ CacheSource/CacheStore *************************/
typedef std::map<uint16_t, CacheData> CacheSet;
class CacheSource
{
public:
CacheSource(uint16_t t, bool m, std::string cachedir);
virtual ~CacheSource() {}
/* called to determine available cache for peer -
* default acceptable (returns all)
*/
virtual bool cachesAvailable(RsPeerId pid, std::map<CacheId, CacheData> &ids);
/* function called at startup to load from
* configuration file....
* to be overloaded by inherited class
*/
virtual bool loadCache(const CacheData &data);
/* control Caches available */
bool refreshCache(const CacheData &data);
bool clearCache(CacheId id);
/* get private data */
std::string getCacheDir() { return cacheDir; }
bool isMultiCache() { return multiCache; }
uint16_t getCacheType() { return cacheType; }
/* display */
void listCaches(std::ostream &out);
/* search */
bool findCache(std::string hash, CacheData &data);
protected:
/*** MUTEX LOCKING - TODO
*/
void lockData();
void unlockData();
CacheSet caches;
private:
uint16_t cacheType; /* for checking */
bool multiCache; /* do we care about subid's */
std::string cacheDir;
RsMutex cMutex;
};
class CacheStore
{
public:
CacheStore(uint16_t t, bool m, CacheTransfer *cft, std::string cachedir);
virtual ~CacheStore() {}
/* current stored data */
bool getStoredCache(CacheData &data); /* use pid/cid in data */
/* input from CacheStrapper -> store can then download new data */
void availableCache(const CacheData &data);
/* called when the download is completed ... updates internal data */
void downloadedCache(const CacheData &data);
/* called if the download fails */
void failedCache(const CacheData &data);
/* virtual functions overloaded by cache implementor */
virtual bool fetchCache(const CacheData &data); /* a question? */
virtual int nameCache(CacheData &data); /* fill in the name/path */
virtual int loadCache(const CacheData &data); /* actual load, once data available */
/* get private data */
std::string getCacheDir() { return cacheDir; }
bool isMultiCache() { return multiCache; }
uint16_t getCacheType() { return cacheType; }
/* display */
void listCaches(std::ostream &out);
protected:
/*** MUTEX LOCKING */
void lockData();
void unlockData();
/* This function is called to store Cache Entry in the CacheStore Table.
* it must be called from within a Mutex Lock....
*
* It doesn't lock itself -> to avoid race conditions
*/
void locked_storeCacheEntry(const CacheData &data);
bool locked_getStoredCache(CacheData &data);
private:
uint16_t cacheType; /* for checking */
bool multiCache; /* do we care about subid's */
CacheTransfer *cacheTransfer;
std::string cacheDir;
std::map<RsPeerId, CacheSet> caches;
RsMutex cMutex;
};
/***************************** CacheStrapper *****************************/
/* Make Sure you get the Ids right! */
class CachePair
{
public:
CachePair()
:source(NULL), store(NULL), id(0, 0) { return; }
CachePair(CacheSource *a, CacheStore *b, CacheId c)
:source(a), store(b), id(c) { return; }
CacheSource *source;
CacheStore *store;
CacheId id;
};
bool operator<(const CachePair &a, const CachePair &b);
class CacheTS
{
public:
time_t query;
time_t answer;
};
#include "pqi/pqimon.h"
class CacheStrapper: public pqimonclient
{
public:
CacheStrapper(RsPeerId id, time_t period);
virtual ~CacheStrapper() { return; }
/* from pqimonclient */
virtual void monUpdate(const std::list<pqipeer> &plist);
void addCachePair(CachePair pair);
void addPeerId(RsPeerId pid);
bool removePeerId(RsPeerId pid);
/*** I/O (1) ***/
/* pass to correct CacheSet */
void recvCacheResponse(CacheData &date, time_t ts);
/* generate periodically or at a change */
bool sendCacheQuery(std::list<RsPeerId> &id, time_t ts);
/*** I/O (2) ***/
/* handle a DirQuery */
void handleCacheQuery(RsPeerId id, std::map<CacheId, CacheData> &data);
/* search through CacheSources. */
bool findCache(std::string hash, CacheData &data);
/* display */
void listCaches(std::ostream &out);
void listPeerStatus(std::ostream &out);
private:
std::map<RsPeerId, CacheTS> status;
std::map<uint16_t, CachePair> caches;
RsPeerId ownId;
time_t queryPeriod;
};
#endif

View File

@ -0,0 +1,63 @@
/*
* RetroShare FileCache Module: cachetest.h
*
* Copyright 2004-2007 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 MRK_TEST_CACHE_H
#define MRK_TEST_CACHE_H
#include "cachestrapper.h"
#define TESTID 0xffff
#define TESTID2 0xffee
class CacheTestSource: public CacheSource
{
public:
CacheTestSource(std::string dir)
:CacheSource(TESTID, false, dir) { return; }
};
class CacheTestStore: public CacheStore
{
public:
CacheTestStore(CacheTransfer *cft, std::string dir)
:CacheStore(TESTID, false, cft, dir) { return; }
};
class CacheTestMultiSource: public CacheSource
{
public:
CacheTestMultiSource(std::string dir)
:CacheSource(TESTID2, true, dir) { return; }
};
class CacheTestMultiStore: public CacheStore
{
public:
CacheTestMultiStore(CacheTransfer *cft, std::string dir)
:CacheStore(TESTID2, true, cft, dir) { return; }
};
#endif

View File

@ -0,0 +1,209 @@
/*
* RetroShare FileCache Module: ficachetest.cc
*
* Copyright 2004-2007 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 "cachestrapper.h"
#include "cachetest.h"
#include <iostream>
/********************************** WINDOWS/UNIX SPECIFIC PART ******************/
#ifndef WINDOWS_SYS
#else
#include <windows.h>
#endif
/********************************** WINDOWS/UNIX SPECIFIC PART ******************/
void handleQuery(CacheStrapper *csp, RsPeerId pid,
std::map<RsPeerId, CacheStrapper *> &strappers);
/* A simple test of the CacheStrapper Code.
*
* create 3 different CacheStrappers, each with a Source/Store Pair and Transfer Class.
* pass queries and responses between the CacheStrappers,
* and ensure that the hashes in the Caches are updated.
*
*/
int main(int argc, char **argv)
{
time_t period = 11;
RsPeerId pid1("0x0101");
RsPeerId pid2("0x0102");
RsPeerId pid3("0x0103");
CacheStrapper sc1(pid1, period);
CacheStrapper sc2(pid2, period);
CacheStrapper sc3(pid3, period);
CacheTransfer ctt1(&sc1);
CacheTransfer ctt2(&sc2);
CacheTransfer ctt3(&sc3);
std::map<RsPeerId, CacheStrapper *> strappers;
strappers[pid1] = &sc1;
strappers[pid2] = &sc2;
strappers[pid3] = &sc3;
std::string nulldir = "";
CacheSource *csrc1 = new CacheTestSource(nulldir);
CacheStore *cstore1 = new CacheTestStore(&ctt1, nulldir);
CacheId cid1(TESTID, 0);
CacheSource *csrc2 = new CacheTestSource(nulldir);
CacheStore *cstore2 = new CacheTestStore(&ctt2, nulldir);
CacheId cid2(TESTID, 0);
CacheSource *csrc3 = new CacheTestSource(nulldir);
CacheStore *cstore3 = new CacheTestStore(&ctt3, nulldir);
CacheId cid3(TESTID, 0);
CachePair cp1(csrc1, cstore1, cid1);
CachePair cp2(csrc2, cstore2, cid2);
CachePair cp3(csrc3, cstore3, cid3);
sc1.addCachePair(cp1);
sc2.addCachePair(cp2);
sc3.addCachePair(cp3);
sc1.addPeerId(pid2);
sc2.addPeerId(pid1);
sc2.addPeerId(pid3);
sc3.addPeerId(pid2);
/* add in a cache to sc2 */
CacheData cdata;
cdata.pid = pid1;
cdata.cid = cid1;
cdata.name = "Perm Cache";
cdata.path = "./";
cdata.hash = "GHJKI";
csrc1->refreshCache(cdata);
cdata.pid = pid2;
cdata.cid = cid2;
cdata.name = "Funny Cache";
cdata.path = "./";
cdata.hash = "ABCDEF";
csrc2->refreshCache(cdata);
/* now exercise it */
for(int i = 0; 1 ; i++)
{
RsPeerId src("");
CacheStrapper *csp = NULL;
if (i % 5 == 1)
{
src = pid1;
csp = &sc1;
}
else if (i % 5 == 2)
{
src = pid2;
csp = &sc2;
}
else if (i % 5 == 3)
{
src = pid3;
csp = &sc3;
}
std::cerr << std::endl;
std::cerr << "Cache Iteraton: " << time(NULL) << std::endl;
std::cerr << std::endl;
if (src != "")
{
handleQuery(csp, src, strappers);
}
if (i % 21 == 0)
{
/* print out the resources */
sc1.listCaches(std::cerr);
sc2.listCaches(std::cerr);
sc3.listCaches(std::cerr);
}
/* every once in a while change the cache on 2 */
if (i % 31 == 25)
{
cdata.hash += "X";
csrc2->refreshCache(cdata);
}
/********************************** WINDOWS/UNIX SPECIFIC PART ******************/
#ifndef WINDOWS_SYS
sleep(1);
#else
Sleep(1000);
#endif
/********************************** WINDOWS/UNIX SPECIFIC PART ******************/
/* tick the systems */
}
/* Cleanup - TODO */
return 1;
}
void handleQuery(CacheStrapper *csp, RsPeerId pid,
std::map<RsPeerId, CacheStrapper *> &strappers)
{
/* query */
std::list<RsPeerId> ids;
std::list<RsPeerId>::iterator pit;
std::cerr << "Cache Query from: " << pid << std::endl;
csp -> sendCacheQuery(ids, time(NULL));
for(pit = ids.begin(); pit != ids.end(); pit++)
{
std::cerr << "Cache Query for: " << (*pit) << std::endl;
std::map<RsPeerId, CacheStrapper *>::iterator sit;
if (strappers.end() != (sit = strappers.find(*pit)))
{
std::map<CacheId, CacheData> hashs;
std::map<CacheId, CacheData>::iterator hit;
(sit -> second) -> handleCacheQuery(pid, hashs);
for(hit = hashs.begin(); hit != hashs.end(); hit++)
{
csp -> recvCacheResponse(hit->second, time(NULL));
}
}
else
{
std::cerr << "Unknown Query Destination!" << std::endl;
}
}
}

View File

@ -0,0 +1,366 @@
/*
* "$Id: filedex.cc,v 1.8 2007-02-18 21:46:49 rmf24 Exp $"
*
* Other Bits for RetroShare.
*
* Copyright 2004-2006 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 "filedex.h"
#include <iostream>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <dirent.h>
fdex::fdex()
{
return;
}
fdex::fdex(const char *p, const char *d, const char *f, const char *e, int l, int v)
:path(p), subdir(d), file(f), ext(e), len(l), vis(v)
{
return;
}
int filedex::load(std::list<DirItem> dirs)
{
std::list<DirItem>::iterator it;
/* these must be done in the correct order to ensure
* that the visibility is correct
*/
for(int i = FD_VIS_EXACT_ONLY; i <= FD_VIS_LISTING; i++)
{
for(it = dirs.begin(); it != dirs.end(); it++)
{
if (i == it -> vis)
{
//std::cerr << "Adding Type(" << it -> vis << ") " << it -> basepath;
//std::cerr << std::endl;
dirtodo.push_back(*it);
}
}
}
return processdirs();
}
int filedex::clear()
{
std::list<fdex *>::iterator it;
dirtodo.clear();
dirdone.clear();
for(it = files.begin(); it != files.end(); it++)
{
delete(*it);
}
files.clear();
for(it = dirlist.begin(); it != dirlist.end(); it++)
{
delete(*it);
}
dirlist.clear();
return 1;
}
std::string strtolower2(std::string in)
{
std::string out = in;
for(int i = 0; i < (signed) out.length(); i++)
{
if (isupper(out[i]))
{
out[i] += 'a' - 'A';
}
}
return out;
}
std::string fileextension2(std::string in)
{
std::string out;
bool found = false;
for(int i = in.length() -1; (i >= 0) && (found == false); i--)
{
if (in[i] == '.')
{
found = true;
for(int j = i+1; j < (signed) in.length(); j++)
{
out += in[j];
}
}
}
return strtolower2(out);
}
std::list<fdex *> filedex::search(std::list<std::string> terms, int limit, bool local)
{
bool found;
std::list<fdex *> newlist;
int matches = 0;
std::list<fdex *>::iterator fit;
std::list<std::string>::iterator tit;
//std::cerr << "filedex::search() looking for" << std::endl;
//for(tit = terms.begin(); tit != terms.end(); tit++)
// std::cerr << "\t(" << *tit << ")" << std::endl;
//std::cerr << "Checking:" << std::endl;
for(fit = files.begin(); fit != files.end(); fit++)
{
// ignore named only files.
if ((!local) && ((*fit)->vis < FD_VIS_SEARCH))
continue;
found = true;
for(tit = terms.begin(); (tit != terms.end()) && (found); tit++)
{
std::string path = (*fit) -> subdir+"/"+(*fit)->file;
std::string lowerpath = strtolower2(path);
std::string lowerterm = strtolower2(*tit);
//std::cerr << "\tLooking for (" << lowerterm;
//std::cerr << ") in (" << lowerpath << ") ";
if (strstr(lowerpath.c_str(), lowerterm.c_str()) == NULL)
{
found = false;
//std::cerr << "\tFalse..." << std::endl;
}
else
{
//std::cerr << "\tTrue..." << std::endl;
}
}
if (found)
{
//std::cerr << "Found Matching!" << std::endl;
newlist.push_back(*fit);
if (++matches == limit)
{
//std::cerr << "Reached Limit(" << limit << ")";
//std::cerr << "Returning Results" << std::endl;
return newlist;
}
}
}
return newlist;
}
std::list<fdex *> filedex::dirlisting(std::string basedir)
{
std::list<fdex *> newlist;
std::list<fdex *>::iterator fit;
//std::cerr << "filedex::dirlisting() looking for subdir: " << basedir << std::endl;
//std::cerr << "Checking:" << std::endl;
for(fit = dirlist.begin(); fit != dirlist.end(); fit++)
{
//std::cerr << "DCHK(" << basedir << ") vs (" << (*fit) -> subdir << ")" << std::endl;
if (basedir == (*fit) -> subdir)
{
/* in the dir */
//std::cerr << "Found Matching SubDir:";
//std::cerr << (*fit) -> subdir << std::endl;
newlist.push_back(*fit);
}
}
for(fit = files.begin(); fit != files.end(); fit++)
{
//std::cerr << "FCHK(" << basedir << ") vs (" << (*fit) -> subdir << ")" << std::endl;
if (basedir == (*fit) -> subdir)
{
/* in the dir */
//std::cerr << "Found Matching File:";
//std::cerr << (*fit) -> subdir << std::endl;
newlist.push_back(*fit);
}
}
return newlist;
}
std::list<fdex *> filedex::findfilename(std::string name)
{
std::list<fdex *> newlist;
std::list<fdex *>::iterator fit;
std::cerr << "filedex::findfilename() looking for: " << name << std::endl;
std::cerr << "Checking:" << std::endl;
for(fit = files.begin(); fit != files.end(); fit++)
{
if (name == (*fit) -> file)
{
/* in the dir */
std::cerr << "Found Matching File!" << std::endl;
newlist.push_back(*fit);
}
}
return newlist;
}
int filedex::processdirs()
{
std::list<DirItem>::iterator it;
std::list<std::string>::iterator sit;
std::string dirname;
std::string subdir;
std::string fname;
std::string fullname;
struct dirent *ent;
struct stat buf;
bool found = false;
fdex *fx;
int count = 0;
int ficount = 0;
while(dirtodo.size() > 0)
{
count++;
it = dirtodo.begin();
DirItem currDir(*it);
dirname = currDir.getFullPath();
dirtodo.erase(it);
//std::cerr << "\tExamining: " << currDir.basepath;
//std::cerr << " -/- " << currDir.subdir << std::endl;
//std::cerr << "\t\t" << count << " Directories done, ";
//std::cerr << dirtodo.size() << " to go! " << std::endl;
// open directory.
DIR *dir = opendir(dirname.c_str());
if (dir != NULL) {
// read the directory.
while(NULL != (ent = readdir(dir)))
{
fname = ent -> d_name;
fullname = dirname + "/" + fname;
subdir = currDir.subdir;
// std::cerr << "Statting dirent: " << fullname.c_str() <<std::endl;
// std::cerr << "Statting dirent: " << fullname <<std::endl;
// stat each file.
if (-1 != stat(fullname.c_str(), &buf))
{
//std::cerr << "buf.st_mode: " << buf.st_mode <<std::endl;
if (S_ISDIR(buf.st_mode))
{
//std::cerr << "Is Directory: " << fullname << std::endl;
found = false;
// remove "." and ".." entries.
if ((fname == ".") || (fname == ".."))
{
found = true;
}
// check if in list of done already.
for(it = dirtodo.begin(); it != dirtodo.end(); it++)
{
if (it -> getFullPath() == fullname)
found = true;
}
for(sit = dirdone.begin(); sit != dirdone.end(); sit++)
{
if ((*sit) == fullname)
found = true;
}
if (found == false)
{
// add to list to read.
DirItem ndir(currDir.basepath, subdir+"/"+fname, currDir.vis);
// Push to the front of the list -> so processing done in order.
dirtodo.push_front(ndir);
// std::cerr << "\t Adding Directory: " << fullname;
// std::cerr << " to dirtodo" << std::endl;
if (currDir.vis == FD_VIS_LISTING)
{
// add to dirlist dbase.
fx = new fdex(fullname.c_str(), subdir.c_str(),
fname.c_str(), "DIR", 0, currDir.vis);
dirlist.push_back(fx);
// std::cerr << "\t Adding Directory: " << fullname;
// std::cerr << " to dirlist" << std::endl;
}
}
}
else if (S_ISREG(buf.st_mode))
{
// add to dbase.
fx = new fdex(fullname.c_str(), subdir.c_str(),
fname.c_str(), (fileextension2(fname)).c_str(),
buf.st_size, currDir.vis);
//fx -> path = fullname;
files.push_back(fx);
ficount++;
if (ficount % 100 == 0)
{
//std::cerr << "\tIndex(" << ficount << ") : ";
//std::cerr << "\tIndexing File: " << fname;
//std::cerr << std::endl;
}
}
else
{
// warning.
std::cerr << "\t Ignoring Unknown FileType";
std::cerr << std::endl;
}
}
else
{
}
}
// should check error message.
dirdone.push_back(dirname);
closedir(dir);
}
else
{
//std::cerr << "Cannot Open Directory:" << dirname << std::endl;
}
}
return 1;
}

View File

@ -0,0 +1,111 @@
/*
* "$Id: filedex.h,v 1.4 2007-02-18 21:46:49 rmf24 Exp $"
*
* Other Bits for RetroShare.
*
* Copyright 2004-2006 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 MRK_PQI_FILEINDEXER
#define MRK_PQI_FILEINDEXER
/* a file index.
*
* initiated with a list of directories.
*
*/
#include <list>
#include <string>
#define FD_VIS_EXACT_ONLY 0
#define FD_VIS_SEARCH 1
#define FD_VIS_LISTING 2
/* if vis = FD_VIS_EXACT_ONLY
* Then only an exact filename match works
* if vis = FD_VIS_SEARCH
* Then only a search will return it.
* if vis = FD_VIS_LISTING
* Then any method will find it.
*/
class fdex
{
public:
fdex();
fdex(const char *path, const char *srchpath,
const char *file, const char *ext, int len, int vis);
std::string path; // full path. (not searched)
std::string subdir; // searched if flag set.
std::string file;
std::string ext;
int len;
int vis;
};
class DirItem
{
public:
DirItem(std::string bp, std::string sd, int v)
: basepath(bp), subdir(sd), vis(v) {}
std::string getFullPath()
{
return basepath + subdir;
}
std::string basepath;
std::string subdir;
int vis;
};
class filedex
{
public:
int load(std::list<DirItem> dirs);
int clear();
// -1 for no limit.
// If remote ... then restrictions apply.
std::list<fdex *> search(std::list<std::string>, int limit, bool local);
std::list<fdex *> dirlisting(std::string);
std::list<fdex *> findfilename(std::string);
private:
int processdirs();
std::list<DirItem> dirtodo;
std::list<std::string> dirdone;
/* dbase */
std::list<fdex *> files;
std::list<fdex *> dirlist;
};
#endif

View File

@ -0,0 +1,538 @@
/*
* "$Id: filelook.cc,v 1.3 2007-03-05 21:26:03 rmf24 Exp $"
*
* Other Bits for RetroShare.
*
* Copyright 2004-2006 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 "dbase/filelook.h"
#include "util/rsdir.h"
#include <sstream>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <dirent.h>
/*
* The Basic Low-Level Local File/Directory Interface.
*
* Requests are queued, and serviced (slowly)
*
*
* So this is a simple
* Local Lookup service,
* with a locked threaded interface.
*
* Input:
* "lookup directory".
*
* Output:
* "FileItems"
* "DirItems"
*
*
* a file index.
*
* initiated with a list of directories.
*
*/
fileLook::fileLook()
{
return;
}
fileLook::~fileLook()
{
return;
}
/* interface */
void fileLook::setSharedDirectories(std::list<std::string> dirs)
{
int i;
lockDirs(); { /* LOCKED DIRS */
/* clear old directories */
sharedDirs.clear();
/* iterate through the directories */
std::list<std::string>::iterator it;
for(it = dirs.begin(); it != dirs.end(); it++)
{
/* get the head directory */
std::string root_dir = *it;
std::string top_dir = RsDirUtil::getTopDir(root_dir);
/* if unique -> add, else add modifier */
bool unique = false;
for(i = 0; !unique; i++)
{
std::string tst_dir = top_dir;
if (i > 0)
{
std::ostringstream out;
out << "-" << i;
tst_dir += out.str();
}
std::map<std::string, std::string>::const_iterator cit;
if (sharedDirs.end()== (cit=sharedDirs.find(tst_dir)))
{
unique = true;
/* add it! */
sharedDirs[tst_dir.c_str()] = root_dir;
std::cerr << "Added [" << tst_dir << "] => " << root_dir << std::endl;
}
}
}
} unlockDirs(); /* UNLOCKED DIRS */
}
int fileLook::lookUpDirectory(PQItem *i)
{
std::cerr << "lookUpDirectory() About to Lock" << std::endl;
lockQueues();
std::cerr << "lookUpDirectory():" << std::endl;
i -> print(std::cerr);
mIncoming.push_back(i);
unlockQueues();
std::cerr << "lookUpDirectory() Unlocked" << std::endl;
return 1;
}
PQItem *fileLook::getResult()
{
PQItem *i = NULL;
lockQueues();
if (mOutgoing.size() > 0)
{
i = mOutgoing.front();
mOutgoing.pop_front();
std::cerr << "getResult()" << std::endl;
//i -> print(std::cerr);
}
unlockQueues();
return i;
}
/* locking
void fileLook::lockQueues()
{}
void fileLook::unlockQueues()
{}
void fileLook::lockDirs()
{}
void fileLook::unlockDirs()
{}
************/
void fileLook::run()
{
std::cerr << "fileLook::run() started." << std::endl;
processQueue();
}
void fileLook::processQueue()
{
while(1)
{
PQItem *i = NULL;
//std::cerr << "fileLook::run() -> lockQueues()" << std::endl;
lockQueues();
if (mIncoming.size() > 0)
{
i = mIncoming.front();
mIncoming.pop_front();
}
unlockQueues();
//std::cerr << "fileLook::run() -> unlockQueues()" << std::endl;
if (i)
{
/* process item */
/* look up the directory */
std::cerr << "fileLook::run() -> loadDirectory()" << std::endl;
loadDirectory(i);
}
else
{
/* sleep */
//std::cerr << "fileLook::sleep() ;)" << std::endl;
#ifndef WINDOWS_SYS /* UNIX */
usleep(50000); /* 50 milli secs (1/20)th of sec */
#else
Sleep(50); /* 50 milli secs (1/20)th of sec */
#endif
}
}
}
/* THIS IS THE ONLY BIT WHICH DEPENDS ON PQITEM STRUCTURE */
void fileLook::loadDirectory(PQItem *dir)
{
/* extract the path */
std::cerr << "loadDirectory()" << std::endl;
/* check its a PQFileItem */
PQFileItem *fi = dynamic_cast<PQFileItem *>(dir);
if (!fi)
{
return;
}
/* we need the root directory, and the rest */
std::string req_dir = fi -> path;
std::string root_dir = RsDirUtil::getRootDir(req_dir);
std::string rest_path = RsDirUtil::removeRootDirs(req_dir, root_dir);
/* get directory listing */
std::string full_root = "/dev/null";
if (root_dir == "")
{
std::cerr << "loadDirectory() Root Request" << std::endl;
loadRootDirs(fi);
}
int err = 0;
lockDirs();
{
/* check that dir is one of the shared */
std::map<std::string, std::string>::iterator it;
it = sharedDirs.find(root_dir.c_str());
if (it == sharedDirs.end())
{
err = 1;
}
else
{
full_root = it -> second;
}
}
unlockDirs();
std::cerr << "root_dir = [" << root_dir << "]" << std::endl;
std::cerr << "full_root = " << full_root << std::endl;
if (err)
{
std::cerr << "Rejected: root_dir = " << root_dir << std::endl;
for(unsigned int i = 0; i < root_dir.length(); i++)
{
std::cerr << "[" << (int) root_dir[i] << "]:[" << (int) root_dir[i] << "]" << std::endl;
}
std::map<std::string, std::string>::iterator it;
for(it = sharedDirs.begin(); it != sharedDirs.end(); it++)
{
std::cerr << "Possible Root: " << it -> first << std::endl;
}
return;
}
/* otherwise load directory */
std::string full_path = full_root;
if (rest_path.length() > 0)
{
full_path += "/" + rest_path;
}
std::cerr << "Looking up path:" << full_path << std::endl;
/* lookup base dir */
DIR *rootdir = opendir(full_path.c_str());
struct dirent *rootent, *subent;
struct stat buf;
if (rootdir == NULL) {
/* error */
std::cerr << "Error in Path" << std::endl;
return;
}
std::list<PQItem *> subitems;
int rootcount = 0;
while(NULL != (rootent = readdir(rootdir)))
{
/* iterate through the entries */
bool issubdir = false;
/* check entry type */
std::string fname = rootent -> d_name;
std::string fullname = full_path + "/" + fname;
std::cerr << "Statting dirent: " << fullname <<std::endl;
if (-1 != stat(fullname.c_str(), &buf))
{
std::cerr << "buf.st_mode: " << buf.st_mode <<std::endl;
if (S_ISDIR(buf.st_mode))
{
std::cerr << "Is Directory: " << fullname << std::endl;
if ((fname == ".") || (fname == ".."))
{
std::cerr << "Skipping:" << fname << std::endl;
continue; /* skipping links */
}
issubdir = true;
}
else if (S_ISREG(buf.st_mode))
{
/* is file */
std::cerr << "Is File: " << fullname << std::endl;
issubdir = false;
}
else
{
/* unknown , ignore */
continue;
}
}
/* If subdir - Count the subentries */
DIR *subdir = NULL;
if (issubdir)
{
subdir = opendir(fullname.c_str());
}
int subdirno = 0;
if (subdir)
{
while(NULL != (subent = readdir(subdir)))
{
std::string fname = subent -> d_name;
if (
#ifndef WINDOWS_SYS /* UNIX */
(DT_DIR == subent -> d_type) && /* Only works under Unix */
#else /* WIndows */
#endif
((fname == ".") || (fname == "..")))
{
/* do not add! */
std::cerr << "Removed entry:" << fname << " from subdir count" << std::endl;
}
else
{
subdirno++;
}
}
/* clean up dir */
closedir(subdir);
}
rootcount++;
std::string subname = rootent -> d_name;
/* create an item */
PQFileItem *finew = fi -> clone();
// path should be copied auto.
finew -> name = subname;
if (issubdir)
{
finew -> reqtype = PQIFILE_DIRLIST_DIR;
finew -> size = subdirno; /* number of entries in dir */
}
else
{
finew -> reqtype = PQIFILE_DIRLIST_FILE;
finew -> size = buf.st_size;
}
subitems.push_back(finew);
}
/* clean up dir */
closedir(rootdir);
/* if necessary create Root Entry */
/* if constructing Tree - do it here */
/* put on queue */
lockQueues();
std::list<PQItem *>::iterator it;
for(it = subitems.begin(); it != subitems.end(); it++)
{
/* push onto outgoing queue */
mOutgoing.push_back(*it);
}
subitems.clear();
unlockQueues();
};
void fileLook::loadRootDirs(PQFileItem *dir)
{
/* extract the path */
std::cerr << "loadRootDirs()" << std::endl;
dir -> path = "";
int rootcount = 0;
lockDirs();
std::list<PQItem *> subitems;
std::map<std::string, std::string>::iterator it;
for(it = sharedDirs.begin(); it != sharedDirs.end(); it++)
{
/* lookup base dir */
DIR *entdir = opendir(it -> second.c_str());
struct dirent *subent;
if (!entdir)
{
std::cerr << "Bad Shared Dir: " << it->second << std::endl;
continue;
}
int subdirno = 0;
while(NULL != (subent = readdir(entdir)))
{
std::string fname = subent -> d_name;
if (
#ifndef WINDOWS_SYS /* UNIX */
(DT_DIR == subent -> d_type) && /* Only works under Unix */
#else /* WIndows */
#endif
((fname == ".") || (fname == "..")))
{
/* do not add! */
std::cerr << "Removed entry:" << fname << " from subdir count" << std::endl;
}
else
{
subdirno++;
}
}
closedir(entdir);
rootcount++;
/* create an item */
PQFileItem *finew = dir -> clone();
// path should be copied auto.
finew -> name = it -> first;
finew -> reqtype = PQIFILE_DIRLIST_DIR;
finew -> size = subdirno; /* number of entries in dir */
subitems.push_back(finew);
}
unlockDirs();
/* put on queue */
lockQueues();
std::list<PQItem *>::iterator it2;
for(it2 = subitems.begin(); it2 != subitems.end(); it2++)
{
/* push onto outgoing queue */
mOutgoing.push_back(*it2);
}
subitems.clear();
unlockQueues();
};
PQFileItem *fileLook::findFileEntry(PQFileItem *fi)
{
/* extract the path */
std::cerr << "findFileEntry()" << std::endl;
/* we need the root directory, and the rest */
std::string req_dir = fi -> path;
std::string root_dir = RsDirUtil::getRootDir(req_dir);
std::string rest_path = RsDirUtil::removeRootDirs(req_dir, root_dir);
/* get directory listing */
std::string full_root = "/dev/null";
int err = 0;
lockDirs();
{
/* check that dir is one of the shared */
std::map<std::string, std::string>::iterator it;
it = sharedDirs.find(root_dir.c_str());
if (it == sharedDirs.end())
{
err = 1;
}
else
{
full_root = it -> second;
}
}
unlockDirs();
PQFileItem *rtn = NULL;
if (err)
return rtn;
rtn = fi -> clone();
rtn -> path = full_root + "/" + rest_path;
return rtn;
}

View File

@ -0,0 +1,113 @@
/*
* "$Id: filelook.h,v 1.1 2007-02-19 20:08:30 rmf24 Exp $"
*
* Other Bits for RetroShare.
*
* Copyright 2004-2006 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 MRK_PQI_FILELOOK
#define MRK_PQI_FILELOOK
/*
* The Basic Low-Level Local File/Directory Interface.
*
* Requests are queued, and serviced (slowly)
*
*
* So this is a simple
* Local Lookup service,
* with a locked threaded interface.
*
* Input:
* "lookup directory".
*
* Output:
* "FileItems"
* "DirItems"
*
*
* a file index.
*
* initiated with a list of directories.
*
*/
#include <list>
#include <map>
#include "pqi/pqi.h"
#include "util/rsthreads.h"
class fileLook: public RsThread
{
public:
fileLook();
virtual ~fileLook();
/* threading */
virtual void run(); /* overloaded */
/* interface */
void setSharedDirectories(std::list<std::string> dirs);
/* I/O */
int lookUpDirectory(PQItem *i);
/* This one goes directly -> for speed, actually just a basepath lookup (no file check) */
PQFileItem *findFileEntry(PQFileItem *);
PQItem *getResult();
private:
/* locking */
void lockQueues() { qMtx.lock(); }
void unlockQueues() { qMtx.unlock(); }
void lockDirs() { dMtx.lock(); }
void unlockDirs() { dMtx.unlock(); }
RsMutex qMtx;
RsMutex dMtx;
/* threading queues */
std::list<PQItem *> mIncoming;
std::list<PQItem *> mOutgoing;
std::map<std::string, std::string> sharedDirs;
/* Processing Fns */
void processQueue();
/* THIS IS THE ONLY BIT WHICH DEPENDS ON PQITEM STRUCTURE */
void loadDirectory(PQItem *dir);
void loadRootDirs(PQFileItem *dir);
};
#endif

View File

@ -0,0 +1,672 @@
/*
* RetroShare FileCache Module: fimonitor.cc
*
* Copyright 2004-2007 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 "dbase/fimonitor.h"
#include "util/rsdir.h"
#include <iostream>
#include <sstream>
#include <iomanip>
#include <dirent.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <openssl/sha.h>
#define FIM_DEBUG 1
FileIndexMonitor::FileIndexMonitor(std::string cachedir, std::string pid)
:CacheSource(CACHE_TYPE_FILE_INDEX, false, cachedir), fi(pid),
pendingDirs(false), pendingForceCacheWrite(false)
{
updatePeriod = 60;
}
FileIndexMonitor::~FileIndexMonitor()
{
/* Data cleanup - TODO */
return;
}
bool FileIndexMonitor::findLocalFile(std::string hash,
std::string &fullpath, uint32_t &size)
{
std::list<FileEntry *> results;
bool ok = false;
fiMutex.lock(); { /* LOCKED DIRS */
std::cerr << "FileIndexMonitor::findLocalFile() Hash: " << hash << std::endl;
/* search through the fileIndex */
fi.searchHash(hash, results);
if (results.size() > 0)
{
/* find the full path for the first entry */
FileEntry *fe = results.front();
DirEntry *de = fe->parent; /* all files must have a valid parent! */
std::cerr << "FileIndexMonitor::findLocalFile() Found Name: " << fe->name << std::endl;
std::string shpath = RsDirUtil::removeRootDir(de->path);
std::string basedir = RsDirUtil::getRootDir(de->path);
std::string realroot = findRealRoot(basedir);
/* construct full name */
if (realroot.length() > 0)
{
fullpath = realroot + "/";
if (shpath != "")
{
fullpath += shpath + "/";
}
fullpath += fe->name;
size = fe->size;
ok = true;
}
std::cerr << "FileIndexMonitor::findLocalFile() Found Path: " << fullpath << std::endl;
std::cerr << "FileIndexMonitor::findLocalFile() Found Size: " << size << std::endl;
}
} fiMutex.unlock(); /* UNLOCKED DIRS */
return ok;
}
bool FileIndexMonitor::loadCache(const CacheData &data) /* called with stored data */
{
bool ok = false;
fiMutex.lock(); { /* LOCKED DIRS */
//fi.root->name = data.pid;
/* More error checking needed here! */
if ((ok = fi.loadIndex(data.path + '/' + data.name,
data.hash, data.size)))
{
std::cerr << "FileIndexMonitor::loadCache() Success!";
std::cerr << std::endl;
}
else
{
std::cerr << "FileIndexMonitor::loadCache() Failed!";
std::cerr << std::endl;
}
} fiMutex.unlock(); /* UNLOCKED DIRS */
if (ok)
{
return updateCache(data);
}
return false;
}
bool FileIndexMonitor::updateCache(const CacheData &data) /* we call this one */
{
return refreshCache(data);
}
void FileIndexMonitor::setPeriod(int period)
{
updatePeriod = period;
}
void FileIndexMonitor::run()
{
updateCycle();
while(1)
{
for(int i = 0; i < updatePeriod; i++)
{
/********************************** WINDOWS/UNIX SPECIFIC PART ******************/
#ifndef WINDOWS_SYS
sleep(1);
#else
Sleep(1000);
#endif
/********************************** WINDOWS/UNIX SPECIFIC PART ******************/
/* check dirs if they've changed */
if (internal_setSharedDirectories())
{
break;
}
}
updateCycle();
}
}
void FileIndexMonitor::updateCycle()
{
time_t startstamp = time(NULL);
/* iterate through all out-of-date directories */
bool moretodo = true;
bool fiMods = false;
while(moretodo)
{
/* sleep a bit for each loop */
/********************************** WINDOWS/UNIX SPECIFIC PART ******************/
#ifndef WINDOWS_SYS
usleep(100000); /* 1/10 sec */
#else
Sleep(100);
#endif
/********************************** WINDOWS/UNIX SPECIFIC PART ******************/
/* check if directories have been updated */
if (internal_setSharedDirectories())
{
/* reset start time */
startstamp = time(NULL);
}
/* Handle a Single out-of-date directory */
time_t stamp = time(NULL);
/* lock dirs */
fiMutex.lock();
DirEntry *olddir = fi.findOldDirectory(startstamp);
if (!olddir)
{
/* finished */
fiMutex.unlock();
moretodo = false;
continue;
}
#ifdef FIM_DEBUG
std::cerr << "FileIndexMonitor::updateCycle()";
std::cerr << " Checking: " << olddir->path << std::endl;
#endif
FileEntry fe;
/* entries that need to be checked properly */
std::list<FileEntry> filesToHash;
std::list<FileEntry>::iterator hit;
/* determine the full root path */
std::string dirpath = olddir->path;
std::string rootdir = RsDirUtil::getRootDir(olddir->path);
std::string remdir = RsDirUtil::removeRootDir(olddir->path);
std::string realroot = findRealRoot(rootdir);
std::string realpath = realroot;
if (remdir != "")
{
realpath += "/" + remdir;
}
#ifdef FIM_DEBUG
std::cerr << "FileIndexMonitor::updateCycle()";
std::cerr << " RealPath: " << realpath << std::endl;
#endif
/* check for the dir existance */
DIR *dir = opendir(realpath.c_str());
if (!dir)
{
std::cerr << "FileIndexMonitor::updateCycle()";
std::cerr << " Missing Dir: " << realpath << std::endl;
/* bad directory - delete */
if (!fi.removeOldDirectory(olddir->parent->path, olddir->name, stamp))
{
/* bad... drop out of updateCycle() - hopefully the initial cleanup
* will deal with it next time! - otherwise we're in a continual loop
*/
std::cerr << "FileIndexMonitor::updateCycle()";
std::cerr << "ERROR Failed to Remove: " << olddir->path << std::endl;
}
fiMutex.unlock();
continue;
}
/* update this dir - as its valid */
fe.name = olddir->name;
fi.updateDirEntry(olddir->parent->path, fe, stamp);
/* update the directories and files here */
std::map<std::string, DirEntry *>::iterator dit;
std::map<std::string, FileEntry *>::iterator fit;
/* flag existing subdirs as old */
for(dit = olddir->subdirs.begin(); dit != olddir->subdirs.end(); dit++)
{
fe.name = (dit->second)->name;
/* set the age as out-of-date so that it gets checked */
fi.updateDirEntry(olddir->path, fe, 0);
}
/* now iterate through the directory...
* directories - flags as old,
* files checked to see if they have changed. (rehashed)
*/
struct dirent *dent;
struct stat buf;
while(NULL != (dent = readdir(dir)))
{
/* check entry type */
std::string fname = dent -> d_name;
std::string fullname = realpath + "/" + fname;
if (-1 != stat(fullname.c_str(), &buf))
{
#ifdef FIM_DEBUG
std::cerr << "buf.st_mode: " << buf.st_mode <<std::endl;
#endif
if (S_ISDIR(buf.st_mode))
{
if ((fname == ".") || (fname == ".."))
{
#ifdef FIM_DEBUG
std::cerr << "Skipping:" << fname << std::endl;
#endif
continue; /* skipping links */
}
#ifdef FIM_DEBUG
std::cerr << "Is Directory: " << fullname << std::endl;
#endif
/* add in directory */
fe.name = fname;
/* set the age as out-of-date so that it gets checked */
fi.updateDirEntry(olddir->path, fe, 0);
}
else if (S_ISREG(buf.st_mode))
{
/* is file */
bool toadd = false;
#ifdef FIM_DEBUG
std::cerr << "Is File: " << fullname << std::endl;
#endif
fe.name = fname;
fe.size = buf.st_size;
fe.modtime = buf.st_mtime;
/* check if it exists already */
fit = olddir->files.find(fname);
if (fit == olddir->files.end())
{
/* needs to be added */
#ifdef FIM_DEBUG
std::cerr << "File Missing from List:" << fname << std::endl;
#endif
toadd = true;
}
else
{
/* check size / modtime are the same */
if ((fe.size != (fit->second)->size) ||
(fe.modtime != (fit->second)->modtime))
{
#ifdef FIM_DEBUG
std::cerr << "File ModTime/Size changed:" << fname << std::endl;
#endif
toadd = true;
}
else
{
/* keep old info */
fe.hash = (fit->second)->hash;
}
}
if (toadd)
{
/* push onto Hash List */
#ifdef FIM_DEBUG
std::cerr << "Adding to Update List: ";
std::cerr << olddir->path;
std::cerr << fname << std::endl;
#endif
filesToHash.push_back(fe);
}
else
{
/* update with new time */
#ifdef FIM_DEBUG
std::cerr << "File Hasn't Changed:" << fname << std::endl;
#endif
fi.updateFileEntry(olddir->path, fe, stamp);
}
}
else
{
/* unknown , ignore */
continue;
}
}
}
/* now we unlock the lock, and iterate through the
* next files - hashing them, before adding into the system.
*/
/* for safety - blank out data we cannot use (TODO) */
olddir = NULL;
/* close directory */
closedir(dir);
/* unlock dirs */
fiMutex.unlock();
if (filesToHash.size() > 0)
{
std::cerr << "List of Files to rehash in: " << dirpath << std::endl;
fiMods = true;
}
for(hit = filesToHash.begin(); hit != filesToHash.end(); hit++)
{
std::cerr << "\t" << hit->name << std::endl;
}
if (filesToHash.size() > 0)
{
std::cerr << std::endl;
}
/* update files */
for(hit = filesToHash.begin(); hit != filesToHash.end(); hit++)
{
if (hashFile(realpath, (*hit)))
{
/* lock dirs */
fiMutex.lock();
/* update fileIndex with new time */
/* update with new time */
fi.updateFileEntry(dirpath, *hit, stamp);
/* unlock dirs */
fiMutex.unlock();
}
else
{
std::cerr << "Failed to Hash File!" << std::endl;
}
/* don't hit the disk too hard! */
/********************************** WINDOWS/UNIX SPECIFIC PART ******************/
#ifndef WINDOWS_SYS
usleep(10000); /* 1/100 sec */
#else
Sleep(10);
#endif
/********************************** WINDOWS/UNIX SPECIFIC PART ******************/
}
}
fiMutex.lock(); { /* LOCKED DIRS */
/* finished update cycle - cleanup extra dirs/files that
* have not had their timestamps updated.
*/
if (fi.cleanOldEntries(startstamp))
{
//fiMods = true;
}
/* print out the new directory structure */
fi.printFileIndex(std::cerr);
/* now if we have changed things -> restore file/hash it/and
* tell the CacheSource
*/
if (pendingForceCacheWrite)
{
pendingForceCacheWrite = false;
fiMods = true;
}
} fiMutex.unlock(); /* UNLOCKED DIRS */
if (fiMods)
{
/* store to the cacheDirectory */
fiMutex.lock(); { /* LOCKED DIRS */
std::string path = getCacheDir();
std::ostringstream out;
out << "fc-own-" << time(NULL) << ".rsfc";
std::string tmpname = out.str();
std::string fname = path + "/" + tmpname;
#ifdef FIM_DEBUG
std::cerr << "FileIndexMonitor::updateCycle() FileIndex modified ... updating";
std::cerr << std::endl;
std::cerr << "FileIndexMonitor::updateCycle() saving to: " << fname;
std::cerr << std::endl;
#endif
std::string calchash;
uint32_t size;
fi.saveIndex(fname, calchash, size);
#ifdef FIM_DEBUG
std::cerr << "FileIndexMonitor::updateCycle() saved with hash:" << calchash;
std::cerr << std::endl;
#endif
/* should clean up the previous cache.... */
/* flag as new info */
CacheData data;
data.pid = fi.root->id;
data.cid.type = getCacheType();
data.cid.subid = 0;
data.path = path;
data.name = tmpname;
data.hash = calchash;
data.size = size;
data.recvd = time(NULL);
updateCache(data);
#ifdef FIM_DEBUG
std::cerr << "FileIndexMonitor::updateCycle() called updateCache()";
std::cerr << std::endl;
#endif
} fiMutex.unlock(); /* UNLOCKED DIRS */
}
}
/* interface */
void FileIndexMonitor::setSharedDirectories(std::list<std::string> dirs)
{
fiMutex.lock(); { /* LOCKED DIRS */
pendingDirs = true;
pendingDirList = dirs;
} fiMutex.unlock(); /* UNLOCKED DIRS */
}
bool FileIndexMonitor::internal_setSharedDirectories()
{
int i;
fiMutex.lock(); /* LOCKED DIRS */
if (!pendingDirs)
{
fiMutex.unlock(); /* UNLOCKED DIRS */
return false;
}
pendingDirs = false;
pendingForceCacheWrite = true;
/* clear old directories */
directoryMap.clear();
/* iterate through the directories */
std::list<std::string>::iterator it;
std::map<std::string, std::string>::const_iterator cit;
for(it = pendingDirList.begin(); it != pendingDirList.end(); it++)
{
/* get the head directory */
std::string root_dir = *it;
std::string top_dir = RsDirUtil::getTopDir(root_dir);
/* if unique -> add, else add modifier */
bool unique = false;
for(i = 0; !unique; i++)
{
std::string tst_dir = top_dir;
if (i > 0)
{
std::ostringstream out;
out << "-" << i;
tst_dir += out.str();
}
if (directoryMap.end()== (cit=directoryMap.find(tst_dir)))
{
unique = true;
/* add it! */
directoryMap[tst_dir.c_str()] = root_dir;
std::cerr << "Added [" << tst_dir << "] => " << root_dir << std::endl;
}
}
}
/* now we've decided on the 'root' dirs set them to the
* fileIndex
*/
std::list<std::string> topdirs;
for(cit = directoryMap.begin(); cit != directoryMap.end(); cit++)
{
topdirs.push_back(cit->first);
}
fi.setRootDirectories(topdirs, 0);
fiMutex.unlock(); /* UNLOCKED DIRS */
return true;
}
/* lookup directory function */
std::string FileIndexMonitor::findRealRoot(std::string rootdir)
{
/**** MUST ALREADY BE LOCKED ****/
std::string realroot = "";
std::map<std::string, std::string>::const_iterator cit;
if (directoryMap.end()== (cit=directoryMap.find(rootdir)))
{
std::cerr << "FileIndexMonitor::findRealRoot() Invalid RootDir: ";
std::cerr << rootdir << std::endl;
}
else
{
realroot = cit->second;
}
return realroot;
}
bool FileIndexMonitor::hashFile(std::string fullpath, FileEntry &fent)
{
std::string f_hash = fullpath + "/" + fent.name;
FILE *fd;
int len;
SHA_CTX *sha_ctx = new SHA_CTX;
unsigned char sha_buf[SHA_DIGEST_LENGTH];
unsigned char gblBuf[512];
std::cerr << "File to hash = " << f_hash << std::endl;
if (NULL == (fd = fopen(f_hash.c_str(), "rb"))) return false;
SHA1_Init(sha_ctx);
while((len = fread(gblBuf,1, 512, fd)) > 0)
{
SHA1_Update(sha_ctx, gblBuf, len);
}
/* reading failed for some reason */
if (ferror(fd))
{
delete sha_ctx;
fclose(fd);
return false;
}
SHA1_Final(&sha_buf[0], sha_ctx);
/* TODO: Actually we should store the hash data as binary ...
* but then it shouldn't be put in a string.
*/
std::ostringstream tmpout;
for(int i = 0; i < SHA_DIGEST_LENGTH; i++)
{
tmpout << std::setw(2) << std::setfill('0') << std::hex << (unsigned int) (sha_buf[i]);
}
fent.hash = tmpout.str();
delete sha_ctx;
fclose(fd);
return true;
}

View File

@ -0,0 +1,120 @@
/*
* RetroShare FileCache Module: fimonitor.h
*
* Copyright 2004-2007 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 FILE_INDEX_MONITOR_H
#define FILE_INDEX_MONITOR_H
#include "dbase/findex.h"
#include "dbase/cachestrapper.h"
#include "util/rsthreads.h"
/******************************************************************************************
* The Local Monitoring Class: FileIndexMonitor.
*
* This periodically scans the directory tree, and updates any modified directories/files.
*
*****************************************************************************************/
/******************************************************************************************
STILL TODO:
(1) Implement Hash function.
bool FileIndexMonitor::hashFile(std::string path, FileEntry &fi);
(2) Add Shared directory controls to Monitor.
int FileIndexMonitor::addSharedDirectory(std::path);
int FileIndexMonitor::removeSharedDirectory(std::path);
std::string FileIndexMonitor::findRealRoot(std::string base);
These must be split into <base>/<top> and the mapping saved.
eg: addSharedDirectory("c:/home/stuff/dir1") --> "c:/home/stuff" <-> "dir1"
This code has been written already, and can just be moved over.
FOR LATER:
(2) Port File/Directory lookup code to windoze. (or compile dirent.c under windoze)
(3) Add Load/Store interface to FileIndexMonitor. (later)
(4) Integrate with real Thread/Mutex code (last thing to do)
******************************************************************************************/
/******************************************************************************************
* FileIndexMonitor
*****************************************************************************************/
class FileIndexMonitor: public CacheSource, public RsThread
{
public:
FileIndexMonitor(std::string cachedir, std::string pid);
virtual ~FileIndexMonitor();
/* external interface for filetransfer */
bool findLocalFile(std::string hash, std::string &fullpath, uint32_t &size);
/* Interacting with CacheSource */
/* overloaded from CacheSource */
virtual bool loadCache(const CacheData &data); /* called with stored data */
bool updateCache(const CacheData &data); /* we call when we have a new cache for others */
/* the FileIndexMonitor inner workings */
virtual void run(); /* overloaded from RsThread */
void updateCycle();
void setSharedDirectories(std::list<std::string> dirs);
void setPeriod(int insecs);
/* util fns */
private:
/* the mutex should be locked before calling... these. */
std::string findRealRoot(std::string base); /* To Implement */
bool hashFile(std::string path, FileEntry &fi); /* To Implement */
/* data */
RsMutex fiMutex;
FileIndex fi;
int updatePeriod;
std::map<std::string, std::string> directoryMap; /* used by findRealRoot */
/* flags to kick - if we were busy or sleeping */
bool pendingDirs;
bool pendingForceCacheWrite;
std::list<std::string> pendingDirList;
bool internal_setSharedDirectories();
};
#endif

View File

@ -0,0 +1,87 @@
/*
* RetroShare FileCache Module: fimontest.cc
*
* Copyright 2004-2007 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 "findex.h"
#include "fimonitor.h"
#include <iostream>
void usage(char *name)
{
std::cerr << "Usage: " << name << " [-p <period> ] shareDir1 [shareDir2 [shareDir3 [...]]]";
std::cerr << std::endl;
exit(1);
}
int main(int argc, char **argv)
{
/* handle commandline arguments */
int c;
int period = 60; /* recheck period in seconds */
while((c = getopt(argc, argv,"p:")) != -1)
{
switch(c)
{
case 'p':
period = atoi(optarg);
break;
default:
std::cerr << "Bad Option.";
std::cerr << std::endl;
usage(argv[0]);
break;
}
}
std::list<std::string> rootdirs;
/* add all the rest of the commandline arguments to rootdirs list */
for(; optind < argc; optind++)
{
rootdirs.push_back(argv[optind]);
std::cerr << "Adding shared directory: " << argv[optind] << std::endl;
}
if (rootdirs.size() < 1)
{
usage(argv[0]);
}
sleep(1);
FileIndexMonitor mon("", "OWN ID");
/* setup monitor */
mon.setPeriod(period);
mon.setSharedDirectories(rootdirs);
/* simulate running the thread */
mon.run();
return 1;
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,229 @@
/*
* RetroShare FileCache Module: findex.h
*
* Copyright 2004-2007 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 FILE_INDEX_H
#define FILE_INDEX_H
#include <string>
#include <map>
#include <list>
#include <vector>
class ostream;
/******************************************************************************************
* The Key Data Types for the File Index:
FileEntry : Information about a single file.
DirEntry : Information about a directory and its children
PersonEntry : Information the root of a FileIndex.
FileIndex : A Collection of root directories, with a set of functions to manipulate them.
In terms of retroshare, There will be a single 'Local' FileIndex used to store
the shared files, and a set of 'Remote' FileIndices which are used to store
the available files of all the peers.
******************************************************************************************/
/******************************************************************************************
STILL TODO:
(1) Load/Store a FileIndex to file...
int FileIndex::loadIndex(FILE *input);
int FileIndex::saveIndex(FILE *input);
This can be done in a recursive manner, or handled completely within FileIndex.
(2) Search Functions for Partial File Names and Hashes.
int FileIndex::searchHash(std::string hash, std::list<FileEntry> &results);
int FileIndex::searchTerms(std::list<string> terms, std::list<FileEntry> &results);
This is probably best done in a recursive manner.
The search could also be extended to handle complex Boolean searches such as :
match (size > 100K) && (name contains 'Blue') .... if anyone is interested.
But this can get quite complicated, and can be left to a later date.
******************************************************************************************/
/******************************************************************************************
* FileEntry
*****************************************************************************************/
class DirEntry;
class FileEntry
{
public:
FileEntry() :parent(NULL), row(-1) { return; }
virtual ~FileEntry() { return; }
virtual int print(std::ostream &out);
/* Data */
std::string name;
std::string hash;
int size; /* file size */
int modtime; /* modification time - most recent mod time for a sub entry for dirs */
int pop; /* popularity rating */
int updtime; /* last updated */
/* References for easy manipulation */
DirEntry *parent;
int row;
};
/******************************************************************************************
* DirEntry
*****************************************************************************************/
class DirEntry: public FileEntry
{
public:
/* cleanup */
virtual ~DirEntry();
/* update local entries */
DirEntry * updateDir(FileEntry fe, time_t updtime);
FileEntry * updateFile(FileEntry fe, time_t updtime);
int checkParentPointers();
int updateChildRows();
/* remove local entries */
int removeFile(std::string name);
int removeDir(std::string name);
int removeOldDir(std::string name, time_t old); /* checks ts first */
/* recursive cleanup */
int removeOldEntries(time_t old, bool recursive);
/* recursive searches */
DirEntry * findOldDirectory(time_t old);
DirEntry * findDirectory(std::string path);
/* recursive update directory mod/pop values */
int updateDirectories(std::string path, int pop, int modtime);
/* output */
int print(std::ostream &out);
int saveEntry(std::ostringstream &out);
/* Data */
std::string path; /* full path (includes name) */
std::map<std::string, DirEntry *> subdirs;
std::map<std::string, FileEntry *> files;
/* Inherited members from FileEntry:
int size - count for dirs
std::string name; - directory name
std::string hash; - not used
int size; - not used
int modtime; - most recent modication time of any child file (recursive)
int pop; - most popular child file (recursive)
int updtime; - last updated
*/
};
/******************************************************************************************
* PersonEntry
*****************************************************************************************/
class PersonEntry: public DirEntry
{
public:
/* cleanup */
PersonEntry(std::string pid) : id(pid) { return; }
virtual ~PersonEntry() { return; }
DirEntry &operator=(DirEntry &src)
{
DirEntry *pdest = this;
(*pdest) = src;
return src;
}
/* Data */
std::string id;
/* Inherited members from FileEntry:
int size - count for dirs
std::string name; - directory name
std::string hash; - not used
int size; - not used
int modtime; - most recent modication time of any child file (recursive)
int pop; - most popular child file (recursive)
int updtime; - last updated
*/
};
/******************************************************************************************
* FileIndex
*****************************************************************************************/
class Expression;
class FileIndex
{
public:
FileIndex(std::string pid);
~FileIndex();
/* control root entries */
int setRootDirectories(std::list<std::string> inlist, time_t utime);
int getRootDirectories(std::list<std::string> &outlist);
/* update (index building) */
DirEntry * updateDirEntry(std::string path, FileEntry fe, time_t utime);
FileEntry * updateFileEntry(std::string path, FileEntry fe, time_t utime);
DirEntry * findOldDirectory(time_t old); /* finds directories older than old */
int removeOldDirectory(std::string fpath, std::string name, time_t old);
int cleanOldEntries(time_t old); /* removes entries older than old */
/* debug */
int printFileIndex(std::ostream &out);
/* load/save to file */
int loadIndex(std::string filename, std::string expectedHash, uint32_t size);
int saveIndex(std::string filename, std::string &fileHash, uint32_t &size);
/* search through this index */
int searchTerms(std::list<std::string> terms, std::list<FileEntry *> &results);
int searchHash(std::string hash, std::list<FileEntry *> &results);
int searchBoolExp(Expression * exp, std::list<FileEntry *> &results);
PersonEntry *root;
};
#endif

View File

@ -0,0 +1,118 @@
/*
* RetroShare FileCache Module: fisavetest.cc
*
* Copyright 2004-2007 by Kefei Zhou.
*
* 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 "dbase/findex.h"
#include <iostream>
FileIndex *createBasicFileIndex(time_t age);
int main()
{
FileIndex *fi1 = createBasicFileIndex(100);
FileIndex *fi2 = new FileIndex("A SILLY ID");
fi1->printFileIndex(std::cout);
std::string fhash;
uint32_t size;
fi1->saveIndex("test.index", fhash, size);
std::cout << " Saved Index: Size: " << size << " Hash: " << fhash << std::endl;
std::cout << " -- new file index -- " << std::endl;
fi2->loadIndex("test.index", fhash, size);
fi2->printFileIndex(std::cout);
delete fi1;
delete fi2;
return 1;
}
FileIndex *createBasicFileIndex(time_t age)
{
FileIndex *fi = new FileIndex("A SILLY ID");
FileEntry fe;
std::list<std::string> rootdirs;
rootdirs.push_back("base1");
rootdirs.push_back("base2");
rootdirs.push_back("base3");
fi -> setRootDirectories(rootdirs, age);
/* add some entries */
fe.name = "dir1";
fi -> updateDirEntry("base1",fe, age);
fe.name = "dir2";
fi -> updateDirEntry("base1",fe, age);
fe.name = "dir01";
fi -> updateDirEntry("/base1/dir1/",fe, age);
fe.name = "dir001";
fi -> updateDirEntry("/base1/dir1/dir01/",fe, age);
fe.name = "file1";
fi -> updateFileEntry("/base1/dir1/",fe, age);
fe.name = "file2";
fi -> updateFileEntry("/base1/dir1/",fe, age);
fe.name = "file3";
fi -> updateFileEntry("/base1/dir1/",fe, age);
fe.name = "file4";
fi -> updateFileEntry("/base1/dir1/",fe, age);
fe.name = "dir2";
fi -> updateDirEntry("/base1",fe, age);
fe.name = "file5";
fi -> updateFileEntry("/base1/dir2/",fe, age);
fe.name = "file6";
fi -> updateFileEntry("/base1/dir2/",fe, age);
fe.name = "file7";
fi -> updateFileEntry("/base1/dir2/",fe, age);
fe.name = "file8";
fi -> updateFileEntry("/base1/",fe, age);
fe.name = "dir3";
fi -> updateDirEntry("/base1/dir2/",fe, age);
fe.name = "file10";
fi -> updateFileEntry("/base1/dir2/dir3",fe, age);
fe.name = "file11";
fi -> updateFileEntry("/base1/dir2/dir3",fe, age);
fe.name = "file12";
fi -> updateFileEntry("/base1/dir2/dir3",fe, age);
fe.name = "dir4";
fi -> updateDirEntry("/base3/",fe, age);
fe.name = "file20";
fi -> updateFileEntry("/base3/dir4/",fe, age);
fe.name = "file21";
fi -> updateFileEntry("/base3/dir4",fe, age);
return fi;
}

View File

@ -0,0 +1,521 @@
/*
* RetroShare FileCache Module: fistore.cc
*
* Copyright 2004-2007 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 "dbase/fistore.h"
#include "rsiface/rsexpr.h"
FileIndexStore::FileIndexStore(CacheTransfer *cft,
NotifyBase *cb_in, RsPeerId ownid, std::string cachedir)
:CacheStore(CACHE_TYPE_FILE_INDEX, false, cft, cachedir),
localId(ownid), localindex(NULL), cb(cb_in)
{
return;
}
FileIndexStore::~FileIndexStore()
{
/* clean up the Index */
return;
}
/***
* #define FIS_DEBUG2 1
* #define FIS_DEBUG 1
**/
/* actual load, once data available */
int FileIndexStore::loadCache(const CacheData &data)
{
#ifdef FIS_DEBUG2
std::cerr << "FileIndexStore::loadCache() hash: " << data.hash << std::endl;
std::cerr << "FileIndexStore::loadCache() path: " << data.path << std::endl;
std::cerr << "FileIndexStore::loadCache() name: " << data.name << std::endl;
std::cerr << "FileIndexStore::loadCache() size: " << data.size << std::endl;
#endif
/* do Callback */
AboutToModify();
/* lock it up */
lockData();
FileIndex *fiold = NULL;
bool local = (data.pid == localId);
std::map<RsPeerId, FileIndex *>::iterator it;
/* remove old cache */
if (local)
{
fiold = localindex;
localindex = NULL;
}
else if (indices.end() != (it = indices.find(data.pid)))
{
fiold = it->second;
indices.erase(it);
//delete fi;
}
/* load Cache */
FileIndex *finew = new FileIndex(data.pid);
if (finew->loadIndex(data.path + '/' + data.name, data.hash, data.size))
{
#ifdef FIS_DEBUG2
std::cerr << "FileIndexStore::loadCache() Succeeded!" << std::endl;
#endif
/* set the name */
finew->root->name = data.pname;
if (local)
{
localindex = finew;
}
else
{
indices[data.pid] = finew;
}
delete fiold;
/* store in tale */
locked_storeCacheEntry(data);
}
else
{
#ifdef FIS_DEBUG2
std::cerr << "FileIndexStore::loadCache() Failed!" << std::endl;
#endif
/* reinstall the old one! */
delete finew;
if (fiold)
{
if (local)
{
localindex = fiold;
}
else
{
indices[data.pid] = fiold;
}
}
}
/* need to correct indices(row) for the roots of the FileIndex */
int i = 0;
for(it = indices.begin(); it != indices.end(); it++)
{
(it->second)->root->row = i++;
}
if (localindex)
{
localindex->root->row = 0;
}
unlockData();
ModCompleted();
bool ret = false;
return ret;
}
/* Search Interface - For Directory Access */
int FileIndexStore::RequestDirDetails(std::string uid, std::string path, DirDetails &details)
{
/* lock it up */
lockData();
std::map<RsPeerId, FileIndex *>::iterator it;
it = indices.find(uid);
bool found = true;
if (it == indices.end())
{
//DirEntry *fdir = (it->second).lookupDirectory(path);
/* translate it
*/
found = false;
}
else
{
found = false;
}
unlockData();
return found;
}
int FileIndexStore::RequestDirDetails(void *ref, DirDetails &details, uint32_t flags)
{
lockData();
bool found = true;
std::map<RsPeerId, FileIndex *>::iterator pit;
/* so cast *ref to a DirEntry */
FileEntry *file = (FileEntry *) ref;
DirEntry *dir = dynamic_cast<DirEntry *>(file);
PersonEntry *person;
/* root case */
#ifdef FIS_DEBUG
std::cerr << "FileIndexStore::RequestDirDetails() CHKS" << std::endl;
for(pit = indices.begin(); pit != indices.end(); pit++)
{
(pit->second)->root->checkParentPointers();
}
#endif
if (!ref)
{
#ifdef FIS_DEBUG
std::cerr << "FileIndexStore::RequestDirDetails() ref=NULL (root)" << std::endl;
#endif
if (flags & DIR_FLAGS_LOCAL)
{
/* local only */
if (localindex)
{
DirStub stub;
stub.type = DIR_TYPE_PERSON;
stub.name = localindex->root->name;
stub.ref = localindex->root;
details.children.push_back(stub);
details.count = 1;
}
else
{
details.count = 0;
}
details.parent = NULL;
details.prow = 0;
details.ref = NULL;
details.type = DIR_TYPE_ROOT;
details.name = "";
details.hash = "";
details.path = "";
details.age = 0;
details.rank = 0;
}
else
{
/* get remote root entries */
for(pit = indices.begin(); pit != indices.end(); pit++)
{
/*
*/
DirStub stub;
stub.type = DIR_TYPE_PERSON;
stub.name = (pit->second)->root->name;
stub.ref = (pit->second)->root;
details.children.push_back(stub);
}
details.parent = NULL;
details.prow = 0;
details.ref = NULL;
details.type = DIR_TYPE_ROOT;
details.name = "";
details.hash = "";
details.path = "";
details.count = indices.size();
details.age = 0;
details.rank = 0;
}
}
else
{
if (dir) /* has children --- fill */
{
#ifdef FIS_DEBUG
std::cerr << "FileIndexStore::RequestDirDetails() ref=dir" << std::endl;
#endif
std::map<std::string, FileEntry *>::iterator fit;
std::map<std::string, DirEntry *>::iterator dit;
/* extract all the entries */
for(dit = dir->subdirs.begin();
dit != dir->subdirs.end(); dit++)
{
DirStub stub;
stub.type = DIR_TYPE_DIR;
stub.name = (dit->second) -> name;
stub.ref = (dit->second);
details.children.push_back(stub);
}
for(fit = dir->files.begin();
fit != dir->files.end(); fit++)
{
DirStub stub;
stub.type = DIR_TYPE_FILE;
stub.name = (fit->second) -> name;
stub.ref = (fit->second);
details.children.push_back(stub);
}
details.type = DIR_TYPE_DIR;
details.hash = "";
details.count = dir->subdirs.size() +
dir->files.size();
}
else
{
#ifdef FIS_DEBUG
std::cerr << "FileIndexStore::RequestDirDetails() ref=file" << std::endl;
#endif
details.type = DIR_TYPE_FILE;
details.count = file->size;
}
#ifdef FIS_DEBUG
std::cerr << "FileIndexStore::RequestDirDetails() name: " << file->name << std::endl;
#endif
details.ref = file;
details.name = file->name;
details.hash = file->hash;
details.age = time(NULL) - file->modtime;
details.rank = file->pop;
/* TODO Path */
details.path = "";
/* find parent pointer, and row */
DirEntry *parent = file->parent;
if (!parent) /* then must be root */
{
details.parent = NULL;
details.prow = 0;
}
else
{
details.parent = parent;
details.prow = parent->row;
}
/* find peer id */
parent = dir;
if (!dir)
{
/* cannot be null -> no files at root level */
parent=file->parent;
}
while(parent->parent)
parent = parent->parent;
/* we should end up on the PersonEntry */
if (NULL == (person = dynamic_cast<PersonEntry *>(parent)))
{
std::cerr << "Major Error- Not PersonEntry!";
exit(1);
}
details.id = person->id;
}
unlockData();
return found;
}
int FileIndexStore::SearchHash(std::string hash, std::list<FileDetail> &results)
{
lockData();
std::map<RsPeerId, FileIndex *>::iterator pit;
std::list<FileEntry *>::iterator rit;
std::list<FileEntry *> firesults;
time_t now = time(NULL);
#ifdef FIS_DEBUG
std::cerr << "FileIndexStore::SearchHash()" << std::endl;
#endif
for(pit = indices.begin(); pit != indices.end(); pit++)
{
firesults.clear();
(pit->second)->searchHash(hash, firesults);
/* translate results */
for(rit = firesults.begin(); rit != firesults.end(); rit++)
{
FileDetail fd;
fd.id = pit->first;
fd.name = (*rit)->name;
fd.hash = (*rit)->hash;
fd.path = ""; /* TODO */
fd.size = (*rit)->size;
fd.age = now - (*rit)->modtime;
fd.rank = (*rit)->pop;
results.push_back(fd);
}
}
unlockData();
return results.size();
}
int FileIndexStore::SearchKeywords(std::list<std::string> keywords, std::list<FileDetail> &results)
{
lockData();
std::map<RsPeerId, FileIndex *>::iterator pit;
std::list<FileEntry *>::iterator rit;
std::list<FileEntry *> firesults;
time_t now = time(NULL);
#ifdef FIS_DEBUG
std::cerr << "FileIndexStore::SearchKeywords()" << std::endl;
#endif
for(pit = indices.begin(); pit != indices.end(); pit++)
{
firesults.clear();
(pit->second)->searchTerms(keywords, firesults);
/* translate results */
for(rit = firesults.begin(); rit != firesults.end(); rit++)
{
FileDetail fd;
fd.id = pit->first;
fd.name = (*rit)->name;
fd.hash = (*rit)->hash;
fd.path = ""; /* TODO */
fd.size = (*rit)->size;
fd.age = now - (*rit)->modtime;
fd.rank = (*rit)->pop;
results.push_back(fd);
}
}
if (localindex)
{
firesults.clear();
localindex->searchTerms(keywords, firesults);
/* translate results */
for(rit = firesults.begin(); rit != firesults.end(); rit++)
{
FileDetail fd;
fd.id = "Local"; //localId;
fd.name = (*rit)->name;
fd.hash = (*rit)->hash;
fd.path = ""; /* TODO */
fd.size = (*rit)->size;
fd.age = now - (*rit)->modtime;
fd.rank = (*rit)->pop;
results.push_back(fd);
}
}
unlockData();
return results.size();
}
int FileIndexStore::searchBoolExp(Expression * exp, std::list<FileDetail> &results)
{
lockData();
std::map<RsPeerId, FileIndex *>::iterator pit;
std::list<FileEntry *>::iterator rit;
std::list<FileEntry *> firesults;
time_t now = time(NULL);
#ifdef FIS_DEBUG
std::cerr << "FileIndexStore::searchBoolExp()" << std::endl;
#endif
for(pit = indices.begin(); pit != indices.end(); pit++)
{
firesults.clear();
(pit->second)->searchBoolExp(exp, firesults);
/* translate results */
for(rit = firesults.begin(); rit != firesults.end(); rit++)
{
FileDetail fd;
fd.id = pit->first;
fd.name = (*rit)->name;
fd.hash = (*rit)->hash;
fd.path = ""; /* TODO */
fd.size = (*rit)->size;
fd.age = now - (*rit)->modtime;
fd.rank = (*rit)->pop;
results.push_back(fd);
}
}
/* finally search local files */
if (localindex)
{
firesults.clear();
localindex->searchBoolExp(exp, firesults);
/* translate results */
for(rit = firesults.begin(); rit != firesults.end(); rit++)
{
FileDetail fd;
fd.id = "Local"; //localId;
fd.name = (*rit)->name;
fd.hash = (*rit)->hash;
fd.path = ""; /* TODO */
fd.size = (*rit)->size;
fd.age = now - (*rit)->modtime;
fd.rank = (*rit)->pop;
results.push_back(fd);
}
}
unlockData();
return results.size();
}
int FileIndexStore::AboutToModify()
{
if (cb)
cb->notifyListPreChange(NOTIFY_LIST_DIRLIST, 0);
return 1;
}
int FileIndexStore::ModCompleted()
{
if (cb)
cb->notifyListChange(NOTIFY_LIST_DIRLIST, 0);
return 1;
}

View File

@ -0,0 +1,100 @@
/*
* RetroShare FileCache Module: fistore.h
*
* Copyright 2004-2007 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 MRK_FILE_INDEX_STORE_H
#define MRK_FILE_INDEX_STORE_H
/**********
* Stores the FileCaches of the Peers
* must implement 'loadCache' to
*
* This class is also accessed by the GUI....
* and the FileTransfer class.
*
*/
#include "dbase/findex.h"
#include "dbase/cachestrapper.h"
#include "rsiface/rsiface.h"
class FileStoreResult
{
public:
std::string id;
std::string path;
std::string hash;
std::string name;
};
class NotifyCallback
{
public:
NotifyCallback() { return; }
virtual ~NotifyCallback() { return; }
virtual void AboutToModify() { return; }
virtual void ModCompleted() { return; }
};
class Expression;
class FileIndexStore: public CacheStore
{
public:
FileIndexStore(CacheTransfer *cft, NotifyBase *cb_in,
RsPeerId ownid, std::string cachedir);
virtual ~FileIndexStore();
/* virtual functions overloaded by cache implementor */
virtual int loadCache(const CacheData &data); /* actual load, once data available */
/* Search Interface - For FileTransfer Lookup */
int SearchHash(std::string hash, std::list<FileDetail> &results);
/* Search Interface - For Search Interface */
int SearchKeywords(std::list<std::string> terms, std::list<FileDetail> &results);
/* Search Interface - for Adv Search Interface */
int searchBoolExp(Expression * exp, std::list<FileDetail> &results);
/* Search Interface - For Directory Access */
int RequestDirDetails(std::string uid, std::string path, DirDetails &details);
int RequestDirDetails(void *ref, DirDetails &details, uint32_t flags);
private:
int AboutToModify();
int ModCompleted();
std::map<RsPeerId, FileIndex *> indices;
RsPeerId localId;
FileIndex *localindex;
NotifyBase *cb;
};
#endif

View File

@ -0,0 +1,213 @@
/*
* RetroShare FileCache Module: fitest2.cc
*
* Copyright 2004-2007 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 "dbase/findex.h"
#include <iostream>
FileIndex *createBasicFileIndex(time_t age);
int test1(FileIndex *fi);
int test2(FileIndex *fi);
int main()
{
FileIndex *fi = createBasicFileIndex(100);
test1(fi);
delete fi;
return 1;
}
int test1(FileIndex *fi)
{
/* in this test we are going to get the old directories - and update them */
time_t stamp = 200;
DirEntry *olddir = NULL;
FileEntry fe;
while((olddir = fi -> findOldDirectory(stamp)))
{
/* update the directories and files here */
std::map<std::string, DirEntry *>::iterator dit;
std::map<std::string, FileEntry *>::iterator fit;
/* update this dir */
fe.name = olddir->name;
fi -> updateDirEntry(olddir->parent->path, fe, stamp);
/* update subdirs */
for(dit = olddir->subdirs.begin(); dit != olddir->subdirs.end(); dit++)
{
fe.name = (dit->second)->name;
/* set the age as out-of-date so that it gets checked */
fi -> updateDirEntry(olddir->path, fe, 0);
}
/* update files */
for(fit = olddir->files.begin(); fit != olddir->files.end(); fit++)
{
fe.name = (fit->second)->name;
fi -> updateFileEntry(olddir->path, fe, stamp);
}
/* clean up the dir (should have no effect) */
fi -> removeOldDirectory(olddir->parent->path, olddir->name, stamp);
fi -> printFileIndex(std::cout);
}
fi -> printFileIndex(std::cout);
return 1;
}
int test2(FileIndex *fi)
{
/* in this test we are going to simulate that 2 directories have disappeared */
time_t stamp = 200;
DirEntry *olddir = NULL;
FileEntry fe;
bool missingdir = false;
int i = 0;
while((olddir = fi -> findOldDirectory(stamp)))
{
missingdir = false;
if (i % 2 == 0)
{
std::cerr << " Simulating that dir doesnt exist :" << olddir->path;
std::cerr << std::endl;
missingdir = true;
}
i++;
if (!missingdir)
{
/* update the directories and files here */
std::map<std::string, DirEntry *>::iterator dit;
std::map<std::string, FileEntry *>::iterator fit;
/* update this dir */
fe.name = olddir->name;
fi -> updateDirEntry(olddir->parent->path, fe, stamp);
/* update subdirs */
for(dit = olddir->subdirs.begin(); dit != olddir->subdirs.end(); dit++)
{
fe.name = (dit->second)->name;
/* set the age as out-of-date so that it gets checked */
fi -> updateDirEntry(olddir->path, fe, 0);
}
/* update files */
for(fit = olddir->files.begin(); fit != olddir->files.end(); fit++)
{
fe.name = (fit->second)->name;
fi -> updateFileEntry(olddir->path, fe, stamp);
}
}
/* clean up the dir */
fi -> removeOldDirectory(olddir->parent->path, olddir->name, stamp);
fi -> printFileIndex(std::cout);
}
fi -> printFileIndex(std::cout);
return 1;
}
FileIndex *createBasicFileIndex(time_t age)
{
FileIndex *fi = new FileIndex("A SILLY ID");
FileEntry fe;
/* print empty FileIndex */
fi -> printFileIndex(std::cout);
std::list<std::string> rootdirs;
rootdirs.push_back("base1");
rootdirs.push_back("base2");
rootdirs.push_back("base3");
fi -> setRootDirectories(rootdirs, age);
/* add some entries */
fe.name = "dir1";
fi -> updateDirEntry("base1",fe, age);
fe.name = "file1";
fi -> updateFileEntry("/base1/dir1/",fe, age);
fe.name = "file2";
fi -> updateFileEntry("/base1/dir1/",fe, age);
fe.name = "file3";
fi -> updateFileEntry("/base1/dir1/",fe, age);
fe.name = "file4";
fi -> updateFileEntry("/base1/dir1/",fe, age);
fe.name = "dir2";
fi -> updateDirEntry("/base1",fe, age);
fe.name = "file5";
fi -> updateFileEntry("/base1/dir2/",fe, age);
fe.name = "file6";
fi -> updateFileEntry("/base1/dir2/",fe, age);
fe.name = "file7";
fi -> updateFileEntry("/base1/dir2/",fe, age);
fe.name = "file8";
fi -> updateFileEntry("/base1/",fe, age);
fe.name = "dir3";
fi -> updateDirEntry("/base1/dir2/",fe, age);
fe.name = "file10";
fi -> updateFileEntry("/base1/dir2/dir3",fe, age);
fe.name = "file11";
fi -> updateFileEntry("/base1/dir2/dir3",fe, age);
fe.name = "file12";
fi -> updateFileEntry("/base1/dir2/dir3",fe, age);
fe.name = "dir4";
fi -> updateDirEntry("/base3/",fe, age);
fe.name = "file20";
fi -> updateFileEntry("/base3/dir4/",fe, age);
fe.name = "file21";
fi -> updateFileEntry("/base3/dir4",fe, age);
// one that will fail.
fe.name = "file20";
fi -> updateFileEntry("/base3/",fe, age);
fi -> printFileIndex(std::cout);
return fi;
}

View File

@ -0,0 +1,111 @@
/*
* "$Id: ftest.cc,v 1.5 2007-02-18 21:46:49 rmf24 Exp $"
*
* Other Bits for RetroShare.
*
* Copyright 2004-2006 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".
*
*/
/* Example Test of filedex index */
#include "filedex.h"
#include <iostream>
int main()
{
filedex fd;
std::string term;
std::list<DirItem> dirs;
std::list<std::string> terms;
std::list<fdex *> results;
std::list<fdex *>::iterator it;
dirs.push_back(DirItem("/usr/local", "", 1));
dirs.push_back(DirItem("/var/log", "", 2));
fd.load(dirs);
// now show the root directories...
results.clear();
results = fd.dirlisting("");
std::cerr << "Root Directory Results:" << std::endl;
for(it = results.begin(); it != results.end(); it++)
{
std::cerr << "Full Path: " << (*it) -> path << std::endl;
std::cerr << "\tFile:" << (*it) -> file << std::endl;
std::cerr << "\tExt:" << (*it) -> ext;
std::cerr << " Size: " << (*it) -> len << std::endl;
std::cerr << "\tDir:" << (*it) -> subdir << std::endl;
}
while(1)
{
std::cerr << "Enter Search Term :";
std::cin >> term;
std::cerr << "Searching For:" << term << std::endl;
terms.clear();
terms.push_back(term);
results.clear();
results = fd.search(terms, 10, false);
std::cerr << "Search Results:" << std::endl;
for(it = results.begin(); it != results.end(); it++)
{
std::cerr << "Full Path: " << (*it) -> path << std::endl;
std::cerr << "\tFile:" << (*it) -> file << std::endl;
std::cerr << "\tExt:" << (*it) -> ext;
std::cerr << " Size: " << (*it) -> len << std::endl;
std::cerr << "\tDir:" << (*it) -> subdir << std::endl;
}
results.clear();
results = fd.dirlisting(term);
std::cerr << "FileName Results:" << std::endl;
for(it = results.begin(); it != results.end(); it++)
{
std::cerr << "Full Path: " << (*it) -> path << std::endl;
std::cerr << "\tFile:" << (*it) -> file << std::endl;
std::cerr << "\tExt:" << (*it) -> ext;
std::cerr << " Size: " << (*it) -> len << std::endl;
std::cerr << "\tDir:" << (*it) -> subdir << std::endl;
}
results.clear();
results = fd.findfilename(term);
std::cerr << "FileName Results:" << std::endl;
for(it = results.begin(); it != results.end(); it++)
{
std::cerr << "Full Path: " << (*it) -> path << std::endl;
std::cerr << "\tFile:" << (*it) -> file << std::endl;
std::cerr << "\tExt:" << (*it) -> ext;
std::cerr << " Size: " << (*it) -> len << std::endl;
std::cerr << "\tDir:" << (*it) -> subdir << std::endl;
}
}
//sleep(5);
return 1;
}

View File

@ -0,0 +1,89 @@
/*
* "$Id: looktest.cc,v 1.1 2007-02-19 20:08:30 rmf24 Exp $"
*
* Other Bits for RetroShare.
*
* Copyright 2004-2006 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 "filedex.h"
#include "dbase/filelook.h"
#include <iostream>
#include "pqi/pqi.h"
int main()
{
fileLook *fl = new fileLook();
std::string term;
std::list<std::string> dirs;
std::list<std::string> terms;
std::list<fdex *> results;
std::list<fdex *>::iterator it;
dirs.push_back("/mnt/disc2/extra/rmf24/mp3s/good");
dirs.push_back("/mnt/disc2/extra/rmf24/mp3s/marks");
dirs.push_back("/mnt/disc2/extra/rmf24/mp3s/incoming");
fl -> start(); /* background look thread */
std::cerr << "FileLook Thread started" << std::endl;
fl -> setSharedDirectories(dirs);
PQFileItem *i = new PQFileItem();
std::cerr << "test Lookup ..." << std::endl;
fl -> lookUpDirectory(i);
std::cerr << "Entering Main Loop" << std::endl;
while(1)
{
std::cerr << "Enter Search Term :";
std::cin >> term;
std::cerr << "Searching For:" << term << std::endl;
terms.clear();
terms.push_back(term);
PQFileItem *i = new PQFileItem();
i -> path = term;
std::cerr << "Root Lookup ..." << std::endl;
fl -> lookUpDirectory(i);
std::cerr << "LookUp done" << std::endl;
while(NULL != (i = (PQFileItem *) fl -> getResult()))
{
std::cerr << "Results:" << std::endl;
i -> print(std::cerr);
std::cerr << std::endl;
}
}
//sleep(5);
return 1;
}

View File

@ -0,0 +1,149 @@
/*
* rs-core/src/dbase: rsexpr.cc
*
* RetroShare C++ Interface.
*
* Copyright 2007-2008 by Kashif Kaleem.
*
* 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 "dbase/findex.h"
#include "rsiface/rsexpr.h"
#include <functional>
/******************************************************************************************
eval functions of relational expressions.
******************************************************************************************/
bool DateExpression::eval(FileEntry *file)
{
return evalRel(file->modtime);
}
bool SizeExpression::eval(FileEntry *file)
{
return evalRel(file->size);
}
bool PopExpression::eval(FileEntry *file)
{
return evalRel(file->pop);
}
/******************************************************************************************
Code for evaluating string expressions
******************************************************************************************/
bool NameExpression::eval(FileEntry *file)
{
return evalStr(file->name);
}
bool PathExpression::eval(FileEntry *file){
std::string path;
/*Construct the path of this file*/
DirEntry * curr = file->parent;
while ( curr != NULL ){
path = curr->name+"/"+ path;
curr = curr->parent;
}
return evalStr(path);
}
bool ExtExpression::eval(FileEntry *file){
std::string ext;
/*Get the part of the string after the last instance of . in the filename */
unsigned int index = file->name.find_last_of('.');
if (index != std::string::npos) {
ext = file->name.substr(index+1);
if (ext != "" ){
return evalStr(ext);
}
}
return false;
}
bool HashExpression::eval(FileEntry *file){
return evalStr(file->hash);
}
/*Check whether two strings are 'equal' to each other*/
static bool StrEquals(const std::string & str1, const std::string & str2,
bool IgnoreCase ){
if ( str1.size() != str2.size() ){
return false;
} else if (IgnoreCase) {
std::equal( str1.begin(), str1.end(),
str2.begin(), CompareCharIC() );
}
return std::equal( str1.begin(), str1.end(),
str2.begin());
}
/*Check whether one string contains the other*/
static bool StrContains( std::string & str1, std::string & str2,
bool IgnoreCase){
std::string::const_iterator iter ;
if (IgnoreCase) {
iter = std::search( str1.begin(), str1.end(),
str2.begin(), str2.end(), CompareCharIC() );
} else {
iter = std::search( str1.begin(), str1.end(),
str2.begin(), str2.end());
}
return ( iter != str1.end() );
}
bool StringExpression :: evalStr ( std::string &str ){
std::list<std::string>::iterator iter;
switch (Op) {
case ContainsAllStrings:
for ( iter = terms.begin(); iter != terms.end(); iter++ ) {
if ( StrContains (str, *iter, IgnoreCase) == false ){
return false;
}
}
return true;
break;
case ContainsAnyStrings:
for ( iter = terms.begin(); iter != terms.end(); iter++ ) {
if ( StrContains (str,*iter, IgnoreCase) == true ) {
return true;
}
}
break;
case EqualsString:
for ( iter = terms.begin(); iter != terms.end(); iter++ ) {
if ( StrEquals (str,*iter, IgnoreCase) == true ) {
return true;
}
}
break;
default:
return false;
}
return false;
}

View File

@ -0,0 +1,74 @@
/*
* RetroShare FileCache Module: searchtest.cc
*
* Copyright 2004-2007 by Kefei Zhou.
*
* 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 "dbase/findex.h"
#include <iostream>
#include <fstream>
int main()
{
std::cout << std::string::npos << std::endl;
std::string testfile = "searchtest.index";
std::string fhash = "6851c28d99a6616a86942c3914476bf11997242a";
FileIndex *fi = new FileIndex("DUMB ID");
// loading fileindex
std::cout << std::endl << "Test load" << std::endl;
fi->loadIndex(testfile, fhash, 1532);
fi->printFileIndex(std::cout);
std::cout << "FileIndex Loaded" << std::endl << std::endl;
std::list<FileEntry *> hashresult;
std::list<FileEntry *> termresult;
// searchhash
std::string findhash = "82bffa6e1cdf8419397311789391238174817481";
std::cout << "Search hash : " << findhash << std::endl;
fi->searchHash(findhash, hashresult);
while(!hashresult.empty())
{
hashresult.back()->print(std::cout);
hashresult.pop_back();
}
// searchterm
std::list<std::string> terms;
terms.push_back("paper");
terms.push_back("doc");
std::cout << "Search terms" << std::endl;
fi->searchTerms(terms, termresult);
while(!termresult.empty())
{
termresult.back()->print(std::cout);
termresult.pop_back();
}
delete fi;
return 1;
}

View File

@ -0,0 +1,28 @@
RS_TOP_DIR = ..
include ../make.opt
OBJ = dhthandler.o
#CADKINC = /home/rmf24/prog/src/KadC
#CFLAGS += -I $(CADKINC)
#RSLIBS += -L $(CADKINC) -lKadC
all : $(OBJ) librs dhttest
dhttest: $(OBJ) dhttest.o
$(CC) $(CFLAGS) -o dhttest $(OBJ) dhttest.o $(RSLIBS)
librs: $(OBJ)
$(AR) r $(LIBRS) $(OBJ)
$(RANLIB) $(LIBRS)
.cc.o:
$(CC) $(CFLAGS) -c $<
clean:
-/bin/rm $(OBJ) dhttest.o
clobber: clean
-/bin/rm dhttest

View File

@ -0,0 +1,710 @@
#include "dht/dhthandler.h"
/* This stuff is actually C */
#ifdef __cplusplus
extern "C" {
#endif
#include <int128.h>
#include <rbt.h>
#include <KadCalloc.h>
#include <KadClog.h>
#ifdef __cplusplus
} /* extern C */
#endif
/* This stuff is actually C */
/* HACK TO SWITCH THIS OFF during testing */
/*define NO_DHT_RUNNING 1*/
#include <iostream>
#include <sstream>
std::ostream &operator<<(std::ostream &out, dhtentry &ent)
{
out << "DHTENTRY(" << ent.id << "): Status: " << ent.status;
out << std::endl;
out << "\taddr: " << inet_ntoa(ent.addr.sin_addr) << ":" << ntohs(ent.addr.sin_port);
out << std::endl;
out << "\tlastTS: " << time(NULL) - ent.lastTs << " secs ago";
out << "\tFlags: " << ent.flags;
out << std::endl;
return out;
}
#define DHT_UNKNOWN 0
#define DHT_SEARCHING 1 /* for peers */
#define DHT_PUBLISHING 1 /* for self */
#define DHT_FOUND 2
/* time periods */
#define DHT_MIN_PERIOD 10
#define DHT_SEARCH_PERIOD 300
#define DHT_REPUBLISH_PERIOD 1200
void cleardhtentry(dhtentry *ent, std::string id)
{
ent -> name = "";
ent -> id = id;
ent -> addr.sin_addr.s_addr = 0;
ent -> addr.sin_port = 0;
ent -> flags = 0;
ent -> status = DHT_UNKNOWN;
ent -> lastTs = 0;
return;
}
void initdhtentry(dhtentry *ent)
{
ent -> name = "";
// leave these ...
//ent -> addr.sin_addr.in_addr = 0;
//ent -> addr.sin_port = 0;
//ent -> flags = 0;
ent -> status = DHT_SEARCHING;
ent -> lastTs = time(NULL);
return;
}
void founddhtentry(dhtentry *ent, struct sockaddr_in inaddr, unsigned int flags)
{
ent -> addr = inaddr;
ent -> flags = flags;
ent -> status = DHT_FOUND;
ent -> lastTs = time(NULL);
return;
}
dhthandler::dhthandler(std::string inifile)
:mShutdown(false), dhtOk(false)
{
/* init own to null */
dataMtx.lock(); /* LOCK MUTEX */
cleardhtentry(&ownId, "");
kadcFile = inifile;
dataMtx.unlock(); /* UNLOCK MUTEX */
/* start up the threads... */
init();
}
dhthandler::~dhthandler()
{
}
/* This is internal - only called when active */
bool dhthandler::networkUp()
{
/* no need for mutex? */
return (20 < KadC_getnknodes(pkcc));
}
/* this is external */
int dhthandler::dhtPeers()
{
int count = 0;
dataMtx.lock(); /* LOCK MUTEX */
if (dhtOk)
{
count = KadC_getnknodes(pkcc);
}
dataMtx.unlock(); /* UNLOCK MUTEX */
return count;
}
/* set own tag */
void dhthandler::setOwnHash(std::string id)
{
dataMtx.lock(); /* LOCK MUTEX */
ownId.id = id;
dataMtx.unlock(); /* UNLOCK MUTEX */
}
void dhthandler::setOwnPort(short port)
{
dataMtx.lock(); /* LOCK MUTEX */
ownId.addr.sin_port = htons(port);
/* reset own status -> so we republish */
ownId.status = DHT_UNKNOWN;
dataMtx.unlock(); /* UNLOCK MUTEX */
}
bool dhthandler::getExtAddr(struct sockaddr_in &addr, unsigned int &flags)
{
dataMtx.lock(); /* LOCK MUTEX */
if (ownId.status == DHT_UNKNOWN)
{
dataMtx.unlock(); /* UNLOCK MUTEX */
return false;
}
addr = ownId.addr;
flags = ownId.flags;
dataMtx.unlock(); /* UNLOCK MUTEX */
return true;
}
/* at startup */
void dhthandler::addFriend(std::string id)
{
dataMtx.lock(); /* LOCK MUTEX */
std::map<std::string, dhtentry>::iterator it;
it = addrs.find(id);
if (it == addrs.end())
{
/* not found - add */
dhtentry ent;
cleardhtentry(&ent, id);
addrs[id] = ent;
}
else
{
/* already there */
std::cerr << "dhthandler::addFriend() Already there!" << std::endl;
}
dataMtx.unlock(); /* UNLOCK MUTEX */
}
void dhthandler::removeFriend(std::string id)
{
dataMtx.lock(); /* LOCK MUTEX */
std::map<std::string, dhtentry>::iterator it;
it = addrs.find(id);
if (it == addrs.end())
{
/* not found - complain*/
std::cerr << "dhthandler::addFriend() Already there!" << std::endl;
}
else
{
/* found */
addrs.erase(it);
}
dataMtx.unlock(); /* UNLOCK MUTEX */
}
/* called prior to connect */
bool dhthandler::addrFriend(std::string id, struct sockaddr_in &addr, unsigned int &flags)
{
dataMtx.lock(); /* LOCK MUTEX */
/* look it up */
bool ret = false;
std::map<std::string, dhtentry>::iterator it;
it = addrs.find(id);
if (it == addrs.end())
{
/* not found - complain*/
std::cerr << "dhthandler::addrFriend() Non-existant!" << std::endl;
ret = false;
}
else
{
if (it->second.status == DHT_FOUND)
{
addr = it->second.addr;
ret = true;
}
}
dataMtx.unlock(); /* UNLOCK MUTEX */
return ret;
}
int dhthandler::init()
{
dataMtx.lock(); /* LOCK MUTEX */
/* HACK TO SWITCH THIS OFF during testing */
#ifdef NO_DHT_RUNNING
dataMtx.unlock(); /* UNLOCK MUTEX */
dhtOk = false;
return 1;
#endif
char *filename = (char *) malloc(1024);
sprintf(filename, "%.1023s", kadcFile.c_str());
/* start up the dht server. */
KadC_log("KadC - library version: %d.%d.%d\n",
KadC_version.major, KadC_version.minor, KadC_version.patchlevel);
/* file, Leaf, StartNetworking (->false in full version) */
kcc = KadC_start(filename, true, 1);
if(kcc.s != KADC_OK) {
KadC_log("KadC_start(%s, %d) returned error %d:\n",
kadcFile.c_str(), 1, kcc.s);
KadC_log("%s %s", kcc.errmsg1, kcc.errmsg2);
dhtOk = false;
}
else
{
dhtOk = true;
}
pkcc = &kcc;
dataMtx.unlock(); /* UNLOCK MUTEX */
return 1;
}
int dhthandler::shutdown()
{
dataMtx.lock(); /* LOCK MUTEX */
/* end the dht server. */
kcs = KadC_stop(&kcc);
if(kcs != KADC_OK) {
KadC_log("KadC_stop(&kcc) returned error %d:\n", kcc.s);
KadC_log("%s %s", kcc.errmsg1, kcc.errmsg2);
}
KadC_list_outstanding_mallocs(10);
dataMtx.unlock(); /* UNLOCK MUTEX */
return 0;
}
int dhthandler::write_inifile()
{
/* if we're up and we have enough valid ones */
#define MIN_KONTACTS 50
if (KadC_getncontacts(pkcc) > MIN_KONTACTS)
{
std::cerr << "DhtHandler::Write_IniFile() Writing File" << std::endl;
if (KADC_OK != KadC_write_inifile(pkcc, NULL))
{
KadC_log("KadC_write_inifile(%s, %d) returned error %d:\n",
kadcFile.c_str(), 1, kcc.s);
KadC_log("%s %s", kcc.errmsg1, kcc.errmsg2);
}
}
else
{
std::cerr << "DhtHandler::Write_IniFile() Not enough contacts" << std::endl;
}
return 1;
}
void dhthandler::run()
{
/* infinite loop */
int totalsleep = 0;
while(1)
{
// std::cerr << "DhtHandler::Run()" << std::endl;
if (!dhtOk)
{
std::cerr << "DhtHandler::Run() Failed to Start" << std::endl;
/********************************** WINDOWS/UNIX SPECIFIC PART ******************/
#ifndef WINDOWS_SYS
sleep(1);
#else
Sleep(1000);
#endif
/********************************** WINDOWS/UNIX SPECIFIC PART ******************/
continue;
}
/* lock it up */
dataMtx.lock(); /* LOCK MUTEX */
bool toShutdown = mShutdown;
/* shutdown */
dataMtx.unlock(); /* UNLOCK MUTEX */
print();
if (toShutdown)
{
shutdown();
dhtOk = false;
}
/* check ids */
int allowedSleep = checkOwnStatus();
int nextPeerCheck = checkPeerIds();
if (nextPeerCheck < allowedSleep)
{
allowedSleep = nextPeerCheck;
}
if (allowedSleep > 10)
{
allowedSleep = 10;
}
else if (allowedSleep < 10)
{
allowedSleep = 10;
}
// std::cerr << "DhtHandler::Run() sleeping for:" << allowedSleep << std::endl;
/********************************** WINDOWS/UNIX SPECIFIC PART ******************/
#ifndef WINDOWS_SYS
sleep(allowedSleep);
#else
Sleep(1000 * allowedSleep);
#endif
/********************************** WINDOWS/UNIX SPECIFIC PART ******************/
#define DHT_INIT_STORE_PERIOD 300
totalsleep += allowedSleep;
if (totalsleep > DHT_INIT_STORE_PERIOD)
{
write_inifile();
totalsleep = 0;
}
}
return;
}
int dhthandler::print()
{
dataMtx.lock(); /* LOCK MUTEX */
std::cerr << "DHT Status:" << std::endl;
std::cerr << "KNodes: " << KadC_getnknodes(pkcc);
std::cerr << std::endl;
std::cerr << "Kontacts: " << KadC_getncontacts(pkcc);
std::cerr << std::endl;
std::cerr << "KBuckets: ";
std::cerr << std::endl;
KadC_listkbuckets(pkcc);
std::cerr << std::endl;
std::cerr << "Own DHT:" << std::endl;
std::cerr << ownId << std::endl;
std::cerr << addrs.size() << " Peers:" << std::endl;
std::map<std::string, dhtentry>::iterator it;
for(it = addrs.begin(); it != addrs.end(); it++)
{
std::cerr << "Peer DHT" << std::endl;
std::cerr << it -> second << std::endl;
}
dataMtx.unlock(); /* UNLOCK MUTEX */
return 1;
}
int dhthandler::checkOwnStatus()
{
dataMtx.lock(); /* LOCK MUTEX */
int nextcall = DHT_REPUBLISH_PERIOD;
bool toPublish = false;
/* if we are publishing, and time up ... republish */
if (ownId.status == DHT_UNKNOWN)
{
/* if valid Hash and Port */
if ((ownId.id != "") && (ownId.addr.sin_port != 0) &&
(networkUp())) /* network is up */
{
unsigned long int extip = KadC_getextIP(pkcc);
ownId.flags = KadC_getfwstatus(pkcc);
if (extip != 0)
{
ownId.addr.sin_addr.s_addr = htonl(extip);
toPublish = true;
}
}
nextcall = DHT_MIN_PERIOD;
}
else /* ownId.status == DHT_PUBLISHING */
{
/* check time.
*/
if (ownId.lastTs + DHT_REPUBLISH_PERIOD < time(NULL))
{
toPublish = true;
}
}
dataMtx.unlock(); /* UNLOCK MUTEX */
if (toPublish)
{
publishOwnId();
}
return nextcall;
}
int dhthandler::checkPeerIds()
{
dataMtx.lock(); /* LOCK MUTEX */
/* if we are unknown .... wait */
int nextcall = DHT_REPUBLISH_PERIOD;
std::map<std::string, dhtentry>::iterator it;
/* local list */
std::list<std::string> idsToUpdate;
std::list<std::string>::iterator it2;
for(it = addrs.begin(); it != addrs.end(); it++)
{
/* if we are publishing, and time up ... republish */
if (it -> second.status == DHT_UNKNOWN)
{
/* startup */
idsToUpdate.push_back(it->first);
}
else if (it -> second.status == DHT_SEARCHING)
{
/* check if time */
if (it -> second.lastTs + DHT_SEARCH_PERIOD < time(NULL))
{
idsToUpdate.push_back(it->first);
}
nextcall = DHT_SEARCH_PERIOD;
}
else if (it -> second.status == DHT_FOUND)
{
/* check if time */
if (it -> second.lastTs + DHT_REPUBLISH_PERIOD < time(NULL))
{
idsToUpdate.push_back(it->first);
}
}
}
dataMtx.unlock(); /* UNLOCK MUTEX */
for(it2 = idsToUpdate.begin(); it2 != idsToUpdate.end(); it2++)
{
searchId(*it2);
}
return nextcall;
}
/* already locked */
int dhthandler::publishOwnId()
{
dataMtx.lock(); /* LOCK MUTEX */
/* publish command */
/* publish {#[khash]|key} {#[vhash]|value} [meta-list [nthreads [nsecs]]] */
char index[1024];
sprintf(index, "#%.1023s", ownId.id.c_str());
char value[1024];
sprintf(value, "#%.1023s", ownId.id.c_str());
/* to store the ip address and flags */
char metalist[1024];
sprintf(metalist, "rsid=%s:%d;flags=%04X;",
inet_ntoa(ownId.addr.sin_addr),
ntohs(ownId.addr.sin_port),
ownId.flags);
dataMtx.unlock(); /* UNLOCK MUTEX */
int nthreads = 10;
int duration = 15;
int status;
/* might as well hash back to us? */
status = KadC_republish(pkcc, index, value, metalist, nthreads, duration);
if(status == 1)
{
KadC_log("Syntax error preparing search. Try: p key #hash [tagname=tagvalue[;...]]\n");
}
dataMtx.lock(); /* LOCK MUTEX */
/* update entry */
initdhtentry(&ownId);
dataMtx.unlock(); /* UNLOCK MUTEX */
return 1;
}
/* must be protected by mutex externally */
dhtentry *dhthandler::finddht(std::string id)
{
std::map<std::string, dhtentry>::iterator it;
it = addrs.find(id);
if (it == addrs.end())
{
return NULL;
}
return &(it->second);
}
int dhthandler::searchId(std::string id)
{
if (!networkUp())
return 0;
/* ack search */
bool updated = false;
/* search */
void *iter;
KadCdictionary *pkd;
char *filter = "";
int nthreads = 10;
int duration = 15;
int maxhits = 100;
time_t starttime = time(NULL);
void *resdictrbt;
int nhits;
char index[1024];
sprintf(index, "#%.1023s", id.c_str());
/* cannot be holding mutex here... (up to 15 secs) */
resdictrbt = KadC_find(pkcc, index, filter, nthreads, maxhits, duration);
nhits = rbt_size(resdictrbt);
/* list each KadCdictionary returned in the rbt */
for(iter = rbt_begin(resdictrbt); iter != NULL; iter = rbt_next(resdictrbt, iter)) {
pkd = rbt_value(iter);
KadC_log("Found: ");
KadC_int128flog(stdout, KadCdictionary_gethash(pkd));
KadC_log("\n");
KadCdictionary_dump(pkd);
KadC_log("\n");
KadCtag_iter iter;
unsigned int i;
bool found = false;
std::string addrline;
std::string flagsline;
for(i = 0, KadCtag_begin(pkd, &iter); (i < iter.tagsleft); i++, KadCtag_next(&iter)) {
if(i > 0)
KadC_log(";");
if ((strncmp("rsid", iter.tagname, 4) == 0)
&& (iter.tagtype == KADCTAG_STRING))
{
KadC_log("DECODING:%s", (char *)iter.tagvalue);
addrline = (char *) iter.tagvalue;
found = true;
}
if ((strncmp("flags", iter.tagname, 5) == 0)
&& (iter.tagtype == KADCTAG_STRING))
{
KadC_log("DECODING:%s", (char *)iter.tagvalue);
flagsline = (char *) iter.tagvalue;
}
}
/* must parse:rsid=ddd.ddd.ddd.ddd:dddd;flags=xxxx */
struct sockaddr_in addr;
unsigned int flags = 0;
unsigned int a, b, c, d, e;
if ((found) &&
(5 == sscanf(addrline.c_str(), "%d.%d.%d.%d:%d", &a, &b, &c, &d, &e)))
{
std::ostringstream out;
out << a << "." << b << "." << c << "." << d;
inet_aton(out.str().c_str(), &(addr.sin_addr));
addr.sin_port = htons(e);
if (flagsline != "")
sscanf(flagsline.c_str(), "%x", &flags);
std::cerr << "Decoded entry: " << out.str() << " : " << e << std::endl;
dataMtx.lock(); /* LOCK MUTEX */
dhtentry *ent = finddht(id);
if (ent)
{
founddhtentry(ent, addr, flags);
updated = true;
}
dataMtx.unlock(); /* UNLOCK MUTEX */
}
else
{
std::cerr << "Failed to Scan:" << addrline << " <-----" << std::endl;
}
}
KadC_log("Search completed in %d seconds - %d hit%s returned\n",
time(NULL)-starttime, nhits, (nhits == 1 ? "" : "s"));
for(iter = rbt_begin(resdictrbt); iter != NULL; iter = rbt_begin(resdictrbt)) {
pkd = rbt_value(iter);
rbt_erase(resdictrbt, iter);
KadCdictionary_destroy(pkd);
}
rbt_destroy(resdictrbt);
dataMtx.lock(); /* LOCK MUTEX */
if (!updated)
{
dhtentry *ent = finddht(id);
if (ent)
{
initdhtentry(ent);
}
}
dataMtx.unlock(); /* UNLOCK MUTEX */
return 1;
}
#if (0)
#include <pthread.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <time.h>
#include <stdlib.h>
#include <signal.h>
#include <unistd.h>
#include <int128.h>
#include <rbt.h>
#include <KadCalloc.h>
#include <KadClog.h>
#include <config.h>
#include <queue.h> /* required by net.h, sigh... */
#include <net.h> /* only for domain2hip() */
#include <KadCapi.h>
#endif

View File

@ -0,0 +1,97 @@
#ifndef _RS_DHT_IFACE_H
#define _RS_DHT_IFACE_H
#include <string.h>
/* This stuff is actually C */
#ifdef __cplusplus
extern "C" {
#endif
#include <int128.h>
#include <KadCapi.h>
#ifdef __cplusplus
} /* extern C */
#endif
/* This stuff is actually C */
#include "util/rsthreads.h"
#include <string>
#include <map>
/* platform independent networking... */
#include "pqi/pqinetwork.h"
#include "pqi/pqiaddrstore.h"
class dhtentry
{
public:
std::string name;
std::string id;
struct sockaddr_in addr;
unsigned int flags;
int status;
int lastTs;
};
class dhthandler: public RsThread, public pqiAddrStore
{
public:
dhthandler(std::string inifile);
~dhthandler();
/* RsIface */
/* set own tag */
void setOwnHash(std::string id);
void setOwnPort(short port);
bool getExtAddr(sockaddr_in &addr, unsigned int &flags);
/* at startup */
void addFriend(std::string id);
void removeFriend(std::string id);
int dhtPeers();
/* pqiAddrStore ... called prior to connect */
virtual bool addrFriend(std::string id, struct sockaddr_in &addr, unsigned int &flags);
int init();
int shutdown();
int print();
/* must run thread */
virtual void run();
private:
int write_inifile();
bool networkUp(); /* get status */
int checkOwnStatus();
int checkPeerIds();
int publishOwnId();
int searchId(std::string id);
dhtentry *finddht(std::string id);
/* Mutex for data below */
RsMutex dataMtx;
dhtentry ownId;
std::map<std::string, dhtentry> addrs;
KadCcontext kcc, *pkcc;
KadC_status kcs;
std::string kadcFile;
bool mShutdown;
bool dhtOk;
};
#endif /* _RS_DHT_IFACE_H */

View File

@ -0,0 +1,90 @@
#include "dht/dhthandler.h"
int main(int argc, char **argv)
{
int id = argc % 3;
char *hash1 = "3509426505463458576487";
char *hash2 = "1549879882341985914515";
char *hash3 = "8743598543269526505434";
int port1 = 8754;
int port2 = 2355;
int port3 = 6621;
std::cerr << "Starting dhttest Id: " << id << std::endl;
/******************************** WINDOWS/UNIX SPECIFIC PART ******************/
#ifndef WINDOWS_SYS
/********************************** WINDOWS/UNIX SPECIFIC PART ******************/
#else
// Windows Networking Init.
WORD wVerReq = MAKEWORD(2,2);
WSADATA wsaData;
if (0 != WSAStartup(wVerReq, &wsaData))
{
std::cerr << "Failed to Startup Windows Networking";
std::cerr << std::endl;
}
else
{
std::cerr << "Started Windows Networking";
std::cerr << std::endl;
}
#endif
/********************************** WINDOWS/UNIX SPECIFIC PART ******************/
#ifdef PTW32_STATIC_LIB
pthread_win32_process_attach_np();
#endif
dhthandler dht("tst.ini");
dht.start();
if (id == 0)
{
dht.setOwnPort(port1);
dht.setOwnHash(hash1);
dht.addFriend(hash2);
dht.addFriend(hash3);
}
else if (id == 1)
{
dht.setOwnPort(port2);
dht.setOwnHash(hash2);
dht.addFriend(hash1);
dht.addFriend(hash3);
}
else
{
dht.setOwnPort(port3);
dht.setOwnHash(hash3);
dht.addFriend(hash1);
dht.addFriend(hash2);
}
while(1)
{
/********************************** WINDOWS/UNIX SPECIFIC PART ******************/
#ifndef WINDOWS_SYS
sleep(1);
#else
Sleep(1000);
#endif
/********************************** WINDOWS/UNIX SPECIFIC PART ******************/
}
}

View File

@ -0,0 +1,272 @@
[local]
# if the hash (first arg) is 0, a random value will be used.
0 0.0.0.0 1234 4662 0
[some_ignored_stuff]
these lines...
...under unrecognized sections...
...are ignored and left alone...
[overnet_peers]
# 259 contacts follow
01e32c7d216d1479ff1738b88f81bf3b 82.224.47.90 11297 0
01ee86531f5070a344e9d0484744d14d 85.157.111.164 6267 0
028b0545ae661b53d1538d90a7728fac 87.238.10.193 8150 0
032a16ddd72ad9873e036db246930163 83.78.25.111 10089 0
035a2148d7da45022bc36088cbeaa2d5 84.188.185.143 6780 0
035d1f176411bd53b4578e383a66bcdd 82.82.140.226 4298 0
03b47000764e0b3be3efaff6f81e1a0b 24.0.148.14 4665 0
057b9a66771826db0bbd51483a10ff93 85.97.196.22 5678 0
084fe60f368e1117c52e88e8f209113e 85.16.152.185 9363 0
0857c84b6c77bf9e0d0cdeea6e56f11a 172.159.137.252 11316 1
08ca7126b6ead7e6ea3870d13f32d004 83.11.233.250 3911 0
090b57278c13cc673230893305538d1f 82.252.210.95 15030 1
09166e1c64456cc7b3a989d1acb6bd65 84.98.135.162 11933 0
092a05ae3c651f430c806bc49aeb2cb9 210.213.140.62 10521 0
0941d60b7b2d83ef565047610570998c 83.181.168.72 3450 0
09729bc4c1639fe3f4d914cbb8ddc213 82.247.37.205 7663 0
098b7599f442273d1ec2f04710ff436f 80.142.123.8 6133 0
09ebe97100d307d2e5419fa2f7cdfec3 87.10.147.210 10301 0
0a157ca24a7445da325322144ee01993 24.74.148.251 9464 0
0a23207ed240aa7f35202bd4e63b8bdd 84.170.225.102 22222 0
0a2e67bee755ff15c5518b3072867034 87.14.169.88 4445 0
0a39d5f89b4910945087ef9886f58c77 82.235.178.185 9818 0
0becaf5dbbe2eb30694c86408cffb25b 82.234.43.27 19632 0
1284fc9d5064cf0c89630fcc06f86f96 122.254.164.2 11839 0
12b0ebaa0b3e17e16e38f7149f899e96 82.52.190.151 5405 0
12cefeb85edc41e33686ec23f707621c 90.27.87.164 5637 0
12dd8d3931c05d9dc7f9fe0fafc54e46 213.103.153.186 11880 0
12e075a67748bd9888a537b1ddfc68bb 75.162.143.84 12100 0
12f298eb89c926b23eef71724794f386 80.97.199.30 7007 0
12f9fb4045af33cb47f5b87ac618b39d 85.140.95.208 6484 0
12fced7a66d90c3c029e2fbb0d27d44e 70.48.189.93 6093 1
13005d05429d43624683fd2c3ce83c65 83.214.38.125 7448 0
13c90dbc29a45b6d8297ce758772c056 58.77.54.12 12291 0
140470e218c7f8184af176e54cecc294 62.94.193.218 5600 0
148a88de9e03129f7e3e15bdeae59fe1 70.48.175.156 10301 0
14d04c790464ad46121934041d6254ec 62.57.36.125 4041 0
14d589f5f766e40c0838fd9a74218f7a 71.56.125.35 7543 0
158889e94d84e71c135935061743d456 200.16.221.180 3432 0
1667353bcc5e4953c9dcb2b025a8e87b 212.76.242.34 9574 1
168d639d6f6b4f87e1bd9b1df8344729 218.162.61.52 12901 0
16c3bcc5ffc4ce92cdfc7db9f8d52184 80.188.8.104 4662 0
182015e86828a195e22ccb2455378e91 220.134.22.185 3315 0
18f43620c84d373a5935eb1cffa4bb96 89.169.146.14 8323 0
1998abaf1be11abe19a2ea5961befa38 75.36.191.184 5002 0
19f0b20dce022dca4ca915b7ce859b17 59.124.237.86 11590 0
19ffaeafef17d524126ed45ff7326c2b 83.2.140.63 3128 0
1a0b0df71afbac06620431e1ddb5f939 212.106.171.142 6711 0
1b6b5245e54d2f68972bfb178b887724 203.49.242.90 6324 0
1c20dc407cfa9b57778e929a7867af8a 87.175.196.166 5713 1
21b3df22b8c563ac18ee4dfe35a155bc 58.232.60.235 4197 0
21d59ad8e70e8e60659638e29eef5c25 80.203.138.183 6350 0
220c4cc811b0511f13ccd0672fe2954a 83.28.247.107 3884 0
287f16f02efd285381d7657ca5cd99d9 87.221.0.217 6672 0
2981223354677a4ddf777902e9225bef 81.179.202.34 4222 0
29a7a5751d92da3ade58ad92a1ed942d 124.8.65.42 4422 0
29be351bbe4318605d535c76b9a76a6d 83.23.38.244 11386 0
29cf29ab2b870b288a292cefed0d94bf 151.44.119.139 7688 0
29d063f9aba16668462ab3edf2f43ab7 61.224.52.103 5687 0
2a0c14e8d6383d9e5bf2730f0d0ec857 82.130.210.82 50020 0
2a11275793d740d102a1348fd3f45909 80.53.196.58 9936 0
2a519604b6a0119c126194063edf4b8c 68.148.121.42 6472 0
2a83ac042d1278798b00d3352aefe98d 24.243.188.178 10301 0
2acf26c3b18173eb4eb6f73622540c6a 86.56.213.115 3558 0
2bf18d609eb338c9697c9e99379fd16a 85.137.81.79 11717 0
3279ca195c2f4ddf598b8a7dbfd670b6 84.125.74.120 23232 0
32ac6a1eeabdcf65f1505d2a95cee6c9 83.24.146.73 11964 1
3304d216ec77e0fa5c18712d53c008f6 85.57.160.211 7721 0
33a550bed46568b18eb91fae70ca0dbe 24.225.232.219 12164 0
33e97bddd82e4d09131b7342acfeb79c 24.132.162.32 3016 0
33e9ca51aa7f521589a2e6a3438b2821 80.180.76.149 12777 0
34085309549df35140c8e27068083a63 212.59.192.220 4029 0
36196c2ea442dd5ae56cd35a7d1f8619 90.10.169.218 12214 0
361cea6dd0d377f200474a2d72ca7ba6 149.135.104.131 8190 0
3625c3d644b80f221568d688f0f135c5 90.7.181.106 12615 0
36317d125a1aff13035bcd3c0dec4978 80.36.124.22 46675 0
3640f164a682b2c5d249bdcd8bf38274 80.35.196.42 4665 0
36a55737e170cc90ef3ebee1c3b0dc72 217.228.164.18 5325 0
36d7979c3328056ab80a53e94588ae9c 87.122.0.101 9902 0
37075f69ca1fe6aabe53567c2ab48a1a 87.227.73.35 7776 0
375615ba9163d8ecc6a5aed410fe4182 81.1.118.25 5667 1
3796255e359f42a5c4fe41976307b5cc 85.141.108.236 4505 0
38b0e0fb572b282ed6a610adf7a90de8 82.232.90.43 12223 0
38b39efee6bf73cdcc5aff57e816d6ea 71.17.52.65 11438 0
38f6091d65b3483cb6f90d670cb3e8fa 151.97.69.209 9997 0
39037677e44d021350494e6f7c055a8b 82.225.33.80 11541 0
39145af608906d68f059d04b64e8a291 84.129.0.36 8940 0
397460b987ff9e9e360f52136618b2c3 83.38.86.240 3378 0
3ab05f4b0cebd8a2ff689ce8bfb55232 82.238.254.166 3868 0
3acac309140ec0f5e906b6c4ad64d4f4 212.241.66.225 10986 0
3b27d9526ef86fbbf0723ae413723c1d 85.16.150.41 9948 0
3ebecd58d1f7263b087d9159664997c3 80.192.21.44 3751 0
3f614043083f37e5c8487d36b237ea78 124.57.75.101 9934 0
3f755464997b43d4d0826fcbbc8b266f 219.84.26.38 7583 0
3fac223d6c8f833c42d2ae248e206f21 220.72.28.213 4105 0
40bbdfb51868764a24fb96ddf1035f33 70.113.90.243 11327 0
40ce92ad1ac65e7290541e2fa1915bdc 148.160.184.5 4669 0
416297dd4a79f9fe526182de7dbb1e4d 88.73.212.252 11139 1
418b6b00550617e913a3f85cb6043aa4 80.33.124.231 7000 0
41d492e47d76f13e4cb76579123a99e7 84.151.121.46 5687 0
48ae47cc410aa2ae05c1b707744301f4 82.55.119.14 5875 0
48d9789199fc1008b36acb095f9fc787 62.43.160.213 12573 0
48e228897865a53b264f4c57db5312d1 71.107.201.77 4864 0
49ad250210a9842cfce8fb6d8b848cc9 70.244.241.16 8155 0
49c0c086162a51a485c8fc579176ba03 84.148.228.169 12762 0
4a6a309f7d179856cffb9e6e47921c6a 88.22.50.75 6955 0
4abd70a4ceeee66563edf074f152d4ce 89.180.5.149 12492 0
4e2006734147d86a4f7f47199014be4c 70.53.44.52 80 0
4e2540fad59bfabd00ff5b28519b1e61 82.7.244.135 4614 0
4f8e9b83504d589c5591d58e81406e18 123.99.82.220 9992 0
4fd92008c42283607a0ce22e90897696 86.139.46.140 8308 0
4fedf465f25cdf48a66e5dec9d1bdd17 83.6.241.127 6882 0
50bb895dd390303527424e828e5b54be 24.202.246.85 8230 0
51ac71921161bcb6d8b7f8880f46eefc 24.232.81.207 7851 0
51b83c36ac4adb9707fbc719f422cbe8 70.80.1.95 10677 0
51f280b2fb3151daee581811edb3460d 172.183.248.32 10456 0
523fcbe15ed90076457197d9e6750f1e 84.60.0.22 12831 0
531d8c87b014bcf993094c420ed08cfe 74.103.42.209 4111 0
53a75112814d14ecca2d80bf4a05304c 195.4.200.62 8750 0
541e2bb43da70411b0ec9e4a2e3aa0bc 84.125.22.187 3867 0
5abf0e1bb97d86db40d4002d4709bf1a 220.70.254.220 5244 0
5dc4f61ca975687da17ad01d7a06285d 211.201.124.116 6059 0
5efb862926700079413f76ab2c3e79e2 84.126.46.156 5444 0
5f27354bfa0ba9ca2bae6106899cc1a3 83.10.113.23 5410 0
5f5774d921ce06f3f12dfcb40dd73a49 213.185.6.53 4665 0
5f5e5d1d9726f0e0149ffaa75751b05d 82.5.42.25 10301 0
6060d6810bc1d07ba691bbe90b95585c 82.56.93.76 4792 0
654bf80221c0dec4c74b0342c045abc6 83.53.130.173 4267 0
68f38041f26ff4625247ccfa6c9645a2 83.27.138.127 3241 0
6928f1993de7d20516fd1dd489213dbc 216.28.31.253 3620 0
6b14fa18fc8b5ed357133b1a2502a094 82.159.13.169 12286 0
6e21525341966500c9900aa17df49bf3 85.53.89.43 4582 0
6e2614fe5389f95f36093d8723536929 58.234.36.88 5225 1
6e4fc1983cc5fe4a310712bd063b9de4 83.192.115.177 6265 0
6e93bca819d46c7c31164938482e276c 82.49.27.239 8463 0
6eb7eb16713cf56f3d8e1ce368bebdab 87.10.218.82 10301 0
6f0083083a91360160326195a59ea476 85.49.253.102 11583 1
6f414f0a142b802b05932ee4fb810b12 62.80.230.79 6000 0
6f548dd7068651c0ee22bfef37080862 172.141.131.116 3003 0
6f66be33cebe99344cfcf328aa702cfc 82.234.247.90 5596 0
70875fedb3fd7b5e49bcf7fb8323caad 211.213.130.221 4152 0
70bbf8199ffef9edd68041ec954dfca0 218.101.206.9 3322 0
70d009412251fd40d46d5475c33b5b4d 213.213.249.47 4662 0
70dff47cbddf76aa58e13b4124076526 83.42.124.195 9256 0
70ecffa5c424f8169d50922cf0de9267 81.60.195.33 47047 0
7102b6d37c71f4bb249b4b6e20ac4c0d 146.115.56.136 3682 1
712d6dc23289c4c269823f5cb6899e25 84.55.206.118 9228 0
7156fd747d07a6865f5b02a8971bc78a 62.235.24.23 17008 0
7186f68b51e03cfb745b65f8612f5619 83.198.187.23 5864 1
71cc7aa04be67418f10bfbe4adb1bacf 87.5.76.116 5569 0
71dbfe600812a1dd9a841951f68edca0 74.78.2.177 4548 0
723b96cefcde27f6394bb312ddb3bc73 62.42.1.125 5783 0
72f43b744b3170537794cde315148361 84.121.109.184 4175 0
7341869dd42cdd9054e2578b68d53029 81.220.168.54 4985 1
7a1956c5b41f66669c4b74c71742a058 88.23.168.112 9433 0
7a1a6c659c387c936fef2666a1912a32 80.132.101.112 3633 0
7a316a90de24721a9733d86d5321e8f0 84.189.143.14 4394 0
7a50edadd981b09ba88b6f06acef3718 62.15.235.127 7095 0
7a552fce17bb88689f601e531a7e572b 61.64.69.133 6719 0
7a753356842ad958e7057a1fcfd2c083 211.201.93.71 10674 0
7aa5334de0f210a741c5f1354104b3b1 70.252.73.94 10504 0
7b0fc9ae76a8a2727ae54e843bfc3977 80.48.142.10 6162 0
7b31f2b3500d8aa49537625afaac52db 24.67.81.50 9469 0
7b441d23d521023f5a42cc9b594dd92a 83.92.40.199 6164 0
7b4ecae988a881b978f7748088d8e051 67.168.85.39 9273 0
7b65226b440f58717ec06ef5d935bc45 86.208.174.157 7253 0
7b870dabafbd3419fe46740a5cd7fdfc 82.121.160.160 5040 0
7b8879cd08a41d3bf18cb6b00b12e61c 88.24.51.189 11127 0
7b8feeeecb097e817fe35416be73fc56 83.6.232.250 5181 0
7bd571d08d784662e96f7bae7f7f17b3 84.57.158.33 7222 0
7bf2513793a5994b5cad8546f6231e89 84.75.199.138 6082 0
7c4e2c83d7417f42afb85c25d903629f 83.26.117.189 4736 0
7db9b910b7a85739740f86b81321c5e1 83.21.71.92 6174 0
7f51b9d5b5e986f212f34274aff7e4c3 90.154.213.232 59800 0
7f9b3a74b692c7bb5b75e450122d6608 84.77.5.138 55000 0
7fd158be4a5f243789e123ef83d3edf0 82.54.224.155 23830 0
84396c8cf1a26258cba101ea007a49d9 89.228.227.215 8654 0
84c97bd4a9fa479440ee7ef35947ce38 70.82.82.220 5290 0
8ae1f2710e59c77f8266a12d028a8aaf 212.241.64.215 4854 0
900ffda15c6702a93b220738f6f6bccb 84.25.7.56 7746 0
90a87e1fe896621f14416995bd3166af 134.109.132.156 16563 0
90a8d8cb9c9af9c2e76dac650c189d00 83.23.155.182 8914 0
90b399ec0fbe1dab3471e208598d2e7e 84.44.231.141 28583 0
90bcf4c6d0620aa9faa928b6da3b1d17 213.47.112.74 3404 0
9200db48b63d6331b747621d73cfd3ef 125.135.73.172 5510 0
923a3ca51d2c173795ea7980fec03fa4 82.61.70.247 8014 0
92de6303460273a43508296b6237c078 124.61.19.247 3348 0
92f2c65e8d8c984ecae982c8f9cad81e 85.16.150.41 9948 0
945f69d2b0fed4d40c501d18ac1ee335 84.255.205.251 6818 0
95f23a606a61d0eedccfc88c671c9504 210.159.160.154 4188 0
960ed75cdf0e8e55d8bdf2122779006b 80.102.115.141 3915 0
96e1ba371333a60439608576f729617e 84.121.87.1 47047 0
98d02d1b5b7ad14dd13535ed11b51c48 85.53.69.99 10003 0
9d9a51252908efca21b7f5940d5c16ae 82.225.38.240 7821 0
9e31d3105d1be1be100c2dbca9c1cedb 84.183.164.47 7204 0
9e53862ce85a043876da4a5784ad1661 85.140.63.22 7516 0
9edc2fc255ebae8396d622cb15957176 83.112.107.20 8180 1
9ee556648ad3baf1f792aad85e470a7c 219.74.80.197 6601 0
9fa9acb2252a2b65b5bfe032cb434281 81.240.140.43 9703 0
a167a1c1a719856704541c0a1c3e03a9 69.241.238.138 11593 0
a82320cb11db5a34d2e692c5b7ad19d8 88.24.214.34 9534 0
a8967880514d80246b2d940d89907976 220.244.126.14 4668 1
a914e917b7c972d0ddb0f5d654e9aadc 84.122.49.158 12769 0
a91b9efdde30841d46de0b12040b948c 85.155.209.92 5707 0
a9b06362d0342d42b24902cb3d71683d 75.46.112.130 9576 0
acaca1572ac1f9cb9953e55b2729249d 83.35.237.97 4665 0
b2ae365b21df68b48988045b63d4d6fc 189.172.29.169 9874 0
b4bddaca531a4f012d4fa46900f69813 71.9.169.115 5775 0
b5c9a247777ddae8fcfa83cee4ac676e 219.68.29.74 6230 1
b74595669f238061c5b30a518ae33fa5 83.25.82.238 5326 0
c12d62c54b9b343874dc7c8366c2cfb6 189.157.29.196 8705 0
c14322f92dc74c67dc0f864d272fcbf7 69.31.93.178 3471 0
c1604c1d202792be1dca16283d8e9d5a 220.124.224.75 9581 0
c1bef91ee0fac09f1a54d827546e6a0a 87.11.206.239 3959 0
c21d96781cc4c3d2b16407d76f02e944 218.163.184.113 8597 0
c23d212ae659766e8e46438fcfd7dc22 172.180.110.81 3086 0
c285e7b2ab22453496522299b15b3801 59.12.208.195 11267 0
c2bd693941ef041db66d2fe5c1692e59 88.9.121.245 9384 1
c30bdae50cb39cba80ba9ac1a5e1a65a 82.58.189.230 10301 0
c3b0f868f4a9abae3eb7007ab9e2e7c8 87.123.217.188 9030 0
c54a4feeb6618bfe854146f560ad4c47 81.214.39.120 10000 0
c57a5e547d138d1f581221f17e0e272e 86.215.168.93 11447 0
c5be09328b367f7702397cae1711f586 83.53.177.127 11315 0
c5bf7360aa07f31c07830a7370431c8a 61.224.78.247 12595 0
c8618647749d12e3e0995e3f0c556a5b 70.111.26.144 6133 0
c8ac99b1bfc68b615e165129f9b182d5 211.233.2.100 12542 0
db19cb61c98529a91384cf06493be556 210.180.124.29 3246 0
db45d9513bbaf7c3c5bf3e2fffd3012c 83.31.233.170 4471 0
db4b83b43f36bc58ac2685743533a389 65.189.237.244 8044 0
db5dc765e684ba9a610a865800de3416 81.198.131.36 12718 0
db8be48ab25ea2ebff67f3f4312dd204 84.48.235.130 5999 1
db9ffaa55e3712f9cee25b805732ee7b 84.9.76.208 10209 0
dbb5697be82496bb0c46c3c0a2df3110 61.247.84.226 12426 0
dbd681193c024ffce547fdb999ae8339 84.177.92.139 7017 0
dbdd57d92f889e6c84a344d862e23826 84.61.146.49 5751 0
dbe7aec6a2535f0ff4172ca2917c853c 89.78.201.185 6787 0
e119f64361e2022eb2f8e16ab704ac79 70.177.168.143 3893 0
e26c5ade9519477fbfb754e142758641 87.123.168.236 5002 0
e32ad67eef113f2788c5e438932968d8 85.216.39.254 8579 0
e36b23d3b0e5c4e653008aa0fe683941 213.216.232.88 11108 0
e38016ff75ecb0de179162256b5afdb1 83.61.12.146 8020 0
e380e102024f2e299e7ed2ed847c0edc 87.103.45.238 10901 0
e39b3800ff70830b5e158f334197cb7b 222.106.229.231 4474 0
e7025c81e4f11bd9595eb5b12635ad88 68.185.86.95 6842 0
e702aab5bf92f3356d3a26590e736def 74.56.202.29 8029 0
e71f3f7252bc12414cd3fa425f9ae8f3 88.17.127.248 10863 0
e75578be101ba7e8a36ae1072682f5f7 122.34.133.174 9592 0
e75f71fd8126965e32e23f1056056141 81.203.63.82 1756 0
edd8190b83b7ed219536320d4ecb7691 67.83.25.1 4662 0
efaff405e405967bae5ea9264229f386 211.187.188.231 3915 0
efbdc05dc73789a0656b091186ee1089 71.100.59.158 7519 0
f0831665903a6b37e4205ace3621a925 74.114.66.20 3420 0
f0a877163f230e7fc690022d564ad4f5 213.46.9.204 9676 0
f0c1976867bfa84bbd0929ebb1ec8028 74.103.127.57 8805 0
f296f17abd4ccb3ad63a99468eb96060 82.232.173.22 8754 0
f5932b7cee522a08ecb627d47f5b60f5 121.124.152.54 4104 0
f66f25c51aa05ea462694b9055b70193 84.143.27.99 7665 0
f7508519f31549d0018f363e58e4646c 125.224.193.111 10729 0
f8aa2bd3d4b288fbc520ad0f121416d7 213.239.205.232 10755 0
f8ca9f346d4ac702695dbddbf5b7f0bb 90.13.150.216 11403 0
[other_stuff]
blah blah
blah
[blacklisted_nodes]

View File

@ -0,0 +1,328 @@
//
// "$Id: Fl_File_Item.cc,v 1.3 2007-02-18 21:46:49 rmf24 Exp $"
//
// This is hacked up FLTK code, and so is released under
// their licence. (below)
// Copyright 2004-2006 by Robert Fernie.
//
// Please report all bugs and problems to "retroshare@lunamutt.com".
//
/////////////////////////////////////////////////////////////////////
//
// C function type code for the Fast Light Tool Kit (FLTK).
//
// Copyright 1998-2004 by Bill Spitzak and others.
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Library General Public
// License as published by the Free Software Foundation; either
// version 2 of the License, or (at your option) any later version.
//
// 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 "fltk-bugs@fltk.org".
//
#include <FL/Fl.H>
#include "Fl_Tree_Browser.h"
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
//
//extern int i18n_type;
//extern const char* i18n_include;
//extern const char* i18n_function;
//extern const char* i18n_file;
//extern const char* i18n_set;
//extern char i18n_program[];
////////////////////////////////////////////////////////////////
// quick check of any C code for legality, returns an error message
static char buffer[128]; // for error messages
// check a quoted string ending in either " or ' or >:
const char *_q_check(const char * & c, int type) {
for (;;) switch (*c++) {
case '\0':
sprintf(buffer,"missing %c",type);
return buffer;
case '\\':
if (*c) c++;
break;
default:
if (*(c-1) == type) return 0;
}
}
// check normal code, match braces and parenthesis:
const char *_c_check(const char * & c, int type) {
const char *d;
for (;;) switch (*c++) {
case 0:
if (!type) return 0;
sprintf(buffer, "missing %c", type);
return buffer;
case '/':
// Skip comments as needed...
if (*c == '/') {
while (*c != '\n' && *c) c++;
} else if (*c == '*') {
c++;
while ((*c != '*' || c[1] != '/') && *c) c++;
if (*c == '*') c+=2;
else {
return "missing '*/'";
}
}
break;
case '#':
// treat cpp directives as a comment:
while (*c != '\n' && *c) c++;
break;
case '{':
if (type==')') goto UNEXPECTED;
d = _c_check(c,'}');
if (d) return d;
break;
case '(':
d = _c_check(c,')');
if (d) return d;
break;
case '\"':
d = _q_check(c,'\"');
if (d) return d;
break;
case '\'':
d = _q_check(c,'\'');
if (d) return d;
break;
case '}':
case ')':
UNEXPECTED:
if (type == *(c-1)) return 0;
sprintf(buffer, "unexpected %c", *(c-1));
return buffer;
}
}
const char *c_check(const char *c, int type) {
return _c_check(c,type);
}
////////////////////////////////////////////////////////////////
// UNSURE
//#include "function_panel.h"
//#include <FL/fl_ask.H>
////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////
Fl_Item *Fl_Dir_Item::make(Fl_Item *p) {
//std::cerr << "Fl_Dir_Item::make()" << std::endl;
//Fl_Item *p = Fl_Item::current;
while (p && p->is_file()) p = p->parent;
Fl_Dir_Item *o = new Fl_Dir_Item();
o->name("Dir: printf(\"Hello, World!\\n\");");
o->add(p);
o->factory = this;
return o;
}
void file_requestdir(std::string person, std::string dir);
void Fl_Dir_Item::open()
{
//std::cerr << "open Dir..." << std::endl;
Fl_Item *p = NULL;
int ccount = 0;
for(p = next; (p && (p->parent == this));p = p->next)
{
ccount++;
}
//std::cerr << "count:" << ccount << std::endl;
if (ccount == 0) // && (lload > time(NULL) + MIN_RELOAD))
{
// get our path....
std::string fulldir(name());
int lvl = level;
//std::cerr << "level:" << level << std::endl;
//std::cerr << "prev:" << (int) prev << std::endl;
//std::cerr << "prev->parent:" << (int) prev->parent << std::endl;
for(p = prev; (p && p->parent);p = p->prev)
{
//std::cerr << "fulldir srch: " << p -> name() << std::endl;
if (p->level < lvl)
{
std::string subdir(p->name());
fulldir = subdir + "/" + fulldir;
lvl = p->level;
}
}
fulldir = "/" + fulldir;
if (p)
{
Fl_Person_Item *pi;
if ((pi = dynamic_cast<Fl_Person_Item *>(p)))
{
std::string person(pi->person_hash);
file_requestdir(person, fulldir);
//std::cerr << "Requesting: " << person << ":" << fulldir << std::endl;
}
else
{
//std::cerr << "Not PersonItem" << std::endl;
}
}
else
{
//std::cerr << "No Requesting: NULL" << ":" << fulldir << std::endl;
}
}
else
{
for(p = next; (p && (p->parent == this));p = p->next)
{
//std::cerr << "Setting Item Visible" << std::endl;
p -> visible = 1;
//p -> open_ = 1;
}
redraw_browser();
}
}
Fl_Dir_Item Fl_Dir_Item_type;
////////////////////////////////////////////////////////////////
Fl_Item *Fl_File_Item::make(Fl_Item *p) {
//std::cerr << "Fl_File_Item::make()" << std::endl;
while (p && p->is_file()) p = p->parent;
if (!p) {
//std::cerr << "File in no directory!" << std::endl;
return 0;
}
Fl_File_Item *o = new Fl_File_Item();
o->name("file: hello world");
o->add(p);
o->factory = this;
//redraw_browser();
return o;
}
void Fl_File_Item::open()
{
//std::cerr << "open File? How..." << std::endl;
redraw_browser();
}
Fl_File_Item Fl_File_Item_type;
////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////
Fl_Item *Fl_Person_Item::make(Fl_Item *p) {
//std::cerr << "Fl_Person_Item::make()" << std::endl;
//while (p) && p->is_file()) p = p->parent;
//while (p) && p->is_file()) p = p->parent;
p = NULL; // always at top.
Fl_Person_Item *o = new Fl_Person_Item();
o->name("person");
o->add(p);
o->factory = this;
return o;
}
void Fl_Person_Item::open()
{
//std::cerr << "open Person? How..." << std::endl;
Fl_Item *p;
{
for(p = next; (p && (p->parent == this));p = p->next)
{
//std::cerr << "Setting Item Visible" << std::endl;
p -> visible = 1;
}
redraw_browser();
}
}
Fl_Person_Item Fl_Person_Item_type;
////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////
Fl_Item *Fl_Msg_Item::make(Fl_Item *p) {
//std::cerr << "Fl_Msg_Item::make()" << std::endl;
while (p && p->is_file()) p = p->parent;
if (!p) {
//std::cerr << "File in no directory!" << std::endl;
return 0;
}
Fl_Msg_Item *o = new Fl_Msg_Item();
o->name("msg");
o->add(p);
o->factory = this;
//redraw_browser();
return o;
}
void Fl_Msg_Item::open()
{
//std::cerr << "open Msg? How..." << std::endl;
redraw_browser();
}
Fl_Msg_Item Fl_Msg_Item_type;
////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////
const char* Fl_Item::class_name(const int need_nest) const {
Fl_Item* p = parent;
while (p) {
if (p->is_class()) {
// see if we are nested in another class, we must fully-qualify name:
// this is lame but works...
const char* q = 0;
if(need_nest) q=p->class_name(need_nest);
if (q) {
static char s[256];
if (q != s) fltk_strlcpy(s, q, sizeof(s));
fltk_strlcat(s, "::", sizeof(s));
fltk_strlcat(s, p->name(), sizeof(s));
return s;
}
return p->name();
}
p = p->parent;
}
return 0;
}
//
// End of "$Id: Fl_File_Item.cc,v 1.3 2007-02-18 21:46:49 rmf24 Exp $".
//

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,179 @@
/*
* "$Id: Fl_Funky_Browser.h,v 1.4 2007-02-18 21:46:49 rmf24 Exp $"
*
* FltkGUI for RetroShare.
*
* Copyright 2004-2006 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 RS_FL_FUNKY_BROWSER
#define RS_FL_FUNKY_BROWSER
/* My new funky browser.....
*
* - Designed to sort/display a tree brower
* for search results....
*
* First we need the basic interface class that
* must wrap the Data....
*/
#include <string>
#include <list>
#include <vector>
class DisplayData;
class DisplayItem
{
public:
int expander;
int index;
int flags;
std::string txt;
DisplayData *ref;
};
class DisplayData
{
public:
DisplayData() { return;}
virtual ~DisplayData() { return;}
// a couple of functions that do the work.
virtual int ndix() = 0; // Number of Indices.
std::string txt(int col, int width)
{
std::string out1 = txt(col);
int i;
for(i = (signed) out1.length() + 1; i < width; i++)
{
out1 += " ";
}
if ((signed) out1.length() > width)
{
std::string out2;
for(i = 0; i < width; i++)
{
out2 += out1[i];
}
return out2;
}
return out1;
}
virtual std::string txt(int col) = 0;
virtual int cmp(int col, DisplayData *) = 0;
virtual int check(int n, int v = -1) { return -1;}
// return -1 unless have a check box. then return 0/1
// if v != -1 attempt to set value.
};
#include <FL/Fl_Browser.H>
class Fl_Funky_Browser : public Fl_Browser
{
public:
Fl_Funky_Browser(int, int, int, int, const char *, int ncol);
//Fl_Funky_Browser(int ncol);
// add items.
int selectDD(DisplayData *);
int addItem(DisplayData *);
// add in a batch (faster)
int addItemSeries(DisplayData *);
int ItemSeriesDone();
int setTitle(int col, std::string name);
int setCheck(int col); // enables check for the column;
DisplayData *removeItem(int idx = -1);
DisplayData *removeItem(int (*fn)(DisplayData *)); // remove first matching fn.
DisplayData *getSelected();
DisplayData *getCurrentItem();
int checkSort(); // check if update affected order.
int updateList(); // if affected call this.
int toggleCheckBox(int row, int col = -1);
int getCheckState(int row = -1, int col = -1);
// old - don't use
int current_SetCollapsed(bool col) { return 1;}
void clear();
// change browser config.
int setup(std::string opts);
std::string setup();
// Worker Functions.
int drawList();
// Overload the Browser Functions.......
protected:
virtual void item_draw(void* v, int X, int Y, int W, int H) const;
virtual int handle(int event);
private:
int toggleCollapseLevel(int row);
int toggle_TreeSetting(int);
int toggle_ArrowSetting(int);
int selectItems(int row);
int cmp_upto(int lvl, DisplayItem *i1, DisplayItem *i2);
int cmp(DisplayItem *i1, DisplayItem *i2);
// Worker Functions.
int checkIndices();
int SortList();
int RePopulate();
// drag and ticks mouse stuff
int handle_push(int x, int y);
bool dragging();
int handle_release(int x, int y);
int ncols;
std::list<DisplayItem *> dlist;
std::vector<int> sort_order;
std::vector<int> sort_direction;
std::vector<int> tree;
std::vector<int> display_order;
std::vector<int> widths;
std::vector<std::string> titles;
std::vector<bool> check_box;
int *fl_widths;
int ntrees;
int drag_mode;
int drag_column; // which column
int drag_x, drag_y;
bool one_select;
};
#endif

View File

@ -0,0 +1,752 @@
//
// "$Id: Fl_Tree_Browser.cc,v 1.3 2007-02-18 21:46:49 rmf24 Exp $"
//
// This is hacked up FLTK code, and so is released under
// their licence. (below)
// Copyright 2004-2006 by Robert Fernie.
//
// Please report all bugs and problems to "retroshare@lunamutt.com".
//
/////////////////////////////////////////////////////////////////////
//
// Widget type code for the Fast Light Tool Kit (FLTK).
//
// Each object described by Fluid is one of these objects. They
// are all stored in a double-linked list.
//
// They "type" of the object is covered by the virtual functions.
// There will probably be a lot of these virtual functions.
//
// The type browser is also a list of these objects, but they
// are "factory" instances, not "real" ones. These objects exist
// only so the "make" method can be called on them. They are
// not in the linked list and are not written to files or
// copied or otherwise examined.
//
// Copyright 1998-2004 by Bill Spitzak and others.
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Library General Public
// License as published by the Free Software Foundation; either
// version 2 of the License, or (at your option) any later version.
//
// 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 "fltk-bugs@fltk.org".
//
#include <FL/Fl.H>
#include <FL/Fl_Browser_.H>
#include <FL/fl_draw.H>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <iostream>
#include "Fl_Tree_Browser.h"
#include <FL/Fl_Pixmap.H>
//static Fl_Pixmap lock_pixmap(lock_xpm);
//static Fl_Pixmap unlock_pixmap(unlock_xpm);
void selection_changed(Fl_Item *p);
size_t fltk_strlcpy(char *dst, const char *src, size_t size);
const char* subclassname(Fl_Item *i) { return i -> type_name(); }
////////////////////////////////////////////////////////////////
class Fl_Tree_Browser : public Fl_Browser_ {
friend class Fl_Item;
// required routines for Fl_Browser_ subclass:
void *item_first() const ;
void *item_next(void *) const ;
void *item_prev(void *) const ;
int item_selected(void *) const ;
void item_select(void *,int);
int item_width(void *) const ;
int item_height(void *) const ;
void item_draw(void *,int,int,int,int) const ;
int incr_height() const ;
public:
int handle(int);
void callback();
Fl_Tree_Browser(int,int,int,int,const char * =0);
};
static Fl_Tree_Browser *tree_browser;
Fl_Widget *make_tree_browser(int x,int y,int w,int h, const char *) {
return (tree_browser = new Fl_Tree_Browser(x,y,w,h));
}
void select(Fl_Item *o, int v) {
tree_browser->select(o,v,1);
// Fl_Item::current = o;
}
void select_only(Fl_Item *o) {
tree_browser->select_only(o,1);
}
void deselect() {
tree_browser->deselect();
//Fl_Item::current = 0; // this breaks the paste & merge functions
}
Fl_Item *Fl_Item::first;
Fl_Item *Fl_Item::last;
Fl_Item *Fl_Item::current;
static void Fl_Tree_Browser_callback(Fl_Widget *o,void *) {
((Fl_Tree_Browser *)o)->callback();
}
Fl_Tree_Browser::Fl_Tree_Browser(int X,int Y,int W,int H,const char*l)
: Fl_Browser_(X,Y,W,H,l) {
type(FL_MULTI_BROWSER);
Fl_Widget::callback(Fl_Tree_Browser_callback);
when(FL_WHEN_RELEASE);
}
void *Fl_Tree_Browser::item_first() const {return Fl_Item::first;}
void *Fl_Tree_Browser::item_next(void *l) const {return ((Fl_Item*)l)->next;}
void *Fl_Tree_Browser::item_prev(void *l) const {return ((Fl_Item*)l)->prev;}
int Fl_Tree_Browser::item_selected(void *l) const {return ((Fl_Item*)l)->new_selected;}
void Fl_Tree_Browser::item_select(void *l,int v) {((Fl_Item*)l)->new_selected = v;}
int Fl_Tree_Browser::item_height(void *l) const {
return ((Fl_Item *)l)->visible ? textsize()+2 : 0;
}
int Fl_Tree_Browser::incr_height() const {return textsize()+2;}
static Fl_Item* pushedtitle;
// Generate a descriptive text for this item, to put in browser & window titles
const char* Fl_Item::title() {
const char* c = name(); if (c) return c;
return type_name();
}
extern const char* subclassname(Fl_Item*);
void Fl_Tree_Browser::item_draw(void *v, int X, int Y, int, int) const {
Fl_Item *l = (Fl_Item *)v;
X += 3 + 18 + l->level * 12;
if (l->new_selected) fl_color(fl_contrast(FL_BLACK,FL_SELECTION_COLOR));
else fl_color(FL_BLACK);
Fl_Pixmap *pm = NULL; //pixmap[l->pixmapID()];
if (pm) pm->draw(X-18, Y);
//if (l->is_public() == 0) lock_pixmap.draw(X - 17, Y);
//else if (l->is_public() > 0) ; //unlock_pixmap.draw(X - 17, Y);
if (l->is_parent()) {
if (!l->next || l->next->level <= l->level) {
if (l->open_!=(l==pushedtitle)) {
fl_loop(X,Y+7,X+5,Y+12,X+10,Y+7);
} else {
fl_loop(X+2,Y+2,X+7,Y+7,X+2,Y+12);
}
} else {
if (l->open_!=(l==pushedtitle)) {
fl_polygon(X,Y+7,X+5,Y+12,X+10,Y+7);
} else {
fl_polygon(X+2,Y+2,X+7,Y+7,X+2,Y+12);
}
}
X += 10;
}
if (l->is_widget() || l->is_class()) {
//if (l->is_widget()) {
const char* c = subclassname(l);
if (!strncmp(c,"Fl_",3)) c += 3;
fl_font(textfont(), textsize());
fl_draw(c, X, Y+13);
X += int(fl_width(c)+fl_width('n'));
c = l->name();
if (c) {
fl_font(textfont()|FL_BOLD, textsize());
fl_draw(c, X, Y+13);
} else if ((c=l->label())) {
char buf[50]; char* p = buf;
*p++ = '"';
for (int i = 20; i--;) {
if (! (*c & -32)) break;
*p++ = *c++;
}
if (*c) {strcpy(p,"..."); p+=3;}
*p++ = '"';
*p = 0;
fl_draw(buf, X, Y+13);
}
} else {
const char* c = l->title();
char buf[60]; char* p = buf;
for (int i = 55; i--;) {
if (! (*c & -32)) break;
*p++ = *c++;
}
if (*c) {strcpy(p,"..."); p+=3;}
*p = 0;
fl_font(textfont() | (l->is_code_block() && (l->level==0 || l->parent->is_class())?0:FL_BOLD), textsize());
fl_draw(buf, X, Y+13);
}
}
int Fl_Tree_Browser::item_width(void *v) const {
Fl_Item *l = (Fl_Item *)v;
if (!l->visible) return 0;
int W = 3 + 16 + 18 + l->level*10;
if (l->is_parent()) W += 10;
if (l->is_widget() || l->is_class()) {
const char* c = l->type_name();
if (!strncmp(c,"Fl_",3)) c += 3;
fl_font(textfont(), textsize());
W += int(fl_width(c) + fl_width('n'));
c = l->name();
if (c) {
fl_font(textfont()|FL_BOLD, textsize());
W += int(fl_width(c));
} else if ((c=l->label())) {
char buf[50]; char* p = buf;
*p++ = '"';
for (int i = 20; i--;) {
if (! (*c & -32)) break;
*p++ = *c++;
}
if (*c) {strcpy(p,"..."); p+=3;}
*p++ = '"';
*p = 0;
W += int(fl_width(buf));
}
} else {
const char* c = l->title();
char buf[60]; char* p = buf;
for (int i = 55; i--;) {
if (! (*c & -32)) break;
*p++ = *c++;
}
if (*c) {strcpy(p,"..."); p+=3;}
*p = 0;
fl_font(textfont() | (l->is_code_block() && (l->level==0 || l->parent->is_class())?0:FL_BOLD), textsize());
W += int(fl_width(buf));
}
return W;
}
void redraw_browser() {
tree_browser->redraw();
}
void Fl_Tree_Browser::callback() {
selection_changed((Fl_Item*)selection());
}
int Fl_Tree_Browser::handle(int e) {
static Fl_Item *title;
Fl_Item *l;
int X,Y,W,H; bbox(X,Y,W,H);
switch (e) {
case FL_PUSH:
if (!Fl::event_inside(X,Y,W,H)) break;
l = (Fl_Item*)find_item(Fl::event_y());
if (l) {
X += 12*l->level + 18 - hposition();
if (l->is_parent() && Fl::event_x()>X && Fl::event_x()<X+13) {
title = pushedtitle = l;
redraw_line(l);
return 1;
}
}
break;
case FL_DRAG:
if (!title) break;
l = (Fl_Item*)find_item(Fl::event_y());
if (l) {
X += 12*l->level + 18 - hposition();
if (l->is_parent() && Fl::event_x()>X && Fl::event_x()<X+13) ;
else l = 0;
}
if (l != pushedtitle) {
if (pushedtitle) redraw_line(pushedtitle);
if (l) redraw_line(l);
pushedtitle = l;
}
return 1;
case FL_RELEASE:
if (!title) {
l = (Fl_Item*)find_item(Fl::event_y());
if (l && l->new_selected && (Fl::event_clicks() || Fl::event_state(FL_CTRL)))
l->open();
break;
}
l = pushedtitle;
title = pushedtitle = 0;
if (l) {
if (l->open_) {
l->open_ = 0;
for (Fl_Item*k = l->next; k&&k->level>l->level; k = k->next)
k->visible = 0;
} else {
l->open_ = 1;
for (Fl_Item*k=l->next; k&&k->level>l->level;) {
k->visible = 1;
if (k->is_parent() && !k->open_) {
Fl_Item *j;
for (j = k->next; j && j->level>k->level; j = j->next);
k = j;
} else
k = k->next;
}
}
redraw();
}
return 1;
}
return Fl_Browser_::handle(e);
}
Fl_Item::Fl_Item() {
factory = 0;
parent = 0;
next = prev = 0;
selected = new_selected = 0;
visible = 0;
name_ = 0;
label_ = 0;
user_data_ = 0;
user_data_type_ = 0;
callback_ = 0;
rtti = 0;
level = 0;
}
static void fixvisible(Fl_Item *p) {
Fl_Item *t = p;
for (;;) {
if (t->parent) t->visible = t->parent->visible && t->parent->open_;
else t->visible = 1;
t = t->next;
if (!t || t->level <= p->level) break;
}
}
// turn a click at x,y on this into the actual picked object:
Fl_Item* Fl_Item::click_test(int,int) {return 0;}
void Fl_Item::add_child(Fl_Item*, Fl_Item*) {}
void Fl_Item::move_child(Fl_Item*, Fl_Item*) {}
void Fl_Item::remove_child(Fl_Item*) {}
// add a list of widgets as a new child of p:
void Fl_Item::add(Fl_Item *p) {
if (p && parent == p) return;
parent = p;
Fl_Item *end = this;
while (end->next) end = end->next;
Fl_Item *q;
int newlevel;
if (p) {
for (q = p->next; q && q->level > p->level; q = q->next);
newlevel = p->level+1;
} else {
q = 0;
newlevel = 0;
}
for (Fl_Item *t = this->next; t; t = t->next) t->level += (newlevel-level);
//std::cerr << "add -> level = " << newlevel << std::endl;
level = newlevel;
if (q) {
prev = q->prev;
prev->next = this;
q->prev = end;
end->next = q;
} else if (first) {
prev = last;
prev->next = this;
end->next = 0;
last = end;
} else {
first = this;
last = end;
prev = end->next = 0;
}
if (p) p->add_child(this,0);
open_ = 1;
fixvisible(this);
//modflag = 1;
tree_browser->redraw();
}
// add to a parent before another widget:
void Fl_Item::insert(Fl_Item *g) {
Fl_Item *end = this;
while (end->next) end = end->next;
parent = g->parent;
int newlevel = g->level;
visible = g->visible;
for (Fl_Item *t = this->next; t; t = t->next) t->level += newlevel-level;
level = newlevel;
prev = g->prev;
if (prev) prev->next = this; else first = this;
end->next = g;
g->prev = end;
fixvisible(this);
if (parent) parent->add_child(this, g);
tree_browser->redraw();
}
// Return message number for I18N...
int
Fl_Item::msgnum() {
int count;
Fl_Item *p;
for (count = 0, p = this; p;) {
if (p->label()) count ++;
//if (p != this && p->is_widget() && ((Fl_Widget_Type *)p)->tooltip()) count ++;
if (p != this && p->is_widget()) count ++;
if (p->prev) p = p->prev;
else p = p->parent;
}
return count;
}
// delete from parent:
Fl_Item *Fl_Item::remove() {
Fl_Item *end = this;
for (;;) {
if (!end->next || end->next->level <= level) break;
end = end->next;
}
if (prev) prev->next = end->next;
else first = end->next;
if (end->next) end->next->prev = prev;
else last = prev;
Fl_Item *r = end->next;
prev = end->next = 0;
if (parent) parent->remove_child(this);
parent = 0;
tree_browser->redraw();
selection_changed(0);
return r;
}
// update a string member:
int storestring(const char *n, const char * & p, int nostrip) {
if (n == p) return 0;
int length = 0;
if (n) { // see if blank, strip leading & trailing blanks
if (!nostrip) while (isspace(*n)) n++;
const char *e = n + strlen(n);
if (!nostrip) while (e > n && isspace(*(e-1))) e--;
length = e-n;
if (!length) n = 0;
}
if (n == p) return 0;
if (n && p && !strncmp(n,p,length) && !p[length]) return 0;
if (p) free((void *)p);
if (!n || !*n) {
p = 0;
} else {
char *q = (char *)malloc(length+1);
fltk_strlcpy(q,n,length+1);
p = q;
}
//modflag = 1;
return 1;
}
void Fl_Item::name(const char *n) {
if (storestring(n,name_)) {
if (visible) tree_browser->redraw();
}
}
void Fl_Item::label(const char *n) {
if (storestring(n,label_,1)) {
setlabel(label_);
if (visible && !name_) tree_browser->redraw();
}
}
void Fl_Item::callback(const char *n) {
storestring(n,callback_);
}
void Fl_Item::user_data(const char *n) {
storestring(n,user_data_);
}
void Fl_Item::user_data_type(const char *n) {
storestring(n,user_data_type_);
}
void Fl_Item::open() {
printf("Open of '%s' is not yet implemented\n",type_name());
}
void Fl_Item::setlabel(const char *) {}
Fl_Item::~Fl_Item() {
// warning: destructor only works for widgets that have been add()ed.
if (tree_browser) tree_browser->deleting(this);
if (prev) prev->next = next; else first = next;
if (next) next->prev = prev; else last = prev;
if (current == this) current = 0;
//modflag = 1;
if (parent) parent->remove_child(this);
}
int Fl_Item::is_parent() const {return 0;}
int Fl_Item::is_widget() const {return 0;}
int Fl_Item::is_valuator() const {return 0;}
int Fl_Item::is_button() const {return 0;}
int Fl_Item::is_menu_item() const {return 0;}
int Fl_Item::is_menu_button() const {return 0;}
int Fl_Item::is_group() const {return 0;}
int Fl_Item::is_window() const {return 0;}
int Fl_Item::is_code_block() const {return 0;}
int Fl_Item::is_decl_block() const {return 0;}
int Fl_Item::is_class() const {return 1;}
int Fl_Item::is_public() const {return 1;}
int Fl_Item::is_file() const {return 0;}
int Fl_File_Item::is_public()const { return 1; }
int Fl_Dir_Item::is_public()const { return 1; }
int Fl_File_Item::is_parent() const {return 0;}
int Fl_Dir_Item::is_parent() const {return 1;}
int Fl_Person_Item::is_public()const { return 1; }
int Fl_Person_Item::is_parent() const {return 1;}
int Fl_Msg_Item::is_public()const { return 1; }
int Fl_Msg_Item::is_parent() const {return 0;}
////////////////////////////////////////////////////////////////
Fl_Item *in_this_only; // set if menu popped-up in window
void select_all_cb(Fl_Widget *,void *) {
Fl_Item *p = Fl_Item::current ? Fl_Item::current->parent : 0;
if (in_this_only) {
Fl_Item *t = p;
for (; t && t != in_this_only; t = t->parent);
if (t != in_this_only) p = in_this_only;
}
for (;;) {
if (p) {
int foundany = 0;
for (Fl_Item *t = p->next; t && t->level>p->level; t = t->next) {
if (!t->new_selected) {tree_browser->select(t,1,0); foundany = 1;}
}
if (foundany) break;
p = p->parent;
} else {
for (Fl_Item *t = Fl_Item::first; t; t = t->next)
tree_browser->select(t,1,0);
break;
}
}
selection_changed(p);
}
// rmfern - removed static....
void delete_children(Fl_Item *p) {
Fl_Item *f;
for (f = p; f && f->next && f->next->level > p->level; f = f->next);
for (; f != p; ) {
Fl_Item *g = f->prev;
delete f;
f = g;
}
}
void delete_all(int selected_only) {
for (Fl_Item *f = Fl_Item::first; f;) {
if (f->selected || !selected_only) {
delete_children(f);
Fl_Item *g = f->next;
delete f;
f = g;
} else f = f->next;
}
//if(!selected_only) include_H_from_C=1;
selection_changed(0);
}
// move f (and it's children) into list before g:
// returns pointer to whatever is after f & children
void Fl_Item::move_before(Fl_Item* g) {
if (level != g->level) printf("move_before levels don't match! %d %d\n",
level, g->level);
Fl_Item* n;
for (n = next; n && n->level > level; n = n->next);
if (n == g) return;
Fl_Item *l = n ? n->prev : Fl_Item::last;
prev->next = n;
if (n) n->prev = prev; else Fl_Item::last = prev;
prev = g->prev;
l->next = g;
if (prev) prev->next = this; else Fl_Item::first = this;
g->prev = l;
if (parent) parent->move_child(this,g);
tree_browser->redraw();
}
// move selected widgets in their parent's list:
void earlier_cb(Fl_Widget*,void*) {
Fl_Item *f;
for (f = Fl_Item::first; f; ) {
Fl_Item* nxt = f->next;
if (f->selected) {
Fl_Item* g;
for (g = f->prev; g && g->level > f->level; g = g->prev);
if (g && g->level == f->level && !g->selected) f->move_before(g);
}
f = nxt;
}
}
void later_cb(Fl_Widget*,void*) {
Fl_Item *f;
for (f = Fl_Item::last; f; ) {
Fl_Item* prv = f->prev;
if (f->selected) {
Fl_Item* g;
for (g = f->next; g && g->level > f->level; g = g->next);
if (g && g->level == f->level && !g->selected) g->move_before(f);
}
f = prv;
}
}
// FROM Fl_Widget_Type.cxx
// Called when ui changes what objects are selected:
// p is selected object, null for all deletions (we must throw away
// old panel in that case, as the object may no longer exist)
void selection_changed(Fl_Item *p) {
// store all changes to the current selected objects:
//if (p && the_panel && the_panel->visible()) {
if (p) {
//set_cb(0,0);
// if there was an error, we try to leave the selected set unchanged:
// if (haderror) {
// Fl_Item *q = 0;
// for (Fl_Item *o = Fl_Item::first; o; o = o->next) {
// o->new_selected = o->selected;
// if (!q && o->selected) q = o;
// }
// if (!p || !p->selected) p = q;
// Fl_Item::current = p;
// redraw_browser();
// return;
// }
}
// update the selected flags to new set:
Fl_Item *q = 0;
for (Fl_Item *o = Fl_Item::first; o; o = o->next) {
o->selected = o->new_selected;
if (!q && o->selected) q = o;
}
if (!p || !p->selected) p = q;
Fl_Item::current = p;
}
/*
* 'fltk_strlcpy()' - Safely copy two strings. (BSD style)
* Taken from fltk/src/flstring.c
*/
size_t /* O - Length of string */
fltk_strlcpy(char *dst, /* O - Destination string */
const char *src, /* I - Source string */
size_t size) { /* I - Size of destination string buffer */
size_t srclen; /* Length of source string */
/*
* Figure out how much room is needed...
*/
size --;
srclen = strlen(src);
/*
* Copy the appropriate amount...
*/
if (srclen > size) srclen = size;
memcpy(dst, src, srclen);
dst[srclen] = '\0';
return (srclen);
}
size_t /* O - Length of string */
fltk_strlcat(char *dst, /* O - Destination string */
const char *src, /* I - Source string */
size_t size) { /* I - Size of destination string buffer */
size_t srclen; /* Length of source string */
size_t dstlen; /* Length of destination string */
/*
* * Figure out how much room is left...
* */
dstlen = strlen(dst);
size -= dstlen + 1;
if (!size) return (dstlen); /* No room, return immediately... */
/*
* * Figure out how much room is needed...
* */
srclen = strlen(src);
/*
* * Copy the appropriate amount...
* */
if (srclen > size) srclen = size;
memcpy(dst + dstlen, src, srclen);
dst[dstlen + srclen] = '\0';
return (dstlen + srclen);
}
//
// End of "$Id: Fl_Tree_Browser.cc,v 1.3 2007-02-18 21:46:49 rmf24 Exp $".
//

View File

@ -0,0 +1,210 @@
//
// "$Id: Fl_Tree_Browser.h,v 1.2 2007-02-18 21:46:49 rmf24 Exp $"
//
// This is hacked up FLTK code, and so is released under
// their licence. (below)
// Copyright 2004-2006 by Robert Fernie.
//
// Please report all bugs and problems to "retroshare@lunamutt.com".
//
///////////////////////////////////////////////////////////////////
//
// Widget type header file for the Fast Light Tool Kit (FLTK).
//
// Each object described by Fluid is one of these objects. They
// are all stored in a double-linked list.
//
// There is also a single "factory" instance of each type of this.
// The method "make()" is called on this factory to create a new
// instance of this object. It could also have a "copy()" function,
// but it was easier to implement this by using the file read/write
// that is needed to save the setup anyways.
// Copyright 1998-2004 by Bill Spitzak and others.
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Library General Public
// License as published by the Free Software Foundation; either
// version 2 of the License, or (at your option) any later version.
//
// 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 "fltk-bugs@fltk.org".
//
#include <FL/Fl_Widget.H>
#include <FL/Fl_Menu.H>
#include <stdlib.h>
#include <string>
size_t fltk_strlcpy(char *dst, const char *src, size_t size);
size_t fltk_strlcat(char *dst, const char *src, size_t size);
Fl_Widget *make_tree_browser(int,int,int,int,const char *l=0);
void redraw_browser();
void delete_all(int selected_only);
class Fl_Item {
friend class Tree_Browser;
friend Fl_Widget *make_tree_browser(int,int,int,int,const char *l);
friend class Fl_Window_Type;
virtual void setlabel(const char *); // virtual part of label(char*)
protected:
Fl_Item();
const char *name_;
const char *label_;
const char *callback_;
const char *user_data_;
const char *user_data_type_;
public: // things that should not be public:
Fl_Item *parent; // parent, which is previous in list
char new_selected; // browser highlight
char selected; // copied here by selection_changed()
char open_; // state of triangle in browser
char visible; // true if all parents are open
char rtti; // hack because I have no rtti, this is 0 for base class
int level; // number of parents over this
static Fl_Item *first, *last; // linked list of all objects
Fl_Item *next, *prev; // linked list of all objects
Fl_Item *factory;
const char *callback_name();
public:
virtual ~Fl_Item();
virtual Fl_Item *make(Fl_Item *p) = 0;
void add(Fl_Item *parent); // add as new child
void insert(Fl_Item *n); // insert into list before n
Fl_Item* remove(); // remove from list
void move_before(Fl_Item*); // move before a sibling
virtual const char *title(); // string for browser
virtual const char *type_name() = 0; // type for code output
const char *name() const {return name_;}
void name(const char *);
const char *label() const {return label_;}
void label(const char *);
const char *callback() const {return callback_;}
void callback(const char *);
const char *user_data() const {return user_data_;}
void user_data(const char *);
const char *user_data_type() const {return user_data_type_;}
void user_data_type(const char *);
virtual Fl_Item* click_test(int,int);
virtual void add_child(Fl_Item*, Fl_Item* beforethis);
virtual void move_child(Fl_Item*, Fl_Item* beforethis);
virtual void remove_child(Fl_Item*);
static Fl_Item *current; // most recently picked object
virtual void open(); // what happens when you double-click
// get message number for I18N
int msgnum();
// fake rtti:
virtual int is_parent() const;
virtual int is_widget() const;
virtual int is_button() const;
virtual int is_valuator() const;
virtual int is_menu_item() const;
virtual int is_menu_button() const;
virtual int is_public() const;
virtual int is_group() const;
virtual int is_window() const;
virtual int is_code_block() const;
virtual int is_decl_block() const;
virtual int is_class() const;
virtual int is_file() const;
virtual int pixmapID() { return 0; }
const char* class_name(const int need_nest) const;
};
class Fl_Dir_Item : public Fl_Item {
public:
Fl_Item *make(Fl_Item *p);
void open();
virtual const char *type_name() {return "dir";}
int is_file() const {return 0;}
int is_parent() const; /* {return 1;} */
int pixmapID() { return 8; }
virtual int is_public() const;
};
extern Fl_Dir_Item Fl_Dir_Item_type;
class Fl_File_Item : public Fl_Item {
public:
int size;
std::string filename;
Fl_Item *make(Fl_Item *p);
void open();
virtual const char *type_name() {return "file";}
int is_file() const {return 1;}
int is_parent() const; /* {return 0;} */
virtual int is_public() const;
int pixmapID() { return 9; }
};
extern Fl_File_Item Fl_File_Item_type;
class Fl_Person_Item : public Fl_Item {
public:
Fl_Item *make(Fl_Item *p);
void open();
virtual const char *type_name() {return "Person:";}
int is_file() const {return 0;}
int is_parent() const; /* {return 1;} */
virtual int is_public() const;
int pixmapID() { return 1; }
std::string person_hash;
};
extern Fl_Person_Item Fl_Person_Item_type;
class Fl_Msg_Item : public Fl_Item {
public:
Fl_Item *make(Fl_Item *p);
void open();
virtual const char *type_name() {return "msg";}
int is_file() const {return 0;}
int is_parent() const; /* {return 1;} */
virtual int is_public() const;
int pixmapID() { return 2; }
};
extern Fl_Msg_Item Fl_Msg_Item_type;
// bonus helper function.
void delete_children(Fl_Item *p);
// replace a string pointer with new value, strips leading/trailing blanks:
int storestring(const char *n, const char * & p, int nostrip=0);
//
// End of "$Id: Fl_Tree_Browser.h,v 1.2 2007-02-18 21:46:49 rmf24 Exp $".
//

View File

@ -0,0 +1,39 @@
RS_TOP_DIR = ..
include ../make.opt
STRIP=strip
OBJ = fltkserver.o guitab.o Fl_Funky_Browser.o pqibrowseitem.o pqistrings.o \
Fl_Tree_Browser.o Fl_File_Item.o fltkpqi.o alertbox.o
WIN_OBJ = retrotray.o
# add in windows objs
ifeq ($(OS),Linux)
else
OBJ += $(WIN_OBJ)
endif
all : $(OBJ) RetroShare
RetroShare : $(OBJ)
$(CC) $(CFLAGS) -static -o RetroShare $(OBJ) -lfltk $(RSLIBS)
# $(STRIP) -s RetroShare.exe
# $(STRIP) -s RetroShare
.cc.o:
$(CC) $(CFLAGS) -c $<
clean:
-$(RM) $(OBJ)
clobber: clean
-$(RM) RetroShare

View File

@ -0,0 +1,197 @@
/*
* "$Id: alertbox.cc,v 1.3 2007-02-18 21:46:49 rmf24 Exp $"
*
* FltkGUI for RetroShare.
*
* Copyright 2004-2006 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 "fltkgui/pqistrings.h"
#include "fltkgui/alertbox.h"
#include <sstream>
alertBox::alertBox(Fl_Window *w, Fl_Text_Display *box)
:showThreshold(2), alert_win(w), alert_box(box),
maxMessages(40)
{
/* can't call virtual fn here! */
alertBox::loadInitMsg();
return;
}
alertBox::~alertBox()
{
/* clean up msgs */
return;
}
int alertBox::loadInitMsg()
{
sendMsg(0, 10,"Welcome to RetroShare ----", "");
return 1;
}
int chatterBox::loadInitMsg()
{
sendMsg(0, 10,"", "");
sendMsg(0, 10,"\tThis is your Universal ChatterBox Window", "");
sendMsg(0, 10,"", "");
sendMsg(0, 10,"\tYou can use it to chat with everyone", "");
sendMsg(0, 10,"\tthat is online at this moment", "");
sendMsg(0, 10,"", "");
sendMsg(0, 10,"\tSometimes the conversations can seem", "");
sendMsg(0, 10,"\tweird and wonderful, if you're not", "");
sendMsg(0, 10,"\tconnected all the same people.", "");
sendMsg(0, 10,"", "");
sendMsg(0, 10,"\tIt is a bit of an experiment, so", "");
sendMsg(0, 10,"\tlet me know if you enjoy it or hate it!", "");
sendMsg(0, 10,"", "");
sendMsg(0, 10,"Note. Your ChatterBox only pop up once, when the", "");
sendMsg(0, 10,"first message is received. After that it'll leave", "");
sendMsg(0, 10,"you in peace. Use the \"Chat\" Button on the main", "");
sendMsg(0, 10,"window to open and close your ChatterBox", "");
sendMsg(0, 10,"", "");
sendMsg(0, 10,"", "");
return 1;
}
int alertBox::sendMsg(int type, int severity,
std::string msg, std::string source)
{
alertMsg newal;
newal.epoch = time(NULL);
newal.type = type;
newal.severity = severity;
newal.msg = msg;
newal.source = source;
msgs.push_front(newal);
if (msgs.size() > (unsigned) maxMessages)
{
msgs.pop_back();
}
displayMsgs();
showMsgs(severity);
return 1;
}
int alertBox::showMsgs(int severity)
{
if (severity <= showThreshold)
{
alert_win -> show();
return 1;
}
return 0;
}
/* chatterbox will only pop up for the first chat */
int chatterBox::showMsgs(int severity)
{
if ((firstMsg) && (alertBox::showMsgs(severity)))
{
firstMsg = false;
return 1;
}
return 0;
}
void alertBox::displayMsgs()
{
std::ostringstream msg;
std::deque<alertMsg>::reverse_iterator it;
for(it = msgs.rbegin(); it != msgs.rend(); it++)
{
if (it -> severity <= showThreshold)
{
msg << "----------------->>>> ALERT: ";
msg << timeFormat(it -> epoch, TIME_FORMAT_NORMAL);
msg << std::endl;
msg << std::endl;
msg << it -> msg << std::endl;
msg << std::endl;
msg << "<<<<----------------";
msg << std::endl;
msg << std::endl;
}
else
{
msg << timeFormat(it -> epoch, TIME_FORMAT_NORMAL);
msg << ":" << it -> msg << std::endl;
msg << std::endl;
}
}
Fl_Text_Buffer *buf = alert_box -> buffer();
buf -> text(msg.str().c_str());
int c = buf -> length();
int lines = buf -> count_lines(0, c-1);
// want to scroll to the bottom.
alert_box -> scroll(lines, 0);
}
void chatterBox::displayMsgs()
{
std::ostringstream msg;
std::deque<alertMsg>::reverse_iterator it;
std::string lsrc = "";
int lts = 0;
for(it = msgs.rbegin(); it != msgs.rend(); it++)
{
if ((it->epoch-lts > 30) || // more than 30 seconds.
(it->source != lsrc)) // not same source
{
msg << "\t\t\t\t\t\t[";
msg << it->source;
msg << " @ ";
msg << timeFormat(it -> epoch, TIME_FORMAT_NORMAL);
msg << "]";
msg << std::endl;
}
msg << it -> msg;
msg << std::endl;
/* store last one */
lts = it->epoch;
lsrc = it->source;
}
Fl_Text_Buffer *buf = alert_box -> buffer();
buf -> text(msg.str().c_str());
int c = buf -> length();
int lines = buf -> count_lines(0, c-1);
// want to scroll to the bottom.
alert_box -> scroll(lines, 0);
}

View File

@ -0,0 +1,91 @@
/*
* "$Id: alertbox.h,v 1.4 2007-02-18 21:46:49 rmf24 Exp $"
*
* FltkGUI for RetroShare.
*
* Copyright 2004-2006 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 RETROSHARE_ALERT_H
#define RETROSHARE_ALERT_H
#include <string>
#include <deque>
#include <FL/Fl_Window.H>
#include <FL/Fl_Text_Display.H>
class alertMsg
{
public:
int epoch;
int type;
int severity;
std::string msg;
std::string source;
};
class alertBox
{
public:
alertBox(Fl_Window *w, Fl_Text_Display *box);
virtual ~alertBox();
int sendMsg(int type, int severity,
std::string msg, std::string source);
protected:
int loadInitMsg();
virtual void displayMsgs();
virtual int showMsgs(int severity);
int showThreshold; // At what severity we show ourselves.
Fl_Window *alert_win;
Fl_Text_Display *alert_box;
int maxMessages;
std::deque<alertMsg> msgs;
};
class chatterBox: public alertBox
{
public:
chatterBox(Fl_Window *w, Fl_Text_Display *box)
:alertBox(w, box), firstMsg(true)
{
chatterBox::loadInitMsg();
return;
}
protected:
int loadInitMsg();
virtual void displayMsgs();
virtual int showMsgs(int severity);
private:
bool firstMsg;
};
#endif

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,222 @@
/*
* "$Id: fltkserver.h,v 1.15 2007-02-18 21:46:49 rmf24 Exp $"
*
* FltkGUI for RetroShare.
*
* Copyright 2004-2006 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 MRK_FLTK_PQI_INTERFACE
#define MRK_FLTK_PQI_INTERFACE
#include "server/filedexserver.h"
#include "pqi/pqipersongrp.h"
#include "pqi/pqissl.h"
#include "fltkgui/Fl_Funky_Browser.h"
#include "fltkgui/pqistrings.h"
#include "fltkgui/alertbox.h"
#include "fltkgui/guitab.h"
#include "pqi/p3disc.h"
class fltkserver
{
public:
fltkserver();
~fltkserver();
int init();
int run();
// setup pqissl
int setuppqissl(filedexserver *fd, pqipersongrp *ph, sslroot *r, UserInterface *u);
int addAutoDiscovery(p3disc *a) {ad = a; return 1; }
int addAlerts(alertBox *msg, alertBox *chat);
int ownchatmsg(std::string);
int chatmsg(std::string msg, std::string source);
int alertmsg(int type, int sev, std::string msg, std::string source);
// flags to indicate if something needs updating.
// This are public advisory flags that
// can be altered by callbacks.
bool cert_list_ok;
bool cert_item_ok;
bool cert_neighbour_list_ok;
bool cert_neighbour_item_ok;
bool search_list_ok;
bool result_list_ok;
bool result_item_ok;
bool msg_list_ok;
bool msg_item_ok;
bool msg_dialog_ok;
bool transfer_ok;
bool transfer_item_ok;
bool dir_list_ok;
bool save_dir_ok;
bool server_set_ok;
bool transfer_rates_ok;
// Neighbour fns
cert * cert_get_current_neighbour();
int cert_add_neighbour();
int neigh_display(cert*);
int neigh_update_auth();
cert * cert_get_current();
int cert_allow_current();
int cert_deny_current();
int cert_listen_current();
int cert_connect_current();
int cert_remove_current();
int cert_tag_current();
/* int cert_save_config(const char *fname); */
int cert_save_config();
int cert_load_gui_config();
int cert_save_servaddr();
int cert_saveaddr_connect();
int cert_check_auto();
int cert_toggle_auto();
int cert_sign_current();
int cert_trust_current_toggle();
int cert_update_auth();
std::string getHomePath();
int config_remove_dir();
int file_select(int);
int file_updateName();
int file_completeIO();
int config_server_update();
int config_server_change();
int fselect_type; // what type of file selection is in progress.
int search_new(); // read words from keyboard.
int search_download();
int search_recommend();
int search_remove();
// new results display system.
int update_search_browser();
int set_recommend(PQFileItem *rec);
PQFileItem *get_recommend();
int getnsend_chat();
int msg_send();
int msg_channel_select();
int msg_remove();
int msg_reply();
int download_recommend();
int transfer_select();
int transfer_cancel();
int transfer_clear();
int transfer_rates();
int load_dir(std::string person, std::string dir);
int dirlist_download();
int dirlist_recommend();
private:
int update();
int update_quick_stats();
int update_other_stats();
int update_certs();
// display certificate details.
int cert_display(cert*, bool);
int update_neighbour_certs();
int update_search();
int update_msgs();
int update_transfer();
int update_config();
int update_dirs();
int update_dirlist();
int check_dirlist();
int check_dirlist2();
#ifdef PQI_USE_CHANNELS
int update_channels();
bool channel_list_ok;
bool channel_msg_list_ok;
bool channel_msg_item_ok;
#endif
std::list<FileTransferItem *> transfers;
// pointers to pqissl stuff.
filedexserver *server;
pqipersongrp *pqih;
sslroot *sslr;
UserInterface *ui;
p3disc *ad;
alertBox *msg;
alertBox *chat;
// recommendation.
PQFileItem *recommend;
// File Import/Export Flags.
bool fileio_import;
int loop;
Fl_Funky_Browser *search_browser;
};
#define FILE_CHOOSER_IMPORT 1
#define FILE_CHOOSER_EXPORT 2
#define FILE_CHOOSER_DIR 3
#define FILE_CHOOSER_SAVEDIR 4
#define FILE_CHOOSER_KEY 5
#define FILE_CHOOSER_CERT 6
/* Helper function to convert windows paths
* into unix (ie switch \ to /) for FLTK's file chooser
*/
std::string make_path_unix(std::string winpath);
#endif

View File

@ -0,0 +1,675 @@
// generated by Fast Light User Interface Designer (fluid) version 1.0107
#include "guitab.h"
Fl_Double_Window* UserInterface::make_windows() {
Fl_Double_Window* w;
{ Fl_Double_Window* o = main_win = new Fl_Double_Window(710, 535, "RetroShare");
w = o;
o->box(FL_DOWN_BOX);
o->user_data((void*)(this));
{ Fl_Tabs* o = gui_tabs = new Fl_Tabs(10, 10, 690, 470);
o->box(FL_UP_BOX);
{ Fl_Group* o = neighbours_tab = new Fl_Group(15, 40, 680, 435, "Connect");
o->labelfont(1);
{ Fl_Button* o = new Fl_Button(50, 439, 280, 31, "Load Certificate from File");
o->callback((Fl_Callback*)file_import);
}
{ Fl_Funky_Browser* o = cert_neighbour_list = new Fl_Funky_Browser(25, 70, 350, 355, "", 4);
o->box(FL_NO_BOX);
o->color(FL_BACKGROUND2_COLOR);
o->selection_color(FL_SELECTION_COLOR);
o->labeltype(FL_NORMAL_LABEL);
o->labelfont(0);
o->labelsize(14);
o->labelcolor(FL_FOREGROUND_COLOR);
o->textfont(4);
o->callback((Fl_Callback*)cert_neighbour_list_select);
o->align(FL_ALIGN_BOTTOM);
o->when(FL_WHEN_RELEASE_ALWAYS);
}
{ Fl_Button* o = neigh_add_button = new Fl_Button(420, 440, 240, 30, "Sign + Add to Friends >>>");
o->callback((Fl_Callback*)cert_move_to_friends);
}
{ Fl_Box* o = new Fl_Box(35, 49, 290, 20, "Your Neighbour List");
o->box(FL_FLAT_BOX);
o->labelfont(1);
}
{ Fl_Input* o = neigh_authcode = new Fl_Input(540, 397, 70, 30, "AUTH CODE:");
o->labelfont(1);
o->callback((Fl_Callback*)neigh_auth_callback);
o->when(FL_WHEN_CHANGED);
}
{ Fl_Group* o = new Fl_Group(390, 54, 295, 305);
o->box(FL_DOWN_BOX);
{ Fl_Box* o = new Fl_Box(395, 65, 125, 20, "Peer Details");
o->box(FL_FLAT_BOX);
o->labelfont(1);
o->labelsize(16);
}
{ Fl_Browser* o = neigh_signers = new Fl_Browser(440, 195, 225, 140, "Certificate signers");
o->type(2);
o->textfont(4);
o->callback((Fl_Callback*)cert_neigh_signers_select);
Fl_Group::current()->resizable(o);
}
neigh_name = new Fl_Output(450, 90, 226, 20, "Name:");
neigh_org = new Fl_Output(450, 115, 226, 20, "Org:");
neigh_loc = new Fl_Output(450, 140, 225, 20, "Loc:");
neigh_country = new Fl_Output(495, 165, 168, 20, "Country:");
neigh_trust = new Fl_Output(565, 65, 110, 20, "Trust:");
o->end();
}
{ Fl_Box* o = neigh_auth_notice = new Fl_Box(405, 369, 270, 26, "AUTH CODE REQUIRED");
o->box(FL_FLAT_BOX);
o->labelfont(1);
o->labelsize(18);
o->labelcolor(FL_YELLOW);
}
o->end();
}
{ Fl_Group* o = connect_tab = new Fl_Group(15, 40, 680, 435, "Friends");
o->labelfont(1);
o->hide();
{ Fl_Button* o = new Fl_Button(62, 440, 185, 25, "<<< Remove Friend");
o->callback((Fl_Callback*)cert_remove_cert);
}
{ Fl_Button* o = new Fl_Button(264, 440, 185, 25, "Configure Friend");
o->callback((Fl_Callback*)cert_show_config);
}
{ Fl_Funky_Browser* o = cert_list = new Fl_Funky_Browser(25, 70, 660, 360, "", 5);
o->type(2);
o->box(FL_NO_BOX);
o->color(FL_BACKGROUND2_COLOR);
o->selection_color(FL_SELECTION_COLOR);
o->labeltype(FL_NORMAL_LABEL);
o->labelfont(0);
o->labelsize(14);
o->labelcolor(FL_FOREGROUND_COLOR);
o->textfont(4);
o->callback((Fl_Callback*)cert_list_select);
o->align(FL_ALIGN_BOTTOM);
o->when(FL_WHEN_RELEASE_ALWAYS);
}
{ Fl_Button* o = new Fl_Button(466, 440, 185, 25, "Export Friend");
o->callback((Fl_Callback*)file_export);
}
{ Fl_Box* o = new Fl_Box(190, 50, 340, 20, "Your Friends ");
o->box(FL_FLAT_BOX);
o->labelfont(1);
}
o->end();
}
{ Fl_Group* o = new Fl_Group(15, 40, 680, 435, "File Listing");
o->labelfont(1);
o->hide();
{ Fl_Widget *o = file_results = make_tree_browser(25, 50, 660, 380);
}
// { Fl_File_Browser* o = file_results = new Fl_File_Browser(45, 50, 625, 380);
// o->callback((Fl_Callback*)file_result_select);
// }
{ Fl_Button* o = file_download_button = new Fl_Button(65, 440, 185, 25, "Download");
o->callback((Fl_Callback*)file_download);
}
{ Fl_Button* o = file_recommend_button = new Fl_Button(465, 440, 185, 25, "Recommend to Friends");
o->callback((Fl_Callback*)file_recommend);
o->deactivate();
}
{ Fl_Button* o = file_channel_button = new Fl_Button(265, 440, 185, 25, "Broadcast on Channel");
o->callback((Fl_Callback*)file_channel_broadcast);
o->deactivate();
}
o->end();
}
{ Fl_Group* o = new Fl_Group(15, 40, 680, 435, "Search ");
o->labelfont(1);
o->hide();
{ Fl_Input* o = new_search = new Fl_Input(105, 50, 225, 25, "Terms:");
o->labelfont(1);
o->callback((Fl_Callback*)do_new_search);
}
{ Fl_Button* o = new Fl_Button(535, 50, 125, 25, "Remove Search");
o->callback((Fl_Callback*)search_remove);
}
{ Fl_Button* o = recommend_button = new Fl_Button(460, 440, 185, 25, "Recommend to Friends");
o->callback((Fl_Callback*)search_recommend);
o->deactivate();
}
{ Fl_Funky_Browser* o = srch_results = new Fl_Funky_Browser(25, 80, 660, 350, "", 5);
o->type(2);
o->box(FL_NO_BOX);
o->color(FL_BACKGROUND2_COLOR);
o->selection_color(FL_SELECTION_COLOR);
o->labeltype(FL_NORMAL_LABEL);
o->labelfont(0);
o->labelsize(14);
o->labelcolor(FL_FOREGROUND_COLOR);
o->callback((Fl_Callback*)search_result_select);
o->align(FL_ALIGN_BOTTOM);
o->when(FL_WHEN_RELEASE_ALWAYS);
}
{ Fl_Button* o = search_button = new Fl_Button(340, 50, 79, 25, "Search");
o->labelfont(1);
o->callback((Fl_Callback*)do_search_button);
}
{ Fl_Button* o = download_button = new Fl_Button(60, 440, 185, 25, "Download");
o->callback((Fl_Callback*)search_download);
}
{ Fl_Button* o = search_channel_button = new Fl_Button(260, 440, 185, 25, "Broadcast on Channel");
o->callback((Fl_Callback*)search_channel_broadcast);
o->deactivate();
}
o->end();
}
{ Fl_Group* o = new Fl_Group(15, 40, 680, 435, "File Transfer");
o->hide();
{ Fl_Funky_Browser* o = transfer_downloads = new Fl_Funky_Browser(25, 50, 660, 250, "", 5);
o->type(2);
o->box(FL_NO_BOX);
o->color(FL_BACKGROUND2_COLOR);
o->selection_color(FL_SELECTION_COLOR);
o->labeltype(FL_NORMAL_LABEL);
o->labelfont(0);
o->labelsize(14);
o->labelcolor(FL_FOREGROUND_COLOR);
o->callback((Fl_Callback*)transfer_select);
o->align(FL_ALIGN_BOTTOM);
o->when(FL_WHEN_RELEASE_ALWAYS);
}
{ Fl_Button* o = transfer_cancel = new Fl_Button(70, 310, 165, 25, "Cancel");
o->callback((Fl_Callback*)file_transfer_cancel);
}
{ Fl_Button* o = transfer_clear = new Fl_Button(275, 310, 155, 25, "Clear Finished");
o->callback((Fl_Callback*)file_transfer_clear);
}
{ Fl_Text_Display* o = transfer_overview = new Fl_Text_Display(25, 345, 450, 120);
o->textfont(5);
}
{ Fl_Counter* o = rate_total = new Fl_Counter(510, 380, 135, 25, "Max Total Data Rate (kB/s)");
o->step(0.1);
o->callback((Fl_Callback*)file_transfer_total_rate);
}
{ Fl_Counter* o = rate_indiv = new Fl_Counter(510, 425, 135, 25, "Rate Per Person (kB/s)");
o->step(0.1);
o->callback((Fl_Callback*)file_transfer_indiv_rate);
}
o->end();
}
{ Fl_Group* o = new Fl_Group(15, 40, 680, 435, "Messages");
o->labelfont(1);
o->hide();
o->deactivate();
{ Fl_Funky_Browser* o = msg_list = new Fl_Funky_Browser(25, 65, 660, 270, "", 5);
o->type(2);
o->box(FL_NO_BOX);
o->color(FL_BACKGROUND2_COLOR);
o->selection_color(FL_SELECTION_COLOR);
o->labeltype(FL_NORMAL_LABEL);
o->labelfont(0);
o->labelsize(14);
o->labelcolor(FL_FOREGROUND_COLOR);
o->callback((Fl_Callback*)msg_select);
o->align(FL_ALIGN_BOTTOM);
o->when(FL_WHEN_RELEASE_ALWAYS);
}
{ Fl_Button* o = new Fl_Button(45, 350, 125, 25, "New Msg");
o->callback((Fl_Callback*)msg_dialog_show);
}
{ Fl_Button* o = new Fl_Button(45, 380, 125, 25, "Reply to Msg");
o->callback((Fl_Callback*)msg_dialog_reply);
}
{ Fl_Button* o = new Fl_Button(245, 450, 380, 25, "(2) -- Get The Recommended File");
o->labelfont(1);
o->callback((Fl_Callback*)msg_get_recommendation);
}
{ Fl_Button* o = new Fl_Button(45, 410, 125, 25, "Remove Msg");
o->callback((Fl_Callback*)msg_remove);
}
{ Fl_Text_Display* o = msg_details = new Fl_Text_Display(180, 340, 485, 105);
o->textfont(5);
}
{ Fl_Box* o = new Fl_Box(55, 45, 305, 20, "(1) -- Select Message");
o->box(FL_FLAT_BOX);
o->labelfont(1);
}
o->end();
}
{ Fl_Group* o = channels = new Fl_Group(15, 40, 680, 435, "Channels");
o->hide();
o->deactivate();
{ Fl_Funky_Browser* o = channel_list = new Fl_Funky_Browser(25, 80, 660, 225, "", 5);
o->type(2);
o->box(FL_NO_BOX);
o->color(FL_BACKGROUND2_COLOR);
o->selection_color(FL_SELECTION_COLOR);
o->labeltype(FL_NORMAL_LABEL);
o->labelfont(0);
o->labelsize(14);
o->labelcolor(FL_FOREGROUND_COLOR);
o->callback((Fl_Callback*)channel_list_select);
o->align(FL_ALIGN_BOTTOM);
o->when(FL_WHEN_RELEASE_ALWAYS);
}
{ Fl_Box* o = new Fl_Box(40, 61, 170, 19, "Available Channels");
o->labelfont(1);
}
{ Fl_Group* o = new Fl_Group(25, 310, 655, 160);
o->box(FL_DOWN_BOX);
{ Fl_Funky_Browser* o = channel_file_list = new Fl_Funky_Browser(35, 345, 635, 120, "", 5);
o->box(FL_NO_BOX);
o->color(FL_BACKGROUND2_COLOR);
o->selection_color(FL_SELECTION_COLOR);
o->labeltype(FL_NORMAL_LABEL);
o->labelfont(0);
o->labelsize(14);
o->labelcolor(FL_FOREGROUND_COLOR);
o->callback((Fl_Callback*)channel_file_list_select);
o->align(FL_ALIGN_BOTTOM);
o->when(FL_WHEN_RELEASE_ALWAYS);
}
{ Fl_Output* o = channel_selected_name = new Fl_Output(185, 315, 270, 25, "Msgs on Channel");
o->labelfont(1);
}
{ Fl_Button* o = channel_show_button = new Fl_Button(485, 315, 160, 25, "Show Msg Details");
o->callback((Fl_Callback*)channel_show_callback);
}
o->end();
}
{ Fl_Button* o = channel_delete_button = new Fl_Button(290, 50, 160, 25, "Delete Channel");
o->callback((Fl_Callback*)channel_delete_callback);
}
{ Fl_Button* o = channel_create_button = new Fl_Button(475, 50, 160, 25, "Create Channel Msg");
o->callback((Fl_Callback*)channel_create);
}
o->end();
}
{ Fl_Group* o = new Fl_Group(15, 40, 680, 435, "Config");
o->hide();
{ Fl_Group* o = new Fl_Group(460, 55, 210, 80);
o->box(FL_DOWN_BOX);
o->hide();
{ Fl_Check_Button* o = config_local_disc = new Fl_Check_Button(490, 80, 145, 25, "local discovery");
o->down_box(FL_DOWN_BOX);
}
{ Fl_Check_Button* o = config_remote_disc = new Fl_Check_Button(490, 100, 145, 25, "remote discovery");
o->down_box(FL_DOWN_BOX);
}
{ Fl_Box* o = new Fl_Box(470, 60, 165, 20, "Discovery Options:");
o->box(FL_FLAT_BOX);
o->labelfont(1);
}
o->end();
}
{ Fl_Group* o = new Fl_Group(25, 225, 405, 240);
o->box(FL_DOWN_BOX);
{ Fl_Browser* o = config_search_dir = new Fl_Browser(40, 245, 355, 105);
o->type(2);
}
{ Fl_Button* o = new Fl_Button(40, 370, 135, 25, "Add Directory");
o->callback((Fl_Callback*)config_add_dir);
}
{ Fl_Button* o = new Fl_Button(40, 400, 135, 25, "Remove Directory");
o->callback((Fl_Callback*)config_remove_dir);
}
config_save_dir = new Fl_Output(145, 435, 250, 20, "Save Directory");
{ Fl_Button* o = new Fl_Button(230, 405, 165, 25, "Select save directory");
o->callback((Fl_Callback*)config_save_dir_change);
}
{ Fl_Box* o = new Fl_Box(41, 230, 174, 15, "Share Directories:");
o->box(FL_FLAT_BOX);
o->labelfont(1);
}
o->end();
}
{ Fl_Group* o = new Fl_Group(25, 55, 405, 160);
o->box(FL_DOWN_BOX);
config_local_addr = new Fl_Input(165, 80, 130, 20, "Local Address:");
config_local_port = new Fl_Value_Input(335, 80, 60, 20, "Port:");
config_server_addr = new Fl_Input(165, 145, 130, 25, "External Address:");
config_server_port = new Fl_Value_Input(335, 145, 60, 25, "Port:");
{ Fl_Check_Button* o = config_firewall = new Fl_Check_Button(195, 100, 190, 25, "behind firewall");
o->down_box(FL_DOWN_BOX);
o->callback((Fl_Callback*)config_server_update);
}
{ Fl_Check_Button* o = config_forward = new Fl_Check_Button(195, 120, 190, 25, "forwarded external port");
o->down_box(FL_DOWN_BOX);
o->callback((Fl_Callback*)config_server_update);
}
{ Fl_Box* o = new Fl_Box(45, 60, 150, 20, "Server Settings:");
o->box(FL_FLAT_BOX);
o->labelfont(1);
}
{ Fl_Button* o = config_server_button = new Fl_Button(185, 180, 190, 25, "Change + Restart Server");
o->callback((Fl_Callback*)config_server_change);
}
o->end();
}
{ Fl_Button* o = new Fl_Button(485, 434, 170, 25, "Save Configuration");
o->callback((Fl_Callback*)cert_save_config);
}
o->end();
}
{ Fl_Group* o = about_help_tab = new Fl_Group(15, 40, 680, 435, "About");
o->hide();
help_view = new Fl_Help_View(25, 50, 660, 415);
o->end();
}
o->end();
}
onlinecounter = new Fl_Value_Output(100, 485, 35, 20, "#Online:");
new Fl_Value_Output(100, 505, 35, 20, "New Msgs:");
{ Fl_Button* o = new Fl_Button(605, 490, 85, 30, "Hide");
o->callback((Fl_Callback*)gui_quit);
}
new Fl_Text_Display(140, 485, 360, 40);
{ Fl_Button* o = chat_button = new Fl_Button(510, 490, 85, 30, "Chat");
o->callback((Fl_Callback*)chat_open_callback);
}
o->end();
}
{ Fl_Double_Window* o = msg_dialog = new Fl_Double_Window(580, 355, "Msg Dialog");
w = o;
o->user_data((void*)(this));
msg_online = new Fl_Check_Browser(20, 25, 140, 215);
{ Fl_Button* o = msg_button_select = new Fl_Button(20, 240, 140, 25, "Select All/None");
o->callback((Fl_Callback*)msg_toggle_select);
}
{ Fl_Text_Editor* o = msg_text = new Fl_Text_Editor(175, 25, 385, 240, "(1) -- Enter Message Text:");
o->labelfont(1);
}
msg_recommend = new Fl_Output(175, 275, 385, 30, "Recommendation:");
{ Fl_Button* o = new Fl_Button(245, 315, 160, 30, "(2) -- Send Msg");
o->labelfont(1);
o->callback((Fl_Callback*)msg_send);
}
{ Fl_Button* o = new Fl_Button(415, 315, 115, 30, "Cancel");
o->callback((Fl_Callback*)msg_dialog_hide);
}
o->end();
}
{ Fl_Double_Window* o = cert_config = new Fl_Double_Window(430, 535, "Certificate Configuration");
w = o;
o->user_data((void*)(this));
{ Fl_Group* o = new Fl_Group(10, 10, 410, 490);
o->box(FL_UP_BOX);
{ Fl_Group* o = new Fl_Group(25, 355, 380, 135);
o->box(FL_DOWN_BOX);
cert_server = new Fl_Input(155, 430, 130, 25, "Server Address:");
{ Fl_Button* o = new Fl_Button(165, 460, 220, 25, "Save and attempt to Connect");
o->callback((Fl_Callback*)cert_save_n_connect);
}
{ Fl_Button* o = new Fl_Button(35, 460, 115, 25, "Save Address");
o->callback((Fl_Callback*)cert_save_servaddr);
}
cert_port = new Fl_Value_Input(325, 430, 60, 25, "Port:");
{ Fl_Check_Button* o = cert_connect = new Fl_Check_Button(30, 410, 365, 20, "Outgoing Connections (Server Address Required)");
o->down_box(FL_DOWN_BOX);
o->callback((Fl_Callback*)cert_connect_change);
}
{ Fl_Check_Button* o = cert_allow = new Fl_Check_Button(30, 380, 115, 20, "Allow Access");
o->down_box(FL_DOWN_BOX);
o->callback((Fl_Callback*)cert_allow_change);
}
{ Fl_Check_Button* o = cert_listen = new Fl_Check_Button(30, 395, 170, 20, "Listen for connection");
o->down_box(FL_DOWN_BOX);
o->callback((Fl_Callback*)cert_listen_change);
}
{ Fl_Check_Button* o = cert_local = new Fl_Check_Button(220, 385, 130, 20, "Local Network");
o->down_box(FL_DOWN_BOX);
o->callback((Fl_Callback*)cert_local_change);
}
{ Fl_Check_Button* o = cert_auto = new Fl_Check_Button(220, 362, 140, 20, "Auto Connect");
o->down_box(FL_DOWN_BOX);
o->labelfont(1);
o->callback((Fl_Callback*)cert_auto_change);
}
{ Fl_Box* o = new Fl_Box(32, 363, 190, 20, "Connectivity Options:");
o->box(FL_FLAT_BOX);
o->labelfont(1);
}
o->end();
}
cert_status = new Fl_Output(80, 20, 130, 25, "Status:");
cert_details = new Fl_Text_Display(25, 50, 380, 210);
{ Fl_Group* o = new Fl_Group(25, 267, 380, 82);
o->box(FL_DOWN_BOX);
{ Fl_Button* o = cert_sign_button = new Fl_Button(239, 295, 145, 29, "Sign Certificate");
o->callback((Fl_Callback*)cert_sign);
}
{ Fl_Check_Button* o = cert_trust_person = new Fl_Check_Button(95, 323, 230, 25, "Trust This Person\'s Signature");
o->down_box(FL_DOWN_BOX);
o->callback((Fl_Callback*)cert_trust_person_change);
}
{ Fl_Input* o = cert_authcode = new Fl_Input(145, 295, 80, 28, "AUTH CODE:");
o->labelfont(1);
o->callback((Fl_Callback*)cert_auth_callback);
o->when(FL_WHEN_CHANGED);
}
{ Fl_Box* o = new Fl_Box(35, 272, 360, 20, "Authenticate Friend By Entering Their Code");
o->box(FL_FLAT_BOX);
o->labelfont(1);
}
o->end();
}
cert_trust = new Fl_Output(260, 20, 140, 25, "Trust:");
o->end();
}
{ Fl_Button* o = new Fl_Button(305, 505, 100, 25, "Done");
o->callback((Fl_Callback*)cert_hide_config);
}
o->end();
}
{ Fl_Double_Window* o = new Fl_Double_Window(360, 290);
w = o;
o->user_data((void*)(this));
{ //Fl_File_Chooser* o = file_chooser = new Fl_File_Chooser(5, 5, 350, 280);
Fl_File_Chooser* o = file_chooser = new Fl_File_Chooser("/",
"Certificate Files (*.{pem,pqi})", 0, "Select File/Dir");
// o->box(FL_NO_BOX);
// o->color(FL_BACKGROUND_COLOR);
// o->selection_color(FL_BACKGROUND_COLOR);
// o->labeltype(FL_NORMAL_LABEL);
// o->labelfont(0);
// o->labelsize(14);
// o->labelcolor(FL_FOREGROUND_COLOR);
// o->callback((Fl_Callback*)file_chooser_select);
o->callback(file_chooser_select);
// o->align(FL_ALIGN_TOP);
// o->when(FL_WHEN_RELEASE);
// o->end();
}
o->end();
}
{ Fl_Double_Window* o = welcome_window = new Fl_Double_Window(405, 580, "RetroShare Setup");
w = o;
o->user_data((void*)(this));
{ Fl_Group* o = new Fl_Group(10, 10, 385, 35);
o->box(FL_DOWN_BOX);
{ Fl_Box* o = new Fl_Box(85, 15, 230, 20, "Welcome to RetroShare");
o->box(FL_FLAT_BOX);
o->labelfont(1);
o->labelsize(16);
}
o->end();
}
{ Fl_Group* o = new Fl_Group(10, 55, 385, 140);
o->box(FL_DOWN_BOX);
{ Fl_Box* o = new Fl_Box(75, 65, 285, 20, "Please login ....");
o->box(FL_FLAT_BOX);
o->labelfont(1);
}
load_name = new Fl_Output(90, 90, 250, 25, "Name:");
{ Fl_Input* o = load_passwd = new Fl_Input(90, 125, 250, 25, "Password");
o->type(5);
o->callback((Fl_Callback*)load_passwd_callback);
o->when(FL_WHEN_ENTER_KEY);
}
{ Fl_Button* o = load_button = new Fl_Button(110, 160, 210, 30, "Load Existing User");
o->callback((Fl_Callback*)load_existing);
}
o->end();
}
{ Fl_Group* o = new Fl_Group(10, 205, 385, 365);
o->box(FL_DOWN_BOX);
{ Fl_Box* o = new Fl_Box(55, 210, 300, 20, "Or create a New User...");
o->box(FL_FLAT_BOX);
o->labelfont(1);
}
{ Fl_Group* o = new Fl_Group(50, 360, 300, 5);
o->box(FL_UP_BOX);
o->end();
}
{ Fl_Group* o = new Fl_Group(50, 440, 300, 5);
o->box(FL_UP_BOX);
o->end();
}
{ Fl_Group* o = new Fl_Group(50, 511, 300, 5);
o->box(FL_UP_BOX);
o->end();
}
gen_name = new Fl_Input(120, 235, 250, 25, "Name:");
gen_org = new Fl_Input(120, 265, 250, 25, "Organisation:");
gen_loc = new Fl_Input(120, 295, 250, 25, "Location:");
gen_country = new Fl_Input(120, 325, 250, 25, "Country:");
{ Fl_Input* o = gen_passwd = new Fl_Input(170, 375, 130, 25, "New Password");
o->type(5);
}
{ Fl_Input* o = gen_passwd2 = new Fl_Input(170, 405, 130, 25, "Password (Again)");
o->type(5);
}
{ Fl_Check_Button* o = gen_trusted_tick_box = new Fl_Check_Button(50, 450, 305, 20, "Load Trusted Certificate (Optional)");
o->down_box(FL_DOWN_BOX);
o->labelfont(1);
o->callback((Fl_Callback*)gen_trusted_tick_callback);
}
gen_trusted_peer = new Fl_Output(105, 474, 135, 25, "Friend:");
{ Fl_Button* o = gen_trusted_select_button = new Fl_Button(252, 470, 93, 30, "Select File");
o->callback((Fl_Callback*)gen_load_trusted);
}
{ Fl_Button* o = gen_button = new Fl_Button(100, 528, 210, 30, "Generate New Certificate");
o->callback((Fl_Callback*)generate_certificate);
}
o->end();
}
o->end();
}
{ Fl_Double_Window* o = chatter_window = new Fl_Double_Window(455, 435, "ChatterBox");
w = o;
o->user_data((void*)(this));
chatter_box = new Fl_Text_Display(5, 10, 445, 370);
{ Fl_Input* o = chatter_input = new Fl_Input(5, 390, 445, 40);
o->callback((Fl_Callback*)chatterbox_message);
o->when(FL_WHEN_ENTER_KEY);
}
o->end();
}
{ Fl_Double_Window* o = alert_window = new Fl_Double_Window(540, 200, "Alerts");
w = o;
o->user_data((void*)(this));
{ Fl_Return_Button* o = alert_okay = new Fl_Return_Button(75, 175, 180, 20, "OK");
o->callback((Fl_Callback*)alert_okay_msg);
}
alert_box = new Fl_Text_Display(15, 5, 515, 165);
{ Fl_Button* o = alert_cancel = new Fl_Button(270, 175, 180, 20, "Cancel");
o->labelfont(3);
o->labelsize(16);
o->labelcolor((Fl_Color)80);
o->callback((Fl_Callback*)alert_cancel_msg);
}
o->end();
}
{ Fl_Double_Window* o = channel_create_window = new Fl_Double_Window(460, 535, "Create New Channel Msg");
w = o;
o->user_data((void*)(this));
{ Fl_Funky_Browser* o = chan_createmsg_filelist = new Fl_Funky_Browser(10, 195, 440, 265, "", 2);
o->type(2);
o->box(FL_NO_BOX);
o->color(FL_BACKGROUND2_COLOR);
o->selection_color(FL_SELECTION_COLOR);
o->labeltype(FL_NORMAL_LABEL);
o->labelfont(0);
o->labelsize(14);
o->labelcolor(FL_FOREGROUND_COLOR);
o->callback((Fl_Callback*)chan_createmsg_list_select);
o->align(FL_ALIGN_BOTTOM);
o->when(FL_WHEN_RELEASE_ALWAYS);
}
{ Fl_Button* o = chan_createmsg_sendmsg_button = new Fl_Button(25, 500, 125, 25, "Send Msg");
o->callback((Fl_Callback*)chan_createmsg_sendmsg_callback);
}
{ Fl_Button* o = chan_createmsg_postpone_button = new Fl_Button(165, 500, 125, 25, "Postpone Msg");
o->callback((Fl_Callback*)chan_createmsg_postpone_callback);
}
{ Fl_Button* o = chan_createmsg_cancel_button = new Fl_Button(305, 500, 125, 25, "Cancel Msg");
o->callback((Fl_Callback*)chan_createmsg_cancel_callback);
}
chan_createmsg_msg = new Fl_Text_Editor(10, 110, 440, 75);
{ Fl_Box* o = new Fl_Box(10, 91, 135, 19, "Message Text:");
o->labelfont(1);
}
{ Fl_Button* o = chan_createmsg_remove_button = new Fl_Button(305, 470, 125, 25, "Remove File");
o->callback((Fl_Callback*)chan_createmsg_remove_callback);
}
{ Fl_Group* o = new Fl_Group(10, 5, 440, 80);
o->box(FL_DOWN_BOX);
{ Fl_Input* o = chan_createmsg_newname = new Fl_Input(155, 50, 280, 25);
o->callback((Fl_Callback*)chan_createmsg_newname_callback);
}
chan_createmsg_title = new Fl_Output(155, 15, 280, 25);
{ Fl_Round_Button* o = chan_createmsg_newname_button = new Fl_Round_Button(20, 55, 135, 20, "Create Channel");
o->type(102);
o->down_box(FL_ROUND_DOWN_BOX);
o->callback((Fl_Callback*)chan_createmsg_newname_button_callback);
}
{ Fl_Round_Button* o = chan_createmsg_title_button = new Fl_Round_Button(20, 15, 135, 20, "Active Channel");
o->type(102);
o->down_box(FL_ROUND_DOWN_BOX);
o->callback((Fl_Callback*)chan_createmsg_title_button_callback);
}
{ Fl_Box* o = new Fl_Box(45, 33, 70, 22, "OR");
o->labelfont(3);
}
o->end();
}
o->end();
}
{ Fl_Double_Window* o = channel_details_window = new Fl_Double_Window(460, 445, "Channel Msg Details");
w = o;
o->user_data((void*)(this));
{ Fl_Funky_Browser* o = chan_msgdetails_filelist = new Fl_Funky_Browser(10, 146, 440, 255, "", 2);
o->type(2);
o->box(FL_NO_BOX);
o->color(FL_BACKGROUND2_COLOR);
o->selection_color(FL_SELECTION_COLOR);
o->labeltype(FL_NORMAL_LABEL);
o->labelfont(0);
o->labelsize(14);
o->labelcolor(FL_FOREGROUND_COLOR);
o->callback((Fl_Callback*)chan_msgdetails_list_select);
o->align(FL_ALIGN_BOTTOM);
o->when(FL_WHEN_RELEASE_ALWAYS);
}
{ Fl_Button* o = chan_msgdetails_download_button = new Fl_Button(165, 410, 125, 25, "Download Files");
o->callback((Fl_Callback*)chan_msgdetails_download_callback);
}
{ Fl_Box* o = new Fl_Box(10, 42, 135, 19, "Message Text:");
o->labelfont(1);
}
{ Fl_Button* o = chan_msgdetails_subscribe_button = new Fl_Button(25, 410, 125, 25, "Subscribe ");
o->callback((Fl_Callback*)chan_msgdetails_subscribe_callback);
}
{ Fl_Output* o = chan_msgdetails_title = new Fl_Output(75, 10, 210, 25, "Channel");
o->labelfont(1);
}
chan_msgdetails_msg = new Fl_Text_Display(10, 61, 440, 75);
{ Fl_Output* o = chan_msgdetails_date = new Fl_Output(330, 10, 120, 25, "Date");
o->labelfont(1);
}
{ Fl_Button* o = chan_msgdetails_close_button = new Fl_Button(305, 410, 125, 25, "Close WIndow");
o->callback((Fl_Callback*)chan_msgdetails_close_callback);
}
o->end();
}
return w;
}

View File

@ -0,0 +1,788 @@
# data file for the Fltk User Interface Designer (fluid)
version 1.0107
header_name {.h}
code_name {.cxx}
class UserInterface {open
} {
Function {make_windows()} {open
} {
Fl_Window main_win {
label RetroShare open
xywh {10 180 710 535} type Double box DOWN_BOX visible
} {
Fl_Tabs gui_tabs {open
xywh {10 10 690 470} box UP_BOX
} {
Fl_Group neighbours_tab {
label Connect
xywh {15 40 680 435} labelfont 1
} {
Fl_Button {} {
label {Load Certificate from File}
callback file_import
xywh {50 439 280 31}
}
Fl_Browser cert_neighbour_list {
callback cert_neighbour_list_select
xywh {25 70 350 355} type Hold textfont 4
code0 {\#include "Fl_Funky_Browser.h"}
class Fl_Funky_Browser
}
Fl_Button neigh_add_button {
label {Sign + Add to Friends >>>}
callback cert_move_to_friends
xywh {420 440 240 30}
}
Fl_Box {} {
label {Your Neighbour List}
xywh {35 49 290 20} box FLAT_BOX labelfont 1
}
Fl_Input neigh_authcode {
label {AUTH CODE:}
callback neigh_auth_callback selected
xywh {540 397 70 30} labelfont 1
}
Fl_Group {} {open
xywh {390 54 295 305} box DOWN_BOX
} {
Fl_Box {} {
label {Peer Details}
xywh {395 65 125 20} box FLAT_BOX labelfont 1 labelsize 16
}
Fl_Browser neigh_signers {
label {Certificate signers}
callback cert_neigh_signers_select
xywh {440 195 225 140} type Hold textfont 4 resizable
}
Fl_Output neigh_name {
label {Name:}
xywh {450 90 226 20}
}
Fl_Output neigh_org {
label {Org:}
xywh {450 115 226 20}
}
Fl_Output neigh_loc {
label {Loc:}
xywh {450 140 225 20}
}
Fl_Output neigh_country {
label {Country:}
xywh {495 165 168 20}
}
Fl_Output neigh_trust {
label {Trust:}
xywh {565 65 110 20}
}
}
Fl_Box neigh_auth_notice {
label {AUTH CODE REQUIRED}
xywh {405 369 270 26} box FLAT_BOX labelfont 1 labelsize 18 labelcolor 95
}
}
Fl_Group connect_tab {
label Friends
xywh {15 40 680 435} labelfont 1 hide
} {
Fl_Button {} {
label {<<< Remove Friend}
callback cert_remove_cert
xywh {62 440 185 25}
}
Fl_Button {} {
label {Configure Friend}
callback cert_show_config
xywh {264 440 185 25}
}
Fl_Browser cert_list {
callback cert_list_select
xywh {25 70 660 360} type Hold textfont 4
code0 {\#include "Fl_Funky_Browser.h"}
class Fl_Funky_Browser
}
Fl_Button {} {
label {Export Friend}
callback file_export
xywh {466 440 185 25}
}
Fl_Box {} {
label {Your Friends }
xywh {190 50 340 20} box FLAT_BOX labelfont 1
}
}
Fl_Group {} {
label {File Listing}
xywh {15 40 680 435} labelfont 1 hide
} {
Fl_File_Browser file_results {
callback file_result_select
xywh {25 50 660 380}
}
Fl_Button file_download_button {
label Download
callback file_download
xywh {65 440 185 25}
}
Fl_Button file_recommend_button {
label {Recommend to Friends}
callback file_recommend
xywh {465 440 185 25} deactivate
}
Fl_Button file_channel_button {
label {Broadcast on Channel}
callback file_channel_broadcast
xywh {265 440 185 25} deactivate
}
}
Fl_Group {} {
label {Search }
xywh {15 40 680 435} labelfont 1 hide
} {
Fl_Input new_search {
label {Terms:}
callback do_new_search
xywh {105 50 225 25} labelfont 1
}
Fl_Button {} {
label {Remove Search}
callback search_remove
xywh {535 50 125 25}
}
Fl_Button recommend_button {
label {Recommend to Friends}
callback search_recommend
xywh {460 440 185 25} deactivate
}
Fl_Browser srch_results {
callback search_result_select
xywh {25 80 660 350} type Hold
code0 {\#include "Fl_Funky_Browser.h"}
class Fl_Funky_Browser
}
Fl_Button search_button {
label Search
callback do_search_button
xywh {340 50 79 25} labelfont 1
}
Fl_Button download_button {
label Download
callback search_download
xywh {60 440 185 25}
}
Fl_Button search_channel_button {
label {Broadcast on Channel}
callback search_channel_broadcast
xywh {260 440 185 25} deactivate
}
}
Fl_Group {} {
label {File Transfer} open
xywh {15 40 680 435} hide
} {
Fl_Browser transfer_downloads {
callback transfer_select
xywh {25 50 660 250} type Hold
class Fl_Funky_Browser
}
Fl_Button transfer_cancel {
label Cancel
callback file_transfer_cancel
xywh {70 310 165 25}
}
Fl_Button transfer_clear {
label {Clear Finished}
callback file_transfer_clear
xywh {275 310 155 25}
}
Fl_Text_Display transfer_overview {
xywh {25 345 450 120} textfont 5
}
Fl_Counter rate_total {
label {Max Total Data Rate (kB/s)}
callback file_transfer_total_rate
xywh {510 380 135 25}
}
Fl_Counter rate_indiv {
label {Rate Per Person (kB/s)}
callback file_transfer_indiv_rate
xywh {510 425 135 25}
}
}
Fl_Group {} {
label Messages
xywh {15 40 680 435} labelfont 1 hide deactivate
} {
Fl_Browser msg_list {
callback msg_select
xywh {25 65 660 270} type Hold
class Fl_Funky_Browser
}
Fl_Button {} {
label {New Msg}
callback msg_dialog_show
xywh {45 350 125 25}
}
Fl_Button {} {
label {Reply to Msg}
callback msg_dialog_reply
xywh {45 380 125 25}
}
Fl_Button {} {
label {(2) -- Get The Recommended File}
callback msg_get_recommendation
xywh {245 450 380 25} labelfont 1
}
Fl_Button {} {
label {Remove Msg}
callback msg_remove
xywh {45 410 125 25}
}
Fl_Text_Display msg_details {
xywh {180 340 485 105} textfont 5
}
Fl_Box {} {
label {(1) -- Select Message}
xywh {55 45 305 20} box FLAT_BOX labelfont 1
}
}
Fl_Group channels {
label Channels
xywh {15 40 680 435} hide deactivate
} {
Fl_Browser channel_list {
callback channel_list_select
xywh {25 80 660 225} type Hold
code0 {\#include "Fl_Funky_Browser.h"}
class Fl_Funky_Browser
}
Fl_Box {} {
label {Available Channels}
xywh {40 61 170 19} labelfont 1
}
Fl_Group {} {open
xywh {25 310 655 160} box DOWN_BOX
} {
Fl_Browser channel_file_list {
callback channel_file_list_select
xywh {35 345 635 120}
code0 {\#include "Fl_Funky_Browser.h"}
class Fl_Funky_Browser
}
Fl_Output channel_selected_name {
label {Msgs on Channel}
xywh {185 315 270 25} labelfont 1
}
Fl_Button channel_show_button {
label {Show Msg Details}
callback channel_show_callback
xywh {485 315 160 25}
}
}
Fl_Button channel_delete_button {
label {Delete Channel}
callback channel_delete_callback
xywh {290 50 160 25}
}
Fl_Button channel_create_button {
label {Create Channel Msg}
callback channel_create
xywh {475 50 160 25}
}
}
Fl_Group {} {
label Config
xywh {15 40 680 435} hide
} {
Fl_Group {} {open
xywh {460 55 210 80} box DOWN_BOX hide
} {
Fl_Check_Button config_local_disc {
label {local discovery}
xywh {490 80 145 25} down_box DOWN_BOX
}
Fl_Check_Button config_remote_disc {
label {remote discovery}
xywh {490 100 145 25} down_box DOWN_BOX
}
Fl_Box {} {
label {Discovery Options:}
xywh {470 60 165 20} box FLAT_BOX labelfont 1
}
}
Fl_Group {} {open
xywh {25 225 405 240} box DOWN_BOX
} {
Fl_Browser config_search_dir {
xywh {40 245 355 105} type Hold
}
Fl_Button {} {
label {Add Directory}
callback config_add_dir
xywh {40 370 135 25}
}
Fl_Button {} {
label {Remove Directory}
callback config_remove_dir
xywh {40 400 135 25}
}
Fl_Output config_save_dir {
label {Save Directory}
xywh {145 435 250 20}
}
Fl_Button {} {
label {Select save directory}
callback config_save_dir_change
xywh {230 405 165 25}
}
Fl_Box {} {
label {Share Directories:}
xywh {41 230 174 15} box FLAT_BOX labelfont 1
}
}
Fl_Group {} {open
xywh {25 55 405 160} box DOWN_BOX
} {
Fl_Input config_local_addr {
label {Local Address:}
xywh {165 80 130 20}
}
Fl_Value_Input config_local_port {
label {Port:}
xywh {335 80 60 20}
}
Fl_Input config_server_addr {
label {External Address:}
xywh {165 145 130 25}
}
Fl_Value_Input config_server_port {
label {Port:}
xywh {335 145 60 25}
}
Fl_Check_Button config_firewall {
label {behind firewall}
callback config_server_update
xywh {195 100 190 25} down_box DOWN_BOX
}
Fl_Check_Button config_forward {
label {forwarded external port}
callback config_server_update
xywh {195 120 190 25} down_box DOWN_BOX
}
Fl_Box {} {
label {Server Settings:}
xywh {45 60 150 20} box FLAT_BOX labelfont 1
}
Fl_Button config_server_button {
label {Change + Restart Server}
callback config_server_change
xywh {185 180 190 25}
}
}
Fl_Button {} {
label {Save Configuration}
callback cert_save_config
xywh {485 434 170 25}
}
}
Fl_Group about_help_tab {
label About
xywh {15 40 680 435} hide
} {
Fl_Help_View help_view {
xywh {25 50 660 415}
}
}
}
Fl_Value_Output onlinecounter {
label {\#Online:}
xywh {100 485 35 20}
}
Fl_Value_Output {} {
label {New Msgs:}
xywh {100 505 35 20}
}
Fl_Button {} {
label Hide
callback gui_quit
xywh {605 490 85 30}
}
Fl_Text_Display {} {
xywh {140 485 360 40}
}
Fl_Button chat_button {
label Chat
callback chat_open_callback
xywh {510 490 85 30}
}
}
Fl_Window msg_dialog {
label {Msg Dialog}
xywh {1 30 580 355} type Double hide
} {
Fl_Check_Browser msg_online {
xywh {20 25 140 215}
}
Fl_Button msg_button_select {
label {Select All/None}
callback msg_toggle_select
xywh {20 240 140 25}
}
Fl_Text_Editor msg_text {
label {(1) -- Enter Message Text:}
xywh {175 25 385 240} labelfont 1
}
Fl_Output msg_recommend {
label {Recommendation:}
xywh {175 275 385 30}
}
Fl_Button {} {
label {(2) -- Send Msg}
callback msg_send
xywh {245 315 160 30} labelfont 1
}
Fl_Button {} {
label Cancel
callback msg_dialog_hide
xywh {415 315 115 30}
}
}
Fl_Window cert_config {
label {Certificate Configuration}
xywh {168 116 430 535} type Double hide
} {
Fl_Group {} {open
xywh {10 10 410 490} box UP_BOX
} {
Fl_Group {} {
xywh {25 355 380 135} box DOWN_BOX
} {
Fl_Input cert_server {
label {Server Address:}
xywh {155 430 130 25}
}
Fl_Button {} {
label {Save and attempt to Connect}
callback cert_save_n_connect
xywh {165 460 220 25}
}
Fl_Button {} {
label {Save Address}
callback cert_save_servaddr
xywh {35 460 115 25}
}
Fl_Value_Input cert_port {
label {Port:}
xywh {325 430 60 25}
}
Fl_Check_Button cert_connect {
label {Outgoing Connections (Server Address Required)}
callback cert_connect_change
xywh {30 410 365 20} down_box DOWN_BOX
}
Fl_Check_Button cert_allow {
label {Allow Access}
callback cert_allow_change
xywh {30 380 115 20} down_box DOWN_BOX
}
Fl_Check_Button cert_listen {
label {Listen for connection}
callback cert_listen_change
xywh {30 395 170 20} down_box DOWN_BOX
}
Fl_Check_Button cert_local {
label {Local Network}
callback cert_local_change
xywh {220 385 130 20} down_box DOWN_BOX
}
Fl_Check_Button cert_auto {
label {Auto Connect}
callback cert_auto_change
xywh {220 362 140 20} down_box DOWN_BOX labelfont 1
}
Fl_Box {} {
label {Connectivity Options:}
xywh {32 363 190 20} box FLAT_BOX labelfont 1
}
}
Fl_Output cert_status {
label {Status:}
xywh {80 20 130 25}
}
Fl_Text_Display cert_details {
xywh {25 50 380 210}
}
Fl_Group {} {
xywh {25 267 380 82} box DOWN_BOX
} {
Fl_Button cert_sign_button {
label {Sign Certificate}
callback cert_sign
xywh {239 295 145 29}
}
Fl_Check_Button cert_trust_person {
label {Trust This Person's Signature}
callback cert_trust_person_change
xywh {95 323 230 25} down_box DOWN_BOX
}
Fl_Input cert_authcode {
label {AUTH CODE:}
callback cert_auth_callback
xywh {145 295 80 28} labelfont 1 when 1
}
Fl_Box {} {
label {Authenticate Friend By Entering Their Code}
xywh {35 272 360 20} box FLAT_BOX labelfont 1
}
}
Fl_Output cert_trust {
label {Trust:}
xywh {260 20 140 25}
}
}
Fl_Button {} {
label Done
callback cert_hide_config
xywh {305 505 100 25}
}
}
Fl_Window {} {
xywh {-32000 -32000 360 290} type Double hide
} {
Fl_Group file_chooser {
callback file_chooser_select open
xywh {5 5 350 280}
code0 {\#include <Fl/Fl_File_Chooser.H>}
class Fl_File_Chooser
} {}
}
Fl_Window welcome_window {
label {RetroShare Setup}
xywh {618 195 405 580} type Double hide
} {
Fl_Group {} {open
xywh {10 10 385 35} box DOWN_BOX
} {
Fl_Box {} {
label {Welcome to RetroShare}
xywh {85 15 230 20} box FLAT_BOX labelfont 1 labelsize 16
}
}
Fl_Group {} {open
xywh {10 55 385 140} box DOWN_BOX
} {
Fl_Box {} {
label {Please login ....}
xywh {75 65 285 20} box FLAT_BOX labelfont 1
}
Fl_Output load_name {
label {Name:}
xywh {90 90 250 25}
}
Fl_Input load_passwd {
label Password
callback load_passwd_callback
xywh {90 125 250 25} type Secret when 8
}
Fl_Button load_button {
label {Load Existing User}
callback load_existing
xywh {110 160 210 30}
}
}
Fl_Group {} {open
xywh {10 205 385 365} box DOWN_BOX
} {
Fl_Box {} {
label {Or create a New User...}
xywh {55 210 300 20} box FLAT_BOX labelfont 1
}
Fl_Group {} {
xywh {50 360 300 5} box UP_BOX
} {}
Fl_Group {} {
xywh {50 440 300 5} box UP_BOX
} {}
Fl_Group {} {
xywh {50 511 300 5} box UP_BOX
} {}
Fl_Input gen_name {
label {Name:}
xywh {120 235 250 25}
}
Fl_Input gen_org {
label {Organisation:}
xywh {120 265 250 25}
}
Fl_Input gen_loc {
label {Location:}
xywh {120 295 250 25}
}
Fl_Input gen_country {
label {Country:}
xywh {120 325 250 25}
}
Fl_Input gen_passwd {
label {New Password}
xywh {170 375 130 25} type Secret
}
Fl_Input gen_passwd2 {
label {Password (Again)}
xywh {170 405 130 25} type Secret
}
Fl_Check_Button gen_trusted_tick_box {
label {Load Trusted Certificate (Optional)}
callback gen_trusted_tick_callback
xywh {50 450 305 20} down_box DOWN_BOX labelfont 1
}
Fl_Output gen_trusted_peer {
label {Friend:}
xywh {105 474 135 25}
}
Fl_Button gen_trusted_select_button {
label {Select File}
callback gen_load_trusted
xywh {252 470 93 30}
}
Fl_Button gen_button {
label {Generate New Certificate}
callback generate_certificate
xywh {100 528 210 30}
}
}
}
Fl_Window chatter_window {
label ChatterBox
xywh {457 94 455 435} type Double hide
} {
Fl_Text_Display chatter_box {
xywh {5 10 445 370}
}
Fl_Input chatter_input {
callback chatterbox_message
xywh {5 390 445 40} when 8
}
}
Fl_Window alert_window {
label Alerts
xywh {46 543 540 200} type Double hide
} {
Fl_Return_Button alert_okay {
label OK
callback alert_okay_msg
xywh {75 175 180 20}
}
Fl_Text_Display alert_box {
xywh {15 5 515 165}
}
Fl_Button alert_cancel {
label Cancel
callback alert_cancel_msg
xywh {270 175 180 20} labelfont 3 labelsize 16 labelcolor 80
}
}
Fl_Window channel_create_window {
label {Create New Channel Msg}
xywh {30 127 460 535} type Double hide
} {
Fl_Browser chan_createmsg_filelist {
callback chan_createmsg_list_select
xywh {10 195 440 265} type Hold
code0 {\#include "Fl_Funky_Browser.h"}
class Fl_Funky_Browser
}
Fl_Button chan_createmsg_sendmsg_button {
label {Send Msg}
callback chan_createmsg_sendmsg_callback
xywh {25 500 125 25}
}
Fl_Button chan_createmsg_postpone_button {
label {Postpone Msg}
callback chan_createmsg_postpone_callback
xywh {165 500 125 25}
}
Fl_Button chan_createmsg_cancel_button {
label {Cancel Msg}
callback chan_createmsg_cancel_callback
xywh {305 500 125 25}
}
Fl_Text_Editor chan_createmsg_msg {
xywh {10 110 440 75}
}
Fl_Box {} {
label {Message Text:}
xywh {10 91 135 19} labelfont 1
}
Fl_Button chan_createmsg_remove_button {
label {Remove File}
callback chan_createmsg_remove_callback
xywh {305 470 125 25}
}
Fl_Group {} {
xywh {10 5 440 80} box DOWN_BOX
} {
Fl_Input chan_createmsg_newname {
callback chan_createmsg_newname_callback
xywh {155 50 280 25}
}
Fl_Output chan_createmsg_title {
xywh {155 15 280 25}
}
Fl_Round_Button chan_createmsg_newname_button {
label {Create Channel}
callback chan_createmsg_newname_button_callback
xywh {20 55 135 20} type Radio down_box ROUND_DOWN_BOX
}
Fl_Round_Button chan_createmsg_title_button {
label {Active Channel}
callback chan_createmsg_title_button_callback
xywh {20 15 135 20} type Radio down_box ROUND_DOWN_BOX
}
Fl_Box {} {
label OR
xywh {45 33 70 22} labelfont 3
}
}
}
Fl_Window channel_details_window {
label {Channel Msg Details}
xywh {714 557 460 445} type Double hide
} {
Fl_Browser chan_msgdetails_filelist {
callback chan_msgdetails_list_select
xywh {10 146 440 255} type Hold
code0 {\#include "Fl_Funky_Browser.h"}
class Fl_Funky_Browser
}
Fl_Button chan_msgdetails_download_button {
label {Download Files}
callback chan_msgdetails_download_callback
xywh {165 410 125 25}
}
Fl_Box {} {
label {Message Text:}
xywh {10 42 135 19} labelfont 1
}
Fl_Button chan_msgdetails_subscribe_button {
label {Subscribe }
callback chan_msgdetails_subscribe_callback
xywh {25 410 125 25}
}
Fl_Output chan_msgdetails_title {
label Channel
xywh {75 10 210 25} labelfont 1
}
Fl_Text_Display chan_msgdetails_msg {
xywh {10 61 440 75}
}
Fl_Output chan_msgdetails_date {
label Date
xywh {330 10 120 25} labelfont 1
}
Fl_Button chan_msgdetails_close_button {
label {Close WIndow}
callback chan_msgdetails_close_callback
xywh {305 410 125 25}
}
}
}
}

View File

@ -0,0 +1,226 @@
// generated by Fast Light User Interface Designer (fluid) version 1.0107
#ifndef guitab_h
#define guitab_h
#include <FL/Fl.H>
#include <FL/Fl_Double_Window.H>
#include <FL/Fl_Tabs.H>
#include <FL/Fl_Group.H>
#include <FL/Fl_Button.H>
extern void file_import(Fl_Button*, void*);
#include "Fl_Tree_Browser.h"
#include "Fl_Funky_Browser.h"
extern void cert_neighbour_list_select(Fl_Funky_Browser*, void*);
extern void cert_move_to_friends(Fl_Button*, void*);
#include <FL/Fl_Box.H>
#include <FL/Fl_Input.H>
extern void neigh_auth_callback(Fl_Input*, void*);
#include <FL/Fl_Browser.H>
extern void cert_neigh_signers_select(Fl_Browser*, void*);
#include <FL/Fl_Output.H>
extern void cert_remove_cert(Fl_Button*, void*);
extern void cert_show_config(Fl_Button*, void*);
extern void cert_list_select(Fl_Funky_Browser*, void*);
extern void file_export(Fl_Button*, void*);
#include <FL/Fl_File_Browser.H>
extern void file_result_select(Fl_File_Browser*, void*);
extern void file_download(Fl_Button*, void*);
extern void file_recommend(Fl_Button*, void*);
extern void file_channel_broadcast(Fl_Button*, void*);
extern void do_new_search(Fl_Input*, void*);
extern void search_remove(Fl_Button*, void*);
extern void search_recommend(Fl_Button*, void*);
extern void search_result_select(Fl_Funky_Browser*, void*);
extern void do_search_button(Fl_Button*, void*);
extern void search_download(Fl_Button*, void*);
extern void search_channel_broadcast(Fl_Button*, void*);
extern void transfer_select(Fl_Funky_Browser*, void*);
extern void file_transfer_cancel(Fl_Button*, void*);
extern void file_transfer_clear(Fl_Button*, void*);
#include <FL/Fl_Text_Display.H>
#include <FL/Fl_Counter.H>
extern void file_transfer_total_rate(Fl_Counter*, void*);
extern void file_transfer_indiv_rate(Fl_Counter*, void*);
extern void msg_select(Fl_Funky_Browser*, void*);
extern void msg_dialog_show(Fl_Button*, void*);
extern void msg_dialog_reply(Fl_Button*, void*);
extern void msg_get_recommendation(Fl_Button*, void*);
extern void msg_remove(Fl_Button*, void*);
extern void channel_list_select(Fl_Funky_Browser*, void*);
extern void channel_file_list_select(Fl_Funky_Browser*, void*);
extern void channel_show_callback(Fl_Button*, void*);
extern void channel_delete_callback(Fl_Button*, void*);
extern void channel_create(Fl_Button*, void*);
#include <FL/Fl_Check_Button.H>
extern void config_add_dir(Fl_Button*, void*);
extern void config_remove_dir(Fl_Button*, void*);
extern void config_save_dir_change(Fl_Button*, void*);
#include <FL/Fl_Value_Input.H>
extern void config_server_update(Fl_Check_Button*, void*);
extern void config_server_change(Fl_Button*, void*);
extern void cert_save_config(Fl_Button*, void*);
#include <FL/Fl_Help_View.H>
#include <FL/Fl_Value_Output.H>
extern void gui_quit(Fl_Button*, void*);
extern void chat_open_callback(Fl_Button*, void*);
#include <FL/Fl_Check_Browser.H>
extern void msg_toggle_select(Fl_Button*, void*);
#include <FL/Fl_Text_Editor.H>
extern void msg_send(Fl_Button*, void*);
extern void msg_dialog_hide(Fl_Button*, void*);
extern void cert_save_n_connect(Fl_Button*, void*);
extern void cert_save_servaddr(Fl_Button*, void*);
extern void cert_connect_change(Fl_Check_Button*, void*);
extern void cert_allow_change(Fl_Check_Button*, void*);
extern void cert_listen_change(Fl_Check_Button*, void*);
extern void cert_local_change(Fl_Check_Button*, void*);
extern void cert_auto_change(Fl_Check_Button*, void*);
extern void cert_sign(Fl_Button*, void*);
extern void cert_trust_person_change(Fl_Check_Button*, void*);
extern void cert_auth_callback(Fl_Input*, void*);
extern void cert_hide_config(Fl_Button*, void*);
#include <Fl/Fl_File_Chooser.H>
extern void file_chooser_select(Fl_File_Chooser*, void*);
extern void load_passwd_callback(Fl_Input*, void*);
extern void load_existing(Fl_Button*, void*);
extern void gen_trusted_tick_callback(Fl_Check_Button*, void*);
extern void gen_load_trusted(Fl_Button*, void*);
extern void generate_certificate(Fl_Button*, void*);
extern void chatterbox_message(Fl_Input*, void*);
#include <FL/Fl_Return_Button.H>
extern void alert_okay_msg(Fl_Return_Button*, void*);
extern void alert_cancel_msg(Fl_Button*, void*);
extern void chan_createmsg_list_select(Fl_Funky_Browser*, void*);
extern void chan_createmsg_sendmsg_callback(Fl_Button*, void*);
extern void chan_createmsg_postpone_callback(Fl_Button*, void*);
extern void chan_createmsg_cancel_callback(Fl_Button*, void*);
extern void chan_createmsg_remove_callback(Fl_Button*, void*);
extern void chan_createmsg_newname_callback(Fl_Input*, void*);
#include <FL/Fl_Round_Button.H>
extern void chan_createmsg_newname_button_callback(Fl_Round_Button*, void*);
extern void chan_createmsg_title_button_callback(Fl_Round_Button*, void*);
extern void chan_msgdetails_list_select(Fl_Funky_Browser*, void*);
extern void chan_msgdetails_download_callback(Fl_Button*, void*);
extern void chan_msgdetails_subscribe_callback(Fl_Button*, void*);
extern void chan_msgdetails_close_callback(Fl_Button*, void*);
class UserInterface {
public:
Fl_Double_Window* make_windows();
Fl_Double_Window *main_win;
Fl_Tabs *gui_tabs;
Fl_Group *neighbours_tab;
Fl_Funky_Browser *cert_neighbour_list;
Fl_Button *neigh_add_button;
Fl_Input *neigh_authcode;
Fl_Browser *neigh_signers;
Fl_Output *neigh_name;
Fl_Output *neigh_org;
Fl_Output *neigh_loc;
Fl_Output *neigh_country;
Fl_Output *neigh_trust;
Fl_Box *neigh_auth_notice;
Fl_Group *connect_tab;
Fl_Funky_Browser *cert_list;
Fl_Widget *file_results;
Fl_Button *file_download_button;
Fl_Button *file_recommend_button;
Fl_Button *file_channel_button;
Fl_Input *new_search;
Fl_Button *recommend_button;
Fl_Funky_Browser *srch_results;
Fl_Button *search_button;
Fl_Button *download_button;
Fl_Button *search_channel_button;
Fl_Funky_Browser *transfer_downloads;
Fl_Button *transfer_cancel;
Fl_Button *transfer_clear;
Fl_Text_Display *transfer_overview;
Fl_Counter *rate_total;
Fl_Counter *rate_indiv;
Fl_Funky_Browser *msg_list;
Fl_Text_Display *msg_details;
Fl_Group *channels;
Fl_Funky_Browser *channel_list;
Fl_Funky_Browser *channel_file_list;
Fl_Output *channel_selected_name;
Fl_Button *channel_show_button;
Fl_Button *channel_delete_button;
Fl_Button *channel_create_button;
Fl_Check_Button *config_local_disc;
Fl_Check_Button *config_remote_disc;
Fl_Browser *config_search_dir;
Fl_Output *config_save_dir;
Fl_Input *config_local_addr;
Fl_Value_Input *config_local_port;
Fl_Input *config_server_addr;
Fl_Value_Input *config_server_port;
Fl_Check_Button *config_firewall;
Fl_Check_Button *config_forward;
Fl_Button *config_server_button;
Fl_Group *about_help_tab;
Fl_Help_View *help_view;
Fl_Value_Output *onlinecounter;
Fl_Button *chat_button;
Fl_Double_Window *msg_dialog;
Fl_Check_Browser *msg_online;
Fl_Button *msg_button_select;
Fl_Text_Editor *msg_text;
Fl_Output *msg_recommend;
Fl_Double_Window *cert_config;
Fl_Input *cert_server;
Fl_Value_Input *cert_port;
Fl_Check_Button *cert_connect;
Fl_Check_Button *cert_allow;
Fl_Check_Button *cert_listen;
Fl_Check_Button *cert_local;
Fl_Check_Button *cert_auto;
Fl_Output *cert_status;
Fl_Text_Display *cert_details;
Fl_Button *cert_sign_button;
Fl_Check_Button *cert_trust_person;
Fl_Input *cert_authcode;
Fl_Output *cert_trust;
Fl_File_Chooser *file_chooser;
Fl_Double_Window *welcome_window;
Fl_Output *load_name;
Fl_Input *load_passwd;
Fl_Button *load_button;
Fl_Input *gen_name;
Fl_Input *gen_org;
Fl_Input *gen_loc;
Fl_Input *gen_country;
Fl_Input *gen_passwd;
Fl_Input *gen_passwd2;
Fl_Check_Button *gen_trusted_tick_box;
Fl_Output *gen_trusted_peer;
Fl_Button *gen_trusted_select_button;
Fl_Button *gen_button;
Fl_Double_Window *chatter_window;
Fl_Text_Display *chatter_box;
Fl_Input *chatter_input;
Fl_Double_Window *alert_window;
Fl_Return_Button *alert_okay;
Fl_Text_Display *alert_box;
Fl_Button *alert_cancel;
Fl_Double_Window *channel_create_window;
Fl_Funky_Browser *chan_createmsg_filelist;
Fl_Button *chan_createmsg_sendmsg_button;
Fl_Button *chan_createmsg_postpone_button;
Fl_Button *chan_createmsg_cancel_button;
Fl_Text_Editor *chan_createmsg_msg;
Fl_Button *chan_createmsg_remove_button;
Fl_Input *chan_createmsg_newname;
Fl_Output *chan_createmsg_title;
Fl_Round_Button *chan_createmsg_newname_button;
Fl_Round_Button *chan_createmsg_title_button;
Fl_Double_Window *channel_details_window;
Fl_Funky_Browser *chan_msgdetails_filelist;
Fl_Button *chan_msgdetails_download_button;
Fl_Button *chan_msgdetails_subscribe_button;
Fl_Output *chan_msgdetails_title;
Fl_Text_Display *chan_msgdetails_msg;
Fl_Output *chan_msgdetails_date;
Fl_Button *chan_msgdetails_close_button;
};
#endif

View File

@ -0,0 +1,996 @@
/*
* "$Id: pqibrowseitem.cc,v 1.11 2007-02-18 21:46:49 rmf24 Exp $"
*
* FltkGUI for RetroShare.
*
* Copyright 2004-2006 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 "fltkgui/pqibrowseitem.h"
#include "pqi/pqichannel.h" /* for mode bits */
// for a helper fn.
#include "fltkgui/pqistrings.h"
#include <sstream>
// a couple of functions that do the work.
int FileDisItem::ndix() // Number of Indices.
{
return 4;
}
static const int FI_COL_SOURCE_NAME = 0;
static const int FI_COL_SEARCH_TERMS = 1;
static const int FI_COL_NAME = 2;
static const int FI_COL_SIZE = 3;
std::string FileDisItem::txt(int col)
{
char numstr[100]; // this will be used regularly....
std::string out;
switch(col)
{
case FI_COL_SOURCE_NAME:
if ((item -> p) != NULL)
{
out = item -> p -> Name();
//std::cerr << "FDI::txt() Returning sn: " << out << std::endl;
return out;
}
return std::string("Local");
//std::cerr << "FDI::txt() person = NULL" << std::endl;
break;
case FI_COL_SEARCH_TERMS:
if (terms != NULL)
{
out = terms -> data;
//std::cerr << "FDI::txt() Returning terms: " << out << std::endl;
return out;
}
//std::cerr << "FDI::txt() terms = NULL" << std::endl;
break;
case FI_COL_NAME:
out = item -> name;
//std::cerr << "FDI::txt() Returning name: " << out << std::endl;
return out;
break;
case FI_COL_SIZE:
sprintf(numstr, "%d kB", item -> size / 1000);
out = numstr;
//std::cerr << "FDI::txt() Returning size: " << out << std::endl;
return out;
break;
default:
break;
}
out = "";
return out;
}
int FileDisItem::cmp(int col, DisplayData *fdi)
{
FileDisItem *other = (FileDisItem *) fdi;
int ret = 0;
switch(col)
{
case FI_COL_SOURCE_NAME:
// std::cerr << "FileDisItem::cmp() SRC NAME" << std::endl;
if (item -> p ==
other -> item -> p)
{
ret = 0;
break;
}
if (item -> p == NULL)
{
ret = -1;
break;
}
if (other -> item -> p == NULL)
{
ret = 1;
break;
}
ret = strcmp((item -> p -> Name()).c_str(),
(other -> item -> p -> Name()).c_str());
break;
case FI_COL_SEARCH_TERMS:
// std::cerr << "FileDisItem::cmp() TERMS" << std::endl;
if (terms == other -> terms)
{
ret = 0;
break;
}
if (terms == NULL)
{
ret = -1;
break;
}
if (other -> terms == NULL)
{
ret = 1;
break;
}
ret = strcmp((terms -> data).c_str(),
(other -> terms -> data).c_str());
break;
case FI_COL_NAME:
// std::cerr << "FileDisItem::cmp() NAME" << std::endl;
ret = strcmp((item -> name).c_str(),
(other -> item -> name).c_str());
break;
case FI_COL_SIZE:
// std::cerr << "FileDisItem::cmp() SIZE" << std::endl;
if (item -> size == other -> item -> size)
{
ret = 0;
break;
}
if (item -> size > other -> item -> size)
{
ret = 1;
break;
}
ret = -1;
break;
default:
// std::cerr << "FileDisItem::cmp() Default" << std::endl;
ret = 0;
break;
}
//std::cerr << "FileDisItem::cmp() ret: " << ret << std::endl;
return ret;
}
// a couple of functions that do the work.
int PersonDisItem::ndix() // Number of Indices.
{
return 5;
}
static const int PI_COL_NAME = 0;
static const int PI_COL_STATUS = 1;
static const int PI_COL_AUTOCONNECT = 2;
static const int PI_COL_TRUST = 3;
static const int PI_COL_SERVER = 4;
std::string PersonDisItem::txt(int col)
{
char numstr[100]; // this will be used regularly....
std::string out;
if (item == NULL)
return out;
switch(col)
{
case PI_COL_NAME:
out = item -> Name();
break;
case PI_COL_STATUS:
out = get_status_string(item -> Status());
break;
case PI_COL_AUTOCONNECT:
out = get_autoconnect_string(item);
break;
case PI_COL_TRUST:
out = get_trust_string(item);
break;
case PI_COL_SERVER:
out = get_server_string(item);
break;
default:
break;
}
return out;
}
int PersonDisItem::cmp(int col, DisplayData *fdi)
{
PersonDisItem *other = (PersonDisItem *) fdi;
switch(col)
{
case PI_COL_NAME:
return strcmp((item -> Name()).c_str(),
(other -> item -> Name()).c_str());
break;
case PI_COL_STATUS:
if (item -> Connected() ==
other -> item -> Connected())
{
if (item -> Accepted() ==
other -> item -> Accepted())
{
return 0;
}
if (item -> Accepted())
return -1;
return 1;
}
if (item -> Connected())
return -1;
return 1;
break;
case PI_COL_AUTOCONNECT:
return 0;
break;
case PI_COL_TRUST:
return other->item->trustLvl - item->trustLvl;
break;
case PI_COL_SERVER:
return 0;
break;
default:
return 0;
break;
}
return 0;
}
// a couple of functions that do the work.
int NeighDisItem::ndix() // Number of Indices.
{
return 3;
}
static const int NI_COL_STATUS = 0;
static const int NI_COL_TRUST = 1;
static const int NI_COL_CONNECT = 2;
static const int NI_COL_NAME = 3;
std::string NeighDisItem::txt(int col)
{
char numstr[100]; // this will be used regularly....
std::string out;
if (item == NULL)
return out;
switch(col)
{
case NI_COL_STATUS:
if (item->Accepted())
{
out = "Accept";
}
else
{
out = "Deny";
}
break;
case NI_COL_TRUST:
out = get_trust_string(item);
break;
case NI_COL_CONNECT:
out = get_lastconnecttime_string(item);
break;
case NI_COL_NAME:
out = item -> Name();
break;
default:
break;
}
return out;
}
int NeighDisItem::cmp(int col, DisplayData *fdi)
{
NeighDisItem *other = (NeighDisItem *) fdi;
switch(col)
{
case NI_COL_STATUS:
if (item -> Accepted() ==
other -> item -> Accepted())
{
return 0;
}
if (item -> Accepted())
return 1;
return -1;
break;
case NI_COL_TRUST:
return other->item->trustLvl - item->trustLvl;
break;
case NI_COL_CONNECT:
return get_lastconnecttime(item)
- get_lastconnecttime(other->item);
break;
case NI_COL_NAME:
return strcmp((item -> Name()).c_str(),
(other -> item -> Name()).c_str());
break;
default:
return 0;
break;
}
return 0;
}
// a couple of functions that do the work.
int MsgDisItem::ndix() // Number of Indices.
{
return 5;
}
static const int MI_COL_NAME = 0;
static const int MI_COL_MSG = 1;
static const int MI_COL_DATE = 2;
static const int MI_COL_REC_NAME = 3;
static const int MI_COL_REC_SIZE = 4;
std::string MsgDisItem::txt(int col)
{
char numstr[100]; // this will be used regularly....
std::string out;
switch(col)
{
case MI_COL_NAME:
if ((item -> p) != NULL)
{
out = item -> p -> Name();
return out;
}
return std::string("Local");
break;
case MI_COL_MSG:
out = "";
// remove \n and \t...
for(unsigned int i =0; i < item -> msg.length(); i++)
{
if ((item -> msg[i] == '\n') ||
(item -> msg[i] == '\t'))
{
out += " ";
}
else
{
out += item -> msg[i];
}
}
return out;
break;
case MI_COL_DATE:
out = timeFormat(item->epoch, TIME_FORMAT_OLDVAGUE);
//out = "Today!";
return out;
break;
case MI_COL_REC_NAME:
out = item -> recommendname;
return out;
break;
case MI_COL_REC_SIZE:
//sprintf(numstr, "%d kB", item -> recommendsize / 1000);
//out = numstr;
out = "N/A";
return out;
break;
default:
break;
}
out = "";
return out;
}
int MsgDisItem::cmp(int col, DisplayData *fdi)
{
MsgDisItem *other = (MsgDisItem *) fdi;
switch(col)
{
case MI_COL_NAME:
if (item -> p ==
other -> item -> p)
{
return 0;
}
if (item -> p == NULL)
{
return -1;
}
if (other -> item -> p == NULL)
{
return 1;
}
return strcmp((item -> p -> Name()).c_str(),
(other -> item -> p -> Name()).c_str());
break;
case MI_COL_MSG:
return strcmp((item -> msg).c_str(),
(other -> item -> msg).c_str());
break;
case MI_COL_DATE:
return 0;
break;
case MI_COL_REC_NAME:
return strcmp((item -> recommendname).c_str(),
(other -> item -> recommendname).c_str());
break;
case MI_COL_REC_SIZE:
return 0;
// if (item -> recommend_size ==
// other -> item -> recommend_size)
// {
// return 0;
// }
// if (item -> recommend_size >
// other -> item -> recommend_size)
// {
// return 1;
// }
// return -1;
break;
default:
return 0;
break;
}
return 0;
}
// a couple of functions that do the work.
int FTDisItem::ndix() // Number of Indices.
{
return 5;
}
static const int FT_COL_SOURCE_NAME = 0;
static const int FT_COL_DIRECTION = 1;
static const int FT_COL_FILE_NAME = 2;
static const int FT_COL_FILE_SIZE = 3;
static const int FT_COL_FILE_RATE = 4;
static const int SEC_PER_DAY = 24 * 3600;
std::string FTDisItem::txt(int col)
{
char numstr[100]; // this will be used regularly....
std::string out;
switch(col)
{
case FT_COL_SOURCE_NAME:
if ((item -> p) != NULL)
{
out = item -> p -> Name();
return out;
}
return std::string("Unknown");
break;
case FT_COL_DIRECTION: /* This has now become state.... */
switch(item -> state)
{
case FT_STATE_OKAY:
if (item->crate > 0)
{
out += "Downloading";
}
else
{
out += "Waiting";
}
break;
case FT_STATE_FAILED:
out += "Failed";
break;
case FT_STATE_COMPLETE:
out += "Complete";
break;
default:
out += "UNKNOWN";
break;
}
return out;
break;
case FT_COL_FILE_NAME:
out = item -> name;
return out;
break;
case FT_COL_FILE_SIZE:
{
float trans = item -> transferred;
float size = item -> size;
float percent = 100 * trans / size;
char lets[] = "kMGT";
char let = ' ';
// if bigger than 50 kbytes -> display
for(int i = 0; (i < 4) && (size / 1024 > 1); i++)
{
size /= 1024;
trans /= 1024;
let = lets[i];
}
sprintf(numstr, "%.2f/%.2f %cBytes (%.2f%%)",
trans, size, let, percent);
out = numstr;
return out;
}
break;
case FT_COL_FILE_RATE:
if (item->size == item->transferred)
{
sprintf(numstr, "Done");
}
else if (item->crate > 0.01) /* 10 bytes / sec */
{
float secs = item->size - item->transferred;
secs /= (item -> crate * 1000.0);
if (secs > SEC_PER_DAY)
{
sprintf(numstr, "%.2f kB/s, %d days to go.", item -> crate,
(int) (secs + SEC_PER_DAY / 2) / SEC_PER_DAY);
}
else
{
int hours = (int) secs / 3600;
secs -= 3600 * hours;
int min = (int) secs / 60;
secs -= 60 * min;
sprintf(numstr, "%.2f kB/s, %d:%02d:%02d to go.", item -> crate,
hours, min, (int) secs);
}
}
else
{
sprintf(numstr, "%.2f kB/s, ... Forever", item -> crate);
}
out = numstr;
return out;
break;
default:
break;
}
out = "";
return out;
}
int FTDisItem::cmp(int col, DisplayData *fdi)
{
FTDisItem *other = (FTDisItem *) fdi;
switch(col)
{
case FT_COL_SOURCE_NAME:
if (item -> p ==
other -> item -> p)
{
return 0;
}
if (item -> p == NULL)
{
return -1;
}
if (other -> item -> p == NULL)
{
return 1;
}
return strcmp((item -> p -> Name()).c_str(),
(other -> item -> p -> Name()).c_str());
break;
case FT_COL_DIRECTION:
if (item -> in == other -> item -> in)
{
return 0;
}
if (item -> in == true)
{
return 1;
}
return -1;
break;
case FT_COL_FILE_NAME:
return strcmp((item -> name).c_str(),
(other -> item -> name).c_str());
break;
case FT_COL_FILE_SIZE:
if (item -> size == other -> item -> size)
{
return 0;
}
if (item -> size > other -> item -> size)
{
return 1;
}
return -1;
break;
case FT_COL_FILE_RATE:
if (item -> crate == other -> item -> crate)
{
return 0;
}
if (item -> crate > other -> item -> crate)
{
return 1;
}
return -1;
break;
default:
return 0;
break;
}
return 0;
}
// a couple of functions that do the work.
int ChanDisItem::ndix() // Number of Indices.
{
return 5;
}
static const int CDI_COL_MODE = 0;
static const int CDI_COL_RANK = 1;
static const int CDI_COL_TITLE = 2;
static const int CDI_COL_COUNT = 3;
static const int CDI_COL_SIGN = 4;
ChanDisItem::ChanDisItem(pqichannel *i)
:mode(0), name("NULL CHANNEL")
{
if (!i)
{
mode = -1;
return;
}
cs = i->getSign();
mode = i->getMode();
name = i->getName();
ranking = i->getRanking();
msgcount = i->getMsgCount();
return;
}
std::string ChanDisItem::txt(int col)
{
char numstr[100]; // this will be used regularly....
std::ostringstream out;
switch(col)
{
case CDI_COL_MODE:
{
if (mode == -1)
{
out << "Invalid";
}
else if (mode & 0x040)
{
out << "Publisher";
}
else if (mode & 0x020)
{
out << "Subscriber";
}
else if (mode & 0x010)
{
out << "Listener";
}
else
{
out << "Other";
}
return out.str();
}
break;
case CDI_COL_RANK:
{
out << ranking;
return out.str();
}
break;
case CDI_COL_TITLE:
{
return name;
}
break;
case CDI_COL_COUNT:
{
out << msgcount;
return out.str();
}
break;
case CDI_COL_SIGN:
{
cs.printHex(out);
return out.str();
}
return std::string("<BAD CHAN>");
break;
default:
break;
}
return out.str();
}
int ChanDisItem::cmp(int col, DisplayData *fdi)
{
ChanDisItem *other = (ChanDisItem *) fdi;
switch(col)
{
case CDI_COL_MODE:
{
return mode - other->mode;
}
case CDI_COL_RANK:
{
return (int) (100.0 * (ranking - other->ranking));
}
case CDI_COL_TITLE:
{
return strcmp(name.c_str(), other->name.c_str());
}
case CDI_COL_COUNT:
{
return msgcount-other->msgcount;
}
break;
case CDI_COL_SIGN:
{
if (cs == other->cs)
return 0;
if (cs < other->cs)
return -1;
return 1;
}
break;
default:
break;
}
return 0;
}
// a couple of functions that do the work.
int ChanMsgDisItem::ndix() // Number of Indices.
{
return 5;
}
static const int CMDI_COL_DATE = 0;
static const int CMDI_COL_MSG = 1;
static const int CMDI_COL_NOFILES = 2;
static const int CMDI_COL_SIZE = 3;
static const int CMDI_COL_MSGHASH = 4;
ChanMsgDisItem::ChanMsgDisItem(chanMsgSummary &s)
:msg(s.msg), mh(s.mh), nofiles(s.nofiles),
totalsize(s.totalsize), recvd(s.recvd)
{
/* change \t & \n into " " */
for(unsigned int i =0; i < msg.length(); i++)
{
if ((msg[i] == '\n') ||
(msg[i] == '\t'))
{
msg[i] = ' ';
}
}
}
std::string ChanMsgDisItem::txt(int col)
{
char numstr[100]; // this will be used regularly....
std::ostringstream out;
switch(col)
{
case CMDI_COL_DATE:
{
int t = time(NULL);
int ago_sec = t - recvd;
out << ago_sec << " secs";
return out.str();
}
break;
case CMDI_COL_MSG:
// remove \n and \t... (done at init)
return msg;
break;
case CMDI_COL_NOFILES:
{
out << nofiles;
return out.str();
}
break;
case CMDI_COL_SIZE:
{
if (totalsize > 1000000)
{
out << (totalsize / 1000000.0) << " MB";
}
else if (totalsize > 1000)
{
out << (totalsize / 1000.0) << " kB";
}
else
{
out << totalsize << " B";
}
return out.str();
}
break;
case CMDI_COL_MSGHASH:
{
mh.printHex(out);
return out.str();
}
break;
default:
break;
}
return out.str();
}
int ChanMsgDisItem::cmp(int col, DisplayData *fdi)
{
ChanMsgDisItem *other = (ChanMsgDisItem *) fdi;
switch(col)
{
case CMDI_COL_DATE:
{
return recvd - other->recvd;
}
break;
case CMDI_COL_MSG:
{
return strcmp(msg.c_str(),
other->msg.c_str());
}
break;
case CMDI_COL_NOFILES:
{
return nofiles-other->nofiles;
}
break;
case CMDI_COL_SIZE:
{
return totalsize-other->totalsize;
}
break;
case CMDI_COL_MSGHASH:
{
if (mh == other->mh)
return 0;
if (mh < other->mh)
return -1;
return 1;
}
break;
default:
break;
}
return 0;
}
static const int CFDI_COL_SIZE = 0;
static const int CFDI_COL_NAME = 1;
// a couple of functions that do the work.
int ChanFileDisItem::ndix() // Number of Indices.
{
return 2;
}
ChanFileDisItem::ChanFileDisItem(std::string n, int s)
:name(n), size(s)
{
return;
}
std::string ChanFileDisItem::txt(int col)
{
char numstr[100]; // this will be used regularly....
std::ostringstream out;
switch(col)
{
case CFDI_COL_SIZE:
{
if (size > 1000000)
{
out << (size / 1000000.0) << " MB";
}
else if (size > 1000)
{
out << (size / 1000.0) << " kB";
}
else
{
out << size << " B";
}
return out.str();
}
break;
case CFDI_COL_NAME:
return name;
break;
default:
break;
}
return out.str();
}
int ChanFileDisItem::cmp(int col, DisplayData *fdi)
{
ChanFileDisItem *other = (ChanFileDisItem *) fdi;
switch(col)
{
case CFDI_COL_SIZE:
{
return size - other->size;
}
break;
case CFDI_COL_NAME:
{
return strcmp(name.c_str(),
other->name.c_str());
}
break;
default:
break;
}
return 0;
}

View File

@ -0,0 +1,219 @@
/*
* "$Id: pqibrowseitem.h,v 1.7 2007-02-18 21:46:49 rmf24 Exp $"
*
* FltkGUI for RetroShare.
*
* Copyright 2004-2006 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 MRKS_PQI_BROWSER_ITEMS
#define MRKS_PQI_BROWSER_ITEMS
/* My new funky browser.....
*
* - Designed to sort/display a tree brower
* for search results....
*
* First we need the basic interface class that
* must wrap the Data....
*/
#include "fltkgui/Fl_Funky_Browser.h"
#include "pqi/pqi.h"
#include "pqi/p3channel.h"
class FileDisItem: public DisplayData
{
public:
FileDisItem(PQFileItem *i, SearchItem *s) :item(i), terms(s) { return; }
// a couple of functions that do the work.
virtual int ndix(); // Number of Indices.
virtual std::string txt(int col);
virtual int cmp(int col, DisplayData *);
PQFileItem *getItem() { return item;}
void setItem(PQFileItem *i) {item = i;}
SearchItem *getSearchItem() { return terms;}
void setSearchItem(SearchItem *s) {terms = s;}
private:
PQFileItem *item;
SearchItem *terms;
};
class PersonDisItem: public DisplayData
{
public:
PersonDisItem(Person *i) :item(i), checked(false) { return; }
// a couple of functions that do the work.
virtual int ndix(); // Number of Indices.
virtual std::string txt(int col);
virtual int cmp(int col, DisplayData *);
virtual int check(int n, int v = -1)
{
if (v == -1)
return (int) checked;
if (v == 0)
return checked = false;
return checked = true;
};
Person *getItem() { return item;}
void setItem(Person *i) {item = i;}
private:
Person *item;
bool checked;
};
class NeighDisItem: public DisplayData
{
public:
NeighDisItem(Person *i) :item(i) { return; }
// a couple of functions that do the work.
virtual int ndix(); // Number of Indices.
virtual std::string txt(int col);
virtual int cmp(int col, DisplayData *);
Person *getItem() { return item;}
void setItem(Person *i) {item = i;}
private:
Person *item;
};
class MsgDisItem: public DisplayData
{
public:
MsgDisItem(MsgItem *i) :item(i) { return; }
// a couple of functions that do the work.
virtual int ndix(); // Number of Indices.
virtual std::string txt(int col);
virtual int cmp(int col, DisplayData *);
MsgItem *getItem() { return item;}
void setItem(MsgItem *i) {item = i;}
private:
MsgItem *item;
};
class FTDisItem: public DisplayData
{
public:
FTDisItem(FileTransferItem *i) :item(i) { return; }
// a couple of functions that do the work.
virtual int ndix(); // Number of Indices.
virtual std::string txt(int col);
virtual int cmp(int col, DisplayData *);
FileTransferItem *getItem() { return item;}
void setItem(FileTransferItem *i) {item = i;}
private:
FileTransferItem *item;
};
/* NOTE The Channel classes should be changed to just
* carry the channelSign around.... this is enough
* to refer to the channels....
*
* don't want pointers to pqichannels....
*/
class ChanDisItem: public DisplayData
{
public:
ChanDisItem(pqichannel *i);
// a couple of functions that do the work.
virtual int ndix(); // Number of Indices.
virtual std::string txt(int col);
virtual int cmp(int col, DisplayData *);
virtual int check(int n, int v = -1)
{
if (v == -1)
return (int) checked;
if (v == 0)
return checked = false;
return checked = true;
};
public:
channelSign cs;
int mode;
std::string name;
float ranking;
int msgcount;
bool checked; // subscribed..
};
class ChanMsgDisItem: public DisplayData
{
public:
ChanMsgDisItem(chanMsgSummary &s);
// a couple of functions that do the work.
virtual int ndix(); // Number of Indices.
virtual std::string txt(int col);
virtual int cmp(int col, DisplayData *);
public:
std::string msg;
MsgHash mh;
int nofiles;
int totalsize;
long recvd;
};
class ChanFileDisItem: public DisplayData
{
public:
ChanFileDisItem(std::string n, int s);
// a couple of functions that do the work.
virtual int ndix(); // Number of Indices.
virtual std::string txt(int col);
virtual int cmp(int col, DisplayData *);
//private:
std::string name;
int size;
};
#endif

View File

@ -0,0 +1,745 @@
/*
* "$Id: pqistrings.cc,v 1.11 2007-02-18 21:46:49 rmf24 Exp $"
*
* FltkGUI for RetroShare.
*
* Copyright 2004-2006 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 "pqi/pqi.h"
#include "pqi/pqinetwork.h"
/**************** PQI_USE_XPGP ******************/
#if defined(PQI_USE_XPGP)
#include "pqi/xpgpcert.h"
#else /* X509 Certificates */
/**************** PQI_USE_XPGP ******************/
#include "pqi/sslcert.h"
#endif /* X509 Certificates */
/**************** PQI_USE_XPGP ******************/
#include "fltkgui/pqistrings.h"
#include <iostream>
#include <iomanip>
#include <sstream>
#include <time.h>
/**************** PQI_USE_XPGP ******************/
#if defined(PQI_USE_XPGP)
std::string getXPGPInfo(XPGP *cert);
#endif /* XPGP Certificates */
/**************** PQI_USE_XPGP ******************/
std::string get_status_string(int status)
{
std::string sstr("");
if (status & PERSON_STATUS_CONNECTED)
{
sstr += "Online";
return sstr;
}
if (!(status & PERSON_STATUS_ACCEPTED))
{
sstr += "Denied Access";
return sstr;
}
if (status & PERSON_STATUS_INUSE)
{
sstr += "Connecting";
/*
if (status & PERSON_STATUS_WILL_LISTEN)
{
sstr += "Listening";
}
sstr += "/";
if (status & PERSON_STATUS_WILL_CONNECT)
{
sstr += "Connecting";
}
sstr += "]";
*/
return sstr;
}
sstr += "Unknown";
return sstr;
}
std::string get_neighbourstatus_string(Person *p)
{
// if connected - show how long
// if !autoconnected - tick to connect.
//
// if connecting.
// show time to next connect attempt.
// else show the last connect time.
std::ostringstream connstr;
connstr << "Last Conn/Recv: ";
int lct = time(NULL) - p -> lc_timestamp;
int lrt = time(NULL) - p -> lr_timestamp;
if (lct < 100000000)
{
connstr << get_timeperiod_string(lct);
}
else
{
connstr << "Never";
}
connstr << "/";
if (lrt < 100000000)
{
connstr << get_timeperiod_string(lrt);
}
else
{
connstr << "Never";
}
return connstr.str();
}
int get_lastconnecttime(Person *p)
{
std::ostringstream connstr;
int lct = time(NULL) - p -> lc_timestamp;
int lrt = time(NULL) - p -> lr_timestamp;
if (lrt < lct)
{
lct = lrt;
}
return lct;
}
std::string get_lastconnecttime_string(Person *p)
{
int lct = get_lastconnecttime(p);
if (lct < 32000000)
{
return get_timeperiod_string(lct);
}
else
{
return std::string("Never");
}
}
std::string get_autoconnect_string(Person *p)
{
// if connected - show how long
// if !autoconnected - tick to connect.
//
// if connecting.
// show time to next connect attempt.
// else show the last connect time.
std::ostringstream connstr;
Person *own = getSSLRoot() -> getOwnCert();
if (p == own)
{
connstr << "Yourself";
return connstr.str();
}
if (p -> Connected())
{
/*
long ct = p->lc_timestamp;
if (ct < p->lr_timestamp)
ct = p->lr_timestamp;
connstr << "Online: " << get_timeperiod_string(time(NULL) - ct);
*/
connstr << "Online";
}
else if (p -> Manual())
{
if (p->trustLvl < TRUST_SIGN_AUTHEN)
{
connstr << "Please Authenticate";
}
else
{
connstr << "Tick to Connect";
}
}
else
{
connstr << "Offline";
}
/*
else if (p -> WillConnect())
{
connstr << "Connect in:";
connstr << get_timeperiod_string(p->nc_timestamp - time(NULL));
}
else
{
connstr << "Last Conn:";
long ct = p->lc_timestamp;
if (ct < p->lr_timestamp)
{
ct = p->lr_timestamp;
connstr << "(I):";
}
else
{
connstr << "(O):";
}
connstr << get_timeperiod_string(time(NULL) - ct);
}
*/
return connstr.str();
}
std::string get_trust_string(Person *p)
{
std::ostringstream srvstr;
/* This is now changing to display 2 things.
*
* (1) - Proxy
* (2) - Auth Level.
*/
Person *own = getSSLRoot() -> getOwnCert();
if (p == own)
{
srvstr << "Yourself"; // Certificate";
return srvstr.str();
}
switch(p -> trustLvl)
{
case TRUST_SIGN_OWN:
srvstr << "Auth (S)"; //Good: Own Signature";
break;
case TRUST_SIGN_TRSTED:
srvstr << "Trusted (ST)"; //Good: Trusted Signer";
break;
case TRUST_SIGN_AUTHEN:
srvstr << "Auth"; //Good: Authenticated";
break;
case TRUST_SIGN_BASIC:
srvstr << "Untrusted"; // : Acquaintance ";
break;
case TRUST_SIGN_UNTRUSTED:
srvstr << "Unknown (2)";
break;
case TRUST_SIGN_UNKNOWN:
srvstr << "Unknown (1)";
break;
case TRUST_SIGN_NONE:
srvstr << "Unknown (0)";
break;
case TRUST_SIGN_BAD: /* not checked yet */
srvstr << "Not Avail";
break;
default:
srvstr << "UNKNOWN";
break;
}
return srvstr.str();
}
std::string get_server_string(Person *p)
{
std::ostringstream srvstr;
if ((0 == inaddr_cmp(p -> serveraddr, 0)) || (p -> Local()))
{
if (0 == inaddr_cmp(p -> localaddr, 0))
{
srvstr << "Unknown Addr";
}
else
{
srvstr << "L: " << inet_ntoa(p -> localaddr.sin_addr);
srvstr << ":" << ntohs(p -> localaddr.sin_port);
}
}
else
{
srvstr << "S: " << inet_ntoa(p -> serveraddr.sin_addr);
srvstr << ":" << ntohs(p -> serveraddr.sin_port);
}
// need own cert!
Person *own = getSSLRoot() -> getOwnCert();
if ((isValidNet(&(p->serveraddr.sin_addr))) &&
(!isPrivateNet(&(p->serveraddr.sin_addr))) &&
(!sameNet(&(own->localaddr.sin_addr), &(p->serveraddr.sin_addr))))
{
srvstr << " (Proxy-S) ";
}
else if ((!p->Firewalled()) && (isValidNet(&(p->localaddr.sin_addr))) &&
(!isPrivateNet(&(p->localaddr.sin_addr))) &&
(!sameNet(&(own->localaddr.sin_addr), &(p->localaddr.sin_addr))))
{
srvstr << " (Proxy-L) ";
}
return srvstr.str();
}
const int sec_per_min = 60;
const int sec_per_hour = 3600;
const int sec_per_day = 3600 * 24;
std::string get_timeperiod_string(int secs)
{
int days = secs / sec_per_day;
secs -= days * sec_per_day;
int hours = secs / sec_per_hour;
secs -= hours * sec_per_hour;
int mins = secs / sec_per_min;
secs -= mins * sec_per_min;
std::ostringstream srvstr;
if (days > 0)
{
srvstr << days << " days ";
}
else if (hours > 0)
{
srvstr << hours << ":" << mins << " hours";
}
else
{
srvstr << mins << ":" << secs << " min";
}
return srvstr.str();
}
std::string get_neighbour_info(cert *c)
{
std::ostringstream ostr;
/**************** PQI_USE_XPGP ******************/
#if defined(PQI_USE_XPGP)
ostr << getX509CNString(c -> certificate -> subject -> subject);
#else /* X509 Certificates */
/**************** PQI_USE_XPGP ******************/
ostr << getX509CNString(c -> certificate -> cert_info -> subject);
#endif /* X509 Certificates */
/**************** PQI_USE_XPGP ******************/
ostr << "\t" << get_neighbourstatus_string(c);
return ostr.str();
}
std::string get_cert_info(cert *c)
{
std::ostringstream ostr;
ostr << "************ Certificate **************" << std::endl;
/**************** PQI_USE_XPGP ******************/
#if defined(PQI_USE_XPGP)
ostr << getXPGPInfo(c -> certificate);
#else /* X509 Certificates */
/**************** PQI_USE_XPGP ******************/
ostr << getX509Info(c -> certificate);
#endif /* X509 Certificates */
/**************** PQI_USE_XPGP ******************/
ostr << "********** Connection Info ************" << std::endl;
ostr << "Local Addr : " << inet_ntoa(c -> localaddr.sin_addr);
ostr << ":" << ntohs(c -> localaddr.sin_port) << std::endl;
ostr << "Server Addr : " << inet_ntoa(c -> serveraddr.sin_addr);
ostr << ":" << ntohs(c -> serveraddr.sin_port) << std::endl;
ostr << "FLAGS: ";
if (!c -> Firewalled())
{
ostr << "Not ";
}
ostr << "Firewalled, ";
if (!c -> Forwarded())
{
ostr << "Not ";
}
ostr << "Forwarded" << std::endl;
ostr << std::endl;
ostr << "Last Connect Addr: " << inet_ntoa(c -> lastaddr.sin_addr);
ostr << ":" << ntohs(c -> lastaddr.sin_port) << std::endl;
ostr << "Last Connect Time: ";
ostr << get_timeperiod_string(time(NULL) - c -> lc_timestamp);
ostr << std::endl;
ostr << "Last Receive Time: ";
ostr << get_timeperiod_string(time(NULL) - c -> lr_timestamp);
ostr << std::endl;
ostr << std::endl;
ostr << "Next Connect in : ";
ostr << get_timeperiod_string(c->nc_timestamp - time(NULL));
ostr << std::endl;
ostr << "AutoConnect: " << get_autoconnect_string(c);
ostr << std::endl;
ostr << "***************************************" << std::endl;
return ostr.str();
}
std::string getX509Info(X509 *cert)
{
// Details from the structure
// cert_info (X509_CINF *)
// sig_alg (X509_ALGOR *)
// signature (ASN1_BIT_STRING *)
// valid (int)
// references (int)
// name (char *)
//
// random flags
//
// skid (ASN1_OCTET_STRING *)
// akid (AUTHORITY_KEYID *)
// aux (X509_CERT_AUX *)
std::string certstr;
char numstr[1000];
sprintf(numstr, "%ld", ASN1_INTEGER_get(cert -> cert_info -> version));
certstr += "Version: ";
certstr += numstr;
sprintf(numstr, "%ld", ASN1_INTEGER_get(cert ->
cert_info -> serialNumber));
certstr += "\nSerial Number: ";
certstr += numstr;
// switch(cert -> cert_info -> signature)
// {
// case STANDRD:
// certstr += "\nSig Algorithm: Standard";
// break;
// default:
// certstr += "\nSig Algorithm: Unknown";
// break;
// }
//
certstr += "\nSubject:\n";
certstr += getX509NameString(cert -> cert_info -> subject);
// Validity in Here. cert -> cert_info -> validity;
certstr += "\nIssuer:\n";
certstr += getX509NameString(cert -> cert_info -> issuer);
// Key cert -> cert_info -> key;
//
// IDS + extensions. cert -> cert_info -> issuerUID/subjectUID;
// cert -> cert_info -> extensions;
// END OF INFO.
// Next sigalg again?
// next sig...
certstr += "\nSignature:";
for(int i = 0; i < cert -> signature -> length;)
{
if (i % 128 == 0)
{
certstr += "\n\t";
}
char hbyte = 0;
for(int j = 0; (j < 4) && (i < cert -> signature -> length);
j++, i++)
{
hbyte = hbyte << 1;
if (ASN1_BIT_STRING_get_bit(cert -> signature, i) == 1)
{
hbyte++;
//std::cerr << "1";
}
else
{
//std::cerr << "0";
}
}
if (hbyte > 9)
{
certstr += ('a' + (hbyte - 10));
}
else
{
certstr += ('0' + hbyte);
}
//std::cerr << " " << i << " " << (char) ('0' + hbyte);
//std::cerr << " " << (int) hbyte << std::endl;
}
sprintf(numstr, "%d/%d", cert -> valid, cert -> references);
certstr += "\nValid/References: ";
certstr += numstr;
certstr += "\n";
// That will do for now.
return certstr;
}
/* Helper function to convert a Epoch Timestamp
* into a string.
*/
static char *TIME_FORMAT_STR_BRIEF = "%H:%M:%S";
static char *TIME_FORMAT_STR_OLDVAGUE_NOW = "%H:%M:%S";
static char *TIME_FORMAT_STR_OLDVAGUE_WEEK = "%a %H:%M";
static char *TIME_FORMAT_STR_OLDVAGUE_OLD = "%a, %d %b";
static char *TIME_FORMAT_STR_LONG = "%c";
static char *TIME_FORMAT_STR_NORMAL = "%a, %H:%M:%S";
std::string timeFormat(int epoch, int format)
{
time_t ctime = epoch;
struct tm *stime = localtime(&ctime);
size_t msize = 1024;
char space[msize];
char *fmtstr = NULL;
if (format == TIME_FORMAT_OLDVAGUE)
{
int itime = time(NULL);
int delta = abs(itime - ctime);
if (delta < 12 * 3600)
{
format = TIME_FORMAT_OLDVAGUE_NOW;
}
else if (delta < 3 * 24 * 3600)
{
format = TIME_FORMAT_OLDVAGUE_WEEK;
}
else
{
format = TIME_FORMAT_OLDVAGUE_OLD;
}
}
switch(format)
{
case TIME_FORMAT_BRIEF:
fmtstr = TIME_FORMAT_STR_BRIEF;
break;
case TIME_FORMAT_OLDVAGUE_NOW:
fmtstr = TIME_FORMAT_STR_OLDVAGUE_NOW;
break;
case TIME_FORMAT_OLDVAGUE_WEEK:
fmtstr = TIME_FORMAT_STR_OLDVAGUE_WEEK;
break;
case TIME_FORMAT_OLDVAGUE_OLD:
fmtstr = TIME_FORMAT_STR_OLDVAGUE_OLD;
break;
case TIME_FORMAT_LONG:
fmtstr = TIME_FORMAT_STR_LONG;
break;
case TIME_FORMAT_NORMAL:
default:
fmtstr = TIME_FORMAT_STR_NORMAL;
break;
}
if (fmtstr != NULL) // Short -> Only Time.
{
int usize = strftime(space, msize, fmtstr, stime);
if (usize > 0)
return std::string(space);
}
return std::string("");
}
/**************** PQI_USE_XPGP ******************/
#if defined(PQI_USE_XPGP)
std::string getXPGPInfo(XPGP *cert)
{
std::stringstream out;
long l;
int i,j;
out << "XPGP Certificate:" << std::endl;
l=XPGP_get_version(cert);
out << " Version: " << l+1 << "(0x" << l << ")" << std::endl;
out << " Subject: " << std::endl;
out << " " << getX509NameString(cert -> subject -> subject);
out << std::endl;
out << std::endl;
out << " Signatures:" << std::endl;
for(i = 0; i < sk_XPGP_SIGNATURE_num(cert->signs); i++)
{
out << "Sign[" << i << "] -> [";
XPGP_SIGNATURE *sig = sk_XPGP_SIGNATURE_value(cert->signs,i);
ASN1_BIT_STRING *signature = sig->signature;
int signlen = ASN1_STRING_length(signature);
unsigned char *signdata = ASN1_STRING_data(signature);
/* only show the first 8 bytes */
if (signlen > 8)
signlen = 8;
for(j=0;j<signlen;j++)
{
out << std::hex << std::setw(2) << (int) (signdata[j]);
if ((j+1)%16==0)
{
out << std::endl;
}
else
{
out << ":";
}
}
out << "] by:";
out << std::endl;
out << getX509NameString(sig->issuer);
out << std::endl;
out << std::endl;
}
return out.str();
}
std::string getXPGPAuthCode(XPGP *xpgp)
{
/* get the self signature -> the first signature */
std::stringstream out;
if (1 > sk_XPGP_SIGNATURE_num(xpgp->signs))
{
out.str();
}
XPGP_SIGNATURE *sig = sk_XPGP_SIGNATURE_value(xpgp->signs,0);
ASN1_BIT_STRING *signature = sig->signature;
int signlen = ASN1_STRING_length(signature);
unsigned char *signdata = ASN1_STRING_data(signature);
/* extract the authcode from the signature */
/* convert it to a string, inverse of 2 bytes of signdata */
if (signlen > 2)
signlen = 2;
int j;
for(j=0;j<signlen;j++)
{
out << std::hex << std::setprecision(2) << std::setw(2)
<< std::setfill('0') << (unsigned int) (signdata[j]);
}
return out.str();
}
std::list<std::string> getXPGPsigners(XPGP *cert)
{
std::list<std::string> signers;
int i;
for(i = 0; i < sk_XPGP_SIGNATURE_num(cert->signs); i++)
{
XPGP_SIGNATURE *sig = sk_XPGP_SIGNATURE_value(cert->signs,i);
std::string str = getX509CNString(sig->issuer);
signers.push_back(str);
std::cerr << "XPGPsigners(" << i << ")" << str << std::endl;
}
return signers;
}
#endif /* XPGP Certificates */
/**************** PQI_USE_XPGP ******************/
std::string get_cert_name(cert *c)
{
/**************** PQI_USE_XPGP ******************/
#if defined(PQI_USE_XPGP)
return getX509CNString(c->certificate->subject -> subject);
#else
return getX509CNString(c->certificate->cert_info -> subject);
#endif /* XPGP Certificates */
/**************** PQI_USE_XPGP ******************/
}
std::string get_cert_org(cert *c)
{
/**************** PQI_USE_XPGP ******************/
#if defined(PQI_USE_XPGP)
return getX509OrgString(c->certificate->subject -> subject);
#else
return getX509OrgString(c->certificate->cert_info -> subject);
#endif /* XPGP Certificates */
/**************** PQI_USE_XPGP ******************/
}
std::string get_cert_loc(cert *c)
{
/**************** PQI_USE_XPGP ******************/
#if defined(PQI_USE_XPGP)
return getX509LocString(c->certificate->subject -> subject);
#else
return getX509LocString(c->certificate->cert_info -> subject);
#endif /* XPGP Certificates */
/**************** PQI_USE_XPGP ******************/
}
std::string get_cert_country(cert *c)
{
/**************** PQI_USE_XPGP ******************/
#if defined(PQI_USE_XPGP)
return getX509CountryString(c->certificate->subject -> subject);
#else
return getX509CountryString(c->certificate->cert_info -> subject);
#endif /* XPGP Certificates */
/**************** PQI_USE_XPGP ******************/
}

View File

@ -0,0 +1,79 @@
/*
* "$Id: pqistrings.h,v 1.6 2007-02-18 21:46:49 rmf24 Exp $"
*
* FltkGUI for RetroShare.
*
* Copyright 2004-2006 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 PQI_STRINGS_H
#define PQI_STRINGS_H
#include <string>
#include <list>
class Person;
class cert;
#include <openssl/ssl.h>
std::string get_cert_country(cert *c);
std::string get_cert_loc(cert *c);
std::string get_cert_org(cert *c);
std::string get_cert_name(cert *c);
std::string get_status_string(int status);
std::string get_autoconnect_string(Person *p);
std::string get_server_string(Person *p);
std::string get_trust_string(Person *p);
std::string get_timeperiod_string(int secs);
std::string get_cert_info(cert *c);
std::string get_neighbour_info(cert *c);
int get_lastconnecttime(Person *p);
std::string get_lastconnecttime_string(Person *p);
std::string getX509NameString(X509_NAME *name);
std::string getX509Info(X509 *cert);
std::string getX509CNString(X509_NAME *name);
#define TIME_FORMAT_BRIEF 0x001
#define TIME_FORMAT_LONG 0x002
#define TIME_FORMAT_NORMAL 0x003
#define TIME_FORMAT_OLDVAGUE 0x004
#define TIME_FORMAT_OLDVAGUE_NOW 0x005
#define TIME_FORMAT_OLDVAGUE_WEEK 0x006
#define TIME_FORMAT_OLDVAGUE_OLD 0x007
std::string timeFormat(int epoch, int format);
#if defined(PQI_USE_XPGP)
std::string getXPGPInfo(XPGP *cert);
std::string getXPGPAuthCode(XPGP *xpgp);
std::list<std::string> getXPGPsigners(XPGP *cert);
#endif /* XPGP Certificates */
#endif

View File

@ -0,0 +1,338 @@
/*
* "$Id: retrotray.cc,v 1.5 2007-02-18 21:46:49 rmf24 Exp $"
*
* FltkGUI for RetroShare.
*
* Copyright 2004-2006 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 <windows.h>
#include <iostream>
#include <stdlib.h>
#include "fltkgui/retroTray.h"
#include "pqi/pqidebug.h"
static retroTray tray;
static NOTIFYICONDATA s_nid;
static std::string icn_path;
int SetIconPath(const char *iconpath)
{
icn_path = iconpath;
return 1;
}
int InitialiseRetroTray(HINSTANCE hi, HICON icn, UserInterface *ui)
{
tray.init(hi);
std::string iconpath = "/programs/icons";
std::string fname = "tst.ico";
// for now install a default one.
// if (icn == (HICON) NULL)
{
//icn = LoadCursorFromFile(fname.c_str());
icn = LoadCursorFromFile(icn_path.c_str());
//icn = (HICON) LoadImage(hi, fname.c_str(), IMAGE_ICON, 16, 16, 0);
std::cerr << "Loaded ICON: " << icn << std::endl;
}
//tray.loadIcons(iconpath);
tray.installIcon(icn, ui);
// while(1)
// Sleep(1000);
return 1;
}
static LRESULT CALLBACK systray_handler(HWND hwnd, UINT msg, WPARAM type0, LPARAM type) {
static UINT taskbarRestartMsg; /* static here means value is kept across multiple calls to this func */
std::cerr << "Call of The Handler(" << msg << ",";
std::cerr << type0 << "," << type << ")" << std::endl;
switch(msg) {
case WM_CREATE:
std::cerr << "WM_CREATE";
//taskbarRestartMsg = RegisterWindowMessage("TaskbarCreated");
break;
case WM_TIMER:
std::cerr << "WM_TIMER";
break;
case WM_DESTROY:
std::cerr << "WM_DESTROY";
break;
case WM_USER:
{
std::cerr << "WM_USER";
tray.buttonPressed(type0, type);
break;
}
default:
std::cerr << "default";
if (msg == taskbarRestartMsg)
{
std::cerr << " RESTART MSG";
//tray.InstallIcon(0);
}
break;
}
std::cerr << std::endl;
//return CallDefWindowProc(hwnd, msg, type0, type);
return CallWindowProc(DefWindowProc, hwnd, msg, type0, type);
}
retroTray::retroTray()
:hInst(0)
{
//ZeroMemory(&hwin, sizeof(hwin));
ZeroMemory(&nid, sizeof(nid));
return;
}
int retroTray::init(HINSTANCE hi)
{
hInst = hi;
return 1;
}
int retroTray::installIcon(HICON ic, UserInterface *ui)
{
retroRoot = ui;
hIcon = ic;
//(HICON) IDI_QUESTION;
//icn;
// First create hidden window (could be RetroShare)
if (nid.cbSize!=sizeof(NOTIFYICONDATA))
{
WNDCLASSEX wcex;
wcex.style = 0;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hIcon = NULL;
wcex.hIconSm = NULL;
wcex.hCursor = NULL;
wcex.hbrBackground = NULL;
wcex.lpszMenuName = NULL;
wcex.lpszClassName = "retroTray";
wcex.hInstance = hInst;
wcex.lpfnWndProc = (WNDPROC) systray_handler;
wcex.cbSize = sizeof(WNDCLASSEX);
RegisterClassEx(&wcex);
hWnd = CreateWindow("retroTray", "", 0,0,0,0,0,
GetDesktopWindow(), NULL, hInst, 0);
std::cerr << "Created Hidden Window" << std::endl;
}
ZeroMemory(&nid, sizeof(nid));
nid.hWnd = hWnd;
nid.uID = 0; //nextid++;
nid.uFlags= NIF_ICON | NIF_MESSAGE | NIF_TIP;
nid.uCallbackMessage=WM_USER;
nid.hIcon=hIcon;
strcpy(nid.szTip, "Hello World from RetroShare");
nid.cbSize=sizeof(NOTIFYICONDATA);
s_nid = nid;
if (Shell_NotifyIcon(NIM_ADD, &s_nid))
{
std::cerr << "Notify Success" << std::endl;
}
else
{
std::cerr << "Notify Failure" << std::endl;
}
std::cerr << "Icon Installed??" << std::endl;
return 1;
}
int retroTray::buttonPressed(int type0, int type)
{
std::cerr << "retroTray::buttonPressed(" << type0;
std::cerr << "," << type << ")" << std::endl;
if (type == WM_LBUTTONDBLCLK)
{
std::cerr << "Showing RetroShare!" << std::endl;
showRetroShare();
}
else if (type == WM_LBUTTONUP)
{
std::cerr << "Showing RetroShare(B)!" << std::endl;
showRetroShare();
}
else if (type == WM_MBUTTONUP)
{
std::cerr << "Hiding RetroShare!" << std::endl;
hideRetroShare();
}
else if (type == WM_RBUTTONDOWN)
{
std::cerr << "Showing TaskMenu!" << std::endl;
showTrayMenu();
}
else //if (type == WM_RBUTTONUP)
{
std::cerr << "Leaving RetroShare!" << std::endl;
// do nothing.
}
return 1;
}
//
//int retroTray::addIcon()
//{
// return 1;
//}
//
//
//int retroTray::removeIcon()
//{
// return 1;
//}
//
//
//int retroTray::exitCall()
//{
// // if
//static int times = 0;
// if (++times > 20)
// removeIcon();
// return 1;
//}
//
//
//
#define RTRAY_MENU_NULL 0
#define RTRAY_MENU_HIDE 1
#define RTRAY_MENU_SHOW 2
#define RTRAY_MENU_QUIT 3
int retroTray::showTrayMenu(void)
{
long menuChoice;
// First We need a Menu.
HMENU popup;
unsigned int flag;
popup = ::CreatePopupMenu();
flag = MF_BYPOSITION;
::InsertMenu(popup, 0, flag, RTRAY_MENU_QUIT, "Quit");
flag = MF_BYPOSITION | MF_SEPARATOR;
::InsertMenu(popup, 0, flag, 0x000, "Seperator");
flag = MF_BYPOSITION;
::InsertMenu(popup, 0, flag, RTRAY_MENU_HIDE, "Hide RetroShare");
::InsertMenu(popup, 0, flag, RTRAY_MENU_SHOW, "Open RetroShare");
flag = MF_BYPOSITION | MF_SEPARATOR;
::InsertMenu(popup, 0, flag, 0x000, "Seperator");
flag = MF_BYPOSITION;
::InsertMenu(popup, 0, flag, 0x001, "About RetroShare");
POINT pp;
RECT rect;
rect.left = 0;
rect.top = 0;
rect.right = 1000;
rect.bottom = 1000;
::GetCursorPos(&pp);
menuChoice = ::TrackPopupMenu(popup,
TPM_LEFTALIGN |
TPM_LEFTBUTTON |
TPM_RIGHTBUTTON |
TPM_NONOTIFY |
TPM_RETURNCMD,
pp.x,pp.y, 0, hWnd, &rect);
::DestroyMenu(popup);
// The value of SelectionMade is the id of the command selected or 0 if no
// selection was made
switch(menuChoice)
{
case RTRAY_MENU_NULL:
/*
AfxMessageBox("Starting Null");
*/
break;
case RTRAY_MENU_HIDE:
hideRetroShare();
break;
case RTRAY_MENU_SHOW:
showRetroShare();
break;
case RTRAY_MENU_QUIT:
/* before exiting - clear the debug log */
clearDebugCrashLog();
exit(1);
break;
}
return 1;
}
/**********************
HWND CreateDialog(
HINSTANCE hInstance,
LPCTSTR lpTemplate,
HWND hWndParent,
DLGPROC lpDialogFunc
);
**********************/

View File

@ -0,0 +1,112 @@
/*
* "$Id: retrotray.h,v 1.5 2007-02-18 21:46:49 rmf24 Exp $"
*
* FltkGUI for RetroShare.
*
* Copyright 2004-2006 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 MRK_RETRO_TRAY_H
#define MRK_RETRO_TRAY_H
/**
*
* This class encapsulates the windows? system tray icon.
*
*/
#include <windows.h>
#include <winsock2.h>
#include <process.h>
//#include <winbase.h>
//#include <winuser.h>
#include <shellapi.h>
#include <io.h>
// The Gui type of Window.
#include "fltkgui/guitab.h"
/**************** PQI_USE_XPGP ******************/
#if defined(PQI_USE_XPGP)
#include "pqi/xpgpcert.h"
#else /* X509 Certificates */
/**************** PQI_USE_XPGP ******************/
#include "pqi/sslcert.h"
#endif /* X509 Certificates */
/**************** PQI_USE_XPGP ******************/
int SetIconPath(const char *path);
int InitialiseRetroTray(HINSTANCE hi, HICON icn, UserInterface *ui);
class retroTray
{
public:
retroTray();
int init(HINSTANCE hi);
int installIcon(HICON icn, UserInterface *ui);
int buttonPressed(int, int);
private:
void showRetroShare()
{
if (getSSLRoot() -> active())
{
retroRoot -> main_win -> show();
visible = true;
}
else
{
retroRoot -> welcome_window -> show();
}
}
void hideRetroShare()
{
retroRoot -> main_win -> hide();
retroRoot -> welcome_window -> hide();
retroRoot -> alert_window -> hide();
retroRoot -> chatter_window -> hide();
visible = false;
}
int showTrayMenu();
HINSTANCE hInst;
HWND hWnd;
HICON hIcon;
NOTIFYICONDATA nid;
UserInterface *retroRoot;
bool visible;
};
#endif

27
libretroshare/src/licence Normal file
View File

@ -0,0 +1,27 @@
/*
* "$Id: licence,v 1.1 2007-02-18 21:46:42 rmf24 Exp $"
*
* TOU + 3P/PQI + RetroShare.
*
* Copyright 2004-2006 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".
*
*/

249
libretroshare/src/make.opt Normal file
View File

@ -0,0 +1,249 @@
####
#Define OS.
#
OS = Linux
#OS = Cygwin
#OS = Win # MinGw.
#
#
#
#
#
###########################################################################
###########################################################################
# Please Define these Variables before Compiling. (Examples below:)
# Linux (SSL_DIR & KADC_DIR)
# Cygwin (SSL_DIR & KADC_DIR & FLTK_DIR & PTHREADS_DIR)
# MinGW (SSL_DIR & KADC_DIR & FLTK_DIR & PTHREADS_DIR)
#### Linux/Cygwin Parameters.
#SSL_DIR=/home/xxx/prog/src/openssl-0.9.7g-xpgp-0.1c
#KADC_DIR=/home/xxx/prog/src/KadC
#
#### Cygwin Only....
#FLTK_DIR=/MinGWlibs/FLTK-1.1.6
#PTHREADS_DIR=/cygdrive/c/home/dev/prog/MinGw/pthreads/Pre-built.2
#KADC_DIR=/cygdrive/c/home/dev/prog/MinGW/KadC
#ZLIB_DIR=/cygdrive/c/home/dev/prog/MinGW/zlib-1.2.3
#
###########################################################################
# My Versions
ifeq ($(OS),Linux)
#Linux.
SSL_DIR=../../../../../../src/openssl-0.9.7g-xpgp-0.1c
KADC_DIR=../../../../../../src/KadC
UPNPC_DIR=../../../../../../src/miniupnpc-20070515
else
###########################################################################
ifeq ($(OS),Cygwin)
#Cygwin....
CYGWIN_SRC_ROOT=/cygdrive/c/home/rmfern/prog/MinGW
SSL_DIR=/home/rmfern/prog/src/openssl-0.9.7g
#SSL_DIR=$(CYGWIN_SRC_ROOT)/openssl-0.9.7g
FLTK_DIR=$(CYGWIN_SRC_ROOT)/FLTK-1.1.6
PTHREADS_DIR=$(CYGWIN_SRC_ROOT)/pthreads/pthreads.2
KADC_DIR=$(CYGWIN_SRC_ROOT)/debug/KadC-2006-Oct-19
ZLIB_DIR=$(CYGWIN_SRC_ROOT)/zlib-1.2.3
UPNPC_DIR=$(CYGWIN_SRC_ROOT)/libs/src/miniupnpc-20070515
else
#MinGw....
MINGW_SRC_ROOT=c:\home\rmfern\prog\MinGW
SSL_DIR=$(MINGW_SRC_ROOT)\openssl-0.9.7g
FLTK_DIR=$(MINGW_SRC_ROOT)\FLTK-1.1.6
PTHREADS_DIR=$(MINGW_SRC_ROOT)\pthreads\pthreads.2
KADC_DIR=$(MINGW_SRC_ROOT)\debug\KadC-2006-Oct-19
ZLIB_DIR=$(MINGW_SRC_ROOT)\zlib-1.2.3
UPNPC_DIR=$(MINGW_SRC_ROOT)\miniupnpc-20070515
endif
###########################################################################
endif
###########################################################################
ifndef RS_TOP_DIR
dummy:
echo "RS_TOP_DIR is not defined in your makefile"
endif
RS_DIR=$(RS_TOP_DIR)
ifndef SSL_DIR
dummy:
echo "you must define SSL_DIR before you can compile"
endif
ifndef KADC_DIR
dummy:
echo "you must define KADC_DIR before you can compile"
endif
ifneq ($(OS),Linux)
# no longer dependancy
# ifndef FLTK_DIR
#dummy:
# echo "you must define FLTK_DIR before you can compile"
# endif
#
ifndef PTHREADS_DIR
dummy:
echo "you must define PTHREADS_DIR before you can compile"
endif
endif
############ ENFORCE DIRECTORY NAMING ########################
CC = g++
# flags for components....
PQI_USE_XPGP = 1
PQI_USE_PROXY = 1
#PQI_USE_CHANNELS = 1
USE_FILELOOK = 1
ifeq ($(OS),Win)
# MinGw
INCLUDE = -I $(RS_DIR) -I$(KADC_DIR)
ifdef PQI_USE_XPGP
INCLUDE += -I $(SSL_DIR)\include
endif
else
# Unix: Linux/Cygwin
INCLUDE = -I $(RS_DIR) -I$(KADC_DIR)
ifdef PQI_USE_XPGP
INCLUDE += -I $(SSL_DIR)/include
endif
endif
CFLAGS = -Wall -g $(INCLUDE)
RANLIB = ranlib
LIBRS = ../lib/libretroshare.a
RSCFLAGS = -Wall -g $(INCLUDE)
ifdef PQI_USE_XPGP
CFLAGS += -DPQI_USE_XPGP
endif
ifdef PQI_USE_PROXY
CFLAGS += -DPQI_USE_PROXY
endif
ifdef PQI_USE_CHANNELS
CFLAGS += -DPQI_USE_CHANNELS
endif
ifdef USE_FILELOOK
CFLAGS += -DUSE_FILELOOK
endif
#########################################################################
# OS specific Includes/Libs.
# LINUX...
ifeq ($(OS),Linux)
# XLIBS arent needed for basic libretroshare.
# only needed for FLTK interface.
#XLIB = -lXft -lpthread -lXext -lX11 \
# -lXrender -lexpat -L/usr/X11R6/lib -lXau \
# -lXinerama -lXdmcp -lXext \
# -lfontconfig -lfreetype -lz
RM = /bin/rm
LIBDIR = $(RS_DIR)/lib
LIBS = -L$(LIBDIR) -lretroshare
ifdef PQI_USE_XPGP
LIBS += -L$(SSL_DIR)
endif
LIBS += -lssl -lcrypto -lpthread
LIBS += -L$(KADC_DIR) -lKadC
LIBS += -L$(UPNPC_DIR) -lminiupnpc
LIBS += $(XLIB) -ldl -lz
RSLIBS = $(LIBS)
else # windows (Cygwin or MinGW)
# for static pthread libs....
WININC += -DPTW32_STATIC_LIB
WINLIB = -lws2_32 -luuid -lole32 -liphlpapi
ifeq ($(OS),Cygwin)
# Cygwin
WININC += -mno-cygwin -mwindows -fno-exceptions -fomit-frame-pointer -DWINDOWS_SYS
WINLIB += -lcrypt32
# Cygwin
#CFLAGS += -I$(FLTK_DIR)/include
CFLAGS += -I$(PTHREADS_DIR) $(WININC)
CFLAGS += -I$(ZLIB_DIR)
LIBDIR = $(RS_DIR)/lib
LIBS = -L$(LIBDIR) -lretroshare
ifdef PQI_USE_XPGP
LIBS += -L$(SSL_DIR)
endif
LIBS += -lssl -lcrypto
LIBS += -L$(KADC_DIR) -lKadC
LIBS += -L$(UPNPC_DIR) -lminiupnpc
LIBS += -L$(ZLIB_DIR) -lz
RSLIBS += $(LIBS)
RSLIBS += -L$(PTHREADS_DIR) -lpthreadGC2d
RSLIBS += $(WINLIB)
LIBS += $(WINLIB)
RSCFLAGS += $(WININC)
RM = /bin/rm
else # MinGw.
#WININC += -mwindows -fno-exceptions -fomit-frame-pointer -DWINDOWS_SYS
WININC += -frtti -fexceptions -DWINDOWS_SYS
WINLIB += -lcrypt32-cygwin
# Cygwin
CFLAGS += -I$(PTHREADS_DIR) $(WININC)
CFLAGS += -I$(ZLIB_DIR)
#CFLAGS += -I$(FLTK_DIR)\include
LIBDIR = $(RS_DIR)\lib
LIBS = -L$(LIBDIR) -lretroshare
ifdef PQI_USE_XPGP
LIBS += -L$(SSL_DIR)
endif
LIBS += -lssl -lcrypto
LIBS += -L$(KADC_DIR) -lKadC
LIBS += -L$(UPNPC_DIR) -lminiupnpc
LIBS += -L$(ZLIB_DIR) -lz
RSLIBS = $(LIBS)
RSLIBS += -L$(PTHREADS_DIR) -lpthreadGC2d
LIBS += $(WINLIB)
RSLIBS += $(WINLIB)
RSCFLAGS += $(WININC)
RM = del
endif
endif

View File

@ -0,0 +1,89 @@
RS_TOP_DIR = ..
include ../make.opt
# All the executables that should be generated.
EXECS = # test_p3items
BASE_OBJ = pqi_base.o pqi.o pqipacket.o \
pqidebug.o pqisecurity.o pqinetwork.o \
pqistreamer.o pqibin.o pqimon.o
TUNN_OBJ = pqitunnel.o pqitunneltst.o
LOOP_OBJ = pqiloopback.o p3loopback.o
DISC_OBJ = discItem.o p3disc.o
ifdef PQI_USE_XPGP
SSL_OBJ = xpgpcert.o
# Disabled for release... EXECS += p3supernode
else
SSL_OBJ = sslcert.o
endif
SSL_OBJ += pqissl.o pqiarchive.o pqissllistener.o
GRP_OBJ = pqiperson.o pqihandler.o pqipersongrp.o
UDP_OBJ = pqistunner.o pqiudpproxy.o pqissludp.o pqitunnelproxyudp.o
PRXY_OBJ = pqiproxy.o pqitunnelproxy.o
CHAN_OBJ = p3channel.o pqichannel.o
SN_OBJ = pqisupernode.o
OBJ = $(BASE_OBJ) $(TUNN_OBJ) $(LOOP_OBJ) $(DISC_OBJ) \
$(GRP_OBJ) $(SSL_OBJ) $(CHAN_OBJ) $(PRXY_OBJ) $(UDP_OBJ)
# Linux only parts.
ifeq ($(OS),Linux)
OBJ += $(SN_OBJ)
endif
BASE_HDR = pqi_base.h pqi.h pqi_data.h pqipacket.h pqisecurity.h pqinetwork.h \
pqidebug.h pqistreamer.h pqiarchive.h pqiindic.h pqibin.h
TUNN_HDR = pqitunnel.h pqitunneltst.h
LOOP_HDR = p3loopback.h pqiloopback.h
DISC_HDR = discItem.h p3disc.h
SSL_HDR = pqissl.h pqissllistener.h xpgpcert.h
GPR_HDR = pqihandler.h pqiperson.h pqipersongrp.h
UDP_HDR = pqistunner.h pqiudpproxy.h pqissludp.h pqitunnelproxyudp.h
PRXY_HDR = pqitunnelproxy.h pqiproxy.h
CHAN_HDR = pqichannel.h p3channel.h
SN_HDR = pqisupernode.h
HDR = $(BASE_HDR) $(TUNN_HDR) $(LOOP_HDR) $(DISC_HDR) \
$(GRP_HDR) $(SSL_HDR) $(CHAN_HDR) $(PRXY_HDR) $(UDP_HDR)
LIBPQIA = $(LIBDIR)/libpqi.a
LIBPQISO = $(LIBDIR)/libpqi.so
# decide on output format...... Lib for Unix, Objs for windows,
ifeq ($(OS),Linux)
all : librs $(EXECS)
else
all : librs
endif
librs: $(OBJ)
$(AR) r $(LIBRS) $(OBJ)
$(RANLIB) $(LIBRS)
$(OBJ) : $(HDR)
p3supernode: p3supernode.o librs
$(CC) $(CFLAGS) -o p3supernode p3supernode.o $(RSLIBS)
.cc.o:
$(CC) $(CFLAGS) -c $<
clean:
-/bin/rm $(OBJ) p3supernode.o
clobber: clean
-/bin/rm $(EXECS) $(LIBPQIA) $(LIBPQISO)

View File

@ -0,0 +1,353 @@
/*
* "$Id: discItem.cc,v 1.8 2007-02-18 21:46:49 rmf24 Exp $"
*
* 3P/PQI network interface for RetroShare.
*
* Copyright 2004-2006 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 "pqi/discItem.h"
static const int pqidizone = 44863;
#include "pqi/pqidebug.h"
#include <sstream>
PQTunnel *createDiscItems(void *d, int n)
{
pqioutput(PQL_DEBUG_BASIC, pqidizone,
"createDiscItems()");
// check the discType of DiscItem;
if ( ((int *) d)[0] == 0)
{
return new DiscItem();
}
return new DiscReplyItem();
}
DiscItem::DiscItem()
:PQTunnel(PQI_TUNNEL_DISC_ITEM_TYPE), discType(0), discFlags(0)
{
pqioutput(PQL_DEBUG_BASIC, pqidizone,
"DiscItem::DiscItem()");
return;
}
DiscItem *DiscItem::clone()
{
pqioutput(PQL_DEBUG_BASIC, pqidizone,
"DiscItem::clone()");
DiscItem *di = new DiscItem();
di -> copy(this);
return di;
}
void DiscItem::copy(const DiscItem *di)
{
pqioutput(PQL_DEBUG_BASIC, pqidizone,
"DiscItem::copy()");
PQTunnel::copy(di);
discType = di -> discType;
saddr = di -> saddr;
laddr = di -> laddr;
receive_tr = di -> receive_tr;
connect_tr = di -> connect_tr;
discFlags = di -> discFlags;
}
// Overloaded from PQTunnel.
const int DiscItem::getSize() const
{
return 3 * 4 + 2 * sizeof(struct sockaddr_in);
}
int DiscItem::out(void *data, const int size) const
{
{
std::ostringstream out;
out << "DiscItem::out() Data: " << data;
out << " Size: " << size << std::endl;
pqioutput(PQL_DEBUG_BASIC, pqidizone, out.str());
}
if (size < DiscItem::getSize())
{
pqioutput(PQL_DEBUG_BASIC, pqidizone,
"DiscItem::out() Packet Too Small!");
return -1;
}
char *dta = (char *) data;
((int *) dta)[0] = discType;
dta += 4;
((struct sockaddr_in *) dta)[0] = saddr;
dta += sizeof(sockaddr_in);
((struct sockaddr_in *) dta)[0] = laddr;
dta += sizeof(sockaddr_in);
// version 1....
// : 4 bytes for receive_tr
// : 4 bytes for connect_tr
//((int *) dta)[0] = receive_tr;
//dta += 4;
//((int *) dta)[0] = connect_tr;
//dta += 4;
// version 2....
// : 2 bytes for receive_tf
// : 2 bytes for connect_tf
// : 4 bytes for cert->flags.
((unsigned short *) dta)[0] = htons(receive_tr);
dta += 2;
((unsigned short *) dta)[0] = htons(connect_tr);
dta += 2;
((unsigned long *) dta)[0] = htonl(discFlags);
dta += 4;
return DiscItem::getSize();
}
int DiscItem::in(const void *data, const int size)
{
{
std::ostringstream out;
out << "DiscItem::in() Data: " << data;
out << " Size: " << size << std::endl;
pqioutput(PQL_DEBUG_BASIC, pqidizone, out.str());
}
if (size < DiscItem::getSize())
{
std::ostringstream out;
out << "DiscItem::in() Pkt to small";
pqioutput(PQL_DEBUG_BASIC, pqidizone, out.str());
return -1;
}
char *dta = (char *) data;
discType = ((int *) dta)[0];
dta += 4;
saddr = ((struct sockaddr_in *) dta)[0];
dta += sizeof(sockaddr_in);
laddr = ((struct sockaddr_in *) dta)[0];
dta += sizeof(sockaddr_in);
// version 1....
// : 4 bytes for receive_tr
// : 4 bytes for connect_tr
//receive_tf = ((int *) dta)[0];
//dta += 4;
//connect_tf = ((int *) dta)[0];
//dta += 4;
// version 2....
// : 2 bytes for receive_tr
// : 2 bytes for connect_tr
// : 4 bytes for cert->flags.
receive_tr = ntohs(((unsigned short *) dta)[0]);
dta += 2;
connect_tr = ntohs(((unsigned short *) dta)[0]);
dta += 2;
discFlags = ntohl(((unsigned long *) dta)[0]);
dta += 4;
return getSize();
}
std::ostream &DiscItem::print(std::ostream &out)
{
out << "-------- DiscItem" << std::endl;
PQItem::print(out);
out << "Peer Details" << std::endl;
out << "Local Address: " << inet_ntoa(laddr.sin_addr);
out << " Port: " << ntohs(laddr.sin_port) << std::endl;
out << "Server Address: " << inet_ntoa(saddr.sin_addr);
out << " Port: " << ntohs(saddr.sin_port) << std::endl;
out << "[R/C]_TF: " << receive_tr;
out << "/" << connect_tr << std::endl;
out << "discFlags: " << discFlags << std::endl;
return out << "--------" << std::endl;
}
DiscReplyItem::DiscReplyItem()
:DiscItem(), certDER(NULL), certLen(0)
{
pqioutput(PQL_DEBUG_BASIC, pqidizone,
"DiscReplyItem::DiscReplyItem()");
discType = 1;
return;
}
DiscReplyItem::~DiscReplyItem()
{
pqioutput(PQL_DEBUG_BASIC, pqidizone,
"DiscReplyItem::~DiscReplyItem()");
if (certDER != NULL)
{
free(certDER);
certDER = NULL;
certLen = 0;
}
}
DiscReplyItem *DiscReplyItem::clone()
{
pqioutput(PQL_DEBUG_BASIC, pqidizone,
"DiscReplyItem::clone()");
DiscReplyItem *di = new DiscReplyItem();
di -> copy(this);
return di;
}
void DiscReplyItem::copy(const DiscReplyItem *di)
{
pqioutput(PQL_DEBUG_BASIC, pqidizone,
"DiscReplyItem::copy()");
DiscItem::copy(di);
if (di -> certDER != NULL)
{
certLen = di -> certLen;
certDER = (unsigned char *) malloc(certLen);
memcpy(certDER, di -> certDER, certLen);
}
else
{
certLen = 0;
certDER = NULL;
}
return;
}
// Overloaded from PQTunnel.
const int DiscReplyItem::getSize() const
{
return DiscItem::getSize() + 4 + certLen;
}
int DiscReplyItem::out(void *data, const int maxsize) const
{
{
std::ostringstream out;
out << "DiscReplyItem::out() Data: " << data;
out << " Size: " << maxsize << std::endl;
pqioutput(PQL_DEBUG_BASIC, pqidizone, out.str());
}
if (maxsize < getSize())
{
std::ostringstream out;
out << "DiscReplyItem::out() Not Enough space";
pqioutput(PQL_DEBUG_BASIC, pqidizone, out.str());
return -1;
}
int basesize = DiscItem::getSize();
// put out the DiscItem Part.
DiscItem::out(data, basesize);
char *loc = ((char *) data) + basesize;
((int *) loc)[0] = certLen;
loc += 4;
memcpy(loc, certDER, certLen);
return getSize();
}
int DiscReplyItem::in(const void *data, const int size)
{
{
std::ostringstream out;
out << "DiscReplyItem::in() Data: " << data;
out << " Size: " << size << std::endl;
pqioutput(PQL_DEBUG_BASIC, pqidizone, out.str());
}
// harder.
int basesize = DiscItem::getSize();
if (basesize + 4 > size)
{
pqioutput(PQL_DEBUG_BASIC, pqidizone,
"DiscReplyItem::in() Not enough space for Base Class!");
return -1; // cant be us.
}
// read in the DiscItem part.
DiscItem::in(data, DiscItem::getSize());
char *loc = ((char *) data) + basesize;
int certsize = ((int *) loc)[0];
// check the size again.
if (basesize + 4 + certsize != size)
{
pqioutput(PQL_DEBUG_BASIC, pqidizone,
"DiscReplyItem::in() Not enough space for Certificate");
return -1;
}
loc += 4;
// allocate memory for certDER....
if ((certLen != certsize) && (!certLen))
{
if (certDER)
free(certDER);
}
certLen = certsize;
if (!certDER)
{
certDER = (unsigned char *) malloc(certsize);
}
memcpy(certDER, loc, certLen);
return getSize();
}
std::ostream &DiscReplyItem::print(std::ostream &out)
{
out << "---------------- DiscReplyItem" << std::endl;
out << "A Friend of a Friend:" << std::endl;
DiscItem::print(out);
if (certDER != NULL)
{
out << "CertLen: " << certLen << std::endl;
}
else
{
out << "No Certificate" << std::endl;
}
return out << "----------------" << std::endl;
}

View File

@ -0,0 +1,90 @@
/*
* "$Id: discItem.h,v 1.6 2007-02-18 21:46:49 rmf24 Exp $"
*
* 3P/PQI network interface for RetroShare.
*
* Copyright 2004-2006 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 MRK_PQI_DISCITEM_H
#define MRK_PQI_DISCITEM_H
#include "pqi/pqitunnel.h"
#define PQI_TUNNEL_DISC_ITEM_TYPE 121
PQTunnel *createDiscItems(void *d, int n);
class DiscItem: public PQTunnel
{
protected:
DiscItem(int st);
public:
DiscItem();
virtual DiscItem *clone();
void copy(const DiscItem *di);
virtual std::ostream &print(std::ostream &out);
// Overloaded from PQTunnel.
virtual const int getSize() const;
virtual int out(void *data, const int size) const;
virtual int in(const void *data, const int size);
int discType; // specifies subtypes.
struct sockaddr_in laddr;
struct sockaddr_in saddr;
// time frame of recent connections.
unsigned short connect_tr;
unsigned short receive_tr;
// flags...
unsigned long discFlags;
};
class DiscReplyItem: public DiscItem
{
public:
DiscReplyItem();
virtual ~DiscReplyItem();
virtual DiscReplyItem *clone();
void copy(const DiscReplyItem *di);
virtual std::ostream &print(std::ostream &out);
// Overloaded from PQTunnel.
virtual const int getSize() const;
virtual int out(void *data, const int size) const;
virtual int in(const void *data, const int size);
unsigned char *certDER;
int certLen;
};
#define AUTODISC_RDI_SUBTYPE_PING 1
#define AUTODISC_RDI_SUBTYPE_RPLY 2
#define AUTODISC_LDI_SUBTYPE_PING 1
#define AUTODISC_LDI_SUBTYPE_RPLY 2
#endif // MRK_PQI_DISCITEM_H

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,314 @@
/*
* "$Id: p3channel.h,v 1.6 2007-03-05 21:26:03 rmf24 Exp $"
*
* 3P/PQI network interface for RetroShare.
*
* Copyright 2004-2006 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 MRK_P3_CHANNEL_H
#define MRK_P3_CHANNEL_H
#include "pqi/pqichannel.h"
/****
* This is our channel class.
* It performs various functions.
* 1) collect channel messages.
* 2) save/restore messages.
* 3) manage their downloads....
* 4) rebroadcast messages.
*
* You need to be able to categorise the channels
* 1) Favourites.
* 2) Standard Subscription
* 3) Listen
* 4) Others.
*
* The first three groups will be maintained.
*
* Controllable how long lists are maintained. (1 week standard)
*
* Messages are rebroadcast, At a random interval (0 - 4 hours) after
* receiving the message.
*
* Popularity rating on how much each is rebroadcast.
*
*
* There should be a couple of rating schemes to decide
* on how long something stays downloaded.
*
* 1) Time, Old stuff first.
* 2) Volume....
* 3) Size.
* 4) Popularity.
*
*/
#include <string>
#include <list>
#include <time.h>
#include "pqi/pqi.h"
/**************** PQI_USE_XPGP ******************/
#if defined(PQI_USE_XPGP)
#include "pqi/xpgpcert.h"
#else /* X509 Certificates */
/**************** PQI_USE_XPGP ******************/
#include "pqi/sslcert.h"
#endif /* X509 Certificates */
/**************** PQI_USE_XPGP ******************/
#include "pqi/discItem.h"
#include "pqi/pqitunnel.h"
/* Size of these should match the RsInterface (for ease of use ) - 16 bytes */
//#define CHAN_SIGN_SIZE 16
class channelSign
{
public:
bool operator<(const channelSign &s) const;
bool operator==(const channelSign &s) const;
std::ostream& print(std::ostream&) const;
std::ostream& printHex(std::ostream&) const;
char sign[CHAN_SIGN_SIZE];
};
typedef channelSign MsgHash;
class channelKey
{
public:
channelKey(EVP_PKEY *k);
channelKey();
virtual ~channelKey();
bool valid();
int load(const unsigned char *d, int len);
int setKey(EVP_PKEY *k);
int out(unsigned char *d, int len);
bool operator<(const channelKey &k) const;
bool operator==(const channelKey &k) const;
std::ostream& print(std::ostream&) const;
channelSign getSign() const;
EVP_PKEY * getKey() const;
private:
int calcSign();
EVP_PKEY *key;
char sign[CHAN_SIGN_SIZE];
};
typedef time_t TimeStamp;
//class TimeStamp
//{
// public:
//
// int yr, month, day, hour, min, sec;
//};
//
class chanMsgSummary
{
public:
std::string msg;
MsgHash mh;
int nofiles;
int totalsize;
TimeStamp recvd;
};
// This is used For Msg + Info storage.
class channelMsg
{
public:
channelMsg(PQChanItem *in, TimeStamp now, TimeStamp reb);
PQChanItem *msg;
int receivedCount;
TimeStamp recvTime;
bool rebroadcast;
TimeStamp rbcTime;
bool downloaded;
TimeStamp dldTime;
bool save;
};
// a little helper function.
channelSign getChannelSign(PQChanItem *ci);
channelKey * getChannelKey(PQChanItem *ci);
MsgHash getMsgHash(PQChanItem *ci);
class pqichannel
{
public:
pqichannel(sslroot *, channelKey *, std::string title, int mode);
virtual ~pqichannel() { return; }
// retrieval.
channelMsg *findMsg(MsgHash mh);
int getMsgSummary(std::list<chanMsgSummary> &summary);
int processMsg(PQChanItem *in);
int pruneOldMsgs();
// check packet signature (with channel key)
// check key matches ours.
// if we have it, increment the counter.
// else add in.
// fill with outgoing
int reBroadcast(std::list<PQTunnel *> &outgoing);
channelSign getSign();
channelKey *getKey();
int getMode() { return mode; }
std::string getName() { return channelTitle; }
float getRanking() { return ranking; }
int getMsgCount() { return msgByHash.size(); }
std::ostream& print(std::ostream&);
protected:
sslroot *sroot;
private:
// analysis functions
TimeStamp getCurrentTimeStamp();
bool checkPktSignature(PQChanItem*);
//MsgHash getPktHash(PQChanItem*);
int mode; // Fav, Sub, Listen, Other.
std::map<MsgHash, channelMsg *> msgByHash;
std::string channelTitle;
float ranking;
protected: // needed by pqichanneler.
channelKey *key;
};
// specialisation with the private key, and output.
class pqichanneler: public pqichannel
{
public:
pqichanneler(sslroot *s,
channelKey *priv, channelKey *pub,
std::string title);
virtual ~pqichanneler() { return; }
// Takes a partially constructed Msg,
// fills in the signature....
// then all it has to do is pass it
// to the pqichannel which will handle the
// distribution.
int sendmsg(PQChanItem *);
private:
channelKey *privkey;
};
class p3channel: public PQTunnelService
{
public:
p3channel(sslroot *r);
virtual ~p3channel();
// PQTunnelService functions.
virtual int receive(PQTunnel *);
virtual PQTunnel *send();
virtual int tick();
// doesn't use the init functions.
virtual int receive(PQTunnelInit *i) { delete i; return 1; }
virtual PQTunnelInit *sendInit() { return NULL; }
// End of PQTunnelService functions.
// load and save configuration.
int save_configuration();
int load_configuration();
// test functions.
int generateRandomMsg();
int generateRandomKeys(channelKey *priv, channelKey *pub);
// retrieval fns.
pqichannel *findChannel(channelSign s);
int getChannelList(std::list<pqichannel *> &chans);
private:
// so we need an interface for the data.
int handleIncoming();
int printMsgs();
// first storage.
std::map<channelSign, pqichannel *> channels;
//
int reBroadcast();
// maintainance.
int pruneOldMsgs();
// counters.
int ts_nextlp;
int min10Count;
std::list<cert *> discovered;
sslroot *sroot;
// Storage for incoming/outgoing.
std::list<PQItem *> inpkts;
std::list<PQItem *> outpkts;
};
#endif // MRK_P3_CHANNEL_H

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,186 @@
/*
* "$Id: p3disc.h,v 1.11 2007-02-18 21:46:49 rmf24 Exp $"
*
* 3P/PQI network interface for RetroShare.
*
* Copyright 2004-2006 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 MRK_PQI_AUTODISC_H
#define MRK_PQI_AUTODISC_H
// The AutoDiscovery Class
#include <string>
#include <list>
// system specific network headers
#include "pqi/pqinetwork.h"
#include "pqi/pqi.h"
/**************** PQI_USE_XPGP ******************/
#if defined(PQI_USE_XPGP)
#include "pqi/xpgpcert.h"
#else /* X509 Certificates */
/**************** PQI_USE_XPGP ******************/
#include "pqi/sslcert.h"
#endif /* X509 Certificates */
/**************** PQI_USE_XPGP ******************/
#include "pqi/discItem.h"
#include "pqi/pqitunnel.h"
class autoserver
{
public:
autoserver()
:id(NULL), ca(NULL), connect(false), c_ts(0),
listen(false), l_ts(0), discFlags(0) { return;}
Person *id;
Person *ca;
bool connect;
unsigned int c_ts; // this is connect_tf converted to timestamp, 0 invalid.
bool listen;
unsigned int l_ts; // this is receive_tf converted to timestamp, 0 invalid.
struct sockaddr_in local_addr;
struct sockaddr_in server_addr;
unsigned long discFlags;
};
class autoneighbour: public autoserver
{
public:
autoneighbour()
:autoserver(), local(false), active(false) {}
bool local;
bool active; // meaning in ssl's list.
std::list<autoserver *> neighbour_of;
};
class p3disc: public PQTunnelService
{
public:
bool local_disc;
bool remote_disc;
//sslroot *sslbase;
p3disc(sslroot *r);
virtual ~p3disc();
// PQTunnelService functions.
virtual int receive(PQTunnel *);
virtual PQTunnel *send();
virtual PQTunnel *getObj();
virtual int tick();
// doesn't use the init functions.
virtual int receive(PQTunnelInit *i) { delete i; return 1; }
virtual PQTunnelInit *sendInit() { return NULL; }
virtual PQTunnelInit *getObjInit() { return NULL; }
// End of PQTunnelService functions.
//
// For Proxy Information.
std::list<sockaddr_in> requestStunServers();
std::list<cert *> potentialproxy(cert *target);
// load and save configuration to sslroot.
int save_configuration();
int load_configuration();
int ts_lastcheck;
int idServers();
// Handle Local Discovery.
int localListen();
int localSetup();
int lsock; // local discovery socket.
struct sockaddr_in laddr; // local addr
struct sockaddr_in baddr; // local broadcast addr.
struct sockaddr_in saddr; // pqi ssl server addr.
// bonus configuration flags.
bool local_firewalled;
bool local_forwarded;
// local message construction/destruction.
void *ldata;
int ldlen;
int ldlenmax;
bool std_port; // if we have bound to default.
int ts_nextlp; // -1 for never (if on default)
// helper functions.
int setLocalAddress(struct sockaddr_in srvaddr);
int determineLocalNetAddr();
int setupLocalPacket(int type, struct sockaddr_in *home,
struct sockaddr_in *server);
int localPing(struct sockaddr_in);
int localReply(struct sockaddr_in);
int addLocalNeighbour(struct sockaddr_in*, struct sockaddr_in*);
// remote discovery function.
int newRequests();
int handleReplies();
int handleDiscoveryData(DiscReplyItem *di);
int handleDiscoveryPing(DiscItem *di);
int sendDiscoveryReply(cert *);
int collectCerts();
int distillData();
//cert *checkDuplicateX509(X509 *x509);
std::list<cert *> &getDiscovered();
// Main Storage
std::list<autoneighbour *> neighbours;
std::list<cert *> ad_init;
std::list<cert *> discovered;
sslroot *sroot;
// Storage for incoming/outgoing.
std::list<PQItem *> inpkts;
std::list<PQItem *> outpkts;
};
#endif // MRK_PQI_AUTODISC_H

View File

@ -0,0 +1,341 @@
/*
* "$Id: p3loopback.cc,v 1.3 2007-02-18 21:46:49 rmf24 Exp $"
*
* 3P/PQI network interface for RetroShare.
*
* Copyright 2004-2006 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 "pqi/pqi.h"
#include "pqi/p3loopback.h"
// Test Interface (LoopBack)
p3loopback::~p3loopback()
{
// should clean up lists ...
// delete all random search items...
// fix later..
return;
}
int p3loopback::Search(SearchItem *si)
{
// no more copy - just use.
// tag as new.
si -> flags = 1;
// add to requested searches.
searches[si -> sid] = si;
return 1;
}
int p3loopback::CancelSearch(SearchItem *item)
{
std::map<int, SearchItem *>::iterator it;
std::list<PQFileItem *>::iterator it2;
unsigned int sid = item -> sid;
// Quick Sanity Check.
it = searches.find(sid);
if (it == searches.end())
{
std::cerr << "p3loopback::CancelSearch(" << sid;
std::cerr << ") Search Not Found!" << std::endl;
return -2;
}
// found search delete.
SearchItem *osi = it -> second;
searches.erase(it);
// find anything matching in the list.
for(it2 = searchResults.begin(); it2 != searchResults.end();)
{
if ((*it2) -> sid == sid) // erase
{
PQFileItem *osr = (*it2);
it2 = searchResults.erase(it2);
delete osr;
}
else
{
it2++;
}
}
cancelledSearches.push_back(osi);
// clean up input.
delete item;
return 1;
}
PQFileItem * p3loopback::GetSearchResult()
{
std::list<PQFileItem *>::iterator it;
it = searchResults.begin();
if (it == searchResults.end()) // empty list
{
return NULL;
}
PQFileItem *osr = (*it);
searchResults.erase(it);
// set as local...
osr -> flags |= PQI_ITEM_FLAG_LOCAL;
return osr;
}
int p3loopback::GetFile(PQFileItem *item, std::ostream &in)
{
// save a stream ....
// send on the request.
//fixme("p3loopback::GetFile()", 1);
return 1;
}
int p3loopback::CancelFile(PQFileItem *item)
{
// close down stream (if we created it)
// send on request.
//fixme("p3loopback::CancelFile()", 1);
return 1;
}
// Remote Requests.
SearchItem *p3loopback::RequestedSearch()
{
std::map<int, SearchItem *>::iterator it;
SearchItem *ns;
for(it = searches.begin(); it != searches.end(); it++)
{
// check if new...
if ((it -> second) -> flags == 1)
{
// generate new sid number.
int rsid = getPQIsearchId();
int sid = (it -> second) -> sid;
// setup translation stuff.
sid2rsid[sid] = rsid;
ns = new SearchItem();
ns -> copy(it -> second);
(it -> second) -> flags = 0;
ns -> sid = rsid;
return ns;
}
}
return NULL;
}
SearchItem *p3loopback::CancelledSearch()
{
std::list<SearchItem *>::iterator it;
std::map<int, int>::iterator mit;
it = cancelledSearches.begin();
if (it == cancelledSearches.end()) // empty list
{
return NULL;
}
// else copy into structure.
SearchItem *ncs = (*it);
cancelledSearches.erase(it);
// get from mapping.
mit = sid2rsid.find(ncs -> sid);
if (mit == sid2rsid.end()) // error
{
std::cerr << "Error No Mapping (Cancelling the Cancel)!";
std::cerr << "But Still deleting item";
std::cerr << std::endl;
delete ncs;
return NULL;
}
else
{
ncs -> sid = mit -> second;
sid2rsid.erase(mit);
}
return ncs;
}
int p3loopback::SendSearchResult(PQFileItem *item)
{
//std::list<SearchItem *> >::iterator it;
std::map<int, int>::iterator it;
int rsid = item -> sid;
int sid = 0;
// get from mapping.
for(it = sid2rsid.begin(); ((it != sid2rsid.end()) && (sid == 0)); it++)
{
if (rsid == (it -> second))
{
sid = it -> first;
}
}
// if no mapping.
if (sid == 0)
{
std::cerr << "SendSearchResult::Error No Mapping (Removing Item)!";
std::cerr << std::endl;
delete item;
return 0;
}
// have mapping.... translate.
item -> sid = sid;
// stick on the queue.
searchResults.push_back(item);
return 1;
}
PQFileItem *p3loopback::RequestedFile()
{
// check for searches with new tag...
// if none return 0;
// copy data from first.
// mark old.
//fixme("p3loopback::RequestedFile()", 1);
return NULL;
}
PQFileItem *p3loopback::CancelledFile()
{
// check for cancelled files.
// if none return 0;
// copy data from first.
// remove/cleanup
//fixme("p3loopback::CancelledFile()", 1);
return NULL;
}
int p3loopback::SendFile(PQFileItem *, std::istream &out)
{
// get data...
// attach streams.....
//
//fixme("p3loopback::SendFile()", 1);
return 1;
}
//
//// control interface.
//int p3loopback::RequestInfo(InfoItem *item)
//{
// switch(item -> querytype)
// {
// case PQI_II_QUERYTYPE_TAG:
// item -> answer = "<++Local++>";
// return 1;
// break;
//
// case PQI_II_QUERYTYPE_CLASS:
// item -> answer = "p3loopback";
// return 1;
// break;
//
// default:
// return 0;
// break;
// }
// return -1;
//
// return 0;
//}
//
//int p3loopback::doCommand(CommandItem *)
//{
// //fixme("p3loopback::doCommand()", 1);
// return 0;
//}
//
// // chat interface.
int p3loopback::SendMsg(ChatItem *item)
{
//fixme("p3loopback::SendMsg()", 1);
return 0;
}
ChatItem *p3loopback::GetMsg()
{
//fixme("p3loopback::GetMsg()", 1);
return NULL;
}
int p3loopback::SendOtherPQItem(PQItem *item)
{
other.push_back(item);
return 1;
}
PQItem *p3loopback::GetOtherPQItem()
{
if (other.size() != 0)
{
PQItem *i = other.front();
other.pop_front();
return i;
}
return NULL;
}
// // PQI interface.
int p3loopback::tick()
{
//fixme("p3loopback::tick()", 1);
return 0;
}
int p3loopback::status()
{
//fixme("p3loopback::status()", 1);
return 0;
}

View File

@ -0,0 +1,91 @@
/*
* "$Id: p3loopback.h,v 1.4 2007-02-18 21:46:49 rmf24 Exp $"
*
* 3P/PQI network interface for RetroShare.
*
* Copyright 2004-2006 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 MRK_P3_LOOPBACK_HEADER
#define MRK_P3_LOOPBACK_HEADER
// The standard data types and the search interface.
#include "pqi/pqi.h"
#include <map>
#include <list>
// Test Interface (LoopBack)
// public interface .... includes the whole p3interface.
class p3loopback: public P3Interface
{
public:
virtual ~p3loopback();
// search Interface.
virtual int Search(SearchItem *item);
virtual int CancelSearch(SearchItem *item);
virtual PQFileItem *GetSearchResult();
virtual int GetFile(PQFileItem *item, std::ostream &in);
virtual int CancelFile(PQFileItem *);
virtual SearchItem *RequestedSearch();
virtual SearchItem *CancelledSearch();
virtual int SendSearchResult(PQFileItem *item);
virtual PQFileItem *RequestedFile();
virtual PQFileItem *CancelledFile();
virtual int SendFile(PQFileItem *, std::istream &out);
// control interface.
//virtual int RequestInfo(InfoItem *);
//virtual int doCommand(CommandItem *);
// chat interface.
virtual int SendMsg(ChatItem *item);
virtual ChatItem *GetMsg();
// PQI interface.
virtual int tick();
virtual int status();
virtual int SendOtherPQItem(PQItem *);
virtual PQItem *GetOtherPQItem();
private:
std::list<PQFileItem *> searchResults;
std::map<int, SearchItem *> searches;
std::map<int, SearchItem *> files;
std::list<SearchItem *> cancelledSearches;
std::list<SearchItem *> cancelledFiles;
std::list<PQItem *> other;
// remote mapping
std::map<int, int> sid2rsid;
};
#endif //MRK_P3_LOOPBACK_HEADER

View File

@ -0,0 +1,317 @@
/*
* "$Id: p3supernode.cc,v 1.3 2007-02-18 21:46:49 rmf24 Exp $"
*
* 3P/PQI network interface for RetroShare.
*
* Copyright 2004-2006 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 "pqi/pqisupernode.h"
#include <list>
#include <string>
// Includes for directory creation.
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
// Conflicts with FLTK def - hope they are the same.
//#include <dirent.h>
// for blocking signals
#include <signal.h>
#include "pqi/pqidebug.h"
void load_check_basedir();
// Global Pointers for the callback functions.
// initial configuration bootstrapping...
static const std::string config_init_file = "default_cert.txt";
static const std::string config_file = "config.rs";
static const std::string cert_dir = "friends";
static const std::string key_dir = "keys";
static const std::string ca_file = "cacerts.pem";
static std::string config_basedir;
static std::string load_cert;
static std::string load_key;
static std::string load_cacert;
void load_check_basedir();
static const char dirSeperator = '/'; // For unix.
// standard start for unix.
int main(int argc, char **argv)
{
// setup debugging for desired zones.
setOutputLevel(PQL_ALERT); // to show the others.
setZoneLevel(PQL_ALERT, 38422); // pqipacket.
setZoneLevel(PQL_ALERT, 96184); // pqinetwork;
setZoneLevel(PQL_ALERT, 82371); // pqiperson.
setZoneLevel(PQL_ALERT, 60478); // pqitunnel.
setZoneLevel(PQL_ALERT, 34283); // pqihandler.
setZoneLevel(PQL_ALERT, 44863); // discItems.
setZoneLevel(PQL_DEBUG_BASIC, 2482); // p3disc
setZoneLevel(PQL_ALERT, 1728); // proxy
setZoneLevel(PQL_ALERT, 1211); // sslroot.
setZoneLevel(PQL_ALERT, 37714); // pqissl.
setZoneLevel(PQL_ALERT, 8221); // pqistreamer.
setZoneLevel(PQL_ALERT, 354); // pqipersongrp.
std::list<std::string> dirs;
short port = 7812; // default port.
bool forceLocalAddr = false;
char inet[256] = "127.0.0.1";
char passwd[256] = "";
char logfname[1024] = "";
int c;
bool havePasswd = false;
bool haveLogFile = false;
while((c = getopt(argc, argv,"i:p:c:s:w:l:")) != -1)
{
switch (c)
{
case 'l':
strncpy(logfname, optarg, 1024);
std::cerr << "LogFile (" << logfname;
std::cerr << ") Selected" << std::endl;
haveLogFile = true;
break;
case 'w':
strncpy(passwd, optarg, 256);
std::cerr << "Password Specified(" << passwd;
std::cerr << ") Selected" << std::endl;
havePasswd = true;
break;
case 'i':
strncpy(inet, optarg, 256);
std::cerr << "New Inet Addr(" << inet;
std::cerr << ") Selected" << std::endl;
forceLocalAddr = true;
break;
case 'p':
port = atoi(optarg);
std::cerr << "New Listening Port(" << port;
std::cerr << ") Selected" << std::endl;
break;
case 'c':
config_basedir = optarg;
std::cerr << "New Base Config Dir(";
std::cerr << config_basedir;
std::cerr << ") Selected" << std::endl;
break;
case 's':
dirs.push_back(std::string(optarg));
std::cerr << "Adding Search Directory (" << optarg;
std::cerr << ")" << std::endl;
break;
default:
std::cerr << "Unknown Option!";
exit(1);
}
}
// Can only log under linux.
// set the debug file.
if (haveLogFile)
{
setDebugFile(logfname);
}
// first check config directories, and set bootstrap values.
load_check_basedir();
// SWITCH off the SIGPIPE - kills process on Linux.
struct sigaction sigact;
sigact.sa_handler = SIG_IGN;
sigact.sa_flags = 0;
if (0 == sigaction(SIGPIPE, &sigact, NULL))
{
std::cerr << "RetroShare:: Successfully Installed";
std::cerr << "the SIGPIPE Block" << std::endl;
}
else
{
std::cerr << "RetroShare:: Failed to Install";
std::cerr << "the SIGPIPE Block" << std::endl;
}
if (!havePasswd)
{
std::cerr << "main() - Fatal Error....." << std::endl;
std::cerr << "Missing Passwd!" << std::endl;
std::cerr << std::endl;
exit(1);
}
/* determine the cert/key parameters....
*/
load_check_basedir();
bool sslroot_ok = false;
sslroot *sr = getSSLRoot();
/**************** PQI_USE_XPGP ******************/
#if defined(PQI_USE_XPGP)
if (0 < sr -> initssl(load_cert.c_str(), load_key.c_str(), passwd))
{
sslroot_ok = true;
}
#else /* X509 Certificates */
/**************** PQI_USE_XPGP ******************/
if (0 < sr -> initssl(load_cert.c_str(), load_key.c_str(),
load_cacert.c_str(), passwd))
{
sslroot_ok = true;
}
#endif /* X509 Certificates */
/**************** PQI_USE_XPGP ******************/
if (!sslroot_ok)
{
std::cerr << "main() - Fatal Error....." << std::endl;
std::cerr << "Invalid Certificate configuration!" << std::endl;
std::cerr << std::endl;
exit(1);
}
// wait for this window to be finished....
if(!(sr -> active()))
{
std::cerr << "main() - Fatal Error....." << std::endl;
std::cerr << "SSLRoot Failed to start" << std::endl;
std::cerr << std::endl;
exit(1);
}
// set the directories for full configuration load.
sr -> setConfigDirs(config_basedir.c_str(), cert_dir.c_str());
sr -> loadCertificates(config_file.c_str());
sr -> checkNetAddress();
SecurityPolicy *none = secpolicy_create();
if (forceLocalAddr)
{
struct sockaddr_in laddr;
laddr.sin_family = AF_INET;
laddr.sin_port = htons(port);
// universal
laddr.sin_addr.s_addr = inet_addr(inet);
// unix specific
//inet_aton(inet, &(laddr.sin_addr));
cert *own = sr -> getOwnCert();
if (own != NULL)
{
own -> localaddr = laddr;
}
}
/**************** PQI_USE_XPGP ******************/
#if defined(PQI_USE_XPGP)
/* can only do this in XPGP */
sr -> superNodeMode();
#endif /* X509 Certificates */
/**************** PQI_USE_XPGP ******************/
pqisupernode psn(none, sr);
psn.load_config();
psn.run();
return 1;
}
void load_check_basedir()
{
// get the default configuration location.
if (config_basedir == "")
{
std::cerr << "load_check_basedir() - Fatal Error....." << std::endl;
std::cerr << "Missing config_basedir" << std::endl;
std::cerr << std::endl;
exit(1);
}
std::string key_subdir = config_basedir + dirSeperator;
key_subdir += key_dir;
// will catch bad files later.
// Check for config file.
std::string initfile = config_basedir + dirSeperator;
initfile += config_init_file;
/* setup the ca cert file */
load_cacert = key_dir + dirSeperator;
load_cacert += ca_file;
// open and read in the lines.
FILE *ifd = fopen(initfile.c_str(), "r");
char path[1024];
int i;
if (ifd != NULL)
{
if (NULL != fgets(path, 1024, ifd))
{
for(i = 0; (path[i] != '\0') && (path[i] != '\n'); i++);
path[i] = '\0';
load_cert = path;
}
if (NULL != fgets(path, 1024, ifd))
{
for(i = 0; (path[i] != '\0') && (path[i] != '\n'); i++);
path[i] = '\0';
load_key = path;
}
fclose(ifd);
}
else
{
std::cerr << "load_check_basedir() - Fatal Error....." << std::endl;
std::cerr << "Cannot open initfile." << std::endl;
std::cerr << std::endl;
exit(1);
}
return;
}

View File

@ -0,0 +1,440 @@
/*
* "$Id: pqi.cc,v 1.8 2007-03-21 18:45:41 rmf24 Exp $"
*
* 3P/PQI network interface for RetroShare.
*
* Copyright 2004-2006 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 "pqi/pqi.h"
#include "pqi/pqi_data.h"
#include <ctype.h>
// local functions.
//int pqiroute_setshift(PQItem *item, int chan);
//int pqiroute_getshift(PQItem *item);
//int pqicid_clear(ChanId *cid);
//int pqicid_copy(const ChanId *cid, ChanId *newcid);
// Helper functions for the PQInterface.
int fixme(char *str, int n)
{
for(int i = 0; i < n; i++)
{
std::cerr << "FIXME:: " << str << std::endl;
}
return 1;
}
SearchItem::SearchItem()
:PQItem(PQI_ITEM_TYPE_SEARCHITEM, PQI_SI_SUBTYPE_SEARCH),
datatype(PQI_SI_DATATYPE_TERMS)
{
//std::cerr << "Creating SearchItem()" << std::endl;
return;
}
SearchItem::SearchItem(int st)
:PQItem(PQI_ITEM_TYPE_SEARCHITEM, st), datatype(PQI_SI_DATATYPE_TERMS)
{
//std::cerr << "Creating SearchItem()" << std::endl;
return;
}
SearchItem::~SearchItem()
{
//std::cerr << "Deleting SearchItem()" << std::endl;
return;
}
// These need to be recursive.
SearchItem *SearchItem::clone()
{
SearchItem *nsi = new SearchItem();
nsi -> copy(this);
return nsi;
}
void SearchItem::copy(const SearchItem *si)
{
// copy below.
PQItem::copy(si);
// do elements of searchItem.
datatype = si -> datatype;
data = si -> data;
}
std::ostream &SearchItem::print(std::ostream &out)
{
out << "---- SearchItem" << std::endl;
PQItem::print(out);
out << "Search Type: " << datatype << std::endl;
out << "Search: " << data << std::endl;
return out << "----" << std::endl;
}
ChatItem::ChatItem()
:PQItem(PQI_ITEM_TYPE_CHATITEM, PQI_MI_SUBTYPE_CHAT)
{
//std::cerr << "Creating ChatItem()" << std::endl;
return;
}
ChatItem::ChatItem(int st)
:PQItem(PQI_ITEM_TYPE_CHATITEM, st)
{
//std::cerr << "Creating ChatItem()" << std::endl;
return;
}
ChatItem::~ChatItem()
{
//std::cerr << "Deleting ChatItem()" << std::endl;
return;
}
MsgItem::MsgItem()
:ChatItem(PQI_MI_SUBTYPE_MSG), msgflags(0), sendTime(0)
{
//std::cerr << "Creating MsgItem()" << std::endl;
return;
}
MsgItem::~MsgItem()
{
//std::cerr << "Deleting MsgItem()" << std::endl;
return;
}
ChatItem *ChatItem::clone()
{
ChatItem *nsi = new ChatItem();
nsi -> copy(this);
return nsi;
}
void ChatItem::copy(const ChatItem *si)
{
// copy below.
PQItem::copy(si);
msg = si -> msg;
return;
}
std::ostream &ChatItem::print(std::ostream &out)
{
out << "---- ChatItem" << std::endl;
PQItem::print(out);
out << "Msg: " << msg;
out << std::endl << "----";
return out << std::endl;
}
MsgItem *MsgItem::clone()
{
MsgItem *nsi = new MsgItem();
nsi -> copy(this);
return nsi;
}
void MsgItem::copy(const MsgItem *mi)
{
// copy below.
ChatItem::copy(mi);
msgflags = mi -> msgflags;
sendTime = mi -> sendTime;
title = mi -> title;
header = mi -> header;
files = mi -> files;
}
std::ostream &MsgItem::print(std::ostream &out)
{
out << "-------- MsgItem" << std::endl;
ChatItem::print(out);
out << "MsgFlags: " << msgflags;
out << std::endl;
out << "SendTime: " << sendTime;
out << std::endl;
out << "Title: " << title;
out << std::endl;
out << "Header: " << header;
out << std::endl;
out << "NoFiles: " << files.size();
out << std::endl;
std::list<MsgFileItem>::iterator it;
for(it = files.begin(); it != files.end(); it++)
{
out << "File: " << it->name;
out << " Size: " << it->size;
out << " Hash: " << it->hash;
out << std::endl;
}
out << std::endl << "--------";
return out << std::endl;
}
//void FileItem::fillsi(SearchItem *si)
//{
// // first copy lowlevel stuff.
// si -> PQItem::copyIDs(this);
// if (hash.length() > 5)
// {
// // use hash.
// si -> data = hash;
// si -> datatype = PQI_SI_DATATYPE_HASH;
// }
// else
// {
// si -> data = name;
// si -> datatype = PQI_SI_DATATYPE_NAME;
// }
// return;
//}
// This uses some helper functions for
// string matching... these
// functions are located at the end
// of this file.
int PQFileItem::match(std::string term)
{
std::string lowerterm = strtolower(term);
std::string haystack = strtolower(path);
if (strstr(haystack.c_str(), lowerterm.c_str()) != NULL)
{
return 1;
}
haystack = strtolower(name);
if (strstr(haystack.c_str(), lowerterm.c_str()) != NULL)
{
return 1;
}
return 0;
}
MediaItem::MediaItem()
{
//std::cerr << "Creating MediaItem()" << std::endl;
return;
}
MediaItem::~MediaItem()
{
//std::cerr << "Deleting MediaItem()" << std::endl;
return;
}
MediaItem *MediaItem::clone()
{
MediaItem *nmi = new MediaItem();
nmi -> copy(this);
return nmi;
}
void MediaItem::copy(const MediaItem *src)
{
// copy fileitem stuff.
PQFileItem::copy(src);
mimetype = src -> mimetype;
title = src -> title;
author = src -> author;
collection = src -> collection;
genre = src -> genre;
len = src -> len;
return;
}
int MediaItem::match(std::string term)
{
std::string lowerterm = strtolower(term);
std::string haystack = strtolower(title);
if (strstr(haystack.c_str(), lowerterm.c_str()) != NULL)
{
return 1;
}
haystack = strtolower(author);
if (strstr(haystack.c_str(), lowerterm.c_str()) != NULL)
{
return 1;
}
haystack = strtolower(collection);
if (strstr(haystack.c_str(), lowerterm.c_str()) != NULL)
{
return 1;
}
haystack = strtolower(genre);
if (strstr(haystack.c_str(), lowerterm.c_str()) != NULL)
{
return 1;
}
return PQFileItem::match(term);
}
/*********************** STRING HELPERS *************************/
std::string strtolower(std::string in)
{
std::string out = in;
for(int i = 0; i < (signed) out.length(); i++)
{
if (isupper(out[i]))
{
out[i] += 'a' - 'A';
}
}
return out;
}
std::string fileextension(std::string in)
{
std::string out;
bool found = false;
for(int i = (signed) in.length() -1; (i >= 0) && (found == false); i--)
{
if (in[i] == '.')
{
found = true;
for(int j = i+1; j < (signed) in.length(); j++)
{
out += in[j];
}
}
}
return strtolower(out);
}
std::list<std::string> createtermlist(std::string in)
{
std::list<std::string> terms;
char str[1024];
strncpy(str, in.c_str(), 1024);
str[1023] = '\0';
int len = strlen(str);
int i;
int sword = 0;
for(i = 0; (i < len - 1) && (str[i] != '\0'); i++)
{
if (isspace(str[i]))
{
str[i] = '\0';
if (i - sword > 0)
{
terms.push_back(std::string(&(str[sword])));
//std::cerr << "Found Search Term: (" << &(str[sword]);
//std::cerr << ")" << std::endl;
}
sword = i+1;
}
}
// do the final term.
if (i - sword > 0)
{
terms.push_back(std::string(&(str[sword])));
//std::cerr << "Found Search Term: (" << &(str[sword]);
//std::cerr << ")" << std::endl;
}
return terms;
}
int match(PQFileItem *fi, SearchItem *si)
{
if (si -> datatype == PQI_SI_DATATYPE_HASH)
{
if (0 == strcmp((fi -> hash).c_str(), (si -> data).c_str()))
return 1;
return 0;
}
else if (si -> datatype == PQI_SI_DATATYPE_NAME)
{
if (0 == strcmp((fi -> name).c_str(), (si -> data).c_str()))
return 1;
return 0;
}
else // try it as terms....
{
std::list<std::string> terms = createtermlist(si -> data);
std::list<std::string>::iterator it;
if (terms.size() == 0)
{
return 0;
}
for(it = terms.begin(); it != terms.end(); it++)
{
if (0 == fi -> match(*it))
{
return 0;
}
}
return 1;
}
}

114
libretroshare/src/pqi/pqi.h Normal file
View File

@ -0,0 +1,114 @@
/*
* "$Id: pqi.h,v 1.8 2007-03-31 09:41:32 rmf24 Exp $"
*
* 3P/PQI network interface for RetroShare.
*
* Copyright 2004-2006 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 MRK_P3_PUBLIC_INTERFACE_HEADER
#define MRK_P3_PUBLIC_INTERFACE_HEADER
// This is the overall include, for public usage
// + extension of the p3 interface.
#include "pqi/pqi_data.h"
#include <iostream>
#include <functional>
#include <algorithm>
/********************** SEARCH INTERFACE ***************************/
// this is an interface.... so should be
// classified as virtual = 0;
class SearchInterface
{
public:
SearchInterface() { return; }
virtual ~SearchInterface() { return; }
// OutGoing Searches...
virtual int Search(SearchItem *) = 0; // Search All people...
virtual int SearchSpecific(SearchItem *) = 0; // Search One person only...
virtual int CancelSearch(SearchItem *) = 0; // no longer used?
virtual PQFileItem *GetSearchResult() = 0;
// Incoming Searches...
virtual SearchItem *RequestedSearch() = 0;
virtual SearchItem *CancelledSearch() = 0;
virtual int SendSearchResult(PQFileItem *item) = 0;
// FileTransfer.
virtual PQFileItem *GetFileItem() = 0;
virtual int SendFileItem(PQFileItem *) = 0;
};
class ChatInterface
{
public:
ChatInterface() {return; };
virtual ~ChatInterface() {return; };
virtual int SendMsg(ChatItem *item) = 0;
virtual int SendGlobalMsg(ChatItem *ns) = 0;
virtual ChatItem *GetMsg() = 0;
};
// This can potentially be moved to where the
// discovery code is!!!!
class HostItem: public PQItem { };
class DiscoveryInterface
{
public:
virtual ~DiscoveryInterface() { return; }
// Discovery Request.
virtual int DiscoveryRequest(PQItem *) = 0; // item is just for direction.
virtual HostItem *DiscoveryResult() = 0;
};
class P3Interface: public SearchInterface,
public ChatInterface
{
public:
P3Interface() {return; }
virtual ~P3Interface() {return; }
virtual int tick() { return 1; }
virtual int status() { return 1; }
virtual int SendOtherPQItem(PQItem *) = 0;
virtual PQItem *GetOtherPQItem() = 0;
virtual PQItem *SelectOtherPQItem(bool (*tst)(PQItem *)) = 0;
};
#endif //MRK_PQI_BASE_HEADER

View File

@ -0,0 +1,791 @@
/*
* "$Id: pqi_base.cc,v 1.17 2007-03-31 09:41:32 rmf24 Exp $"
*
* 3P/PQI network interface for RetroShare.
*
* Copyright 2004-2006 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 "pqi/pqi_base.h"
#include <ctype.h>
// local functions.
int pqiroute_setshift(ChanId *item, int chan);
int pqiroute_getshift(ChanId *item);
// these ones are also exported!
int pqicid_clear(ChanId *cid);
int pqicid_copy(const ChanId *cid, ChanId *newcid);
int pqicid_cmp(const ChanId *cid1, ChanId *cid2);
// Helper functions for the PQInterface.
static int next_search_id = 1;
int getPQIsearchId()
{
return next_search_id++;
}
// SI Operations.
PQItem::PQItem()
:sid(0), type(0), subtype(0), p(0)
{
//std::cerr << "Creating PQItem(0,0)@" << std::endl;
//std::cerr << (void *) this << std::endl;
pqicid_clear(&cid);
return;
}
PQItem::~PQItem()
{
//std::cerr << "Deleting PQItem(" << type << ",";
//std::cerr << subtype << ")@" << (void *) this << std::endl;
return;
}
PQItem::PQItem(int t, int st)
:sid(0), type(t), subtype(st), flags(0), p(0)
{
//std::cerr << "Creating PQItem(" << t << "," << st << ")@";
//std::cerr << (void *) this << std::endl;
pqicid_clear(&cid);
return;
}
PQItem *PQItem::clone()
{
PQItem *npqi = new PQItem();
npqi -> copy(this);
return npqi;
}
void PQItem::copy(const PQItem *pqi)
{
sid = pqi -> sid;
pqicid_copy(&(pqi -> cid), &(cid));
type = pqi -> type;
subtype = pqi -> subtype;
flags = pqi -> flags;
p = pqi -> p;
return;
}
void PQItem::copyIDs(const PQItem *pqi)
{
sid = pqi -> sid;
pqicid_copy(&(pqi -> cid), &(cid));
// Person ref should also be part of the id.
p = pqi -> p;
return;
}
std::ostream &PQItem::print(std::ostream &out)
{
out << "-- PQItem" << std::endl;
out << "CID [" << cid.route[0];
for(int i = 0; i < 10; i++)
out << ":" << cid.route[i];
out << "] SID: " << sid << std::endl;
out << "Type: " << type << "/" << subtype;
out << " Flags: " << flags << std::endl;
out << " Source: ";
if (p == NULL)
{
out << "*Unknown*" << std::endl;
}
else
{
out << p -> Name() << std::endl;
}
return out << "--" << std::endl;
}
int PQItem::cidpop()
{
return pqiroute_getshift(&cid);
}
void PQItem::cidpush(int id)
{
pqiroute_setshift(&cid, id);
return;
}
PQFileItem::PQFileItem()
:PQItem(PQI_ITEM_TYPE_FILEITEM, PQI_FI_SUBTYPE_GENERAL),
reqtype(PQIFILE_STD)
{
//std::cerr << "Creating PQFileItem()" << std::endl;
return;
}
PQFileItem::PQFileItem(int subtype)
:PQItem(PQI_ITEM_TYPE_FILEITEM, subtype),
reqtype(PQIFILE_STD)
{
//std::cerr << "Creating PQFileItem()" << std::endl;
return;
}
PQFileItem::~PQFileItem()
{
//std::cerr << "Deleting PQFileItem()" << std::endl;
return;
}
PQFileItem *PQFileItem::clone()
{
PQFileItem *nfi = new PQFileItem();
nfi -> copy(this);
return nfi;
}
void PQFileItem::copy(const PQFileItem *src)
{
PQItem::copy(src);
hash = src -> hash;
name = src -> name;
path = src -> path;
ext = src -> ext;
size = src -> size;
fileoffset = src -> fileoffset;
chunksize = src -> chunksize;
exttype = src -> exttype;
reqtype = src -> reqtype;
return;
}
std::ostream &PQFileItem::print(std::ostream &out)
{
out << "-------- PQFileItem" << std::endl;
PQItem::print(out);
out << "Name: " << name << std::endl;
out << "Hash: " << hash << std::endl;
out << "Path: " << path << std::endl;
out << "Ext: " << ext << std::endl;
out << "Size: " << size << std::endl;
out << "FileOffset: " << fileoffset << std::endl;
out << "ChunkSize: " << chunksize << std::endl;
out << "Ext/Req Types: " << exttype << "/" << reqtype << std::endl;
return out << "--------" << std::endl;
}
PQFileData::PQFileData()
:PQFileItem(PQI_FI_SUBTYPE_DATA),
datalen(0), data(NULL), fileflags(0)
{
//std::cerr << "Creating PQFileData()" << std::endl;
flags = 0;
return;
}
PQFileData::~PQFileData()
{
if (data != NULL)
{
free(data);
}
//std::cerr << "Deleting PQFileData()" << std::endl;
return;
}
PQFileData *PQFileData::clone()
{
PQFileData *nfd = new PQFileData();
nfd -> copy(this);
return nfd;
}
void PQFileData::copy(const PQFileData *fd)
{
// copy below.
PQItem::copy(fd);
if (data != NULL)
{
free(data);
}
data = malloc(fd -> datalen);
memcpy(data, fd -> data, fd -> datalen);
datalen = fd -> datalen;
fileflags = fd -> fileflags;
return;
}
std::ostream &PQFileData::print(std::ostream &out)
{
out << "-------- PQFileData" << std::endl;
PQItem::print(out);
out << "DataLen: " << datalen << std::endl;
out << "FileFlags: " << fileflags << std::endl;
return out << "--------" << std::endl;
}
int PQFileData::writedata(std::ostream &out)
{
//std::cerr << "PQFileData::writedata() len: " << datalen << std::endl;
if (data != NULL)
{
out.write((char *) data, datalen);
if (out.bad())
{
//std::cerr << "PQFileData::writedata() Bad ostream!" << std::endl;
return -1;
}
return 1;
}
return 1;
}
int PQFileData::readdata(std::istream &in, int maxbytes)
{
if (data != NULL)
{
free(data);
}
data = malloc(maxbytes);
in.read((char *) data, maxbytes);
int read = in.gcount();
// if read < maxread then finished?
if (read < maxbytes)
{
// check if finished.
if (in.eof())
{
isend();
}
else
{
//std::cerr << "pqi_makeFilePkt() Only Read: ";
//std::cerr << read << "/" << maxbytes << " Why?";
//std::cerr << std::endl;
}
// adjust the space.
void *tmpdata = data;
data = malloc(read);
memcpy(data, tmpdata, read);
free(tmpdata);
}
datalen = read;
return 1;
}
int PQFileData::endstream()
{
if (fileflags & PQI_FD_FLAG_ENDSTREAM)
return 1;
return 0;
}
void PQFileData::isend()
{
fileflags |= PQI_FD_FLAG_ENDSTREAM;
return;
}
FileTransferItem::FileTransferItem()
:PQFileItem(PQI_FI_SUBTYPE_TRANSFER),
transferred(0), state(FT_STATE_OKAY),
crate(0), trate(0), in(false), ltransfer(0), lrate(0)
{
//std::cerr << "Creating FileTransferItem()" << std::endl;
return;
}
FileTransferItem::~FileTransferItem()
{
//std::cerr << "Deleting FileTransferItem()" << std::endl;
return;
}
FileTransferItem *FileTransferItem::clone()
{
FileTransferItem *nfd = new FileTransferItem();
nfd -> copy(this);
return nfd;
}
void FileTransferItem::copy(const FileTransferItem *fd)
{
// copy below.
PQFileItem::copy(fd);
transferred = fd -> transferred;
state = fd -> state;
crate = fd -> crate;
trate = fd -> trate;
in = fd -> in;
ltransfer = fd -> ltransfer;
lrate = fd -> lrate;
return;
}
std::ostream &FileTransferItem::print(std::ostream &out)
{
out << "-------- FileTransferItem" << std::endl;
PQFileItem::print(out);
if (in == true)
{
out << "Incoming File.....";
}
else
{
out << "Outgoing File.....";
}
out << "Transferred: " << transferred << std::endl;
out << "Transfer State: " << state << std::endl;
out << "Current/Total Rate: " << crate << "/" << trate << std::endl;
out << "LTransfer/LRate: " << ltransfer << "/" << lrate << std::endl;
return out << "--------" << std::endl;
}
RateCntrlItem::RateCntrlItem()
:PQFileItem(PQI_FI_SUBTYPE_RATE),
total(0), individual(0)
{
//std::cerr << "Creating RateCntrlItem()" << std::endl;
return;
}
RateCntrlItem::~RateCntrlItem()
{
//std::cerr << "Deleting RateCntrlItem()" << std::endl;
return;
}
RateCntrlItem *RateCntrlItem::clone()
{
RateCntrlItem *nfd = new RateCntrlItem();
nfd -> copy(this);
return nfd;
}
void RateCntrlItem::copy(const RateCntrlItem *fd)
{
// copy below.
PQFileItem::copy(fd);
total = fd -> total;
individual = fd -> individual;
return;
}
std::ostream &RateCntrlItem::print(std::ostream &out)
{
out << "-------- RateCntrlItem" << std::endl;
PQFileItem::print(out);
out << "Total Rate: " << total << std::endl;
out << "Individual Rate: " << individual << std::endl;
return out << "--------" << std::endl;
}
// CHANID Operations.
int pqicid_clear(ChanId *cid)
{
for(int i = 0; i < 10; i++)
{
cid -> route[i] = 0;
}
return 1;
}
int pqicid_copy(const ChanId *cid, ChanId *newcid)
{
for(int i = 0; i < 10; i++)
{
(newcid -> route)[i] = (cid -> route)[i];
}
return 1;
}
int pqicid_cmp(const ChanId *cid1, ChanId *cid2)
{
int ret = 0;
for(int i = 0; i < 10; i++)
{
ret = cid1->route[i] - cid2->route[i];
if (ret != 0)
{
return ret;
}
}
return 0;
}
int pqiroute_getshift(ChanId *id)
{
int *array = id -> route;
int next = array[0];
// shift.
for(int i = 0; i < 10 - 1; i++)
{
array[i] = array[i+1];
}
array[10 - 1] = 0;
return next;
}
int pqiroute_setshift(ChanId *id, int chan)
{
int *array = id -> route;
// shift.
for(int i = 10 - 1; i > 0; i--)
{
array[i] = array[i-1];
}
array[0] = chan;
return 1;
}
/****************** PERSON DETAILS ***********************/
Person::Person()
:dhtFound(false), dhtFlags(0),
lc_timestamp(0), lr_timestamp(0),
nc_timestamp(0), nc_timeintvl(5),
name("Unknown"), status(PERSON_STATUS_MANUAL)
{
for(int i = 0; i < (signed) sizeof(lastaddr); i++)
{
((unsigned char *) (&lastaddr))[i] = 0;
((unsigned char *) (&localaddr))[i] = 0;
((unsigned char *) (&serveraddr))[i] = 0;
((unsigned char *) (&dhtaddr))[i] = 0;
}
pqicid_clear(&cid);
return;
}
Person::~Person()
{
}
int Person::cidpop()
{
return pqiroute_getshift(&cid);
}
void Person::cidpush(int id)
{
pqiroute_setshift(&cid, id);
return;
}
bool Person::Group(std::string in)
{
std::list<std::string>::iterator it;
for(it = groups.begin(); it != groups.end(); it++)
{
if (in == (*it))
{
return true;
}
}
return false;
}
int Person::addGroup(std::string in)
{
groups.push_back(in);
return 1;
}
int Person::removeGroup(std::string in)
{
std::list<std::string>::iterator it;
for(it = groups.begin(); it != groups.end(); it++)
{
if (in == (*it))
{
groups.erase(it);
return 1;
}
}
return 0;
}
bool Person::Valid()
{
return (status & PERSON_STATUS_VALID);
}
void Person::Valid(bool b)
{
if (b)
status |= PERSON_STATUS_VALID;
else
status &= ~PERSON_STATUS_VALID;
}
bool Person::Accepted()
{
return (status & PERSON_STATUS_ACCEPTED);
}
void Person::Accepted(bool b)
{
if (b)
status |= PERSON_STATUS_ACCEPTED;
else
status &= ~PERSON_STATUS_ACCEPTED;
}
bool Person::InUse()
{
return (status & PERSON_STATUS_INUSE);
}
void Person::InUse(bool b)
{
if (b)
status |= PERSON_STATUS_INUSE;
else
status &= ~(PERSON_STATUS_INUSE);
}
bool Person::Listening()
{
return (status & PERSON_STATUS_LISTENING);
}
void Person::Listening(bool b)
{
if (b)
status |= PERSON_STATUS_LISTENING;
else
status &= ~PERSON_STATUS_LISTENING;
}
bool Person::Connected()
{
return (status & PERSON_STATUS_CONNECTED);
}
void Person::Connected(bool b)
{
if (b)
status |= PERSON_STATUS_CONNECTED;
else
status &= ~PERSON_STATUS_CONNECTED;
}
bool Person::WillListen()
{
return (status & PERSON_STATUS_WILL_LISTEN);
}
void Person::WillListen(bool b)
{
if (b)
status |= PERSON_STATUS_WILL_LISTEN;
else
status &= ~PERSON_STATUS_WILL_LISTEN;
}
bool Person::WillConnect()
{
return (status & PERSON_STATUS_WILL_CONNECT);
}
void Person::WillConnect(bool b)
{
if (b)
status |= PERSON_STATUS_WILL_CONNECT;
else
status &= ~PERSON_STATUS_WILL_CONNECT;
}
bool Person::Manual()
{
return (status & PERSON_STATUS_MANUAL);
}
void Person::Manual(bool b)
{
if (b)
status |= PERSON_STATUS_MANUAL;
else
status &= ~PERSON_STATUS_MANUAL;
}
bool Person::Firewalled()
{
return (status & PERSON_STATUS_FIREWALLED);
}
void Person::Firewalled(bool b)
{
if (b)
status |= PERSON_STATUS_FIREWALLED;
else
status &= ~PERSON_STATUS_FIREWALLED;
}
bool Person::Forwarded()
{
return (status & PERSON_STATUS_FORWARDED);
}
void Person::Forwarded(bool b)
{
if (b)
status |= PERSON_STATUS_FORWARDED;
else
status &= ~PERSON_STATUS_FORWARDED;
}
bool Person::Local()
{
return (status & PERSON_STATUS_LOCAL);
}
void Person::Local(bool b)
{
if (b)
status |= PERSON_STATUS_LOCAL;
else
status &= ~PERSON_STATUS_LOCAL;
}
bool Person::Trusted()
{
return (status & PERSON_STATUS_TRUSTED);
}
void Person::Trusted(bool b)
{
if (b)
status |= PERSON_STATUS_TRUSTED;
else
status &= ~PERSON_STATUS_TRUSTED;
}
unsigned int Person::Status()
{
return status;
}
void Person::Status(unsigned int s)
{
status = s;
}
std::string Person::Name()
{
return name;
}
void Person::Name(std::string n)
{
name = n;
}
/* Dynamic Address Foundation */
bool Person::hasDHT()
{
return dhtFound;
}
void Person::setDHT(struct sockaddr_in addr, unsigned int flags)
{
dhtFound = true;
dhtFlags = flags;
dhtaddr = addr;
}
/* GUI Flags */
bool Person::InChat()
{
return (status & PERSON_STATUS_INCHAT);
}
void Person::InChat(bool b)
{
if (b)
status |= PERSON_STATUS_INCHAT;
else
status &= ~PERSON_STATUS_INCHAT;
}
bool Person::InMessage()
{
return (status & PERSON_STATUS_INMSG);
}
void Person::InMessage(bool b)
{
if (b)
status |= PERSON_STATUS_INMSG;
else
status &= ~PERSON_STATUS_INMSG;
}

View File

@ -0,0 +1,596 @@
/*
* "$Id: pqi_base.h,v 1.18 2007-05-05 16:10:05 rmf24 Exp $"
*
* 3P/PQI network interface for RetroShare.
*
* Copyright 2004-2006 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 PQI_BASE_ITEM_HEADER
#define PQI_BASE_ITEM_HEADER
#include <list>
#include <string>
#include <iostream>
#include <functional>
#include <algorithm>
#include "pqi/pqinetwork.h"
#define PQI_MIN_PORT 1024
#define PQI_MAX_PORT 16000
#define PQI_DEFAULT_PORT 7812
int getPQIsearchId();
int fixme(char *str, int n);
struct chan_id
{
int route[10];
};
typedef unsigned long SearchId; /* unsigned 32 bits */
typedef struct chan_id ChanId;
/* basic worker fns on cids */
int pqicid_clear(ChanId *cid);
int pqicid_copy(const ChanId *cid, ChanId *newcid);
int pqicid_cmp(const ChanId *cid1, ChanId *cid2);
// So the basic pqi interface defines
//
// 1) Person -> reference object
// 2) PQItem
// 3) PQInterface
// which defines:
// - send/recieve objs
// - send/recieve files
//
// This is then extended to
// 4) SInterface
// which seperates the data into providing a basic search interface.
// chat/messages/files/search objs.
//
// TODO IN THIS CLASS.
// 1) Add serialisation.... (later)
// 2) reduce base interface to the minimum.
// 3) Convert cid -> std::stack.
// Base for all Security/Id/Certificate schemes.
// The list of these must be maintained seperately
// from the PQItems....
// Person - includes
// 1) name + signature (unique id)
// 2) address + timestamps of connections.
// 3) status
// 4) groups.
//
// only requires certificate. to complete...
#define PERSON_STATUS_VALID 0x0001
#define PERSON_STATUS_ACCEPTED 0x0002
#define PERSON_STATUS_INUSE 0x0004
#define PERSON_STATUS_LISTENING 0x0008
#define PERSON_STATUS_CONNECTED 0x0010
#define PERSON_STATUS_WILL_LISTEN 0x0020
#define PERSON_STATUS_WILL_CONNECT 0x0040
#define PERSON_STATUS_MANUAL 0x0080
#define PERSON_STATUS_FIREWALLED 0x0100
#define PERSON_STATUS_FORWARDED 0x0200
#define PERSON_STATUS_LOCAL 0x0400
#define PERSON_STATUS_TRUSTED 0x0800
/* some extra flags for advising the gui....
* have no affect on the pqi networking.
*/
#define PERSON_STATUS_INCHAT 0x1000
#define PERSON_STATUS_INMSG 0x2000
class Person
{
public:
Person();
virtual ~Person();
std::string Name();
void Name(std::string);
// Signature needs to be defined.
virtual std::string Signature() { return Name(); };
// These operate on the status.
bool Valid();
void Valid(bool);
bool Accepted();
void Accepted(bool);
bool InUse();
void InUse(bool);
bool Listening();
void Listening(bool);
bool Connected();
void Connected(bool);
bool WillListen();
void WillListen(bool);
bool WillConnect();
void WillConnect(bool);
bool Manual();
void Manual(bool);
bool Firewalled();
void Firewalled(bool);
bool Forwarded();
void Forwarded(bool);
bool Local();
void Local(bool);
bool Trusted();
void Trusted(bool);
/* GUI Flags */
bool InChat();
void InChat(bool);
bool InMessage();
void InMessage(bool);
unsigned int Status();
void Status(unsigned int s);
int addGroup(std::string);
int removeGroup(std::string);
bool Group(std::string);
int cidpop();
void cidpush(int id);
/* Dynamic Address Foundation */
bool hasDHT();
std::string getDHTId();
void setDHT(struct sockaddr_in addr, unsigned int flags);
// public for the moment.
struct sockaddr_in lastaddr, localaddr, serveraddr;
std::string dynDNSaddr;
bool dhtFound;
unsigned int dhtFlags;
struct sockaddr_in dhtaddr;
time_t lc_timestamp; // last connect timestamp
time_t lr_timestamp; // last receive timestamp
time_t nc_timestamp; // next connect timestamp.
time_t nc_timeintvl; // next connect time interval.
ChanId cid; // to get to the correct pqissl.
int trustLvl; /* new field */
private:
std::string name;
unsigned int status;
std::list<std::string> groups;
};
class PQItem
{
// include serialisation (Boost) functions...
// private copy constructor... prevent copying...
PQItem(const PQItem &) {return; }
public:
PQItem();
PQItem(int t, int st); // initialise with subtypes.
virtual ~PQItem();
// other type of serialise....
virtual std::ostream &print(std::ostream &out);
// copy functions.
virtual PQItem *clone();
void copy(const PQItem *pqi);
void copyIDs(const PQItem *pqi);
// stack operations -> could be converted to STL stack.
int cidpop();
void cidpush(int id);
// data
ChanId cid;
SearchId sid;
int type;
int subtype;
int flags;
Person *p; // This is shallow copied inside to itself,
// Over serialisation - becomes a name....
};
// Some Functional Objects for operations on PQItems
class PQItem_MatchSid
//: public unary_function <PQItem *, bool>
{
unsigned long sid;
public:
explicit PQItem_MatchSid(const unsigned long s) : sid(s) {}
bool operator()(const PQItem *pqi) const
{
if (pqi == NULL)
return false;
return (pqi -> sid == sid);
}
};
class PQItem_MatchType
//: public unary_function <PQItem *, bool>
{
int type, subtype;
public:
explicit PQItem_MatchType(const int t, const int s = 0)
: type(t), subtype(s) {}
bool operator()(const PQItem *pqi) const
{
if (pqi == NULL)
return false;
if (type == pqi -> type)
{
if (subtype == 0)
return true;
return (pqi -> subtype == subtype);
}
return false;
}
};
#define PQIFILE_STD 0x0001
#define PQIFILE_DIRLIST_FILE 0x0002
#define PQIFILE_DIRLIST_DIR 0x0004
class PQFileItem: public PQItem
{
// private copy constructor... prevent copying...
PQFileItem(const PQFileItem &) {return; }
public:
PQFileItem();
PQFileItem(int st); // initialise with subtypes.
virtual ~PQFileItem();
// copy functions.
virtual PQFileItem *clone();
void copy(const PQFileItem *src);
std::ostream &print(std::ostream &out);
virtual int match(std::string term);
std::string hash;
std::string name;
std::string path;
std::string ext;
int size; // total size of file.
long fileoffset; // used for file requests.
long chunksize; // used for file requests.
int reqtype;
int exttype;
};
class PQFileData: public PQFileItem
{
public:
PQFileData();
virtual ~PQFileData();
virtual PQFileData *clone();
void copy(const PQFileData *fd);
virtual std::ostream &print(std::ostream &out);
int writedata(std::ostream &out);
int readdata(std::istream &in, int maxbytes);
int endstream();
void isend();
// data
int datalen;
void *data;
int fileflags;
};
// And finally the Control/Info Interface.
class FileTransferItem: public PQFileItem
{
// private copy constructor... prevent copying...
// FileTransferItem(const FileTransferItem &) {return; }
public:
FileTransferItem();
virtual ~FileTransferItem();
virtual FileTransferItem *clone();
void copy(const FileTransferItem *ft);
virtual std::ostream &print(std::ostream &out);
int transferred;
int state;
float crate;
float trate;
bool in;
int ltransfer;
float lrate;
};
#define FT_STATE_FAILED 0
#define FT_STATE_OKAY 1
#define FT_STATE_COMPLETE 2
class RateCntrlItem: public PQFileItem
{
public:
RateCntrlItem();
virtual ~RateCntrlItem();
virtual RateCntrlItem *clone();
void copy(const RateCntrlItem *ft);
virtual std::ostream &print(std::ostream &out);
float total;
float individual;
};
class RateInterface
{
// controlling data rates.
public:
RateInterface()
:bw_in(0), bw_out(0), bwMax_in(0), bwMax_out(0) { return; }
virtual ~RateInterface() { return; }
virtual float getRate(bool in)
{
if (in)
return bw_in;
return bw_out;
}
virtual float getMaxRate(bool in)
{
if (in)
return bwMax_in;
return bwMax_out;
}
virtual void setMaxRate(bool in, float val)
{
if (in)
bwMax_in = val;
else
bwMax_out = val;
return;
}
protected:
void setRate(bool in, float val)
{
if (in)
bw_in = val;
else
bw_out = val;
return;
}
private:
float bw_in, bw_out, bwMax_in, bwMax_out;
};
/*********************** PQI INTERFACE ******************************\
* The basic exchange interface.
* This inherits the RateInterface, as Bandwidth control
* is a critical to a networked application.
*
*/
class NetInterface;
class PQInterface: public RateInterface
{
public:
PQInterface() { return; }
virtual ~PQInterface() { return; }
virtual int SendItem(PQItem *) = 0;
virtual PQItem *GetItem() = 0;
// also there are tick + person id functions.
virtual int tick() { return 0; }
virtual int status() { return 0; }
virtual Person *getContact() { return NULL; }
// the callback from NetInterface Connection Events.
virtual int notifyEvent(NetInterface *ni, int event) { return 0; }
};
/********************** Binary INTERFACE ****************************
* This defines the binary interface used by Network/loopback/file
* interfaces
*/
#define BIN_FLAGS_NO_CLOSE 0x0001
#define BIN_FLAGS_READABLE 0x0002
#define BIN_FLAGS_WRITEABLE 0x0004
class BinInterface
{
public:
BinInterface() { return; }
virtual ~BinInterface() { return; }
virtual int tick() = 0;
virtual int senddata(void *data, int len) = 0;
virtual int readdata(void *data, int len) = 0;
virtual int netstatus() = 0;
virtual int isactive() = 0;
virtual bool moretoread() = 0;
virtual bool cansend() = 0;
/* used by pqistreamer to limit transfers */
virtual bool bandwidthLimited() { return true; }
};
/********************** Network INTERFACE ***************************
* This defines the Network interface used by sockets/SSL/XPGP
* interfaces
*
* NetInterface: very pure interface, so no tick....
*
* It is passed a pointer to a PQInterface *parent,
* this is used to notify the system of Connect/Disconnect Events.
*
* Below are the Events for callback.
*/
static const int NET_CONNECT_RECEIVED = 1;
static const int NET_CONNECT_SUCCESS = 2;
static const int NET_CONNECT_UNREACHABLE = 3;
static const int NET_CONNECT_FIREWALLED = 4;
static const int NET_CONNECT_FAILED = 5;
class NetInterface
{
public:
NetInterface(PQInterface *p_in, Person *person_in)
:p(p_in), person(person_in) { return; }
virtual ~NetInterface()
{ return; }
// virtual int tick() = 0; // Already defined for BinInterface.
virtual int connectattempt() = 0;
virtual int listen() = 0;
virtual int stoplistening() = 0;
virtual int disconnect() = 0;
virtual int reset() = 0;
virtual Person *getContact() { return person; }
protected:
PQInterface *parent() { return p; }
private:
PQInterface *p;
Person *person;
};
class NetBinInterface: public NetInterface, public BinInterface
{
public:
NetBinInterface(PQInterface *parent, Person *person)
:NetInterface(parent, person)
{ return; }
virtual ~NetBinInterface() { return; }
};
#define CHAN_SIGN_SIZE 16
#define CERTSIGNLEN 16
class certsign
{
public:
bool operator<(const certsign &ref) const;
bool operator==(const certsign &ref) const;
char data[CERTSIGNLEN];
};
// IDS aren't inportant in the base class.
// EXCEPT FOR MAYBE THE FLAGS.
// These are OR'ed together.
const int PQI_ITEM_FLAG_NEW = 0x001;
const int PQI_ITEM_FLAG_LOCAL = 0x002;
const int PQI_ITEM_FLAG_PRIVATE = 0x004;
const int PQI_ITEM_TYPE_ITEM = 0x000;
const int PQI_ITEM_TYPE_FILEITEM = 0x001;
const int PQI_ITEM_TYPE_SEARCHITEM = 2;
const int PQI_ITEM_TYPE_CHATITEM = 3;
const int PQI_ITEM_TYPE_INFOITEM = 5;
const int PQI_ITEM_TYPE_COMMANDITEM = 6;
const int PQI_ITEM_TYPE_AUTODISCITEM = 7;
const int PQI_ITEM_TYPE_TUNNELITEM = 777;
const int PQI_ITEM_TYPE_TUNNELINITITEM = 778;
// Sub Type.
const int PQI_FI_SUBTYPE_GENERAL = 1;
const int PQI_FI_SUBTYPE_DATA = 2;
const int PQI_FI_SUBTYPE_CANCELRECV = 3;
const int PQI_FI_SUBTYPE_CANCELSEND = 4;
const int PQI_FI_SUBTYPE_REQUEST = 5;
const int PQI_FI_SUBTYPE_TRANSFER = 6;
const int PQI_FI_SUBTYPE_RATE = 7;
const int PQI_FI_SUBTYPE_ERROR = 8;
const int PQI_FD_FLAG_ENDSTREAM = 1;
#endif // PQI_BASE_ITEM_HEADER

View File

@ -0,0 +1,169 @@
/*
* "$Id: pqi_data.h,v 1.8 2007-04-07 08:40:55 rmf24 Exp $"
*
* 3P/PQI network interface for RetroShare.
*
* Copyright 2004-2006 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 PQI_ITEM_HEADER
#define PQI_ITEM_HEADER
#include "pqi/pqi_base.h"
#include <list>
#include <string>
#include <iostream>
// Definitions of some of the commonly used classes.
// These will all be made streamable! via Boost C++
class SearchItem: public PQItem
{
public:
SearchItem();
SearchItem(int st);
virtual ~SearchItem();
virtual SearchItem *clone();
void copy(const SearchItem *si);
virtual std::ostream &print(std::ostream &out);
// data
int datatype;
std::string data;
int siflags;
};
int match(PQFileItem *fi, SearchItem *si);
class MediaItem: public PQFileItem
{
public:
MediaItem();
virtual ~MediaItem();
virtual MediaItem *clone();
void copy(const MediaItem *src);
int match(std::string term);
// data.
std::string mimetype;
std::string title;
std::string author;
std::string collection;
std::string genre;
int len;
};
class ChatItem: public PQItem
{
public:
ChatItem();
ChatItem(int st);
virtual ~ChatItem();
virtual ChatItem *clone();
void copy(const ChatItem *si);
virtual std::ostream &print(std::ostream &out);
// data
std::string msg;
// Timestamp (Not transmitted currently!).
// Stamped on arrival.
int epoch;
};
class MsgFileItem
{
public:
std::string name; /* and dir! */
std::string hash;
unsigned long size;
};
class MsgItem: public ChatItem
{
public:
MsgItem();
virtual ~MsgItem();
virtual MsgItem *clone();
void copy(const MsgItem *mi);
std::ostream &print(std::ostream &out);
// Note this breaks the old client....
// Old data.....
//int mode;
//std::string recommendname;
//std::string recommendhash;
//std::string channel;
//int recommendsize;
//int datalen;
//void *data;
// Flags
unsigned long msgflags;
unsigned long sendTime;
std::string title;
std::string header;
std::list<MsgFileItem> files;
};
std::string strtolower(std::string in);
std::string fileextension(std::string in);
std::list<std::string> createtermlist(std::string in);
// IDS
const int PQI_SI_SUBTYPE_SEARCH = 1;
const int PQI_SI_SUBTYPE_CANCEL = 2;
const int PQI_SI_SUBTYPE_FILEREQ = 3;
const int PQI_SI_SUBTYPE_FILECANCEL = 4;
const int PQI_SI_DATATYPE_TERMS = 1;
const int PQI_SI_DATATYPE_HASH = 2;
const int PQI_SI_DATATYPE_NAME = 3;
const int PQI_SI_DATATYPE_DIR = 4;
const int PQI_MI_SUBTYPE_CHAT = 1;
const int PQI_MI_SUBTYPE_MSG = 2;
/* not really used here, but at higher layers */
const unsigned long PQI_MI_FLAGS_OUTGOING = 0x0001;
const unsigned long PQI_MI_FLAGS_PENDING = 0x0002;
const unsigned long PQI_MI_FLAGS_DRAFT = 0x0004;
const unsigned long PQI_MI_FLAGS_NEW = 0x0010;
#endif // PQI_ITEM_HEADER

View File

@ -0,0 +1,22 @@
#ifndef PQI_ADDR_STORE_H
#define PQI_ADDR_STORE_H
#include "pqi/pqinetwork.h"
#include <string>
class pqiAddrStore
{
public:
virtual ~pqiAddrStore() { return; }
/* pqiAddrStore ... called prior to connect */
virtual bool addrFriend(std::string id, struct sockaddr_in &addr, unsigned int &flags) = 0;
};
/* implemented elsewhere, to provide pqi with AddrStore */
extern pqiAddrStore *getAddrStore();
#endif /* PQI_ADDR_STORE_H */

View File

@ -0,0 +1,471 @@
/*
* "$Id: pqiarchive.cc,v 1.5 2007-03-21 18:45:41 rmf24 Exp $"
*
* 3P/PQI network interface for RetroShare.
*
* Copyright 2004-2006 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".
*
*/
/* This is dependent on the sslroot at the moment.
* -> as we need to create/restore references to the Person.
* -> and store the signatures to do this.
*/
/*******************************************************************
* pqiarchive provides an archive stream.
* This stores PQItem + Person Reference + Timestamp,
*
* and allows Objects to be replayed or restored,
* independently of the rest of the pqi system.
*
*/
#include "pqi/pqiarchive.h"
#include "pqi/pqipacket.h"
#include <iostream>
#include <fstream>
#include <sstream>
#include "pqi/pqidebug.h"
const int pqiarchivezone = 9326;
struct pqiarchive_header
{
uint32_t type;
uint32_t length;
uint32_t ts;
uint8_t personSig[CERTSIGNLEN];
};
const int PQIARCHIVE_TYPE_PQITEM = 0x0001;
pqiarchive::pqiarchive(BinInterface *bio_in, int bio_flags_in, sslroot *s)
:bio(bio_in), bio_flags(bio_flags_in),
nextPkt(NULL), nextPktTS(0), firstPktTS(0), initTS(0),
sslr(s)
{
{
std::ostringstream out;
out << "pqiarchive::pqiarchive()";
out << " Initialisation!" << std::endl;
pqioutput(PQL_DEBUG_ALL, pqiarchivezone, out.str());
}
if (!bio_in)
{
std::ostringstream out;
out << "pqiarchive::pqiarchive()";
out << " NULL bio, FATAL ERROR!" << std::endl;
pqioutput(PQL_ALERT, pqiarchivezone, out.str());
exit(1);
}
return;
}
pqiarchive::~pqiarchive()
{
{
std::ostringstream out;
out << "pqiarchive::~pqiarchive()";
out << " Destruction!" << std::endl;
pqioutput(PQL_DEBUG_ALL, pqiarchivezone, out.str());
}
if (bio_flags & BIN_FLAGS_NO_CLOSE)
{
std::ostringstream out;
out << "pqiarchive::~pqiarchive()";
out << " Not Closing BinInterface!" << std::endl;
pqioutput(PQL_DEBUG_ALL, pqiarchivezone, out.str());
}
else if (bio)
{
std::ostringstream out;
out << "pqiarchive::~pqiarchive()";
out << " Deleting BinInterface!" << std::endl;
pqioutput(PQL_DEBUG_ALL, pqiarchivezone, out.str());
delete bio;
}
if (nextPkt)
{
pqipkt_delete(nextPkt);
}
return;
}
// Get/Send Items.
int pqiarchive::SendItem(PQItem *si)
{
{
std::ostringstream out;
out << "pqiarchive::SendItem()" << std::endl;
si -> print(out);
pqioutput(PQL_DEBUG_BASIC, pqiarchivezone, out.str());
}
// check if this is a writing bio.
if (!(bio_flags & BIN_FLAGS_WRITEABLE))
{
delete si;
return -1;
}
int ret = writePkt(si);
return ret; /* 0 - failure, 1 - success*/
}
PQItem *pqiarchive::GetItem()
{
{
std::ostringstream out;
out << "pqiarchive::GetItem()";
pqioutput(PQL_DEBUG_ALL, pqiarchivezone, out.str());
}
// check if this is a reading bio.
if (!(bio_flags & BIN_FLAGS_READABLE))
{
std::ostringstream out;
out << "pqiarchive::GetItem()";
out << "Error Not Readable" << std::endl;
pqioutput(PQL_DEBUG_BASIC, pqiarchivezone, out.str());
return NULL;
}
// load if we dont have a packet.
if (!nextPkt)
{
if (!readPkt(&nextPkt, &nextPktTS))
{
std::ostringstream out;
out << "pqiarchive::GetItem()";
out << "Failed to ReadPkt" << std::endl;
pqioutput(PQL_DEBUG_BASIC, pqiarchivezone, out.str());
return NULL;
}
}
if (!nextPkt) return NULL;
/* if realtime - check delta */
bool rtnPkt = true;
if ((realTime) && (initTS))
{
int delta = time(NULL) - initTS;
int delta2 = nextPktTS - firstPktTS;
if (delta >= delta2)
{
rtnPkt = true;
}
else
{
rtnPkt = false;
}
}
if (rtnPkt)
{
if (!initTS)
{
/* first read! */
initTS = time(NULL);
firstPktTS = nextPktTS;
}
PQItem *outPkt = nextPkt;
nextPkt = NULL;
if (outPkt != NULL)
{
std::ostringstream out;
out << "pqiarchive::GetItem() Returning:" << std::endl;
outPkt -> print(out);
pqioutput(PQL_DEBUG_BASIC, pqiarchivezone, out.str());
}
return outPkt;
}
return NULL;
}
// // PQInterface
int pqiarchive::tick()
{
{
std::ostringstream out;
out << "pqiarchive::tick()";
out << std::endl;
}
return 0;
}
int pqiarchive::status()
{
{
std::ostringstream out;
out << "pqiarchive::status()";
pqioutput(PQL_DEBUG_ALL, pqiarchivezone, out.str());
}
return 0;
}
//
/**************** HANDLE OUTGOING TRANSLATION + TRANSMISSION ******/
int pqiarchive::writePkt(PQItem *pqi)
{
{
std::ostringstream out;
out << "pqiarchive::writePkt()";
pqioutput(PQL_DEBUG_ALL, pqiarchivezone, out.str());
}
void *ptr = pqipkt_makepkt(pqi);
if (NULL == ptr)
{
std::ostringstream out;
out << "pqiarchive::writePkt() Null Pkt generated!";
out << std::endl;
out << "Caused By: " << std::endl;
pqi -> print(out);
pqioutput(PQL_ALERT, pqiarchivezone, out.str());
pqipkt_delete(ptr);
delete pqi;
return 0;
}
/* extract the extra details */
int len = pqipkt_rawlen(ptr);
if (!(bio->cansend()))
{
std::ostringstream out;
out << "pqiarchive::writePkt() BIO cannot write!";
out << std::endl;
out << "Discarding: " << std::endl;
pqi -> print(out);
pqioutput(PQL_ALERT, pqiarchivezone, out.str());
pqipkt_delete(ptr);
delete pqi;
return 0;
}
std::ostringstream out;
out << "Writing Pkt Header" << std::endl;
struct pqiarchive_header hdr;
hdr.type = PQIARCHIVE_TYPE_PQITEM;
hdr.length = len;
hdr.ts = time(NULL);
certsign sig;
// NB: At the moment, the messages we have sent don't have
// pqi->p set, and so they will be discarded......
if (!sslr -> getcertsign((cert *) (pqi -> p), sig))
{
out << "pqiarchive::writePkt() cannot get certsign!";
out << std::endl;
out << "Caused By: " << std::endl;
pqi -> print(out);
pqioutput(PQL_ALERT, pqiarchivezone, out.str());
pqipkt_delete(ptr);
delete pqi;
return 0;
}
memcpy(hdr.personSig, sig.data, CERTSIGNLEN);
// write packet header.
if (sizeof(hdr) != bio->senddata(&hdr, sizeof(hdr)))
{
out << "Trouble writing header!";
out << std::endl;
pqioutput(PQL_ALERT, pqiarchivezone, out.str());
pqipkt_delete(ptr);
delete pqi;
return 0;
}
out << "Writing Pkt Body" << std::endl;
// write packet.
if (len != bio->senddata(ptr, len))
{
out << "Problems with Send Data!";
out << std::endl;
pqioutput(PQL_ALERT, pqiarchivezone, out.str());
pqipkt_delete(ptr);
delete pqi;
return 0;
}
out << " Success!" << std::endl;
pqioutput(PQL_DEBUG_BASIC, pqiarchivezone, out.str());
pqipkt_delete(ptr);
delete pqi;
return 1;
}
/* Reads a single packet from the input stream
* gets the timestamp as well.
*
*/
int pqiarchive::readPkt(PQItem **item_out, long *ts_out)
{
{
std::ostringstream out;
out << "pqiarchive::readPkt()";
pqioutput(PQL_DEBUG_ALL, pqiarchivezone, out.str());
}
if ((!(bio->isactive())) || (!(bio->moretoread())))
{
return 0;
}
// header
struct pqiarchive_header hdr;
// enough space to read any packet.
int maxlen = pqipkt_maxsize();
void *block = malloc(maxlen);
// initial read size: basic packet.
int blen = pqipkt_basesize();
int tmplen;
/* read in the header */
if (sizeof(hdr) != bio->readdata(&hdr, sizeof(hdr)))
{
/* error */
pqioutput(PQL_WARNING, pqiarchivezone,
"pqiarchive::readPkt() bad read(1)");
free(block);
return 0;
}
/* we have the header */
// read the basic block (minimum packet size)
if (blen != (tmplen = bio->readdata(block, blen)))
{
pqioutput(PQL_WARNING, pqiarchivezone,
"pqiarchive::readPkt() bad read(2)");
free(block);
return 0;
}
// workout how much more to read.
int extralen = pqipkt_rawlen(block) - blen;
if (extralen > 0)
{
void *extradata = (void *) (((char *) block) + blen);
if (extralen != (tmplen = bio->readdata(extradata, extralen)))
{
std::ostringstream out;
out << "pqiarchive::readPkt() ";
out << "Error Completing Read (read ";
out << tmplen << "/" << extralen << ")" << std::endl;
pqioutput(PQL_ALERT, pqiarchivezone, out.str());
free(block);
return 0;
}
}
// create packet, based on header.
std::cerr << "Read Data Block -> Incoming Pkt(";
std::cerr << blen + extralen << ")" << std::endl;
int readbytes = extralen + blen;
PQItem *item = NULL;
if (pqipkt_check(block, readbytes))
{
item = pqipkt_create(block);
}
free(block);
if (item == NULL)
{
pqioutput(PQL_ALERT, pqiarchivezone,
"pqiarchive::readPkt() Failed to create Item from archive!");
return 0;
}
/* get the PersonSign out of the header */
certsign sig;
memcpy(sig.data, hdr.personSig, CERTSIGNLEN);
item -> p = sslr -> findcertsign(sig);
/* if we can't identify the person it is from,
* then we need to discard it!..... (happens
* when they've been removed from our friend list....
*/
if (item->p==NULL)
{
std::ostringstream out;
out << "pqiarchive::readPkt() Couldn't translate certsign";
out << " into cert for pkt:" << std::endl;
item->print(out);
out << "Discarding!";
pqioutput(PQL_ALERT, pqiarchivezone, out.str());
delete item;
item = NULL;
return 0;
}
else
{
/* copy cid ... to ensure outgoing
* msgs work properly
*/
item->cid = item->p->cid;
}
*item_out = item;
*ts_out = hdr.ts;
/* cid/sid will be wrong */
return 1;
}

View File

@ -0,0 +1,87 @@
/*
* "$Id: pqiarchive.h,v 1.3 2007-02-18 21:46:49 rmf24 Exp $"
*
* 3P/PQI network interface for RetroShare.
*
* Copyright 2004-2006 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 MRK_PQI_ARCHIVE_STREAMER_HEADER
#define MRK_PQI_ARCHIVE_STREAMER_HEADER
// Only dependent on the base stuff.
#include "pqi/pqi_base.h"
/**************** PQI_USE_XPGP ******************/
#if defined(PQI_USE_XPGP)
#include "pqi/xpgpcert.h"
#else /* X509 Certificates */
/**************** PQI_USE_XPGP ******************/
#include "pqi/sslcert.h"
#endif /* X509 Certificates */
/**************** PQI_USE_XPGP ******************/
#include <list>
/*******************************************************************
* pqiarchive provides an archive stream.
* This stores PQItem + Person Reference + Timestamp,
*
* and allows Objects to be replayed or restored,
* independently of the rest of the pqi system.
*
*/
class pqiarchive: PQInterface
{
public:
pqiarchive(BinInterface *bio_in, int bio_flagsin, sslroot *);
virtual ~pqiarchive();
// PQInterface
virtual int SendItem(PQItem *);
virtual PQItem *GetItem();
virtual int tick();
virtual int status();
virtual void setRealTime(bool r) { realTime = r; }
private:
int writePkt(PQItem *item);
int readPkt(PQItem **item_out, long *ts);
// Binary Interface for IO, initialisated at startup.
BinInterface *bio;
unsigned int bio_flags; // only BIN_NO_CLOSE at the moment.
// Temp Storage for transient data.....
PQItem *nextPkt;
long nextPktTS; /* timestamp associated with nextPkt */
long firstPktTS; /* timestamp associated with first read Pkt */
long initTS; /* clock timestamp at first read */
sslroot *sslr;
bool realTime;
};
#endif //MRK_PQI_ARCHIVE_STREAMER_HEADER

View File

@ -0,0 +1,165 @@
/*
* "$Id: pqibin.cc,v 1.4 2007-02-18 21:46:49 rmf24 Exp $"
*
* 3P/PQI network interface for RetroShare.
*
* Copyright 2004-2006 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 "pqi/pqibin.h"
BinFileInterface::BinFileInterface(char *fname, int flags)
:bin_flags(flags), buf(NULL)
{
/* if read + write - open r+ */
if ((bin_flags & BIN_FLAGS_READABLE) &&
(bin_flags & BIN_FLAGS_WRITEABLE))
{
buf = fopen(fname, "r+");
/* if the file don't exist */
if (!buf)
{
buf = fopen(fname, "w+");
}
}
else if (bin_flags & BIN_FLAGS_READABLE)
{
buf = fopen(fname, "r");
}
else if (bin_flags & BIN_FLAGS_WRITEABLE)
{
// This is enough to remove old file in Linux...
// but not in windows.... (what to do)
buf = fopen(fname, "w");
fflush(buf); /* this might help windows! */
}
else
{
/* not read or write! */
}
if (buf)
{
/* no problem */
/* go to the end */
fseek(buf, 0L, SEEK_END);
/* get size */
size = ftell(buf);
/* back to the start */
fseek(buf, 0L, SEEK_SET);
}
else
{
size = 0;
}
}
BinFileInterface::~BinFileInterface()
{
if (buf)
{
fclose(buf);
}
}
int BinFileInterface::senddata(void *data, int len)
{
if (!buf)
return -1;
if (1 != fwrite(data, len, 1, buf))
{
return -1;
}
return len;
}
int BinFileInterface::readdata(void *data, int len)
{
if (!buf)
return -1;
if (1 != fread(data, len, 1, buf))
{
return -1;
}
return len;
}
BinMemInterface::BinMemInterface(int defsize, int flags)
:bin_flags(flags), buf(NULL), size(defsize),
recvsize(0), readloc(0)
{
buf = malloc(defsize);
}
BinMemInterface::~BinMemInterface()
{
if (buf)
free(buf);
return;
}
/* some fns to mess with the memory */
int BinMemInterface::fseek(int loc)
{
if (loc <= recvsize)
{
readloc = loc;
return 1;
}
return 0;
}
int BinMemInterface::senddata(void *data, int len)
{
if(recvsize + len > size)
{
/* resize? */
return -1;
}
memcpy((char *) buf + recvsize, data, len);
recvsize += len;
return len;
}
int BinMemInterface::readdata(void *data, int len)
{
if(readloc + len > recvsize)
{
/* no more stuff? */
return -1;
}
memcpy(data, (char *) buf + readloc, len);
readloc += len;
return len;
}

View File

@ -0,0 +1,108 @@
/*
* "$Id: pqibin.h,v 1.2 2007-02-18 21:46:49 rmf24 Exp $"
*
* 3P/PQI network interface for RetroShare.
*
* Copyright 2004-2006 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 PQI_BIN_INTERFACE_HEADER
#define PQI_BIN_INTERFACE_HEADER
#include "pqi/pqi_base.h"
class BinFileInterface: public BinInterface
{
public:
BinFileInterface(char *fname, int flags);
virtual ~BinFileInterface();
virtual int tick() { return 1; }
virtual int senddata(void *data, int len);
virtual int readdata(void *data, int len);
virtual int netstatus() { return 1;}
virtual int isactive() { return (buf != NULL);}
virtual bool moretoread()
{
if ((buf) && (bin_flags | BIN_FLAGS_READABLE))
{
if ((size - ftell(buf)) > 0)
{
return true;
}
}
return false;
}
virtual bool cansend() { return (bin_flags | BIN_FLAGS_WRITEABLE); }
private:
int bin_flags;
FILE *buf;
int size;
};
class BinMemInterface: public BinInterface
{
public:
BinMemInterface(int defsize, int flags);
virtual ~BinMemInterface();
int fseek(int loc);
int memsize() { return recvsize; }
void *memptr() { return buf; }
virtual int tick() { return 1; }
virtual int senddata(void *data, int len);
virtual int readdata(void *data, int len);
virtual int netstatus() { return 1; }
virtual int isactive() { return 1; }
virtual bool moretoread()
{
if ((buf) && (bin_flags | BIN_FLAGS_READABLE ))
{
if (readloc < recvsize)
{
return true;
}
}
return false;
}
virtual bool cansend() { return (bin_flags | BIN_FLAGS_WRITEABLE); }
private:
int bin_flags;
void *buf;
int size;
int recvsize;
int readloc;
};
#endif // PQI_BINARY_INTERFACES_HEADER

View File

@ -0,0 +1,610 @@
/*
* "$Id: pqichannel.cc,v 1.4 2007-02-18 21:46:49 rmf24 Exp $"
*
* 3P/PQI network interface for RetroShare.
*
* Copyright 2004-2006 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 "pqi/pqichannel.h"
static const int pqicizone = 449;
#include "pqi/pqidebug.h"
#include <sstream>
const int PQChan_MsgType = 0x5601;
const int PQChan_NameType = 0x5602;
const int PQChan_HashType = 0x5604;
const int PQChan_TitleType = 0x5608;
const int PQChan_FileType = 0x5610;
const int PQChan_SizeType = 0x5620;
const int PQChan_ListType = 0x5640;
PQTunnel *createChannelItems(void *d, int n)
{
pqioutput(PQL_DEBUG_BASIC, pqicizone,
"createChannelItems()");
return new PQChanItem();
}
PQChanItem::PQChanItem()
:PQTunnel(PQI_TUNNEL_CHANNEL_ITEM_TYPE),
certDER(NULL), certType(0), certLen(0), msg(""),
signature(NULL), signType(0), signLen(0)
{
pqioutput(PQL_DEBUG_BASIC, pqicizone,
"PQChanItem::PQChanItem()");
return;
}
PQChanItem::~PQChanItem()
{
pqioutput(PQL_DEBUG_BASIC, pqicizone,
"PQChanItem::~PQChanItem()");
clear();
return;
}
PQChanItem *PQChanItem::clone()
{
pqioutput(PQL_DEBUG_BASIC, pqicizone,
"PQChanItem::clone()");
PQChanItem *di = new PQChanItem();
di -> copy(this);
return di;
}
void PQChanItem::copy(const PQChanItem *di)
{
pqioutput(PQL_DEBUG_BASIC, pqicizone,
"PQChanItem::copy()");
PQTunnel::copy(di);
clear();
certType = di -> certType;
certLen = di -> certLen;
// allocate memory and copy.
if (NULL == (certDER = (unsigned char *) malloc(certLen)))
{
pqioutput(PQL_DEBUG_BASIC, pqicizone,
"PQChanItem::in() Not enough Memory!");
return; // cant be us.
}
memcpy(certDER, di -> certDER, certLen);
msg = di -> msg;
files = di -> files;
// only the signature to go!.
signType = di -> signType;
signLen = di -> signLen;
// allocate memory and copy.
if (NULL == (signature = (unsigned char *) malloc(signLen)))
{
pqioutput(PQL_DEBUG_BASIC, pqicizone,
"PQChanItem::copy() Not enough Memory!");
return; // cant be us.
}
memcpy(signature, di -> signature, signLen);
}
// Overloaded from PQTunnel.
const int PQChanItem::getSize() const
{
// 8 bytes for cert + certLen;
// 8 bytes for msg + msgLen;
// 12 bytes for files + sum(file -> getSize())
// 8 bytes for sign + signLen;
int files_size = 0;
FileList::const_iterator it;
for(it = files.begin(); it != files.end(); it++)
{
files_size += it -> getSize();
}
return 8 + certLen + 8 + msg.length() +
12 + files_size + 8 + signLen;
}
int PQChanItem::out(void *data, const int size) const
{
{
std::ostringstream out;
out << "PQChanItem::out() Data: " << data;
out << " Size: " << size << std::endl;
pqioutput(PQL_DEBUG_BASIC, pqicizone, out.str());
}
if (size < PQChanItem::getSize())
{
pqioutput(PQL_DEBUG_BASIC, pqicizone,
"PQChanItem::out() Packet Too Small!");
return -1;
}
// out is easy cos the getSize should be correct.
char *dta = (char *) data;
// first we put down the certificate;
((int *) dta)[0] = certType;
((int *) dta)[1] = certLen;
dta += 8; // 4 bytes per int.
memcpy(dta, certDER, certLen);
dta += certLen;
// now the message.
((int *) dta)[0] = PQChan_MsgType;
((int *) dta)[1] = msg.length();
dta += 8; // 4 bytes per int.
memcpy(dta, msg.c_str(), msg.length());
dta += msg.length();
// now list counter.
((int *) dta)[0] = PQChan_ListType;
((int *) dta)[1] = files.size();
// calc the length.
int files_size = 0;
FileList::const_iterator it;
for(it = files.begin(); it != files.end(); it++)
{
files_size += it -> getSize();
}
((int *) dta)[2] = files_size;
dta += 12; // 4 bytes per int.
// for each item of the list we need to put the data out.
for(it = files.begin(); it != files.end(); it++)
{
int fsize = it -> getSize();
it -> out(dta, fsize);
dta += fsize;
}
// finally the signature.
((int *) dta)[0] = signType;
((int *) dta)[1] = signLen;
dta += 8; // 4 bytes per int.
memcpy(dta, signature, signLen);
return PQChanItem::getSize();
}
void PQChanItem::clear()
{
// first reset all our dataspaces.
if (certDER != NULL)
{
free(certDER);
certDER = NULL;
}
certLen = 0;
msg.clear();
files.clear();
if (signature != NULL)
{
free(signature);
signature = NULL;
}
signLen = 0;
}
int PQChanItem::in(const void *data, const int size)
{
{
std::ostringstream out;
out << "PQChanItem::in() Data: " << data;
out << " Size: " << size << std::endl;
pqioutput(PQL_DEBUG_BASIC, pqicizone, out.str());
}
clear();
int i;
int basesize = PQChanItem::getSize();
if (size < basesize)
{
pqioutput(PQL_ALERT, pqicizone,
"PQChanItem::in() Not enough space for Class (Base)!");
return -1; // cant be us.
}
// now get certLen.
char *loc = ((char *) data);
certType = ((int *) loc)[0];
certLen = ((int *) loc)[1];
loc += 8;
// check size again.
if (size < (basesize = PQChanItem::getSize()))
{
pqioutput(PQL_ALERT, pqicizone,
"PQChanItem::in() Not enough space for Class (Cert)!");
return -1; // cant be us.
}
// allocate memory and copy.
if (NULL == (certDER = (unsigned char *) malloc(certLen)))
{
pqioutput(PQL_ALERT, pqicizone,
"PQChanItem::in() Not enough Memory!");
return -1; // cant be us.
}
memcpy(certDER, loc, certLen);
loc += certLen;
// now get msgSize.
if (((int *) loc)[0] != PQChan_MsgType)
{
pqioutput(PQL_ALERT, pqicizone,
"PQChanItem::in() Bad Msg Data Type!");
return -1; // cant be us.
}
int msize = ((int *) loc)[1];
loc += 8;
if (size < basesize + msize)
{
pqioutput(PQL_ALERT, pqicizone,
"PQChanItem::in() Not enough space for Class (Msg)!");
return -1; // cant be us.
}
for(i = 0; i < msize; i++)
{
msg += loc[i];
}
loc += msize;
// now the files....
// get total size... and check.
// now list counter.
// now get msgSize.
if (((int *) loc)[0] != PQChan_ListType)
{
pqioutput(PQL_ALERT, pqicizone,
"PQChanItem::in() Bad List Data Type!");
return -1; // cant be us.
}
int fcount = ((int *) loc)[1];
int fsize = ((int *) loc)[2];
loc += 12;
{
std::ostringstream out;
out << "PQChanItem::in() Size before Files: " << PQChanItem::getSize();
out << " FileCount: " << fcount;
out << " FileSize: " << fsize;
pqioutput(PQL_DEBUG_BASIC, pqicizone, out.str());
}
// check the size again.
if (size < PQChanItem::getSize() + fsize)
{
pqioutput(PQL_ALERT, pqicizone,
"PQChanItem::in() Not enough space for Class (Files)!");
return -1; // cant be us.
}
// Loop through the the files.
int remain_fsize = fsize;
for(i = 0; i < fcount; i++)
{
FileItem file;
// loc, and the space left.
if (0 >= file.in(loc, remain_fsize))
{
std::ostringstream out;
out << "PQChanItem::in() Not enough space for Class (File2)!";
out << std::endl;
out << "\tWhen loading File #" << i+1 << " of " << fcount;
out << "\tCurrent Loc: " << loc << " Remaining: " << remain_fsize;
pqioutput(PQL_ALERT, pqicizone, out.str());
return -1; // cant be us.
}
{
std::ostringstream out;
out << "PQChanItem::in() Loaded File #" << i+1;
out << " Loc: " << loc << " size: " << file.getSize();
pqioutput(PQL_DEBUG_BASIC, pqicizone, out.str());
}
loc += file.getSize();
remain_fsize -= file.getSize();
files.push_back(file);
}
if (remain_fsize != 0)
{
std::ostringstream out;
out << "PQChanItem::in() Warning files size incorrect:";
out << std::endl;
out << "Indicated Size: " << fsize << " Indicated Count:";
out << fcount << std::endl;
out << "Real Size: " << fsize - remain_fsize;
pqioutput(PQL_ALERT, pqicizone, out.str());
}
// only the signature to go!.
signType = ((int *) loc)[0];
signLen = ((int *) loc)[1];
loc += 8;
// check size again.
if (size != PQChanItem::getSize())
{
std::ostringstream out;
out << "PQChanItem::in() Size of Packet Incorrect!";
out << std::endl;
out << "getSize(): " << PQChanItem::getSize();
out << "data size: " << size;
pqioutput(PQL_ALERT, pqicizone, out.str());
return -1; // cant be us.
}
// allocate memory and copy.
if (NULL == (signature = (unsigned char *) malloc(signLen)))
{
pqioutput(PQL_ALERT, pqicizone,
"PQChanItem::in() Not enough Memory!");
return -1; // cant be us.
}
memcpy(signature, loc, signLen);
loc += signLen;
return PQChanItem::getSize();
}
std::ostream &PQChanItem::print(std::ostream &out)
{
out << "-------- PQChanItem" << std::endl;
PQItem::print(out);
out << "Cert Type/Len: " << certType << "/";
out << certLen << std::endl;
out << "Msg: " << msg << std::endl;
FileList::iterator it;
for(it = files.begin(); it != files.end(); it++)
{
it -> print(out);
}
out << "Sign Type/Len: " << signType << "/";
out << signLen << std::endl;
return out << "--------" << std::endl;
}
std::ostream &PQChanItem::FileItem::print(std::ostream &out)
{
out << "-- PQChanItem::FileItem" << std::endl;
out << "Name: " << name << std::endl;
out << "Hash: " << hash << std::endl;
out << "Size: " << size << std::endl;
return out << "--" << std::endl;
}
// Overloaded from PQTunnel.
const int PQChanItem::FileItem::getSize() const
{
// 8 bytes
// 8 bytes file + size;
// 8 bytes message + size;
// 8 bytes size;
return 8 + 8 + name.length() + 8 + hash.length() + 8;
}
int PQChanItem::FileItem::out(void *data, const int size) const
{
{
std::ostringstream out;
out << "PQChanItem::FileItem::out() Data: " << data;
out << " Size: " << size << std::endl;
pqioutput(PQL_DEBUG_BASIC, pqicizone, out.str());
}
if (size < PQChanItem::FileItem::getSize())
{
pqioutput(PQL_DEBUG_BASIC, pqicizone,
"PQChanItem::FileItem::out() Packet Too Small!");
return -1;
}
// out is easy cos the getSize should be correct.
char *dta = (char *) data;
// first we put down the total
((int *) dta)[0] = PQChan_FileType;
((int *) dta)[1] = PQChanItem::FileItem::getSize();
dta += 8; // 4 bytes per int.
((int *) dta)[0] = PQChan_NameType;
((int *) dta)[1] = name.length();
dta += 8; // 4 bytes per int.
memcpy(dta, name.c_str(), name.length());
dta += name.length();
((int *) dta)[0] = PQChan_HashType;
((int *) dta)[1] = hash.length();
dta += 8; // 4 bytes per int.
memcpy(dta, hash.c_str(), hash.length());
dta += hash.length();
((int *) dta)[0] = PQChan_SizeType;
((int *) dta)[1] = this -> size;
dta += 8; // 4 bytes per int.
return PQChanItem::FileItem::getSize();
}
void PQChanItem::FileItem::clear()
{
// first reset all our dataspaces.
name.clear();
hash.clear();
}
int PQChanItem::FileItem::in(const void *data, const int size)
{
{
std::ostringstream out;
out << "PQChanItem::FileItem::in() Data: " << data;
out << " Size: " << size << std::endl;
pqioutput(PQL_DEBUG_BASIC, pqicizone, out.str());
}
clear();
int i;
int basesize = PQChanItem::FileItem::getSize();
if (size < basesize)
{
pqioutput(PQL_ALERT, pqicizone,
"PQChanItem::FileItem::in() No space for Class (Base)!");
return -1; // cant be us.
}
char *loc = ((char *) data);
if (((int *) loc)[0] != PQChan_FileType)
{
pqioutput(PQL_ALERT, pqicizone,
"PQChanItem::FileItem::in() Bad File Data Type!");
return -1; // cant be us.
}
int real_size = ((int *) loc)[1];
if (size < real_size)
{
pqioutput(PQL_ALERT, pqicizone,
"PQChanItem::FileItem::in() No space for Class (TotalSize)!");
return -1; // cant be us.
}
loc += 8; // 4 bytes per int.
// now get name;
if (((int *) loc)[0] != PQChan_NameType)
{
pqioutput(PQL_ALERT, pqicizone,
"PQChanItem::FileItem::in() Bad Name Data Type!");
return -1; // cant be us.
}
int msize = ((int *) loc)[1];
loc += 8;
if (real_size < basesize + msize)
{
pqioutput(PQL_ALERT, pqicizone,
"PQChanItem::FileItem::in() No space for Class (Name)!");
return -1; // cant be us.
}
for(i = 0; i < msize; i++)
{
name += loc[i];
}
loc += msize;
// now get hash;
if (((int *) loc)[0] != PQChan_HashType)
{
pqioutput(PQL_ALERT, pqicizone,
"PQChanItem::FileItem::in() Bad Hash Data Type!");
return -1; // cant be us.
}
int hsize = ((int *) loc)[1];
loc += 8;
if (real_size < basesize + msize + hsize)
{
pqioutput(PQL_ALERT, pqicizone,
"PQChanItem::FileItem::in() No space for Class (Hash)!");
return -1; // cant be us.
}
for(i = 0; i < hsize; i++)
{
hash += loc[i];
}
loc += hsize;
// now get size.
if (((int *) loc)[0] != PQChan_SizeType)
{
pqioutput(PQL_ALERT, pqicizone,
"PQChanItem::FileItem::in() Bad Size Data Type!");
return -1; // cant be us.
}
this -> size = ((int *) loc)[1];
loc += 8;
// finally verify that the sizes are correct.
if (real_size != PQChanItem::FileItem::getSize())
{
pqioutput(PQL_ALERT, pqicizone,
"PQChanItem::FileItem::in() Size Mismatch!");
return -1; // cant be us.
}
return PQChanItem::FileItem::getSize();
}

View File

@ -0,0 +1,111 @@
/*
* "$Id: pqichannel.h,v 1.3 2007-02-18 21:46:49 rmf24 Exp $"
*
* 3P/PQI network interface for RetroShare.
*
* Copyright 2004-2006 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 MRK_PQI_CHANNELITEM_H
#define MRK_PQI_CHANNELITEM_H
#include "pqi/pqitunnel.h"
#define PQI_TUNNEL_CHANNEL_ITEM_TYPE 162
PQTunnel *createChannelItems(void *d, int n);
class PQChanItem: public PQTunnel
{
protected:
//PQChanItem(int st);
public:
PQChanItem();
~PQChanItem();
virtual PQChanItem *clone();
void copy(const PQChanItem *di);
void clear();
virtual std::ostream &print(std::ostream &out);
// Overloaded from PQTunnel.
virtual const int getSize() const;
virtual int out(void *data, const int size) const;
virtual int in(const void *data, const int size);
// So what data do we need.
// data load.
//
// 1) a Message.
// 2) a list of filenames/hashs/sizes.
//
// So you can different types
// of channels.
//
// 1) Clear Text Signed.
// -> name
// -> public key.
// -> data load
// -> signature. (of all)
//
// 2) Encrypted.
// -> name
// -> public key
// -> encrypted data load.
// -> signature (of all)
//
class FileItem
{
public:
std::string name;
std::string hash;
long size;
void clear();
std::ostream &print(std::ostream &out);
const int getSize() const;
int out(void *data, const int size) const;
int in(const void *data, const int size);
};
typedef std::list<FileItem> FileList;
// Certificate/Key (containing Name)
unsigned char *certDER;
int certType;
int certLen;
std::string msg;
std::string title;
FileList files;
unsigned char *signature;
int signType;
int signLen;
bool signValid; // not transmitted.
};
#endif // MRK_PQI_CHANNELITEM_H

View File

@ -0,0 +1,216 @@
/*
* "$Id: pqidebug.cc,v 1.6 2007-02-18 21:46:49 rmf24 Exp $"
*
* 3P/PQI network interface for RetroShare.
*
* Copyright 2004-2006 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 "pqi/pqidebug.h"
#include <map>
#include <stdio.h>
const int PQI_DEBUG_STDERR = 1; /* stuff goes to stderr */
const int PQI_DEBUG_LOGFILE = 2; /* stuff goes to logfile */
const int PQI_DEBUG_LOGCRASH = 3; /* minimal logfile stored after crashes */
const int PQI_DEBUG_LOGC_MAX = 1000; /* max length of carshfile log */
const int PQI_DEBUG_LOGC_MIN_SAVE = 100; /* max length of carshfile log */
static std::map<int, int> zoneLevel;
static int defaultLevel = PQL_WARNING;
static FILE *ofd = stderr;
static int debugMode = PQI_DEBUG_STDERR;
static int lineCount = 0;
static std::string crashfile;
static int debugTS = 0;
int setDebugCrashMode(const char *cfile)
{
crashfile = cfile;
/* if the file exists - then we crashed, save it */
FILE *tmpin = fopen(crashfile.c_str(), "r");
if (tmpin)
{
/* see how long it is */
fseek(tmpin, 0, SEEK_END);
if (ftell(tmpin) > PQI_DEBUG_LOGC_MIN_SAVE)
{
std::string crashfile_save = crashfile + "-save";
fprintf(stderr, "Detected Old Crash File: %s\n", crashfile.c_str());
fprintf(stderr, "Copying to: %s\n", crashfile_save.c_str());
/* go back to the start */
fseek(tmpin, 0, SEEK_SET);
FILE *tmpout = fopen(crashfile_save.c_str(), "w");
int da_size = 10240;
char dataarray[da_size]; /* 10k */
unsigned int da_read = 0;
if (!tmpout)
{
fprintf(stderr, "Failed to open CrashSave\n");
fclose(tmpin);
return -1;
}
while(0 != (da_read = fread(dataarray, 1, da_size, tmpin)))
{
if (da_read != fwrite(dataarray, 1, da_read, tmpout))
{
fprintf(stderr, "Failed writing to CrashSave\n");
fclose(tmpout);
fclose(tmpin);
return -1;
}
}
fclose(tmpout);
fclose(tmpin);
}
else
{
fprintf(stderr, "Negligable Old CrashLog, ignoring\n");
fclose(tmpin);
}
}
if (0 < setDebugFile(crashfile.c_str()))
{
fprintf(stderr, "Switching To CrashLog Mode!\n");
debugMode = PQI_DEBUG_LOGCRASH;
lineCount = 0;
debugTS = time(NULL);
}
return 1;
}
/* this is called when we exit normally */
int clearDebugCrashLog()
{
/* check we are in crashLog Mode */
if (debugMode != PQI_DEBUG_LOGCRASH)
{
fprintf(stderr, "Not in CrashLog Mode - nothing to clear!\n");
return 1;
}
fprintf(stderr, "clearDebugCrashLog() Cleaning up\n");
/* shutdown crashLog Mode */
fclose(ofd);
ofd = stderr;
debugMode = PQI_DEBUG_STDERR;
/* just open the file, and then close */
FILE *tmpin = fopen(crashfile.c_str(), "w");
fclose(tmpin);
return 1;
}
int setDebugFile(const char *fname)
{
if (NULL != (ofd = fopen(fname, "w")))
{
fprintf(stderr, "Logging redirected to %s\n", fname);
debugMode = PQI_DEBUG_LOGFILE;
return 1;
}
else
{
ofd = stderr;
debugMode = PQI_DEBUG_STDERR;
fprintf(stderr, "Logging redirect to %s FAILED\n", fname);
return -1;
}
}
int setOutputLevel(int lvl)
{
return defaultLevel = lvl;
}
int setZoneLevel(int lvl, int zone)
{
zoneLevel[zone] = lvl;
return zone;
}
int getZoneLevel(int zone)
{
std::map<int, int>::iterator it = zoneLevel.find(zone);
if (it == zoneLevel.end())
{
return defaultLevel;
}
return it -> second;
}
int pqioutput(unsigned int lvl, int zone, std::string msg)
{
if ((signed) lvl <= getZoneLevel(zone))
{
time_t t = time(NULL);
if (debugMode == PQI_DEBUG_LOGCRASH)
{
if (lineCount > PQI_DEBUG_LOGC_MAX)
{
/* restarting logging */
fprintf(stderr, "Rolling over the CrashLog\n");
fclose(ofd);
ofd = NULL;
if (0 < setDebugFile(crashfile.c_str()))
{
fprintf(ofd, "Debug CrashLog:");
fprintf(ofd, " retroShare uptime %ld secs\n",
t-debugTS);
debugMode = PQI_DEBUG_LOGCRASH;
lineCount = 0;
}
else
{
fprintf(stderr, "Rollover Failed!\n");
}
}
}
std::string timestr = ctime(&t);
std::string timestr2 = timestr.substr(0,timestr.length()-1);
/* remove the endl */
fprintf(ofd, "(%s Z: %d, lvl:%d): %s \n",
timestr2.c_str(), zone, lvl, msg.c_str());
fflush(ofd);
lineCount++;
}
return 1;
}

View File

@ -0,0 +1,49 @@
/*
* "$Id: pqidebug.h,v 1.4 2007-02-18 21:46:49 rmf24 Exp $"
*
* 3P/PQI network interface for RetroShare.
*
* Copyright 2004-2006 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 PQI_LOG_DEBUG_H
#define PQI_LOG_DEBUG_H
#define PQL_NONE -1
#define PQL_ALERT 1
#define PQL_ERROR 3
#define PQL_WARNING 5
#define PQL_DEBUG_ALERT 6
#define PQL_DEBUG_BASIC 8
#define PQL_DEBUG_ALL 10
#include <string>
int setDebugCrashMode(const char *cfile);
int clearDebugCrashLog();
int setDebugFile(const char *fname);
int setOutputLevel(int lvl);
int setZoneLevel(int lvl, int zone);
int pqioutput(unsigned int lvl, int zone, std::string msg);
#endif

View File

@ -0,0 +1,763 @@
/*
* "$Id: pqihandler.cc,v 1.12 2007-03-31 09:41:32 rmf24 Exp $"
*
* 3P/PQI network interface for RetroShare.
*
* Copyright 2004-2006 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 "pqi/pqihandler.h"
#include <sstream>
#include "pqi/pqidebug.h"
const int pqihandlerzone = 34283;
pqihandler::pqihandler(SecurityPolicy *Global)
{
// The global security....
// if something is disabled here...
// cannot be enabled by module.
globsec = Global;
{
std::ostringstream out;
out << "New pqihandler()" << std::endl;
out << "Security Policy: " << secpolicy_print(globsec);
out << std::endl;
pqioutput(PQL_DEBUG_BASIC, pqihandlerzone, out.str());
}
// setup minimal total+individual rates.
rateIndiv_out = 0.01;
rateIndiv_in = 0.01;
rateMax_out = 0.01;
rateMax_in = 0.01;
return;
}
int pqihandler::tick()
{
// tick all interfaces...
std::map<int, SearchModule *>::iterator it;
int moreToTick = 0;
for(it = mods.begin(); it != mods.end(); it++)
{
if (0 < ((it -> second) -> pqi) -> tick())
{
moreToTick = 1;
}
}
// get the items, and queue them correctly
if (0 < GetItems())
{
moreToTick = 1;
}
UpdateRates();
return moreToTick;
}
int pqihandler::status()
{
std::map<int, SearchModule *>::iterator it;
{ // for output
std::ostringstream out;
out << "pqihandler::status() Active Modules:" << std::endl;
// display all interfaces...
for(it = mods.begin(); it != mods.end(); it++)
{
out << "\tModule [" << it -> first << "] Pointer <";
out << (void *) ((it -> second) -> pqi) << ">" << std::endl;
}
pqioutput(PQL_DEBUG_BASIC, pqihandlerzone, out.str());
} // end of output.
// status all interfaces...
for(it = mods.begin(); it != mods.end(); it++)
{
((it -> second) -> pqi) -> status();
}
return 1;
}
int pqihandler::AddSearchModule(SearchModule *mod, int chanid)
{
// if chan id set, then use....
// otherwise find empty channel.
int realchanid = -1;
std::map<int, SearchModule *>::iterator it;
if ((chanid > 0) && (mods.find(chanid) == mods.end()))
{
// okay id.
realchanid = chanid;
}
else
{
// find empty chan.
for(int i = 1; (i < 1000) && (realchanid == -1); i++)
{
if (mods.find(i) == mods.end())
{
realchanid = i;
}
}
if (realchanid > 0)
{
std::ostringstream out;
out << "Allocated Chan Id: " << realchanid << std::endl;
pqioutput(PQL_DEBUG_BASIC, pqihandlerzone, out.str());
}
else
{
std::ostringstream out;
out << "Unable to Allocate Channel!" << std::endl;
pqioutput(PQL_DEBUG_BASIC, pqihandlerzone, out.str());
return -1;
}
}
// check security.
if (mod -> sp == NULL)
{
// create policy.
mod -> sp = secpolicy_create();
}
// limit to what global security allows.
secpolicy_limit(globsec, mod -> sp);
// store.
mods[realchanid] = mod;
mod -> smi = realchanid;
// experimental ... pushcid.
Person *p = (mod -> pqi) -> getContact();
if (p != NULL)
{
p -> cidpush(realchanid);
}
return realchanid;
}
int pqihandler::RemoveSearchModule(SearchModule *mod)
{
std::map<int, SearchModule *>::iterator it;
for(it = mods.begin(); it != mods.end(); it++)
{
if (mod == it -> second)
{
mods.erase(it);
return 1;
}
}
return -1;
}
// dummy output check
int pqihandler::checkOutgoingPQItem(PQItem *item, int global)
{
pqioutput(PQL_WARNING, pqihandlerzone,
"pqihandler::checkOutgoingPQItem() NULL fn");
return 1;
}
// generalised output
int pqihandler::HandlePQItem(PQItem *item, int allowglobal)
{
std::map<int, SearchModule *>::iterator it;
pqioutput(PQL_DEBUG_BASIC, pqihandlerzone,
"pqihandler::HandlePQItem()");
if ((!allowglobal) && (!checkOutgoingPQItem(item, allowglobal)))
{
std::ostringstream out;
out << "pqihandler::HandlePQItem() checkOutgoingPQItem";
out << " Failed on item: " << std::endl;
item -> print(out);
pqioutput(PQL_DEBUG_BASIC, pqihandlerzone, out.str());
delete item;
return -1;
}
// need to get channel id. (and remove from stack)
int chan = item -> cidpop();
if (chan > 0)
{
pqioutput(PQL_DEBUG_BASIC, pqihandlerzone,
"pqihandler::HandlePQItem() Sending to One Channel");
// find module.
if ((it = mods.find(chan)) == mods.end())
{
std::ostringstream out;
out << "pqihandler::HandlePQItem() Invalid chan!";
pqioutput(PQL_DEBUG_BASIC, pqihandlerzone, out.str());
delete item;
return -1;
}
// check security... is output allowed.
if(0 < secpolicy_check((it -> second) -> sp, 0, PQI_OUTGOING))
{
std::ostringstream out;
out << "pqihandler::HandlePQItem() sending to chan:";
out << it -> first << std::endl;
pqioutput(PQL_DEBUG_BASIC, pqihandlerzone, out.str());
// if yes send on item.
((it -> second) -> pqi) -> SendItem(item);
return 1;
}
else
{
std::ostringstream out;
out << "pqihandler::HandlePQItem()";
out << " Sec not approved";
pqioutput(PQL_DEBUG_BASIC, pqihandlerzone, out.str());
delete item;
return -1;
}
}
else
{
if (allowglobal <= 0)
{
std::ostringstream out;
out << "pqihandler::HandleSearchItem()";
out << " invalid routing for non-global searchitem";
pqioutput(PQL_DEBUG_BASIC, pqihandlerzone, out.str());
return -1;
}
pqioutput(PQL_DEBUG_BASIC, pqihandlerzone,
"pqihandler::HandlePQItem() Sending to All Channels");
// loop through all channels.
// for each one.
// find module
// if yes send.
for(it = mods.begin(); it != mods.end(); it++)
{
// check security... is output allowed.
if(0 < secpolicy_check((it -> second) -> sp, 0, PQI_OUTGOING))
{
std::ostringstream out;
out << "pqihandler::HandlePQItem()";
out << "Sending to chan:" << it -> first;
pqioutput(PQL_DEBUG_BASIC, pqihandlerzone, out.str());
// if yes send on item.
((it -> second) -> pqi) -> SendItem(item -> clone());
}
else
{
std::ostringstream out;
out << "pqihandler::HandlePQItem()";
out << " List Send - Not in this channel!";
pqioutput(PQL_DEBUG_BASIC, pqihandlerzone, out.str());
}
}
// now we can clean up!
delete item;
return 1;
}
// if successfully sent to at least one.
return 1;
}
// 4 very similar outputs.....
int pqihandler::Search(SearchItem *ns)
{
return HandlePQItem(ns, 1);
}
/* This is called when we only want it to go to 1 person.... */
int pqihandler::SearchSpecific(SearchItem *ns)
{
return HandlePQItem(ns, 0);
}
int pqihandler::CancelSearch(SearchItem *ns)
{
return HandlePQItem(ns, 1);
}
int pqihandler::SendFileItem(PQFileItem *ns)
{
return HandlePQItem(ns, 0);
}
int pqihandler::SendSearchResult(PQFileItem *ns)
{
return HandlePQItem(ns, 0);
}
int pqihandler::SendMsg(ChatItem *ns)
{
/* switch from 1 -> 0 for specific directed Msg */
return HandlePQItem(ns, 0);
}
int pqihandler::SendGlobalMsg(ChatItem *ns)
{
return HandlePQItem(ns, 1);
}
int pqihandler::SendOtherPQItem(PQItem *ns)
{
pqioutput(PQL_DEBUG_BASIC, pqihandlerzone,
"pqihandler::SendOtherPQItem()");
return HandlePQItem(ns, 1);
}
// inputs. This is a very basic
// system that is completely biased and slow...
// someone please fix.
int pqihandler::GetItems()
{
std::map<int, SearchModule *>::iterator it;
PQItem *item;
int count = 0;
// loop through modules....
for(it = mods.begin(); it != mods.end(); it++)
{
SearchModule *mod = (it -> second);
// check security... is output allowed.
if(0 < secpolicy_check((it -> second) -> sp,
PQI_ITEM_TYPE_ITEM, PQI_INCOMING))
{
// if yes... attempt to read.
while((item = (mod -> pqi) -> GetItem()) != NULL)
{
std::ostringstream out;
out << "pqihandler::GetItems() Incoming Item ";
out << " from: " << mod -> pqi << std::endl;
item -> print(out);
pqioutput(PQL_DEBUG_BASIC,
pqihandlerzone, out.str());
// got one!....
// update routing.
item -> cidpush(mod -> smi);
SortnStoreItem(item);
count++;
}
}
else
{
// not allowed to recieve from here....
while((item = (mod -> pqi) -> GetItem()) != NULL)
{
std::ostringstream out;
out << "pqihandler::GetItems() Incoming Item ";
out << " from: " << mod -> pqi << std::endl;
item -> print(out);
out << std::endl;
out << "Item Not Allowed (Sec Pol). deleting!";
out << std::endl;
pqioutput(PQL_DEBUG_BASIC,
pqihandlerzone, out.str());
delete item;
}
}
}
return count;
}
void pqihandler::SortnStoreItem(PQItem *item)
{
// some template comparors for sorting incoming.
const static PQItem_MatchType match_fileitem(PQI_ITEM_TYPE_FILEITEM,
0);
const static PQItem_MatchType match_result(PQI_ITEM_TYPE_FILEITEM,
PQI_FI_SUBTYPE_GENERAL);
const static PQItem_MatchType match_endsrch(PQI_ITEM_TYPE_SEARCHITEM,
PQI_SI_SUBTYPE_CANCEL);
const static PQItem_MatchType match_reqsrch(PQI_ITEM_TYPE_SEARCHITEM,
PQI_SI_SUBTYPE_SEARCH);
const static PQItem_MatchType match_info(PQI_ITEM_TYPE_INFOITEM, 0);
const static PQItem_MatchType match_chat(PQI_ITEM_TYPE_CHATITEM, 0);
if (match_fileitem(item))
{
if (match_result(item))
{
pqioutput(PQL_DEBUG_BASIC, pqihandlerzone,
"SortnStore -> Result");
in_result.push_back(item);
}
else
{
pqioutput(PQL_DEBUG_BASIC, pqihandlerzone,
"SortnStore -> FileItem");
in_file.push_back(item);
}
}
else if (match_endsrch(item))
{
pqioutput(PQL_DEBUG_BASIC, pqihandlerzone,
"SortnStore -> Cancel Search");
in_endsrch.push_back(item);
}
else if (match_reqsrch(item))
{
pqioutput(PQL_DEBUG_BASIC, pqihandlerzone,
"SortnStore -> Search Request");
in_reqsrch.push_back(item);
}
else if (match_chat(item))
{
pqioutput(PQL_DEBUG_BASIC, pqihandlerzone,
"SortnStore -> Chat");
in_chat.push_back(item);
}
else if (match_info(item))
{
pqioutput(PQL_DEBUG_BASIC, pqihandlerzone,
"SortnStore -> Info");
in_info.push_back(item);
}
else
{
pqioutput(PQL_DEBUG_BASIC, pqihandlerzone,
"SortnStore -> Other");
in_other.push_back(item);
}
return;
}
// much like the input stuff.
PQFileItem *pqihandler::GetSearchResult()
{
if (in_result.size() != 0)
{
PQFileItem *fi = (PQFileItem *) in_result.front();
in_result.pop_front();
return fi;
}
return NULL;
}
SearchItem *pqihandler::RequestedSearch()
{
if (in_reqsrch.size() != 0)
{
SearchItem *si = (SearchItem *) in_reqsrch.front();
in_reqsrch.pop_front();
return si;
}
return NULL;
}
SearchItem * pqihandler::CancelledSearch()
{
if (in_endsrch.size() != 0)
{
SearchItem *si = (SearchItem *) in_endsrch.front();
in_endsrch.pop_front();
return si;
}
return NULL;
}
PQFileItem *pqihandler::GetFileItem()
{
if (in_file.size() != 0)
{
PQFileItem *fi = (PQFileItem *) in_file.front();
in_file.pop_front();
return fi;
}
return NULL;
}
// Chat Interface
ChatItem *pqihandler::GetMsg()
{
if (in_chat.size() != 0)
{
ChatItem *ci = (ChatItem *) in_chat.front();
in_chat.pop_front();
return ci;
}
return NULL;
}
PQItem *pqihandler::GetOtherPQItem()
{
if (in_other.size() != 0)
{
PQItem *pqi = in_other.front();
in_other.pop_front();
return pqi;
}
return NULL;
}
PQItem *pqihandler::SelectOtherPQItem(bool (*tst)(PQItem *))
{
std::list<PQItem *>::iterator it;
it = find_if(in_other.begin(), in_other.end(), *tst);
if (it != in_other.end())
{
PQItem *pqi = (*it);
in_other.erase(it);
return pqi;
}
return NULL;
}
static const float MIN_RATE = 0.01; // 10 B/s
// internal fn to send updates
int pqihandler::UpdateRates()
{
std::map<int, SearchModule *>::iterator it;
int num_sm = mods.size();
float avail_in = getMaxRate(true);
float avail_out = getMaxRate(false);
float avg_rate_in = avail_in/num_sm;
float avg_rate_out = avail_out/num_sm;
float indiv_in = getMaxIndivRate(true);
float indiv_out = getMaxIndivRate(false);
float used_bw_in = 0;
float used_bw_out = 0;
float extra_bw_in = 0;
float extra_bw_out = 0;
int maxxed_in = 0;
int maxxed_out = 0;
// loop through modules....
for(it = mods.begin(); it != mods.end(); it++)
{
SearchModule *mod = (it -> second);
float crate_in = mod -> pqi -> getRate(true);
float crate_out = mod -> pqi -> getRate(false);
used_bw_in += crate_in;
used_bw_out += crate_out;
if (crate_in > avg_rate_in)
{
if (mod -> pqi -> getMaxRate(true) == indiv_in)
{
maxxed_in++;
}
extra_bw_in += crate_in - avg_rate_in;
}
if (crate_out > avg_rate_out)
{
if (mod -> pqi -> getMaxRate(false) == indiv_out)
{
maxxed_out++;
}
extra_bw_out += crate_out - avg_rate_out;
}
// std::cerr << "\tSM(" << mod -> smi << ")";
// std::cerr << "In A: " << mod -> pqi -> getMaxRate(true);
// std::cerr << " C: " << crate_in;
// std::cerr << " && Out A: " << mod -> pqi -> getMaxRate(false);
// std::cerr << " C: " << crate_out << std::endl;
}
// std::cerr << "Totals (In) Used B/W " << used_bw_in;
// std::cerr << " Excess B/W " << extra_bw_in;
// std::cerr << " Available B/W " << avail_in << std::endl;
// std::cerr << "Totals (Out) Used B/W " << used_bw_out;
// std::cerr << " Excess B/W " << extra_bw_out;
// std::cerr << " Available B/W " << avail_out << std::endl;
if (used_bw_in > avail_in)
{
//std::cerr << "Decreasing Incoming B/W!" << std::endl;
// drop all above the avg down!
float fchg = (used_bw_in - avail_in) / (float) extra_bw_in;
for(it = mods.begin(); it != mods.end(); it++)
{
SearchModule *mod = (it -> second);
float crate_in = mod -> pqi -> getRate(true);
float new_max = avg_rate_in;
if (crate_in > avg_rate_in)
{
new_max = avg_rate_in + (1 - fchg) *
(crate_in - avg_rate_in);
}
if (new_max > indiv_in)
{
new_max = indiv_in;
}
mod -> pqi -> setMaxRate(true, new_max);
}
}
// if not maxxed already and using less than 95%
else if ((maxxed_in != num_sm) && (used_bw_in < 0.95 * avail_in))
{
//std::cerr << "Increasing Incoming B/W!" << std::endl;
// increase.
float fchg = (avail_in - used_bw_in) / avail_in;
for(it = mods.begin(); it != mods.end(); it++)
{
SearchModule *mod = (it -> second);
float crate_in = mod -> pqi -> getRate(true);
float max_in = mod -> pqi -> getMaxRate(true);
if (max_in == indiv_in)
{
// do nothing...
}
else
{
float new_max = max_in;
if (max_in < avg_rate_in)
{
new_max = avg_rate_in * (1 + fchg);
}
else if (crate_in > 0.5 * max_in)
{
new_max = max_in * (1 + fchg);
}
if (new_max > indiv_in)
{
new_max = indiv_in;
}
mod -> pqi -> setMaxRate(true, new_max);
}
}
}
if (used_bw_out > avail_out)
{
//std::cerr << "Decreasing Outgoing B/W!" << std::endl;
// drop all above the avg down!
float fchg = (used_bw_out - avail_out) / (float) extra_bw_out;
for(it = mods.begin(); it != mods.end(); it++)
{
SearchModule *mod = (it -> second);
float crate_out = mod -> pqi -> getRate(false);
float new_max = avg_rate_out;
if (crate_out > avg_rate_out)
{
new_max = avg_rate_out + (1 - fchg) *
(crate_out - avg_rate_out);
}
if (new_max > indiv_out)
{
new_max = indiv_out;
}
mod -> pqi -> setMaxRate(false, new_max);
}
}
// if not maxxed already and using less than 95%
else if ((maxxed_out != num_sm) && (used_bw_out < 0.95 * avail_out))
{
//std::cerr << "Increasing Outgoing B/W!" << std::endl;
// increase.
float fchg = (avail_out - used_bw_out) / avail_out;
for(it = mods.begin(); it != mods.end(); it++)
{
SearchModule *mod = (it -> second);
float crate_out = mod -> pqi -> getRate(false);
float max_out = mod -> pqi -> getMaxRate(false);
if (max_out == indiv_out)
{
// do nothing...
}
else
{
float new_max = max_out;
if (max_out < avg_rate_out)
{
new_max = avg_rate_out * (1 + fchg);
}
else if (crate_out > 0.5 * max_out)
{
new_max = max_out * (1 + fchg);
}
if (new_max > indiv_out)
{
new_max = indiv_out;
}
mod -> pqi -> setMaxRate(false, new_max);
}
}
}
return 1;
}

View File

@ -0,0 +1,169 @@
/*
* "$Id: pqihandler.h,v 1.10 2007-03-31 09:41:32 rmf24 Exp $"
*
* 3P/PQI network interface for RetroShare.
*
* Copyright 2004-2006 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 MRK_PQI_HANDLER_HEADER
#define MRK_PQI_HANDLER_HEADER
#include "pqi/pqi.h"
#include "pqi/pqisecurity.h"
/**************** PQI_USE_XPGP ******************/
#if defined(PQI_USE_XPGP)
#include "pqi/xpgpcert.h"
#else /* X509 Certificates */
/**************** PQI_USE_XPGP ******************/
#include "pqi/sslcert.h"
#endif /* X509 Certificates */
/**************** PQI_USE_XPGP ******************/
#include <map>
#include <list>
class SearchModule
{
public:
int smi; // id.
PQInterface *pqi;
SecurityPolicy *sp;
};
// Presents a P3 Face to the world!
// and funnels data through to a PQInterface.
//
class pqihandler: public P3Interface
{
public:
pqihandler(SecurityPolicy *Global);
int AddSearchModule(SearchModule *mod, int chanid = -1);
int RemoveSearchModule(SearchModule *mod);
// P3Interface.
// 4 very similar outputs.....
virtual int Search(SearchItem *ns);
virtual int SearchSpecific(SearchItem *ns); /* search one person only */
virtual int CancelSearch(SearchItem *ns); /* no longer used? */
virtual int SendSearchResult(PQFileItem *);
// inputs.
virtual PQFileItem * GetSearchResult();
virtual SearchItem * RequestedSearch();
virtual SearchItem * CancelledSearch();
// file i/o
virtual int SendFileItem(PQFileItem *ns);
virtual PQFileItem * GetFileItem();
// Chat Interface
virtual int SendMsg(ChatItem *item);
virtual int SendGlobalMsg(ChatItem *ns); /* needed until chat complete */
virtual ChatItem *GetMsg();
// Rest of P3Interface
virtual int tick();
virtual int status();
// Control Interface
virtual int SendOtherPQItem(PQItem *);
virtual PQItem *GetOtherPQItem();
virtual PQItem *SelectOtherPQItem(bool (*tst)(PQItem *));
// rate control.
void setMaxIndivRate(bool in, float val);
float getMaxIndivRate(bool in);
void setMaxRate(bool in, float val);
float getMaxRate(bool in);
protected:
/* check to be overloaded by those that can
* generates warnings otherwise
*/
virtual int checkOutgoingPQItem(PQItem *item, int global);
int HandlePQItem(PQItem *ns, int allowglobal);
int GetItems();
void SortnStoreItem(PQItem *item);
std::map<int, SearchModule *> mods;
SecurityPolicy *globsec;
// Temporary storage...
std::list<PQItem *> in_result, in_endsrch, in_reqsrch, in_reqfile,
in_file, in_chat, in_info, in_host, in_other;
private:
// rate control.
int UpdateRates();
float rateIndiv_in;
float rateIndiv_out;
float rateMax_in;
float rateMax_out;
};
inline void pqihandler::setMaxIndivRate(bool in, float val)
{
if (in)
rateIndiv_in = val;
else
rateIndiv_out = val;
return;
}
inline float pqihandler::getMaxIndivRate(bool in)
{
if (in)
return rateIndiv_in;
else
return rateIndiv_out;
}
inline void pqihandler::setMaxRate(bool in, float val)
{
if (in)
rateMax_in = val;
else
rateMax_out = val;
return;
}
inline float pqihandler::getMaxRate(bool in)
{
if (in)
return rateMax_in;
else
return rateMax_out;
}
#endif // MRK_PQI_HANDLER_HEADER

View File

@ -0,0 +1,65 @@
/*
* "$Id: pqiindic.h,v 1.3 2007-02-18 21:46:49 rmf24 Exp $"
*
* 3P/PQI network interface for RetroShare.
*
* Copyright 2004-2006 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 MRK_PQI_INDICATOR_HEADER
#define MRK_PQI_INDICATOR_HEADER
#include <vector>
// This will indicate to num different sources
// when the event has occured.
class Indicator
{
public:
Indicator(int n = 0)
:num(n), changeFlags(n) {IndicateChanged();}
void IndicateChanged()
{
for(int i = 0; i < num; i++)
changeFlags[i]=true;
}
bool Changed(int idx)
{
/* catch overflow */
if (idx > num - 1)
return false;
bool ans = changeFlags[idx];
changeFlags[idx] = false;
return ans;
}
private:
int num;
std::vector<bool> changeFlags;
};
#endif

View File

@ -0,0 +1,117 @@
/*
* "$Id: pqiloopback.cc,v 1.8 2007-02-19 20:08:30 rmf24 Exp $"
*
* 3P/PQI network interface for RetroShare.
*
* Copyright 2004-2006 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 "pqi/pqi.h"
#include "pqi/pqiloopback.h"
/**************** PQI_USE_XPGP ******************/
#if defined(PQI_USE_XPGP)
#include "pqi/xpgpcert.h"
#else /* X509 Certificates */
/**************** PQI_USE_XPGP ******************/
#include "pqi/sslcert.h"
#endif /* X509 Certificates */
/**************** PQI_USE_XPGP ******************/
// Test Interface (LoopBack)
pqiloopback::pqiloopback()
{
//std::cerr << "pqiloopback construction()" << std::endl;
// rates are irrelevant..... no B/W consumed.
setMaxRate(true, 0);
setMaxRate(false, 0);
setRate(true, 0);
setRate(false, 0);
return;
}
pqiloopback::~pqiloopback()
{
return;
}
int pqiloopback::SendItem(PQItem *i)
{
i -> p = getContact();
i -> flags |= PQI_ITEM_FLAG_LOCAL;
objs.push_back(i);
return 1;
}
PQItem * pqiloopback::GetItem()
{
if (objs.size() > 0)
{
PQItem *pqi = objs.front();
objs.pop_front();
// breaks the module, through ssl dependance.
// but necessary for running system..
//pqi -> p = getSSLRoot() -> getOwnCert();
return pqi;
}
return NULL;
}
int pqiloopback::GetFile(PQFileItem *item, std::ostream &in)
{
return 1;
}
int pqiloopback::SendFile(PQFileItem *, std::istream &out)
{
return 1;
}
Person *pqiloopback::getContact()
{
sslroot *root = getSSLRoot();
cert *c = root -> getOwnCert();
return c;
}
// // PQI interface.
int pqiloopback::tick()
{
return 0;
}
int pqiloopback::status()
{
return 0;
}

View File

@ -0,0 +1,67 @@
/*
* "$Id: pqiloopback.h,v 1.5 2007-02-19 20:08:30 rmf24 Exp $"
*
* 3P/PQI network interface for RetroShare.
*
* Copyright 2004-2006 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 MRK_PQI_LOOPBACK_HEADER
#define MRK_PQI_LOOPBACK_HEADER
// The standard data types and the search interface.
#include "pqi/pqi.h"
#include <map>
#include <list>
#include <iostream>
// Test Interface (LoopBack)
// public interface .... includes the whole p3interface.
class pqiloopback: public PQInterface
{
public:
pqiloopback();
virtual ~pqiloopback();
// search Interface.
virtual int SendItem(PQItem *item);
virtual PQItem *GetItem();
virtual int GetFile(PQFileItem *item, std::ostream &in);
virtual int SendFile(PQFileItem *item, std::istream &out);
// PQI interface.
virtual int tick();
virtual int status();
virtual Person *getContact();
private:
std::list<PQItem *> objs;
};
#endif //MRK_PQI_LOOPBACK_HEADER

View File

@ -0,0 +1,124 @@
/*
* "$Id: pqimon.cc,v 1.2 2007-02-18 21:46:49 rmf24 Exp $"
*
* 3P/PQI network interface for RetroShare.
*
* Copyright 2004-2006 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".
*
*/
/**************** PQI_USE_XPGP ******************/
#if defined(PQI_USE_XPGP)
#include "pqi/xpgpcert.h"
#else /* X509 Certificates */
/**************** PQI_USE_XPGP ******************/
#include "pqi/sslcert.h"
#endif /* X509 Certificates */
/**************** PQI_USE_XPGP ******************/
#include "pqi/pqimon.h"
pqimonitor::pqimonitor() { return; }
pqimonitor::~pqimonitor() { return; }
int pqimonitor::tick()
{
/* grab the sslroot - and check the state of the peers */
sslroot *sslr = getSSLRoot();
std::list<cert *> &certlist = sslr->getCertList();
std::list<cert *>::iterator it;
std::list<pqipeer>::iterator pit;
std::list<pqimonclient *>::iterator cit;
//std::cerr << "pqimonitor::tick() plist:" << plist.size() << " clist:" << certlist.size() << std::endl;
bool ok = true;
if (plist.size() != certlist.size())
{
ok = false;
}
pit = plist.begin();
for(it = certlist.begin(); (ok) && (it != certlist.end()); it++, pit++)
{
certsign sign;
if (!sslr->getcertsign(*it, sign))
{
ok = false;
break;
}
std::string id = convert_to_str(sign);
if (id != pit->id)
{
ok = false;
break;
}
}
if (!ok)
{
//std::cerr << "pqimonitor::tick() Updating plist" << std::endl;
/* copy the list */
plist.clear();
for(it = certlist.begin(); it != certlist.end(); it++)
{
/* list */
certsign sign;
if (!sslr->getcertsign(*it, sign))
{
std::cerr << "Major Error in pqimonitor!";
std::cerr << std::endl;
exit(1);
}
pqipeer peer;
peer.id = convert_to_str(sign);
peer.name = (*it)->Name();
if ((*it)->Connected())
{
peer.state = PQI_PEER_STATE_ONLINE;
}
else
{
peer.state = PQI_PEER_STATE_OFFLINE;
}
plist.push_back(peer);
}
/* now notify clients */
for(cit = clients.begin(); cit != clients.end(); cit++)
{
//std::cerr << "pqimonitor::tick() Calling Client" << std::endl;
(*cit)->monUpdate(plist);
}
}
return 0; /* don't make more work for anyone */
}

View File

@ -0,0 +1,72 @@
/*
* "$Id: pqibin.h,v 1.2 2007-02-18 21:46:49 rmf24 Exp $"
*
* 3P/PQI network interface for RetroShare.
*
* Copyright 2004-2006 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 PQI_MONITOR_HEADER
#define PQI_MONITOR_HEADER
/**** Rough sketch of a Monitor class
* expect it to change significantly
*
*/
const uint32_t PQI_PEER_STATE_OFFLINE = 0;
const uint32_t PQI_PEER_STATE_ONLINE = 1;
class pqipeer
{
public:
std::string id;
std::string name;
int state;
};
class pqimonclient
{
public:
pqimonclient() { return; }
virtual ~pqimonclient() { return; }
virtual void monUpdate(const std::list<pqipeer> &plist) = 0;
};
class pqimonitor
{
public:
pqimonitor();
~pqimonitor();
int tick();
int addClient(pqimonclient *cli) { clients.push_back(cli); return 1; }
private:
std::list<pqimonclient *> clients;
std::list<pqipeer> plist;
};
#endif

View File

@ -0,0 +1,852 @@
/*
* "$Id: pqinetwork.cc,v 1.18 2007-04-15 18:45:18 rmf24 Exp $"
*
* 3P/PQI network interface for RetroShare.
*
* Copyright 2004-2006 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 "pqi/pqinetwork.h"
#include <errno.h>
#include <iostream>
#include "pqi/pqidebug.h"
#include <sstream>
#include <iomanip>
static const int pqinetzone = 96184;
#ifdef WINDOWS_SYS /* Windows - define errno */
int errno;
#else /* Windows - define errno */
#include <netdb.h>
#endif
/********************************** WINDOWS/UNIX SPECIFIC PART ******************/
#ifndef WINDOWS_SYS
std::ostream &showSocketError(std::ostream &out)
{
int err = errno;
out << "\tSocket Error(" << err << ") : ";
out << socket_errorType(err) << std::endl;
return out;
}
std::string socket_errorType(int err)
{
if (err == EBADF)
{
return std::string("EBADF");
}
else if (err == EINVAL)
{
return std::string("EINVAL");
}
else if (err == EFAULT)
{
return std::string("EFAULT");
}
else if (err == ENOTSOCK)
{
return std::string("ENOTSOCK");
}
else if (err == EISCONN)
{
return std::string("EISCONN");
}
else if (err == ECONNREFUSED)
{
return std::string("ECONNREFUSED");
}
else if (err == ETIMEDOUT)
{
return std::string("ETIMEDOUT");
}
else if (err == ENETUNREACH)
{
return std::string("ENETUNREACH");
}
else if (err == EADDRINUSE)
{
return std::string("EADDRINUSE");
}
else if (err == EINPROGRESS)
{
return std::string("EINPROGRESS");
}
else if (err == EALREADY)
{
return std::string("EALREADY");
}
else if (err == EAGAIN)
{
return std::string("EAGAIN");
}
else if (err == EISCONN)
{
return std::string("EISCONN");
}
else if (err == ENOTCONN)
{
return std::string("ENOTCONN");
}
return std::string("UNKNOWN ERROR CODE");
}
#include <net/if.h>
#include <sys/ioctl.h>
std::list<std::string> getLocalInterfaces()
{
std::list<std::string> addrs;
int sock = 0;
struct ifreq ifreq;
struct if_nameindex *iflist = if_nameindex();
struct if_nameindex *ifptr = iflist;
//need a socket for ioctl()
if( (sock = socket(AF_INET, SOCK_STREAM, 0)) < 0)
{
pqioutput(PQL_ALERT, pqinetzone,
"Cannot Determine Local Addresses!");
exit(1);
}
// loop through the interfaces.
for(; *(char *)ifptr != 0; ifptr++)
{
//copy in the interface name to look up address of
strncpy(ifreq.ifr_name, ifptr->if_name, IF_NAMESIZE);
if(ioctl(sock, SIOCGIFADDR, &ifreq) != 0)
{
std::ostringstream out;
out << "Cannot Determine Address for Iface: ";
out << ifptr -> if_name << std::endl;
pqioutput(PQL_DEBUG_BASIC, pqinetzone, out.str());
}
else
{
struct sockaddr_in *aptr =
(struct sockaddr_in *) &ifreq.ifr_addr;
const char *astr=inet_ntoa(aptr -> sin_addr);
std::ostringstream out;
out << "Iface: ";
out << ifptr -> if_name << std::endl;
out << " Address: " << astr;
out << std::endl;
pqioutput(PQL_DEBUG_BASIC, pqinetzone, out.str());
addrs.push_back(astr);
}
}
// free socket -> or else run out of fds.
close(sock);
if_freenameindex(iflist);
return addrs;
}
/********************************** WINDOWS/UNIX SPECIFIC PART ******************/
#else
std::ostream &showSocketError(std::ostream &out)
{
int err = WSAGetLastError();
out << "\tSocket Error(" << err << ") : ";
out << socket_errorType(err) << std::endl;
return out;
}
std::string socket_errorType(int err)
{
if (err == WSAEBADF)
{
return std::string("WSABADF");
}
else if (err == WSAEINTR)
{
return std::string("WSAEINTR");
}
else if (err == WSAEACCES)
{
return std::string("WSAEACCES");
}
else if (err == WSAEFAULT)
{
return std::string("WSAEFAULT");
}
else if (err == WSAEINVAL)
{
return std::string("WSAEINVAL");
}
else if (err == WSAEMFILE)
{
return std::string("WSAEMFILE");
}
else if (err == WSAEWOULDBLOCK)
{
return std::string("WSAEWOULDBLOCK");
}
else if (err == WSAEINPROGRESS)
{
return std::string("WSAEINPROGRESS");
}
else if (err == WSAEALREADY)
{
return std::string("WSAEALREADY");
}
else if (err == WSAENOTSOCK)
{
return std::string("WSAENOTSOCK");
}
else if (err == WSAEDESTADDRREQ)
{
return std::string("WSAEDESTADDRREQ");
}
else if (err == WSAEMSGSIZE)
{
return std::string("WSAEMSGSIZE");
}
else if (err == WSAEPROTOTYPE)
{
return std::string("WSAEPROTOTYPE");
}
else if (err == WSAENOPROTOOPT)
{
return std::string("WSAENOPROTOOPT");
}
else if (err == WSAENOTSOCK)
{
return std::string("WSAENOTSOCK");
}
else if (err == WSAEISCONN)
{
return std::string("WSAISCONN");
}
else if (err == WSAECONNREFUSED)
{
return std::string("WSACONNREFUSED");
}
else if (err == WSAECONNRESET)
{
return std::string("WSACONNRESET");
}
else if (err == WSAETIMEDOUT)
{
return std::string("WSATIMEDOUT");
}
else if (err == WSAENETUNREACH)
{
return std::string("WSANETUNREACH");
}
else if (err == WSAEADDRINUSE)
{
return std::string("WSAADDRINUSE");
}
else if (err == WSAEAFNOSUPPORT)
{
return std::string("WSAEAFNOSUPPORT (normally UDP related!)");
}
return std::string("----WINDOWS OPERATING SYSTEM FAILURE----");
}
#include <iphlpapi.h>
//#include <iprtrmib.h>
// A function to determine the interfaces on your computer....
// No idea of how to do this in windows....
// see if it compiles.
std::list<std::string> getLocalInterfaces()
{
std::list<std::string> addrs;
/* USE MIB IPADDR Interface */
PMIB_IPADDRTABLE iptable = NULL;
DWORD dwSize = 0;
if (GetIpAddrTable(iptable, &dwSize, 0) !=
ERROR_INSUFFICIENT_BUFFER)
{
pqioutput(PQL_ALERT, pqinetzone,
"Cannot Find Windoze Interfaces!");
exit(0);
}
iptable = (MIB_IPADDRTABLE *) malloc(dwSize);
GetIpAddrTable(iptable, &dwSize, 0);
struct in_addr addr;
for(unsigned int i = 0; i < iptable -> dwNumEntries; i++)
{
std::ostringstream out;
out << "Iface(" << iptable->table[i].dwIndex << ") ";
addr.s_addr = iptable->table[i].dwAddr;
out << " => " << inet_ntoa(addr);
out << std::endl;
pqioutput(PQL_DEBUG_BASIC, pqinetzone, out.str());
addrs.push_back(inet_ntoa(addr));
}
return addrs;
}
// implement the improved unix inet address fn.
// using old one.
int inet_aton(const char *name, struct in_addr *addr)
{
return (((*addr).s_addr = inet_addr(name)) != INADDR_NONE);
}
// This returns in Net Byte Order.
// NB: Linux man page claims it is in Host Byte order, but
// this is blatantly wrong!..... (for Debian anyway)
// Making this consistent with the Actual behavior (rather than documented).
in_addr_t inet_netof(struct in_addr addr)
{
return pqi_inet_netof(addr);
}
// This returns in Host Byte Order. (as the man page says)
// Again, to be consistent with Linux.
in_addr_t inet_network(char *inet_name)
{
struct in_addr addr;
if (inet_aton(inet_name, &addr))
{
// std::cerr << "inet_network(" << inet_name << ") : ";
// std::cerr << inet_ntoa(addr) << std::endl;
return ntohl(inet_netof(addr));
}
return 0xffffffff;
//return -1;
}
#endif
/********************************** WINDOWS/UNIX SPECIFIC PART ******************/
#include <iostream>
// This returns in Net Byte Order.
// NB: Linux man page claims it is in Host Byte order, but
// this is blatantly wrong!..... (for Debian anyway)
// Making this consistent with the Actual behavior (rather than documented).
in_addr_t pqi_inet_netof(struct in_addr addr)
{
// decide if A class address.
unsigned long haddr = ntohl(addr.s_addr);
unsigned long abit = haddr & 0xff000000UL;
unsigned long bbit = haddr & 0xffff0000UL;
unsigned long cbit = haddr & 0xffffff00UL;
std::cerr << "inet_netof(" << inet_ntoa(addr) << ") ";
if (!((haddr >> 31) | 0x0UL)) // MSB = 0
{
std::cerr << " Type A " << std::endl;
std::cerr << "\tShifted(31): " << (haddr >> 31);
std::cerr << " Xord(0x0UL): " <<
!((haddr >> 31) | 0x0UL) << std::endl;
return htonl(abit);
//return abit;
}
else if (!((haddr >> 30) ^ 0x2UL)) // 2MSBs = 10
{
std::cerr << " Type B " << std::endl;
std::cerr << "\tShifted(30): " << (haddr >> 30);
std::cerr << " Xord(0x2UL): " <<
!((haddr >> 30) | 0x2UL) << std::endl;
return htonl(bbit);
//return bbit;
}
else if (!((haddr >> 29) ^ 0x6UL)) // 3MSBs = 110
{
std::cerr << " Type C " << std::endl;
std::cerr << "\tShifted(29): " << (haddr >> 29);
std::cerr << " Xord(0x6UL): " <<
!((haddr >> 29) | 0x6UL) << std::endl;
return htonl(cbit);
//return cbit;
}
else if (!((haddr >> 28) ^ 0xeUL)) // 4MSBs = 1110
{
std::cerr << " Type Multicast " << std::endl;
std::cerr << "\tShifted(28): " << (haddr >> 28);
std::cerr << " Xord(0xeUL): " <<
!((haddr >> 29) | 0xeUL) << std::endl;
return addr.s_addr; // return full address.
//return haddr;
}
else if (!((haddr >> 27) ^ 0x1eUL)) // 5MSBs = 11110
{
std::cerr << " Type Reserved " << std::endl;
std::cerr << "\tShifted(27): " << (haddr >> 27);
std::cerr << " Xord(0x1eUL): " <<
!((haddr >> 27) | 0x1eUL) << std::endl;
return addr.s_addr; // return full address.
//return haddr;
}
return htonl(abit);
//return abit;
}
int inaddr_cmp(struct sockaddr_in addr1, struct sockaddr_in addr2 )
{
std::ostringstream out;
out << "inaddr_cmp(" << inet_ntoa(addr1.sin_addr);
out << "-" << addr1.sin_addr.s_addr;
out << "," << inet_ntoa(addr2.sin_addr);
out << "-" << addr2.sin_addr.s_addr << ")" << std::endl;
pqioutput(PQL_DEBUG_BASIC, pqinetzone, out.str());
if (addr1.sin_addr.s_addr == addr2.sin_addr.s_addr)
{
return 0;
}
if (addr1.sin_addr.s_addr < addr2.sin_addr.s_addr)
return -1;
return 1;
}
int inaddr_cmp(struct sockaddr_in addr1, unsigned long addr2)
{
struct in_addr inaddr_tmp;
inaddr_tmp.s_addr = addr2;
std::ostringstream out;
out << "inaddr_cmp2(" << inet_ntoa(addr1.sin_addr);
out << " vs " << inet_ntoa(inaddr_tmp);
out << " /or/ ";
out << std::hex << std::setw(10) << addr1.sin_addr.s_addr;
out << " vs " << std::setw(10) << addr2 << ")" << std::endl;
pqioutput(PQL_DEBUG_BASIC, pqinetzone, out.str());
if (addr1.sin_addr.s_addr == addr2)
{
return 0;
}
if (addr1.sin_addr.s_addr < addr2)
return -1;
return 1;
}
bool isLoopbackNet(struct in_addr *addr)
{
if (0 == strcmp(inet_ntoa(*addr), "127.0.0.1"))
{
return true;
}
return false;
}
// returns all possible addrs.
// all processing is done in network byte order.
bool isPrivateNet(struct in_addr *addr)
{
bool ret = false;
std::ostringstream out;
in_addr_t taddr = inet_netof(*addr);
out << "isPrivateNet(" << inet_ntoa(*addr) << ") ? ";
out << std::endl;
struct in_addr addr2;
addr2.s_addr = taddr;
out << "Checking (" << inet_ntoa(addr2) << ") Against: " << std::endl;
// shouldn't need to rotate these...h -> n (in network already.
// check text output....
addr2.s_addr = htonl(inet_network("10.0.0.0"));
out << "\t(" << inet_ntoa(addr2) << ")" << std::endl;
addr2.s_addr = htonl(inet_network("172.16.0.0"));
out << "\t(" << inet_ntoa(addr2) << ")" << std::endl;
addr2.s_addr = htonl(inet_network("192.168.0.0"));
out << "\t(" << inet_ntoa(addr2) << ")" << std::endl;
addr2.s_addr = htonl(inet_network("169.254.0.0"));
out << "\t(" << inet_ntoa(addr2) << ")" << std::endl;
if ((taddr == htonl(inet_network("10.0.0.0"))) ||
(taddr == htonl(inet_network("172.16.0.0"))) ||
(taddr == htonl(inet_network("192.168.0.0"))) ||
(taddr == htonl(inet_network("169.254.0.0"))))
{
out << " True" << std::endl;
ret = true;
}
else
{
out << " False" << std::endl;
ret = false;
}
pqioutput(PQL_DEBUG_BASIC, pqinetzone, out.str());
return ret;
}
bool isExternalNet(struct in_addr *addr)
{
if (!isValidNet(addr))
{
return false;
}
if (isLoopbackNet(addr))
{
return false;
}
if (isPrivateNet(addr))
{
return false;
}
return true;
}
struct in_addr getPreferredInterface() // returns best addr.
{
std::list<std::string> addrs = getLocalInterfaces();
std::list<std::string>::iterator it;
struct in_addr addr_zero = {0}, addr_loop = {0}, addr_priv = {0}, addr_ext = {0}, addr = {0};
bool found_zero = false;
bool found_loopback = false;
bool found_priv = false;
bool found_ext = false;
// find the first of each of these.
// if ext - take first.
// if no ext -> first priv
// if no priv -> first loopback.
for(it = addrs.begin(); it != addrs.end(); it++)
{
inet_aton((*it).c_str(), &addr);
// for windows silliness (returning 0.0.0.0 as valid addr!).
if (addr.s_addr == 0)
{
if (!found_zero)
{
found_zero = true;
addr_zero = addr;
}
}
else if (isLoopbackNet(&addr))
{
if (!found_loopback)
{
found_loopback = true;
addr_loop = addr;
}
}
else if (isPrivateNet(&addr))
{
if (!found_priv)
{
found_priv = true;
addr_priv = addr;
}
}
else
{
if (!found_ext)
{
found_ext = true;
addr_ext = addr;
return addr_ext;
}
}
}
if (found_priv)
return addr_priv;
// next bit can happen under windows,
// a general address is still
// preferable to a loopback device.
if (found_zero)
return addr_zero;
if (found_loopback)
return addr_loop;
// shound be 255.255.255.255 (error).
addr.s_addr = 0xffffffff;
return addr;
}
bool sameNet(struct in_addr *addr, struct in_addr *addr2)
{
return (inet_netof(*addr) == inet_netof(*addr2));
}
bool isValidNet(struct in_addr *addr)
{
// invalid address.
if((*addr).s_addr == INADDR_NONE)
return false;
if((*addr).s_addr == 0)
return false;
// should do more tests.
return true;
}
bool isSameSubnet(struct in_addr *addr1, struct in_addr *addr2)
{
/*
* check that the (addr1 & 255.255.255.0) == (addr2 & 255.255.255.0)
*/
unsigned long a1 = ntohl(addr1->s_addr);
unsigned long a2 = ntohl(addr2->s_addr);
return ((a1 & 0xffffff00) == (a2 & 0xffffff00));
}
/* This just might be portable!!! will see!!!
* Unfortunately this is usable on winXP+, determined by: (_WIN32_WINNT >= 0x0501)
* but not older platforms.... which must use gethostbyname.
*
* include it for now.....
*/
bool LookupDNSAddr(std::string name, struct sockaddr_in &addr)
{
#if 0
char service[100];
struct addrinfo hints_st;
struct addrinfo *hints = &hints_st;
struct addrinfo *res;
hints -> ai_flags = 0; // (cygwin don;t like these) AI_ADDRCONFIG | AI_NUMERICSERV;
hints -> ai_family = AF_INET;
hints -> ai_socktype = 0;
hints -> ai_protocol = 0;
hints -> ai_addrlen = 0;
hints -> ai_addr = NULL;
hints -> ai_canonname = NULL;
hints -> ai_next = NULL;
/* get the port number */
sprintf(service, "%d", ntohs(addr.sin_port));
/* set it to IPV4 */
std::cerr << "LookupDNSAddr() name: " << name << " service: " << service << std::endl;
int err = 0;
if (0 != (err = getaddrinfo(name.c_str(), service, hints, &res)))
{
std::cerr << "LookupDNSAddr() getaddrinfo failed!" << std::endl;
std::cerr << "Error: " << gai_strerror(err) << std::endl;
return false;
}
if ((res) && (res->ai_family == AF_INET))
{
std::cerr << "LookupDNSAddr() getaddrinfo found address" << std::endl;
addr = *((struct sockaddr_in *) res->ai_addr);
std::cerr << "addr: " << inet_ntoa(addr.sin_addr) << std::endl;
std::cerr << "port: " << ntohs(addr.sin_port) << std::endl;
freeaddrinfo(res);
return true;
}
std::cerr << "getaddrinfo failed - no address" << std::endl;
#endif
std::cerr << "getaddrinfo disabled" << std::endl;
return false;
}
/*************************************************************
* Socket Library Wrapper Functions
* to get over the crapness of the windows.
*
*/
int unix_close(int fd)
{
int ret;
/******************* WINDOWS SPECIFIC PART ******************/
#ifndef WINDOWS_SYS // ie UNIX
ret = close(fd);
#else
std::cerr << "unix_close()" << std::endl;
ret = closesocket(fd);
/* translate error */
#endif
/******************* WINDOWS SPECIFIC PART ******************/
return ret;
}
int unix_socket(int domain, int type, int protocol)
{
int osock = socket(PF_INET, SOCK_STREAM, 0);
/******************* WINDOWS SPECIFIC PART ******************/
#ifdef WINDOWS_SYS // WINDOWS
std::cerr << "unix_socket()" << std::endl;
if ((unsigned) osock == INVALID_SOCKET)
{
// Invalidate socket Unix style.
osock = -1;
errno = WinToUnixError(WSAGetLastError());
}
#endif
/******************* WINDOWS SPECIFIC PART ******************/
return osock;
}
int unix_fcntl_nonblock(int fd)
{
int ret;
/******************* WINDOWS SPECIFIC PART ******************/
#ifndef WINDOWS_SYS // ie UNIX
ret = fcntl(fd, F_SETFL, O_NONBLOCK);
std::cerr << "unix_fcntl_nonblock():" << ret << " errno:" << errno << std::endl;
#else
unsigned long int on = 1;
ret = ioctlsocket(fd, FIONBIO, &on);
std::cerr << "unix_fcntl_nonblock()" << std::endl;
if (ret != 0)
{
/* store unix-style error
*/
ret = -1;
errno = WinToUnixError(WSAGetLastError());
}
#endif
/******************* WINDOWS SPECIFIC PART ******************/
return ret;
}
int unix_connect(int fd, const struct sockaddr *serv_addr, socklen_t addrlen)
{
int ret = connect(fd, serv_addr, addrlen);
/******************* WINDOWS SPECIFIC PART ******************/
#ifdef WINDOWS_SYS // WINDOWS
std::cerr << "unix_connect()" << std::endl;
if (ret != 0)
{
errno = WinToUnixError(WSAGetLastError());
ret = -1;
}
#endif
/******************* WINDOWS SPECIFIC PART ******************/
return ret;
}
int unix_getsockopt_error(int sockfd, int *err)
{
int ret;
*err = 1;
/******************* WINDOWS SPECIFIC PART ******************/
#ifndef WINDOWS_SYS // ie UNIX
socklen_t optlen = 4;
ret=getsockopt(sockfd, SOL_SOCKET, SO_ERROR, err, &optlen);
#else // WINDOWS_SYS
int optlen = 4;
ret=getsockopt(sockfd, SOL_SOCKET, SO_ERROR, (char *) err, &optlen);
/* translate */
std::cerr << "unix_getsockopt_error() returned: " << (int) err << std::endl;
if (*err != 0)
{
*err = WinToUnixError(*err);
}
#endif
/******************* WINDOWS SPECIFIC PART ******************/
return ret;
}
/******************* WINDOWS SPECIFIC PART ******************/
#ifdef WINDOWS_SYS // ie WINDOWS.
int WinToUnixError(int error)
{
std::cerr << "WinToUnixError(" << error << ")" << std::endl;
switch(error)
{
case WSAEINPROGRESS:
return EINPROGRESS;
break;
case WSAEWOULDBLOCK:
return EINPROGRESS;
break;
case WSAENETUNREACH:
return ENETUNREACH;
break;
case WSAETIMEDOUT:
return ETIMEDOUT;
break;
case WSAEHOSTDOWN:
return EHOSTDOWN;
break;
case WSAECONNREFUSED:
return ECONNREFUSED;
break;
case WSAECONNRESET:
return ECONNRESET;
break;
default:
std::cerr << "WinToUnixError(" << error << ") Code Unknown!";
std::cerr << std::endl;
break;
}
return ECONNREFUSED; /* sensible default? */
}
#endif
/******************* WINDOWS SPECIFIC PART ******************/

View File

@ -0,0 +1,140 @@
/*
* "$Id: pqinetwork.h,v 1.15 2007-04-15 18:45:18 rmf24 Exp $"
*
* 3P/PQI network interface for RetroShare.
*
* Copyright 2004-2006 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 MRK_PQI_NETWORKING_HEADER
#define MRK_PQI_NETWORKING_HEADER
/********************************** WINDOWS/UNIX SPECIFIC PART ******************/
#ifndef WINDOWS_SYS
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/poll.h>
//socket blocking/options.
#include <fcntl.h>
#else
/* This defines the platform to be WinXP or later...
* and is needed for getaddrinfo.... (not used anymore)
*
#define _WIN32_WINNT 0x0501
*/
#include <winsock2.h>
#include <ws2tcpip.h>
typedef int socklen_t;
typedef unsigned long in_addr_t;
// Some Network functions that are missing from windows.
in_addr_t inet_netof(struct in_addr addr);
in_addr_t inet_network(char *inet_name);
int inet_aton(const char *name, struct in_addr *addr);
extern int errno; /* Define extern errno, to duplicate unix behaviour */
/* define the Unix Error Codes that we use...
* NB. we should make the same, but not necessary
*/
#define EAGAIN 11
#define EWOULDBLOCK EAGAIN
#define EUSERS 87
#define ENOTSOCK 88
#define EOPNOTSUPP 95
#define EADDRINUSE 98
#define EADDRNOTAVAIL 99
#define ENETDOWN 100
#define ENETUNREACH 101
#define ECONNRESET 104
#define ETIMEDOUT 110
#define ECONNREFUSED 111
#define EHOSTDOWN 112
#define EHOSTUNREACH 113
#define EALREADY 114
#define EINPROGRESS 115
#endif
/********************************** WINDOWS/UNIX SPECIFIC PART ******************/
#include <iostream>
#include <string>
#include <list>
// Same def - different functions...
std::ostream &showSocketError(std::ostream &out);
std::string socket_errorType(int err);
int inaddr_cmp(struct sockaddr_in addr1, struct sockaddr_in addr1 );
int inaddr_cmp(struct sockaddr_in addr1, unsigned long);
std::list<std::string> getLocalInterfaces(); // returns all possible addrs.
bool isExternalNet(struct in_addr *addr); // if Valid & is not Private or Loopback.
bool isPrivateNet(struct in_addr *addr); // if inside 10.0.0.0 or
// other then firewalled.
bool isLoopbackNet(struct in_addr *addr);
bool sameNet(struct in_addr *addr, struct in_addr *addr2);
bool isValidNet(struct in_addr *addr);
// checks (addr1 & 255.255.255.0) == (addr2 & 255.255.255.0)
bool isSameSubnet(struct in_addr *addr1, struct in_addr *addr2);
struct in_addr getPreferredInterface(); // returns best addr.
in_addr_t pqi_inet_netof(struct in_addr addr); // our implementation.
bool LookupDNSAddr(std::string name, struct sockaddr_in &addr);
/* universal socket interface */
int unix_close(int sockfd);
int unix_socket(int domain, int type, int protocol);
int unix_fcntl_nonblock(int sockfd);
int unix_connect(int sockfd, const struct sockaddr *serv_addr, socklen_t addrlen);
int unix_getsockopt_error(int sockfd, int *err);
#ifdef WINDOWS_SYS // WINDOWS
/******************* WINDOWS SPECIFIC PART ******************/
int WinToUnixError(int error);
#endif
#endif

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,79 @@
/*
* "$Id: pqipacket.h,v 1.6 2007-02-18 21:46:49 rmf24 Exp $"
*
* 3P/PQI network interface for RetroShare.
*
* Copyright 2004-2006 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 MRK_PQI_PACKET_HEADER
#define MRK_PQI_PACKET_HEADER
/* This is a set of functions for packaging
* the search queries/replies/data into packets
*
* Currently it makes very simple 1kb packets.
*
*/
// The standard data types and the search interface.
#include "pqi/pqi.h"
// defs for streams.
#include <iostream>
typedef void pqipkt;
// Handle Incoming Pkts......
// constants
int pqipkt_basesize();
int pqipkt_maxsize();
// determine properties. (possible from incomplete pkt).
int pqipkt_rawlen(pqipkt *);
bool pqipkt_check(pqipkt *pkt, int size);
PQItem *pqipkt_create(pqipkt *block);
// Outgoing Pkts.... (These are raw packets....(a chunk of data))
pqipkt *pqipkt_makepkt(PQItem *pqi);
// delete the raw packet (allocated using above).
void pqipkt_delete(pqipkt *);
// print packet.
//
void pqipkt_print(pqipkt *pkt);
// Type Extension methods for PQTunnel.
class PQTunnel;
class PQTunnelInit;
int registerTunnelType(int subtype, PQTunnel *(*fn)(void *d, int n));
PQTunnel *createTunnelType(int subtype, void *d, int n);
int registerTunnelInitType(int subtype, PQTunnelInit *(*fn)(void *d, int n));
PQTunnelInit *createTunnelInitType(int subtype, void *d, int n);
#endif //MRK_PQI_PACKET_HEADER

View File

@ -0,0 +1,552 @@
/*
* "$Id: pqiperson.cc,v 1.9 2007-02-18 21:46:49 rmf24 Exp $"
*
* 3P/PQI network interface for RetroShare.
*
* Copyright 2004-2006 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 "pqi/pqi.h"
#include <list>
#include "pqi/pqiperson.h"
const int pqipersonzone = 82371;
#include "pqi/pqidebug.h"
#include <sstream>
pqiperson::pqiperson(cert *c)
:sslcert(c), active(false), activepqi(NULL),
inConnectAttempt(false), waittimes(0)
{
sroot = getSSLRoot();
// check certificate
/**************** PQI_USE_XPGP ******************/
#if defined(PQI_USE_XPGP)
sroot -> validateCertificateXPGP(sslcert);
#else /* X509 Certificates */
/**************** PQI_USE_XPGP ******************/
sroot -> validateCertificate(sslcert);
#endif /* X509 Certificates */
/**************** PQI_USE_XPGP ******************/
if (!(sslcert -> Valid()))
{
std::cerr << "pqiperson::Warning Certificate Not Approved!";
std::cerr << " pqiperson will not initialise...." << std::endl;
}
return;
}
pqiperson::~pqiperson()
{
// clean up the children.
std::list<pqiconnect *>::iterator it = kids.begin();
for(it = kids.begin(); it != kids.end(); )
{
pqiconnect *pc = (*it);
it = kids.erase(it);
delete pc;
}
}
// The PQInterface interface.
int pqiperson::SendItem(PQItem *i)
{
std::ostringstream out;
out << "pqiperson::SendItem()";
if (active)
{
out << " Active: Sending On";
return activepqi -> SendItem(i);
}
else
{
out << " Not Active: Used to put in ToGo Store";
out << std::endl;
out << " Now deleting...";
// no longer storing in togo...
//togo.push_back(i);
delete i;
}
pqioutput(PQL_DEBUG_BASIC, pqipersonzone, out.str());
return 0; // queued.
}
PQItem *pqiperson::GetItem()
{
if (active)
return activepqi -> GetItem();
// else not possible.
return NULL;
}
int pqiperson::status()
{
if (active)
return activepqi -> status();
return -1;
}
cert * pqiperson::getContact()
{
return sslcert;
}
// tick......
int pqiperson::tick()
{
int activeTick = 0;
{
std::ostringstream out;
out << "pqiperson::tick() Cert: " << sslcert -> Name() << " ";
if (active)
out << "***Active***";
else
out << ">>InActive<<";
out << std::endl;
out << "Activepqi: " << activepqi << " inConnectAttempt: ";
if (inConnectAttempt)
out << "In Connection Attempt";
else
out << " Not Connecting ";
out << std::endl;
// tick the children.
std::list<pqiconnect *>::iterator it;
for(it = kids.begin(); it != kids.end(); it++)
{
if (0 < (*it) -> tick())
{
activeTick = 1;
}
out << "\tTicking Child: " << (*it) << std::endl;
}
pqioutput(PQL_DEBUG_ALL, pqipersonzone, out.str());
} // end of pqioutput.
// use cert settings to control everything.
if (!active)
{
if ((sslcert -> WillConnect()) && (!inConnectAttempt))
{
if (sslcert -> nc_timestamp < time(NULL))
{
// calc the time til next connect.
sslcert -> nc_timestamp = time(NULL) +
connectWait();
connectattempt(NULL);
}
}
if (sslcert -> Listening())
{
if (!(sslcert -> WillListen()))
{
stoplistening();
}
}
else
{
if (sslcert -> WillListen())
{
listen();
}
}
}
// if active and togo!.
else if (togo.size() > 0)
{
while(togo.size() > 0)
{
PQItem *item = togo.front();
togo.pop_front();
std::ostringstream out;
out << "pqiperson::tick() Sending on Stored Item";
out << " to activepqi @ " << (void *) activepqi;
out << std::endl;
item -> print(out);
out << std::endl;
pqioutput(PQL_DEBUG_BASIC, pqipersonzone, out.str());
activepqi -> SendItem(item);
}
activeTick = 1;
}
return activeTick;
}
// callback function for the child - notify of a change.
// This is only used for out-of-band info....
// otherwise could get dangerous loops.
int pqiperson::notifyEvent(NetInterface *ni, int newState)
{
{
std::ostringstream out;
out << "pqiperson::notifyEvent() Cert: " << sslcert -> Name();
out << std::endl;
out << "Message: " << newState << " from: " << ni << std::endl;
pqioutput(PQL_DEBUG_BASIC, pqipersonzone, out.str());
}
/* find the pqi, */
pqiconnect *pqi = NULL;
std::list<pqiconnect *>::iterator it;
/* start again */
int i = 0;
for(it = kids.begin(); it != kids.end(); it++)
{
std::ostringstream out;
out << "pqiperson::connectattempt() Kid# ";
out << i << " of " << kids.size();
out << std::endl;
out << " pqiconn: " << (*it);
out << " ni: " << (*it)->ni;
out << " in_ni: " << ni;
pqioutput(PQL_DEBUG_BASIC, pqipersonzone, out.str());
i++;
if ((*it)->thisNetInterface(ni))
{
pqi = (*it);
}
}
if (!pqi)
{
pqioutput(PQL_WARNING, pqipersonzone, "Unknown notfyEvent Source!");
return -1;
}
switch(newState)
{
case CONNECT_RECEIVED:
case CONNECT_SUCCESS:
if ((active) && (activepqi != pqi)) // already connected - trouble
{
pqioutput(PQL_WARNING, pqipersonzone,
"CONNECT_SUCCESS+active->trouble: shutdown EXISTING->switch to new one!");
//pqi -> stoplistening();
// This is the RESET that's killing the connections.....
activepqi -> reset();
// this causes a recursive call back into this fn.
// which cleans up state.
// we only do this if its not going to mess with new conn.
}
/* now install a new one. */
{
pqioutput(PQL_WARNING, pqipersonzone,
"CONNECT_SUCCESS->marking so!");
// mark as active.
active = true;
activepqi = pqi;
sslcert -> Connected(true);
sroot -> IndicateCertsChanged();
connectSuccess();
inConnectAttempt = false;
// dont stop listening.
//stoplistening();
return 1;
}
break;
case CONNECT_UNREACHABLE:
case CONNECT_FIREWALLED:
case CONNECT_FAILED:
if (active)
{
if (activepqi == pqi)
{
pqioutput(PQL_WARNING, pqipersonzone,
"CONNECT_FAILED->marking so!");
active = false;
activepqi = NULL;
sslcert -> Connected(false);
sroot -> IndicateCertsChanged();
return 1;
}
else
{
pqioutput(PQL_WARNING, pqipersonzone,
"CONNECT_FAIL+not activepqi->strange!");
// something strange!
return -1;
}
}
else
{
pqioutput(PQL_WARNING, pqipersonzone,
"CONNECT_FAILED+NOT active -> try connect again");
connectattempt(pqi);
return 1;
}
break;
default:
break;
}
return -1;
}
/***************** Not PQInterface Fns ***********************/
int pqiperson::reset()
{
{
std::ostringstream out;
out << "pqiperson::reset() Cert: " << sslcert -> Name();
out << std::endl;
pqioutput(PQL_DEBUG_BASIC, pqipersonzone, out.str());
}
std::list<pqiconnect *>::iterator it;
for(it = kids.begin(); it != kids.end(); it++)
{
(*it) -> reset();
}
activepqi = NULL;
active = false;
sslcert -> Listening(false);
sslcert -> Connected(false);
sroot -> IndicateCertsChanged();
// check auto setting at reset.
if (!sslcert -> Manual())
autoconnect(true);
return 1;
}
int pqiperson::autoconnect(bool b)
{
{
std::ostringstream out;
out << "pqiperson::autoconnect() Cert: " << sslcert -> Name();
out << " - " << (int) b << std::endl;
pqioutput(PQL_DEBUG_BASIC, pqipersonzone, out.str());
}
sslcert -> Manual(!b);
sslcert -> WillConnect(b);
sslcert -> WillListen(b);
sroot -> IndicateCertsChanged();
return 1;
}
int pqiperson::addChildInterface(pqiconnect *pqi)
{
{
std::ostringstream out;
out << "pqiperson::addChildInterface() : " << pqi;
out << std::endl;
pqioutput(PQL_DEBUG_BASIC, pqipersonzone, out.str());
}
kids.push_back(pqi);
return 1;
}
/***************** PRIVATE FUNCTIONS ***********************/
// functions to iterate over the connects and change state.
int pqiperson::listen()
{
{
std::ostringstream out;
out << "pqiperson::listen() Cert: " << sslcert -> Name();
out << std::endl;
pqioutput(PQL_DEBUG_BASIC, pqipersonzone, out.str());
}
if (!active)
{
std::list<pqiconnect *>::iterator it;
for(it = kids.begin(); it != kids.end(); it++)
{
// set them all listening.
(*it) -> listen();
}
sslcert -> Listening(true);
sroot -> IndicateCertsChanged();
}
return 1;
}
int pqiperson::stoplistening()
{
{
std::ostringstream out;
out << "pqiperson::stoplistening() Cert: " << sslcert -> Name();
out << std::endl;
pqioutput(PQL_DEBUG_BASIC, pqipersonzone, out.str());
}
std::list<pqiconnect *>::iterator it;
for(it = kids.begin(); it != kids.end(); it++)
{
// set them all listening.
(*it) -> stoplistening();
}
sslcert -> Listening(false);
sroot -> IndicateCertsChanged();
return 1;
}
int pqiperson::connectattempt(pqiconnect *last)
{
{
std::ostringstream out;
out << "pqiperson::connectattempt() Cert: " << sslcert -> Name();
out << std::endl;
pqioutput(PQL_DEBUG_BASIC, pqipersonzone, out.str());
}
std::list<pqiconnect *>::iterator it = kids.begin();
int i = 0;
if (last != NULL)
{
// find the current connection.
for(; (it != kids.end()) && ((*it) != last); it++, i++);
if (it != kids.end())
{
std::ostringstream out;
out << "pqiperson::connectattempt() Last Cert#: ";
out << i << " of " << kids.size();
out << std::endl;
pqioutput(PQL_DEBUG_BASIC, pqipersonzone, out.str());
it++;
i++;
}
}
// now at the first one to try.
{
std::ostringstream out;
out << "pqiperson::connectattempt() Cert: " << sslcert -> Name();
out << " Starting Attempts at Interface " << i << " of " << kids.size();
out << std::endl;
pqioutput(PQL_DEBUG_BASIC, pqipersonzone, out.str());
}
// try to connect on the next one.
for(; (it != kids.end()) && (0 > (*it)->connectattempt()); it++, i++);
if (it == kids.end())
{
std::ostringstream out;
out << "pqiperson::connectattempt() Cert: " << sslcert -> Name();
out << " Failed on All Interfaces";
out << std::endl;
pqioutput(PQL_DEBUG_BASIC, pqipersonzone, out.str());
}
else
{
std::ostringstream out;
out << "pqiperson::connectattempt() Cert: " << sslcert -> Name();
out << " attempt on pqiconnect #" << i << " suceeded";
out << std::endl;
pqioutput(PQL_DEBUG_BASIC, pqipersonzone, out.str());
}
// flag if we started a new connectionAttempt.
inConnectAttempt = (it != kids.end());
return 1;
}
// returns (in secs) the time til next connect attempt
// this is based on the
//
#define SEC_PER_LOG_UNIT 600 /* ten minutes? */
#define MAX_WAITTIMES 10 /* ten minutes? */
int pqiperson::connectWait()
{
int log_weight = (1 << waittimes);
// max wait of 2^10 = 1024 * X min (over a month)
// 10240 min = 1 day
waittimes++;
if (waittimes > MAX_WAITTIMES)
waittimes = MAX_WAITTIMES;
// make it linear instead!.
return waittimes * SEC_PER_LOG_UNIT;
//return log_weight * SEC_PER_LOG_UNIT;
}
// called to reduce the waittimes, next time.
int pqiperson::connectSuccess()
{
return waittimes = 0;
}
float pqiperson::getRate(bool in)
{
// get the rate from the active one.
if ((!active) || (activepqi == NULL))
return 0;
return activepqi -> getRate(in);
}
void pqiperson::setMaxRate(bool in, float val)
{
// set to all of them. (and us)
PQInterface::setMaxRate(in, val);
// clean up the children.
std::list<pqiconnect *>::iterator it = kids.begin();
for(it = kids.begin(); it != kids.end(); it++)
{
(*it) -> setMaxRate(in, val);
}
}

View File

@ -0,0 +1,162 @@
/*
* "$Id: pqiperson.h,v 1.7 2007-02-18 21:46:49 rmf24 Exp $"
*
* 3P/PQI network interface for RetroShare.
*
* Copyright 2004-2006 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 MRK_PQI_PERSON_HEADER
#define MRK_PQI_PERSON_HEADER
#include "pqi/pqi.h"
/**************** PQI_USE_XPGP ******************/
#if defined(PQI_USE_XPGP)
#include "pqi/xpgpcert.h"
#else /* X509 Certificates */
/**************** PQI_USE_XPGP ******************/
#include "pqi/sslcert.h"
#endif /* X509 Certificates */
/**************** PQI_USE_XPGP ******************/
#include <list>
class pqiperson;
class sslroot;
static const int CONNECT_RECEIVED = 1;
static const int CONNECT_SUCCESS = 2;
static const int CONNECT_UNREACHABLE = 3;
static const int CONNECT_FIREWALLED = 4;
static const int CONNECT_FAILED = 5;
#include "pqi/pqistreamer.h"
class pqiconnect: public pqistreamer, public NetInterface
{
public:
pqiconnect(NetBinInterface *ni_in)
:pqistreamer(ni_in, 0), // pqistreamer will cleanup NetInterface.
NetInterface(NULL, NULL), // No need for callback.
ni(ni_in)
{
if (!ni_in)
{
std::cerr << "pqiconnect::pqiconnect() NetInterface == NULL, FATAL!";
std::cerr << std::endl;
exit(1);
}
return;
}
virtual ~pqiconnect() { return; }
// presents a virtual NetInterface -> passes to ni.
virtual int connectattempt() { return ni -> connectattempt(); }
virtual int listen() { return ni -> listen(); }
virtual int stoplistening() { return ni -> stoplistening(); }
virtual int reset() { return ni -> reset(); }
virtual int disconnect() { return ni -> reset(); }
// get the contact from the net side!
virtual Person *getContact()
{
if (ni)
{
return ni->getContact();
}
else
{
return PQInterface::getContact();
}
}
// to check if our interface.
virtual bool thisNetInterface(NetInterface *ni_in) { return (ni_in == ni); }
//protected:
NetBinInterface *ni;
protected:
};
class pqiperson: public PQInterface
{
public:
pqiperson(cert *c);
virtual ~pqiperson(); // must clean up children.
// control of the connection.
int reset();
int autoconnect(bool);
// add in connection method.
int addChildInterface(pqiconnect *pqi);
// The PQInterface interface.
virtual int SendItem(PQItem *);
virtual PQItem *GetItem();
virtual int status();
virtual int tick();
virtual cert * getContact();
// overloaded callback function for the child - notify of a change.
int notifyEvent(NetInterface *ni, int event);
// PQInterface for rate control overloaded....
virtual float getRate(bool in);
virtual void setMaxRate(bool in, float val);
private:
// outgoing PQItems can be queued (nothing else).
std::list<PQItem *> togo;
std::list<pqiconnect *> kids;
cert *sslcert;
bool active;
pqiconnect *activepqi;
bool inConnectAttempt;
int waittimes;
sslroot *sroot;
private: /* Helper functions */
int connectWait();
int connectSuccess();
int listen();
int stoplistening();
int connectattempt(pqiconnect *last);
};
#endif

View File

@ -0,0 +1,480 @@
/*
* "$Id: pqipersongrp.cc,v 1.14 2007-02-19 20:08:30 rmf24 Exp $"
*
* 3P/PQI network interface for RetroShare.
*
* Copyright 2004-2006 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 "pqi/pqipersongrp.h"
/*
#include "pqi/pqiproxy.h"
#include "pqi/pqitunnelproxy.h"
*/
#include "pqi/p3disc.h"
#include "pqi/p3channel.h"
#include "pqi/pqissl.h"
#include "pqi/pqissllistener.h"
/*
* #include "pqi/pqiudpproxy.h"
* #include "pqi/pqissludp.h"
*/
#ifdef PQI_USE_PROXY
#include "pqi/pqiudpproxy.h"
#include "pqi/pqissludp.h"
#endif
//#include "pqi/pqitunneltst.h"
#include "pqi/pqidebug.h"
#include <sstream>
const int pqipersongrpzone = 354;
// get the Tunnel and TunnelInit packets from the queue.
bool isTunnelItem(PQItem *item)
{
if (item -> type == PQI_ITEM_TYPE_TUNNELITEM)
return true;
return false;
}
bool isTunnelInitItem(PQItem *item)
{
if (item -> type == PQI_ITEM_TYPE_TUNNELINITITEM)
return true;
return false;
}
// handle the tunnel services.
int pqipersongrp::tickTunnelServer()
{
PQItem *pqi = NULL;
int i = 0;
{
std::ostringstream out;
out << "pqipersongrp::tickTunnelServer()";
pqioutput(PQL_DEBUG_ALL, pqipersongrpzone, out.str());
}
PQTunnelServer::tick();
while(NULL != (pqi = SelectOtherPQItem(isTunnelInitItem)))
{
++i;
pqioutput(PQL_DEBUG_BASIC, pqipersongrpzone,
"pqipersongrp::tickTunnelServer() Incoming TunnelInitItem");
incoming(pqi);
}
while(NULL != (pqi = SelectOtherPQItem(isTunnelItem)))
{
++i;
pqioutput(PQL_DEBUG_BASIC, pqipersongrpzone,
"pqipersongrp::tickTunnelServer() Incoming TunnelItem");
incoming(pqi);
}
while(NULL != (pqi = outgoing()))
{
++i;
pqioutput(PQL_DEBUG_BASIC, pqipersongrpzone,
"pqipersongrp::tickTunnelServer() OutGoing PQItem");
SendOtherPQItem(pqi);
}
if (0 < i)
{
return 1;
}
return 0;
}
// inits
pqipersongrp::pqipersongrp(SecurityPolicy *glob, sslroot *sr, unsigned long flags)
:pqihandler(glob), sslr(sr), p3d(NULL),
#ifdef PQI_USE_PROXY
p3p(NULL),
#endif
initFlags(flags)
{
// add a p3proxy & p3disc.
p3d = new p3disc(sr);
#ifdef PQI_USE_PROXY
p3p = new p3udpproxy(p3d);
#endif
#ifdef PQI_USE_CHANNELS
p3c = new p3channel(sr);
#endif
if (!(sr -> active()))
{
pqioutput(PQL_ALERT, pqipersongrpzone, "sslroot not active... exiting!");
exit(1);
}
// make listen
Person *us = sr -> getOwnCert();
if (us != NULL)
{
if (flags & PQIPERSON_NO_SSLLISTENER)
{
pqil = NULL;
}
else
{
pqil = new pqissllistener(us -> localaddr);
}
#ifdef PQI_USE_PROXY
pqiudpl = new pqiudplistener((p3udpproxy *) p3p,
us -> localaddr);
#endif
}
else
{
pqioutput(PQL_ALERT, pqipersongrpzone, "No Us! what are we!");
exit(1);
}
// now we run through any certificates
// already made... and reactivate them.
std::list<cert *>::iterator it;
std::list<cert *> &clist = sr -> getCertList();
for(it = clist.begin(); it != clist.end(); it++)
{
cert *c = (*it);
c -> InUse(false);
c -> Listening(false);
c -> Connected(false);
// make new
if (c -> Accepted())
{
cert_accept(c);
}
}
// finally lets
// add in a tunneltest.
// register the packet creations.
//addService(new PQTStst());
//registerTunnelType(PQI_TUNNEL_TST_TYPE, createPQTStst);
addService(p3d);
registerTunnelType(PQI_TUNNEL_DISC_ITEM_TYPE, createDiscItems);
#ifdef PQI_USE_PROXY
addService(p3p);
registerTunnelType(PQI_TUNNEL_PROXY_TYPE, createPQTunnelProxy);
registerTunnelInitType(PQI_TUNNEL_PROXY_TYPE, createPQTunnelProxyInit);
#endif
#ifdef PQI_USE_CHANNELS
addService(p3c);
registerTunnelType(PQI_TUNNEL_CHANNEL_ITEM_TYPE, createChannelItems);
#endif
return;
}
int pqipersongrp::tick()
{
/* could limit the ticking of listener / tunnels to 1/sec...
* but not to important.
*/
if (pqil)
{
pqil -> tick();
}
#ifdef PQI_USE_PROXY
pqiudpl->tick();
#endif
tickTunnelServer();
return pqihandler::tick();
}
int pqipersongrp::status()
{
if (pqil)
{
pqil -> status();
}
#ifdef PQI_USE_PROXY
//pqiudpl->status();
#endif
return pqihandler::status();
}
// control the connections.
int pqipersongrp::cert_accept(cert *a)
{
if (a -> InUse())
{
pqioutput(PQL_DEBUG_BASIC, pqipersongrpzone,
"pqipersongrp::cert_accept() Cert in Use!");
return -1;
}
pqiperson *pqip = new pqiperson(a);
pqissl *pqis = new pqissl(a, pqil, pqip);
pqiconnect *pqisc = new pqiconnect(pqis);
pqip -> addChildInterface(pqisc);
#ifdef PQI_USE_PROXY
pqiudpproxy *pqipxy = new pqiudpproxy(a, (p3udpproxy *) p3p, NULL);
pqissludp *pqius = new pqissludp(a, pqip, pqipxy);
pqiconnect *pqiusc = new pqiconnect(pqius);
// add a ssl + proxy interface.
// Add Proxy First.
pqip -> addChildInterface(pqiusc);
#endif
a -> InUse(true);
a -> Accepted(true);
// setup no behaviour. (no remote address)
// attach to pqihandler
SearchModule *sm = new SearchModule();
sm -> smi = 2;
sm -> pqi = pqip;
sm -> sp = secpolicy_create();
// reset it to start it working.
pqis -> reset();
return AddSearchModule(sm);
}
int pqipersongrp::cert_deny(cert *a)
{
std::map<int, SearchModule *>::iterator it;
SearchModule *mod;
bool found = false;
// if used find search module....
if (a -> InUse())
{
// find module.
for(it = mods.begin(); (!found) && (it != mods.end());it++)
{
mod = it -> second;
if (a == (cert *) ((pqiperson *)
(mod -> pqi)) -> getContact())
{
found = true;
}
}
if (found)
{
RemoveSearchModule(mod);
secpolicy_delete(mod -> sp);
pqiperson *p = (pqiperson *) mod -> pqi;
p -> reset();
delete p;
a -> InUse(false);
}
}
a -> Accepted(false);
return 1;
}
int pqipersongrp::cert_auto(cert *a, bool b)
{
std::map<int, SearchModule *>::iterator it;
if (b)
{
cert_accept(a);
// find module.
for(it = mods.begin(); it != mods.end();it++)
{
SearchModule *mod = it -> second;
pqiperson *p = (pqiperson *) mod -> pqi;
if (a == (cert *) p -> getContact())
{
p -> autoconnect(b);
return 1;
}
}
}
else
{
a -> Manual(true);
cert_deny(a);
}
return 1;
}
int pqipersongrp::restart_listener()
{
// stop it,
// change the address.
// restart.
cert *own = sslr -> getOwnCert();
if (pqil)
{
pqil -> resetlisten();
pqil -> setListenAddr(own -> localaddr);
pqil -> setuplisten();
}
#ifdef PQI_USE_PROXY
pqiudpl -> resetlisten();
pqiudpl -> setListenAddr(own -> localaddr);
pqiudpl -> setuplisten();
#endif
return 1;
}
static const std::string pqih_ftr("PQIH_FTR");
int pqipersongrp::save_config()
{
char line[512];
sprintf(line, "%f %f %f %f", getMaxRate(true), getMaxRate(false),
getMaxIndivRate(true), getMaxIndivRate(false));
sslr -> setSetting(pqih_ftr, std::string(line));
return 1;
}
int pqipersongrp::load_config()
{
std::string line = sslr -> getSetting(pqih_ftr);
float mri, mro, miri, miro;
if (4 == sscanf(line.c_str(), "%f %f %f %f", &mri, &mro, &miri, &miro))
{
setMaxRate(true, mri);
setMaxRate(false, mro);
setMaxIndivRate(true, miri);
setMaxIndivRate(false, miro);
}
else
{
pqioutput(PQL_DEBUG_BASIC, pqipersongrpzone,
"pqipersongrp::load_config() Loading Default Rates!");
setMaxRate(true, 50.0);
setMaxRate(false,50.0);
setMaxIndivRate(true, 50.0);
setMaxIndivRate(false, 50.0);
}
return 1;
}
/* Overloaded PQItem Check */
int pqipersongrp::checkOutgoingPQItem(PQItem *item, int global)
{
/* check cid vs Person */
if ((global) && (item->cid.route[0] == 0))
{
/* allowed through as for all! */
pqioutput(PQL_DEBUG_BASIC, pqipersongrpzone,
"pqipersongrp::checkOutgoingPQItem() Allowing global");
return 1;
}
if ((!global) && (item->cid.route[0] == 0))
{
/* not allowed for all! */
std::ostringstream out;
out << "Bad CID on non-global traffic" << std::endl;
item -> print(out);
pqioutput(PQL_ALERT, pqipersongrpzone,out.str());
return 0;
}
if (item -> p == NULL)
{
pqioutput(PQL_ALERT, pqipersongrpzone,
"pqipersongrp::checkOutgoingPQItem() ERROR: NULL Person");
std::ostringstream out;
item -> print(out);
pqioutput(PQL_ALERT, pqipersongrpzone,out.str());
return 0;
}
cert *c = (cert *) item -> p;
if (0 != pqicid_cmp(&(c -> cid), &(item -> cid)))
{
std::ostringstream out;
out << "pqipersongrp::checkOutgoingPQItem() c->cid != item->cid";
out << std::endl;
out << "c -> CID [" << c->cid.route[0];
for(int i = 0; i < 10; i++)
{
out << ":" << c->cid.route[i];
}
out << "]" << std::endl;
out << "item -> CID [" << item->cid.route[0];
for(int i = 0; i < 10; i++)
{
out << ":" << item->cid.route[i];
}
out << "]" << std::endl;
item -> print(out);
pqioutput(PQL_ALERT, pqipersongrpzone,out.str());
pqicid_copy(&(c->cid), &(item->cid));
}
/* check the top one */
return 1;
}

View File

@ -0,0 +1,117 @@
/*
* "$Id: pqipersongrp.h,v 1.13 2007-02-18 21:46:49 rmf24 Exp $"
*
* 3P/PQI network interface for RetroShare.
*
* Copyright 2004-2006 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 MRK_PQI_PERSON_HANDLER_HEADER
#define MRK_PQI_PERSON_HANDLER_HEADER
#include "pqi/pqihandler.h"
#include "pqi/pqiperson.h"
#include "pqi/pqitunnel.h"
// So this is a specific implementation
//
// it is designed to have one pqilistensocket + a series of pqisockets
//
// as an added bonus, we are going to
// make this a pqitunnelserver, to which services can be attached.
#ifdef PQI_USE_PROXY
class p3proxy;
class pqiudplistener;
#endif
const unsigned long PQIPERSON_NO_SSLLISTENER = 0x0001;
const unsigned long PQIPERSON_ALL_BW_LIMITED = 0x0010;
class p3disc;
class p3channel;
class pqissllistener;
class pqipersongrp: public pqihandler, public PQTunnelServer
{
public:
pqipersongrp(SecurityPolicy *, sslroot *sr, unsigned long flags);
// control the connections.
int cert_accept(cert *a);
int cert_deny(cert *a);
int cert_auto(cert *a, bool b);
int restart_listener();
int save_config();
int load_config();
// tick interfaces.
virtual int tick();
virtual int status();
// + SearchInterface which should automatically handle stuff
// acess to services.
p3disc *getP3Disc() { return p3d; }
#ifdef PQI_USE_PROXY
p3proxy *getP3Proxy() { return p3p; }
#endif
#ifdef PQI_USE_CHANNELS
p3channel *getP3Channel() { return p3c; }
#endif
protected:
/* Overloaded PQItem Check
* checks item->cid vs Person
*/
virtual int checkOutgoingPQItem(PQItem *item, int global);
private:
// The tunnelserver operation.
int tickTunnelServer();
pqissllistener *pqil;
sslroot *sslr;
p3disc *p3d;
#ifdef PQI_USE_PROXY
p3proxy *p3p;
pqiudplistener *pqiudpl;
#endif
#ifdef PQI_USE_CHANNELS
p3channel *p3c;
#endif
unsigned long initFlags;
};
#endif // MRK_PQI_PERSON_HANDLER_HEADER

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,376 @@
/*
* "$Id: pqiproxy.h,v 1.7 2007-02-18 21:46:49 rmf24 Exp $"
*
* 3P/PQI network interface for RetroShare.
*
* Copyright 2004-2006 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 MRK_PQI_PROXY_HEADER
#define MRK_PQI_PROXY_HEADER
#include <openssl/ssl.h>
#include <string>
#include <map>
#include <list>
#include "pqi/pqi.h"
#include "pqi/pqiperson.h"
#include "pqi/pqitunnel.h"
#include "pqi/pqitunnelproxy.h"
class cert;
class pqiproxy;
class pqifilter;
class p3disc;
// PQItem derived classes.
class PQTunnelInit;
class PQTunnelProxyInit;
class PQTunnel;
class PQTunnelProxy;
/*
* #ifdef PQI_USE_XPGP
* #include "xpgpcert.h"
*/
class p3proxy : public PQTunnelService
{
public:
p3proxy(p3disc *p)
:PQTunnelService(PQI_TUNNEL_PROXY_TYPE), p3d(p)
{
sroot = getSSLRoot();
return;
}
virtual ~p3proxy() { return; }
// PQTunnelService Overloading.
virtual int receive(PQTunnel *);
virtual PQTunnel * send();
virtual int receive(PQTunnelInit *);
virtual PQTunnelInit * sendInit();
// interface to pqiproxy.
int attach(pqiproxy *p, cert *c);
int detach(pqiproxy *p, cert *c);
int listen(pqiproxy *p, cert *c);
int stoplistening(pqiproxy *p, cert *c);
int stopconnecting(pqiproxy *p, cert *c);
int reset(pqiproxy *p, cert *c);
int outgoingpkt(pqiproxy *p, cert *, void *d, int size);
int incomingpkt(pqiproxy *p, void *d, int maxsize);
// overloaded from many sources.
virtual int tick();
int status();
int connectattempt(pqiproxy*, cert*);
int connectattempt();
int nextconnectattempt(cert *, cert *);
protected:
// Fn to translate the sig to a cert.
bool filter(PQTunnelProxy *in);
cert *findcert(certsign &cs);
PQTunnelProxyInit *createProxyInit(cert *dest, cert *proxy);
PQTunnelProxy *createProxyPkt(cert *dest, cert *proxy, long nextseq,
const char *data, int size);
// Register Connections for which we are the Proxy.
// (only channels registered this way can send proxy packets)
int registerProxyConnection(cert *src, cert *proxy,
cert *dest, PQTunnelProxyInit *pinit);
// indicates if a proxy connection has been established.
int isConnection(cert *src, cert *dest);
// Init Proxy Connections.
int respondConnect(cert *o, cert *p, PQTunnelProxyInit *in);
int completeConnect(cert *o, cert *p, PQTunnelProxyInit *in);
int endConnect(cert *o, cert *p, PQTunnelProxyInit *in);
// process incoming.
virtual int processincoming();
// Overload to provide alternative behaviour.
// These fns are called from receive(PQTunnel *);
virtual int connectionCompletedAsProxy(cert *n1, cert *n2) { return 1; }
virtual int connectionCompletedAsPeer(cert *proxy, cert *peer) { return 1; }
// Overload to provide alternative behaviour.
// These fns are called from receive(PQTunnel *);
virtual int receiveAsProxy(PQTunnelProxy* pqtp, cert *src, cert *dest);
virtual int receiveAsDestination(PQTunnelProxy* pqtp,
cert *src, cert *from, cert *dest, pqiproxy *pqip);
virtual int receiveAsError(PQTunnelProxy* pqtp, cert *src, cert *from, cert *dest);
// Proxy Control functions.
int sendProxyInit(cert *c);
// Fn to send
int sendEndProxyConnectionPkt(cert *other, cert *proxy);
bool active;
// the registered proxies.
// All of these maps are
// indexed by the destination, not the proxy.
// which is the second cert is some cases.
std::map<cert *, pqiproxy *> proxymap;
std::list<cert *> listenqueue; // the ones to listen for.
std::list<cert *> connectqueue; // the ones to attempt to connect.
std::map<cert *, cert *> initmap; // ones we sent init, wait for init.
std::map<cert *, cert *> replymap; // ones that need a auth reply.
std::map<cert *, cert *> connectionmap;
std::map<cert *, cert *> lastproxymap;
std::map<cert *, unsigned long> connecttimemap; // timeout map.
std::map<cert *, bool> passivemap; // who inited connection.
// double direction map.
//std::map<pqiproxy *, ChanId> outmap;
std::map<pqiproxy *, std::list<PQTunnelProxy *> > inqueue;
// filters. (remove bad packets/cache data).
std::list<pqifilter *> filters;
// Map of the connections we are proxy for.
std::map<std::pair<cert *, cert *>, int> proxyconnect;
p3disc *p3d; // needed to find proxies.
sslroot *sroot; // for certificate references.
// input fn for details.
int addOutInitPkt(PQTunnelInit *pkt);
std::list<PQTunnel *> outPkts;
std::list<PQTunnelInit *> outInitPkts;
};
// pqiconnect, derives from pqistreamer/PQInterface.
//
// this class needs to provide.
// 1) read/write data.
// 2) connect functions.
// base interface for pqiproxy....
class pqiproxy
{
public:
pqiproxy(cert *c, p3proxy *l)
:sslcert(c), p3p(l) { return; }
virtual ~pqiproxy() { return; }
// The interface to p3proxy.
virtual int notifyEvent(int type) = 0;
// notification from p3proxy.
virtual int connected(bool active) = 0;
virtual int disconnected() = 0;
protected:
cert *sslcert;
p3proxy *p3p;
};
/* use a common peer as a proxy, to pass messages
* between proxied peers.
*/
class pqipeerproxy: public pqiproxy, public NetBinInterface
{
public:
pqipeerproxy(cert *c, p3proxy *l, PQInterface *parent);
virtual ~pqipeerproxy();
// Net Interface.
virtual int connectattempt();
virtual int listen();
virtual int stoplistening();
virtual int reset();
virtual int disconnect();
// Overloaded from PQInterface
virtual int status();
virtual int tick();
virtual cert * getContact();
// Bin Interface.
virtual int senddata(void*, int);
virtual int readdata(void*, int);
virtual int netstatus();
virtual int isactive();
virtual bool moretoread();
virtual bool cansend();
// The interface to p3proxy.
virtual int notifyEvent(int type);
// notification from p3proxy.
virtual int connected(bool active);
virtual int disconnected();
protected:
/* data */
//p3proxy *p3p;
bool active;
int connect_mode;
void *pkt;
int maxpktlen;
int pktlen;
int pktn;
};
/* Documenting the virtual (proxy) pqi interface.
*
* This is used to create proxy interface
* for people behind firewalls.
*
* There are two options for such an
* interface.
* 1) Encrypted Tunneling - This has the
* the advantage/disadvantage that it
* allows multiple layers of proxying,
* and very private.
*
* 2) Open Proxying - This lets people
* see the data, and allows restriction to one
* layer. This option allow the proxier,
* to collect the files passing through.
* (benefit for allowing proxying).
*
* As this option will less impact on the
* persons bandwidth, and give them some
* benefit, it'll be implemented first.
*
* The data will be saved in a cache,
* with a first in, first out policy,
*
* maybe show a window of cached files,
* and allow the user to save any from
* a list.
*
* So to do this we need
* i) a cache system.
* ii) extra message types to indicate
* proxied files, and searches etc.
* iii) a proxy server, to handle proxy messages.
*
* actually, this class will need to
*
* a proxy interface in someway or another.
*
*
* P1 PROXY P2
* requests a
* proxy interface.
* --------->
* end attempt <----- IF Not
* Available.
*
* else ---------------> Check for proxy/person auth
* end attempt <------ cancel ------- If Not Auth.
*
* else, if allowed.
* build proxy server.
* Build proxy <------ setup ---------- send okay
* server connection.
*
* pqissl.
* -> proxy interface.
* Send()
* return proxymsg locally
* pulled by proxy server.
*
* ps -> send proxy msg
* to correct pqissl.
* ----------> popped out to
* the proxy server.
* if file cache.
* redirect ------> recieved by pqissl.
* pulled by proxy server.
*
* proxy server
*
* all proxied information is
* going to be signed/or encrypted.
*
* very simple - that is the only
* necessary change.
*
* proxy msg.
* ---------------------
* type : init
* end
* msg (signed)
* tunnelled (includes init of ssl.)
* dest cert signature:
*
* encryption/signature mode.
*
* signature len:
* signature:
*
* data len:
* data
*
*
*
*
*
* is this the right place to add it?
* or is pqistreamer the answer.
*
*/
#endif

View File

@ -0,0 +1,69 @@
/*
* "$Id: pqisecurity.cc,v 1.3 2007-02-18 21:46:49 rmf24 Exp $"
*
* 3P/PQI network interface for RetroShare.
*
* Copyright 2004-2006 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 "pqi/pqisecurity.h"
// Can keep the structure hidden....
// but won't at the moment.
// functions for checking what is allowed...
// currently these are all dummies.
std::string secpolicy_print(SecurityPolicy *)
{
return std::string("secpolicy_print() Implement Me Please!");
}
SecurityPolicy * secpolicy_create()
{
return (SecurityPolicy *) malloc(sizeof(SecurityPolicy));
}
int secpolicy_delete(SecurityPolicy *p)
{
free(p);
return 1;
}
int secpolicy_limit(SecurityPolicy *limiter,
SecurityPolicy *alter)
{
return 1;
}
int secpolicy_check(SecurityPolicy *, int type_transaction,
int direction)
{
return 1;
}

View File

@ -0,0 +1,56 @@
/*
* "$Id: pqisecurity.h,v 1.3 2007-02-18 21:46:49 rmf24 Exp $"
*
* 3P/PQI network interface for RetroShare.
*
* Copyright 2004-2006 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 MRK_PQI_SECURITY_HEADER
#define MRK_PQI_SECURITY_HEADER
#include "pqi/pqi.h"
#include "pqi/pqipacket.h"
#define PQI_INCOMING 2
#define PQI_OUTGOING 5
//structure.
typedef struct sec_policy
{
int searchable; // flags indicate how searchable we are..
} SecurityPolicy;
// functions for checking what is allowed...
//
std::string secpolicy_print(SecurityPolicy *);
SecurityPolicy * secpolicy_create();
int secpolicy_delete(SecurityPolicy *);
int secpolicy_limit(SecurityPolicy *limiter,
SecurityPolicy *alter);
int secpolicy_check(SecurityPolicy *, int type_transaction,
int direction);
#endif

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,262 @@
/*
* "$Id: pqissl.h,v 1.18 2007-03-11 14:54:22 rmf24 Exp $"
*
* 3P/PQI network interface for RetroShare.
*
* Copyright 2004-2006 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 MRK_PQI_SSL_HEADER
#define MRK_PQI_SSL_HEADER
#include <openssl/ssl.h>
// operating system specific network header.
#include "pqi/pqinetwork.h"
#include <string>
#include <map>
#include "pqi/pqi_base.h"
/**************** PQI_USE_XPGP ******************/
#if defined(PQI_USE_XPGP)
#include "pqi/xpgpcert.h"
#else /* X509 Certificates */
/**************** PQI_USE_XPGP ******************/
#include "pqi/sslcert.h"
#endif /* X509 Certificates */
/**************** PQI_USE_XPGP ******************/
#define WAITING_NOT 0
#define WAITING_PROXY_CONNECT 1
#define WAITING_LOCAL_ADDR 2
#define WAITING_REMOTE_ADDR 3
#define WAITING_SOCK_CONNECT 4
#define WAITING_SSL_CONNECTION 5
#define WAITING_SSL_AUTHORISE 6
#define WAITING_FAIL_INTERFACE 7
#define PQISSL_PASSIVE 0x00
#define PQISSL_ACTIVE 0x01
const int PQISSL_LOCAL_FLAG = 0x01;
const int PQISSL_REMOTE_FLAG = 0x02;
const int PQISSL_DNS_FLAG = 0x04;
/* not sure about the value? */
const int PQISSL_UDP_FLAG = 0x02;
/***************************** pqi Net SSL Interface *********************************
* This provides the base SSL interface class,
* and handles most of the required functionality.
*
* there are a series of small fn's that can be overloaded
* to provide alternative behaviour....
*
* Classes expected to inherit from this are:
*
* pqissllistener -> pqissllistener (tcp only)
* -> pqixpgplistener (tcp only)
*
* pqissl -> pqissltcp
* -> pqissludp
* -> pqixpgptcp
* -> pqixpgpudp
*
*/
class pqissl;
class cert;
class pqissllistener;
#if 0 /* REMOVING pqissllistener */
class pqissllistener
{
public:
pqissllistener(struct sockaddr_in addr);
int addlistenaddr(cert *c, pqissl *acc);
int removeListenPort(cert *c);
int setListenAddr(struct sockaddr_in addr);
int setuplisten();
int resetlisten();
int acceptconnection();
int continueaccepts();
int continueSSL(SSL *ssl, bool);
int continueSocket(int fd, bool);
//int connectCertExchange(cert *);
//
int tick();
int status();
private:
// fn to get cert, anyway
int Extract_Failed_SSL_Certificate(SSL *ssl, struct sockaddr_in *inaddr);
struct sockaddr_in raddr;
struct sockaddr_in laddr;
socklen_t addrlen;
bool active;
int lsock;
cert *localcert;
std::map<cert *, pqissl *> listenaddr;
std::list<SSL *> incoming_ssl;
std::list<int> incoming_skts;
sslroot *sslccr;
};
#endif /* removing pqisllistener */
class pqissl: public NetBinInterface
{
public:
pqissl(cert *c, pqissllistener *l, PQInterface *parent);
virtual ~pqissl();
// NetInterface
virtual int connectattempt();
virtual int listen();
virtual int stoplistening();
virtual int reset();
virtual int disconnect();
// BinInterface
virtual int tick();
virtual int status();
virtual int senddata(void*, int);
virtual int readdata(void*, int);
virtual int netstatus();
virtual int isactive();
virtual bool moretoread();
virtual bool cansend();
virtual bool bandwidthLimited();
protected:
// A little bit of information to describe
// the SSL state, this is needed
// to allow full Non-Blocking Connect behaviour.
// This fn loops through the following fns.
// to complete an SSL.
int ConnectAttempt();
int waiting;
// These first five fns are overloaded for udp/etc connections.
virtual int Reattempt_Connection();
virtual int Request_Proxy_Connection();
virtual int Check_Proxy_Connection();
virtual int Request_Local_Address();
virtual int Determine_Local_Address();
virtual int Determine_Remote_Address();
virtual int Initiate_Connection();
virtual int Basic_Connection_Complete();
// These should be identical for all cases,
// differences are achieved via the net_internal_* fns.
int Initiate_SSL_Connection();
int SSL_Connection_Complete();
int Authorise_SSL_Connection();
int Extract_Failed_SSL_Certificate(); // try to get cert anyway.
public:
/* Completion of the SSL connection,
* this is public, so it can be called by
* the listener (should make friends??)
*/
int accept(SSL *ssl, int fd, struct sockaddr_in foreign_addr);
protected:
//protected internal fns that are overloaded for udp case.
virtual int net_internal_close(int fd) { return unix_close(fd); }
virtual int net_internal_SSL_set_fd(SSL *ssl, int fd) { return SSL_set_fd(ssl, fd); }
virtual int net_internal_fcntl_nonblock(int fd) { return unix_fcntl_nonblock(fd);}
/* data */
bool active;
bool certvalid;
// addition for udp (tcp version == ACTIVE).
int sslmode;
SSL *ssl_connection;
int sockfd;
cert *sslcert;
sslroot *sslccr;
pqissllistener *pqil;
struct sockaddr_in remote_addr;
void *readpkt;
int pktlen;
int attempt_ts;
// Some flags to indicate
// the status of the various interfaces
// (local), (server)
unsigned int net_attempt;
unsigned int net_failure;
unsigned int net_unreachable;
bool sameLAN; /* flag use to allow high-speed transfers */
int n_read_zero; /* a counter to determine if the connection is really dead */
int ssl_connect_timeout; /* timeout to ensure that we don't get stuck (can happen on udp!) */
private:
// ssl only fns.
int connectInterface(sockaddr_in&);
};
#endif // MRK_PQI_SSL_HEADER

Some files were not shown because too many files have changed in this diff Show More