mirror of
https://github.com/RetroShare/RetroShare.git
synced 2025-02-04 09:05:34 -05:00
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:
commit
935745a08e
11
libretroshare/src/BUGS
Normal file
11
libretroshare/src/BUGS
Normal file
@ -0,0 +1,11 @@
|
||||
|
||||
This is the list of known BUGS:
|
||||
-------------------------------
|
||||
* None!
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
6
libretroshare/src/FAQ
Normal file
6
libretroshare/src/FAQ
Normal file
@ -0,0 +1,6 @@
|
||||
|
||||
RetroShare FAQ
|
||||
---------------
|
||||
|
||||
Ask a Question.
|
||||
|
39
libretroshare/src/Makefile
Normal file
39
libretroshare/src/Makefile
Normal 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
|
||||
|
150
libretroshare/src/Readme.txt
Normal file
150
libretroshare/src/Readme.txt
Normal 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
|
||||
---------------------------------------------
|
||||
|
||||
|
||||
|
54
libretroshare/src/Readme.txt-V0.2.1
Normal file
54
libretroshare/src/Readme.txt-V0.2.1
Normal 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
7
libretroshare/src/TODO
Normal file
@ -0,0 +1,7 @@
|
||||
|
||||
TODO
|
||||
---------------
|
||||
|
||||
Too much to list...
|
||||
|
||||
|
53
libretroshare/src/dbase/Makefile
Normal file
53
libretroshare/src/dbase/Makefile
Normal 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)
|
||||
|
721
libretroshare/src/dbase/cachestrapper.cc
Normal file
721
libretroshare/src/dbase/cachestrapper.cc
Normal 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;
|
||||
}
|
||||
|
||||
|
||||
|
321
libretroshare/src/dbase/cachestrapper.h
Normal file
321
libretroshare/src/dbase/cachestrapper.h
Normal 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
|
63
libretroshare/src/dbase/cachetest.h
Normal file
63
libretroshare/src/dbase/cachetest.h
Normal 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
|
||||
|
209
libretroshare/src/dbase/ficachetest.cc
Normal file
209
libretroshare/src/dbase/ficachetest.cc
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
366
libretroshare/src/dbase/filedex.cc
Normal file
366
libretroshare/src/dbase/filedex.cc
Normal 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;
|
||||
}
|
||||
|
||||
|
111
libretroshare/src/dbase/filedex.h
Normal file
111
libretroshare/src/dbase/filedex.h
Normal 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
|
538
libretroshare/src/dbase/filelook.cc
Normal file
538
libretroshare/src/dbase/filelook.cc
Normal 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;
|
||||
}
|
||||
|
113
libretroshare/src/dbase/filelook.h
Normal file
113
libretroshare/src/dbase/filelook.h
Normal 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
|
||||
|
672
libretroshare/src/dbase/fimonitor.cc
Normal file
672
libretroshare/src/dbase/fimonitor.cc
Normal 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;
|
||||
}
|
||||
|
120
libretroshare/src/dbase/fimonitor.h
Normal file
120
libretroshare/src/dbase/fimonitor.h
Normal 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
|
||||
|
||||
|
87
libretroshare/src/dbase/fimontest.cc
Normal file
87
libretroshare/src/dbase/fimontest.cc
Normal 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;
|
||||
}
|
||||
|
||||
|
1062
libretroshare/src/dbase/findex.cc
Normal file
1062
libretroshare/src/dbase/findex.cc
Normal file
File diff suppressed because it is too large
Load Diff
229
libretroshare/src/dbase/findex.h
Normal file
229
libretroshare/src/dbase/findex.h
Normal 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
|
||||
|
118
libretroshare/src/dbase/fisavetest.cc
Normal file
118
libretroshare/src/dbase/fisavetest.cc
Normal 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;
|
||||
}
|
||||
|
521
libretroshare/src/dbase/fistore.cc
Normal file
521
libretroshare/src/dbase/fistore.cc
Normal 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;
|
||||
}
|
||||
|
||||
|
100
libretroshare/src/dbase/fistore.h
Normal file
100
libretroshare/src/dbase/fistore.h
Normal 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
|
213
libretroshare/src/dbase/fitest2.cc
Normal file
213
libretroshare/src/dbase/fitest2.cc
Normal 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;
|
||||
}
|
||||
|
111
libretroshare/src/dbase/ftest.cc
Normal file
111
libretroshare/src/dbase/ftest.cc
Normal 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;
|
||||
}
|
||||
|
||||
|
89
libretroshare/src/dbase/looktest.cc
Normal file
89
libretroshare/src/dbase/looktest.cc
Normal 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;
|
||||
}
|
||||
|
||||
|
149
libretroshare/src/dbase/rsexpr.cc
Normal file
149
libretroshare/src/dbase/rsexpr.cc
Normal 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;
|
||||
}
|
74
libretroshare/src/dbase/searchtest.cc
Normal file
74
libretroshare/src/dbase/searchtest.cc
Normal 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;
|
||||
}
|
28
libretroshare/src/dht/Makefile
Normal file
28
libretroshare/src/dht/Makefile
Normal 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
|
||||
|
710
libretroshare/src/dht/dhthandler.cc
Normal file
710
libretroshare/src/dht/dhthandler.cc
Normal 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
|
||||
|
97
libretroshare/src/dht/dhthandler.h
Normal file
97
libretroshare/src/dht/dhthandler.h
Normal 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 */
|
90
libretroshare/src/dht/dhttest.cc
Normal file
90
libretroshare/src/dht/dhttest.cc
Normal 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 ******************/
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
272
libretroshare/src/dht/tst.ini
Normal file
272
libretroshare/src/dht/tst.ini
Normal 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]
|
328
libretroshare/src/fltkgui/Fl_File_Item.cc
Normal file
328
libretroshare/src/fltkgui/Fl_File_Item.cc
Normal 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 $".
|
||||
//
|
1704
libretroshare/src/fltkgui/Fl_Funky_Browser.cc
Normal file
1704
libretroshare/src/fltkgui/Fl_Funky_Browser.cc
Normal file
File diff suppressed because it is too large
Load Diff
179
libretroshare/src/fltkgui/Fl_Funky_Browser.h
Normal file
179
libretroshare/src/fltkgui/Fl_Funky_Browser.h
Normal 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
|
||||
|
752
libretroshare/src/fltkgui/Fl_Tree_Browser.cc
Normal file
752
libretroshare/src/fltkgui/Fl_Tree_Browser.cc
Normal 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 $".
|
||||
//
|
210
libretroshare/src/fltkgui/Fl_Tree_Browser.h
Normal file
210
libretroshare/src/fltkgui/Fl_Tree_Browser.h
Normal 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 $".
|
||||
//
|
39
libretroshare/src/fltkgui/Makefile
Normal file
39
libretroshare/src/fltkgui/Makefile
Normal 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
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
197
libretroshare/src/fltkgui/alertbox.cc
Normal file
197
libretroshare/src/fltkgui/alertbox.cc
Normal 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);
|
||||
}
|
||||
|
||||
|
||||
|
91
libretroshare/src/fltkgui/alertbox.h
Normal file
91
libretroshare/src/fltkgui/alertbox.h
Normal 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
|
1852
libretroshare/src/fltkgui/fltkpqi.cc
Normal file
1852
libretroshare/src/fltkgui/fltkpqi.cc
Normal file
File diff suppressed because it is too large
Load Diff
3448
libretroshare/src/fltkgui/fltkserver.cc
Normal file
3448
libretroshare/src/fltkgui/fltkserver.cc
Normal file
File diff suppressed because it is too large
Load Diff
222
libretroshare/src/fltkgui/fltkserver.h
Normal file
222
libretroshare/src/fltkgui/fltkserver.h
Normal 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
|
675
libretroshare/src/fltkgui/guitab.cc
Normal file
675
libretroshare/src/fltkgui/guitab.cc
Normal 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;
|
||||
}
|
788
libretroshare/src/fltkgui/guitab.fld
Normal file
788
libretroshare/src/fltkgui/guitab.fld
Normal 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}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
226
libretroshare/src/fltkgui/guitab.h
Normal file
226
libretroshare/src/fltkgui/guitab.h
Normal 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
|
996
libretroshare/src/fltkgui/pqibrowseitem.cc
Normal file
996
libretroshare/src/fltkgui/pqibrowseitem.cc
Normal 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;
|
||||
}
|
||||
|
219
libretroshare/src/fltkgui/pqibrowseitem.h
Normal file
219
libretroshare/src/fltkgui/pqibrowseitem.h
Normal 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
|
||||
|
745
libretroshare/src/fltkgui/pqistrings.cc
Normal file
745
libretroshare/src/fltkgui/pqistrings.cc
Normal 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 ******************/
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
79
libretroshare/src/fltkgui/pqistrings.h
Normal file
79
libretroshare/src/fltkgui/pqistrings.h
Normal 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
|
338
libretroshare/src/fltkgui/retrotray.cc
Normal file
338
libretroshare/src/fltkgui/retrotray.cc
Normal 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
|
||||
);
|
||||
|
||||
**********************/
|
||||
|
112
libretroshare/src/fltkgui/retrotray.h
Normal file
112
libretroshare/src/fltkgui/retrotray.h
Normal 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
27
libretroshare/src/licence
Normal 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
249
libretroshare/src/make.opt
Normal 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
|
||||
|
||||
|
||||
|
89
libretroshare/src/pqi/Makefile
Normal file
89
libretroshare/src/pqi/Makefile
Normal 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)
|
||||
|
||||
|
353
libretroshare/src/pqi/discItem.cc
Normal file
353
libretroshare/src/pqi/discItem.cc
Normal 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;
|
||||
}
|
||||
|
90
libretroshare/src/pqi/discItem.h
Normal file
90
libretroshare/src/pqi/discItem.h
Normal 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
|
1322
libretroshare/src/pqi/p3channel.cc
Normal file
1322
libretroshare/src/pqi/p3channel.cc
Normal file
File diff suppressed because it is too large
Load Diff
314
libretroshare/src/pqi/p3channel.h
Normal file
314
libretroshare/src/pqi/p3channel.h
Normal 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
|
2276
libretroshare/src/pqi/p3disc.cc
Normal file
2276
libretroshare/src/pqi/p3disc.cc
Normal file
File diff suppressed because it is too large
Load Diff
186
libretroshare/src/pqi/p3disc.h
Normal file
186
libretroshare/src/pqi/p3disc.h
Normal 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
|
341
libretroshare/src/pqi/p3loopback.cc
Normal file
341
libretroshare/src/pqi/p3loopback.cc
Normal 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;
|
||||
}
|
91
libretroshare/src/pqi/p3loopback.h
Normal file
91
libretroshare/src/pqi/p3loopback.h
Normal 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
|
317
libretroshare/src/pqi/p3supernode.cc
Normal file
317
libretroshare/src/pqi/p3supernode.cc
Normal 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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
440
libretroshare/src/pqi/pqi.cc
Normal file
440
libretroshare/src/pqi/pqi.cc
Normal 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
114
libretroshare/src/pqi/pqi.h
Normal 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
|
791
libretroshare/src/pqi/pqi_base.cc
Normal file
791
libretroshare/src/pqi/pqi_base.cc
Normal 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;
|
||||
}
|
||||
|
||||
|
596
libretroshare/src/pqi/pqi_base.h
Normal file
596
libretroshare/src/pqi/pqi_base.h
Normal 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
|
||||
|
169
libretroshare/src/pqi/pqi_data.h
Normal file
169
libretroshare/src/pqi/pqi_data.h
Normal 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
|
||||
|
22
libretroshare/src/pqi/pqiaddrstore.h
Normal file
22
libretroshare/src/pqi/pqiaddrstore.h
Normal 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 */
|
471
libretroshare/src/pqi/pqiarchive.cc
Normal file
471
libretroshare/src/pqi/pqiarchive.cc
Normal 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;
|
||||
}
|
||||
|
||||
|
||||
|
87
libretroshare/src/pqi/pqiarchive.h
Normal file
87
libretroshare/src/pqi/pqiarchive.h
Normal 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
|
165
libretroshare/src/pqi/pqibin.cc
Normal file
165
libretroshare/src/pqi/pqibin.cc
Normal 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;
|
||||
}
|
||||
|
||||
|
108
libretroshare/src/pqi/pqibin.h
Normal file
108
libretroshare/src/pqi/pqibin.h
Normal 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
|
||||
|
610
libretroshare/src/pqi/pqichannel.cc
Normal file
610
libretroshare/src/pqi/pqichannel.cc
Normal 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();
|
||||
}
|
||||
|
||||
|
||||
|
111
libretroshare/src/pqi/pqichannel.h
Normal file
111
libretroshare/src/pqi/pqichannel.h
Normal 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
|
216
libretroshare/src/pqi/pqidebug.cc
Normal file
216
libretroshare/src/pqi/pqidebug.cc
Normal 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;
|
||||
}
|
||||
|
||||
|
||||
|
49
libretroshare/src/pqi/pqidebug.h
Normal file
49
libretroshare/src/pqi/pqidebug.h
Normal 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
|
763
libretroshare/src/pqi/pqihandler.cc
Normal file
763
libretroshare/src/pqi/pqihandler.cc
Normal 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;
|
||||
}
|
||||
|
||||
|
169
libretroshare/src/pqi/pqihandler.h
Normal file
169
libretroshare/src/pqi/pqihandler.h
Normal 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
|
65
libretroshare/src/pqi/pqiindic.h
Normal file
65
libretroshare/src/pqi/pqiindic.h
Normal 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
|
117
libretroshare/src/pqi/pqiloopback.cc
Normal file
117
libretroshare/src/pqi/pqiloopback.cc
Normal 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;
|
||||
}
|
||||
|
||||
|
67
libretroshare/src/pqi/pqiloopback.h
Normal file
67
libretroshare/src/pqi/pqiloopback.h
Normal 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
|
124
libretroshare/src/pqi/pqimon.cc
Normal file
124
libretroshare/src/pqi/pqimon.cc
Normal 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 */
|
||||
}
|
||||
|
||||
|
||||
|
72
libretroshare/src/pqi/pqimon.h
Normal file
72
libretroshare/src/pqi/pqimon.h
Normal 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
|
852
libretroshare/src/pqi/pqinetwork.cc
Normal file
852
libretroshare/src/pqi/pqinetwork.cc
Normal 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 ******************/
|
140
libretroshare/src/pqi/pqinetwork.h
Normal file
140
libretroshare/src/pqi/pqinetwork.h
Normal 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
|
||||
|
1783
libretroshare/src/pqi/pqipacket.cc
Normal file
1783
libretroshare/src/pqi/pqipacket.cc
Normal file
File diff suppressed because it is too large
Load Diff
79
libretroshare/src/pqi/pqipacket.h
Normal file
79
libretroshare/src/pqi/pqipacket.h
Normal 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
|
552
libretroshare/src/pqi/pqiperson.cc
Normal file
552
libretroshare/src/pqi/pqiperson.cc
Normal 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);
|
||||
}
|
||||
}
|
||||
|
162
libretroshare/src/pqi/pqiperson.h
Normal file
162
libretroshare/src/pqi/pqiperson.h
Normal 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
|
||||
|
480
libretroshare/src/pqi/pqipersongrp.cc
Normal file
480
libretroshare/src/pqi/pqipersongrp.cc
Normal 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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
117
libretroshare/src/pqi/pqipersongrp.h
Normal file
117
libretroshare/src/pqi/pqipersongrp.h
Normal 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
|
2337
libretroshare/src/pqi/pqiproxy.cc
Normal file
2337
libretroshare/src/pqi/pqiproxy.cc
Normal file
File diff suppressed because it is too large
Load Diff
376
libretroshare/src/pqi/pqiproxy.h
Normal file
376
libretroshare/src/pqi/pqiproxy.h
Normal 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
|
||||
|
69
libretroshare/src/pqi/pqisecurity.cc
Normal file
69
libretroshare/src/pqi/pqisecurity.cc
Normal 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;
|
||||
}
|
||||
|
||||
|
||||
|
56
libretroshare/src/pqi/pqisecurity.h
Normal file
56
libretroshare/src/pqi/pqisecurity.h
Normal 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
|
||||
|
2417
libretroshare/src/pqi/pqissl.cc
Normal file
2417
libretroshare/src/pqi/pqissl.cc
Normal file
File diff suppressed because it is too large
Load Diff
262
libretroshare/src/pqi/pqissl.h
Normal file
262
libretroshare/src/pqi/pqissl.h
Normal 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
Loading…
x
Reference in New Issue
Block a user