RetroShare/libretroshare/src/pqi/pqibin.cc
drbob 5e41b21cef Lots of bugfixes and tweaks:
* Switched p3Ranking to share Friends Links as well as own.
 * Modified rankmsgs to contain source id.
 * Fixed up rsNotify, added pqiNotify and global function call to get it.
 * Added notify for Bad Incoming Directory
 * Added Emergency Incoming directory so RS can keep running.
 * Added notify for Bad Packet (connecting to V0.3.X)
 * Added notify for Incomplete Packet Read (not been triggered yet!)
 * added close() to BinInterface, close on pqissl calls reset() 
 * removed exit(1) calls from pqistreamer, replaced with bio->close().
 * Increased Maximum Packet Size for HTML messages.
 * Fixed Online/Offline Message Forwarding. (TEST).
 * Increased DHT bootstrap buckets to 4.
 * Cleaned up much of serialiser debug (was slowing down Mac)
 * Added directory path to File Listings.
 * added ConvertSharedFilePath() so correct local dir can be found.
 * Added ForceDirectoryCheck() and InDirectoryCheck() for file hashing.
 * removed old TMP cache loading.
 * switched off Cache debug.



git-svn-id: http://svn.code.sf.net/p/retroshare/code/trunk@448 b45a01b8-16f6-495d-af2f-9b41ad6348cc
2008-03-31 14:06:59 +00:00

558 lines
9.7 KiB
C++

/*
* "$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(const char *fname, int flags)
:bin_flags(flags), buf(NULL), hash(NULL), bcount(0)
{
/* if read + write - open r+ */
if ((bin_flags & BIN_FLAGS_READABLE) &&
(bin_flags & BIN_FLAGS_WRITEABLE))
{
buf = fopen(fname, "rb+");
/* if the file don't exist */
if (!buf)
{
buf = fopen(fname, "wb+");
}
}
else if (bin_flags & BIN_FLAGS_READABLE)
{
buf = fopen(fname, "rb");
}
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, "wb");
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;
}
if (bin_flags & BIN_FLAGS_HASH_DATA)
{
hash = new pqihash();
}
}
BinFileInterface::~BinFileInterface()
{
if (buf)
{
fclose(buf);
}
}
int BinFileInterface::close()
{
if (buf)
{
fclose(buf);
buf = NULL;
}
return 1;
}
int BinFileInterface::senddata(void *data, int len)
{
if (!buf)
return -1;
if (1 != fwrite(data, len, 1, buf))
{
return -1;
}
if (bin_flags & BIN_FLAGS_HASH_DATA)
{
hash->addData(data, len);
bcount += len;
}
return len;
}
int BinFileInterface::readdata(void *data, int len)
{
if (!buf)
return -1;
if (1 != fread(data, len, 1, buf))
{
return -1;
}
if (bin_flags & BIN_FLAGS_HASH_DATA)
{
hash->addData(data, len);
bcount += len;
}
return len;
}
std::string BinFileInterface::gethash()
{
std::string hashstr;
if (bin_flags & BIN_FLAGS_HASH_DATA)
{
hash->Complete(hashstr);
}
return hashstr;
}
uint64_t BinFileInterface::bytecount()
{
if (bin_flags & BIN_FLAGS_HASH_DATA)
{
return bcount;
}
return 0;
}
BinMemInterface::BinMemInterface(int defsize, int flags)
:bin_flags(flags), buf(NULL), size(defsize),
recvsize(0), readloc(0), hash(NULL), bcount(0)
{
buf = malloc(defsize);
if (bin_flags & BIN_FLAGS_HASH_DATA)
{
hash = new pqihash();
}
}
BinMemInterface::BinMemInterface(const void *data, const int defsize, int flags)
:bin_flags(flags), buf(NULL), size(defsize),
recvsize(0), readloc(0), hash(NULL), bcount(0)
{
buf = malloc(defsize);
if (bin_flags & BIN_FLAGS_HASH_DATA)
{
hash = new pqihash();
}
/* just remove the const
* *BAD* but senddata don't change it anyway
*/
senddata((void *) data, defsize);
}
BinMemInterface::~BinMemInterface()
{
if (buf)
free(buf);
return;
}
int BinMemInterface::close()
{
if (buf)
{
free(buf);
buf = NULL;
}
size = 0;
recvsize = 0;
readloc = 0;
return 1;
}
/* 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, const int len)
{
if(recvsize + len > size)
{
/* resize? */
return -1;
}
memcpy((char *) buf + recvsize, data, len);
if (bin_flags & BIN_FLAGS_HASH_DATA)
{
hash->addData(data, len);
bcount += 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);
if (bin_flags & BIN_FLAGS_HASH_DATA)
{
hash->addData(data, len);
bcount += len;
}
readloc += len;
return len;
}
std::string BinMemInterface::gethash()
{
std::string hashstr;
if (bin_flags & BIN_FLAGS_HASH_DATA)
{
hash->Complete(hashstr);
}
return hashstr;
}
uint64_t BinMemInterface::bytecount()
{
if (bin_flags & BIN_FLAGS_HASH_DATA)
{
return bcount;
}
return 0;
}
bool BinMemInterface::writetofile(const char *fname)
{
FILE *fd = fopen(fname, "wb");
if (!fd)
{
return false;
}
if (1 != fwrite(buf, recvsize, 1, fd))
{
fclose(fd);
return false;
}
fclose(fd);
return true;
}
bool BinMemInterface::readfromfile(const char *fname)
{
FILE *fd = fopen(fname, "rb");
if (!fd)
{
return false;
}
/* get size */
::fseek(fd, 0L, SEEK_END);
int fsize = ftell(fd);
if (fsize > size)
{
/* not enough room */
std::cerr << "BinMemInterface::readfromfile() not enough room";
std::cerr << std::endl;
fclose(fd);
return false;
}
::fseek(fd, 0L, SEEK_SET);
if (1 != fread(buf, fsize, 1, fd))
{
/* not enough room */
std::cerr << "BinMemInterface::readfromfile() failed fread";
std::cerr << std::endl;
fclose(fd);
return false;
}
recvsize = fsize;
readloc = 0;
fclose(fd);
return true;
}
/**************************************************************************/
void printNetBinID(std::ostream &out, std::string id, uint32_t t)
{
out << "NetBinId(" << id << ",";
if (t == PQI_CONNECT_TCP)
{
out << "TCP)";
}
else
{
out << "UDP)";
}
}
/************************** NetBinDummy ******************************
* A test framework,
*
*/
#include "pqi/pqiperson.h"
const uint32_t DEFAULT_DUMMY_DELTA = 5;
NetBinDummy::NetBinDummy(PQInterface *parent, std::string id, uint32_t t)
:NetBinInterface(parent, id), type(t), dummyConnected(false),
toConnect(false), connectDelta(DEFAULT_DUMMY_DELTA)
{
return;
}
// Net Interface
int NetBinDummy::connect(struct sockaddr_in raddr)
{
std::cerr << "NetBinDummy::connect(";
std::cerr << inet_ntoa(raddr.sin_addr) << ":";
std::cerr << htons(raddr.sin_port);
std::cerr << ") ";
printNetBinID(std::cerr, PeerId(), type);
std::cerr << std::endl;
std::cerr << "NetBinDummy::dummyConnect = true!";
std::cerr << std::endl;
if (type == PQI_CONNECT_TCP)
{
std::cerr << "NetBinDummy:: Not connecting TCP";
std::cerr << std::endl;
if (parent())
{
parent()->notifyEvent(this, CONNECT_FAILED);
}
}
else if (!dummyConnected)
{
toConnect = true;
connectTS = time(NULL) + connectDelta;
std::cerr << "NetBinDummy::toConnect = true, connect in: ";
std::cerr << connectDelta << " secs";
std::cerr << std::endl;
}
else
{
std::cerr << "NetBinDummy:: Already Connected!";
std::cerr << std::endl;
}
return 1;
}
int NetBinDummy::listen()
{
std::cerr << "NetBinDummy::connect() ";
printNetBinID(std::cerr, PeerId(), type);
std::cerr << std::endl;
return 1;
}
int NetBinDummy::stoplistening()
{
std::cerr << "NetBinDummy::stoplistening() ";
printNetBinID(std::cerr, PeerId(), type);
std::cerr << std::endl;
return 1;
}
int NetBinDummy::disconnect()
{
std::cerr << "NetBinDummy::disconnect() ";
printNetBinID(std::cerr, PeerId(), type);
std::cerr << std::endl;
std::cerr << "NetBinDummy::dummyConnect = false!";
std::cerr << std::endl;
dummyConnected = false;
if (parent())
{
parent()->notifyEvent(this, CONNECT_FAILED);
}
return 1;
}
int NetBinDummy::reset()
{
std::cerr << "NetBinDummy::reset() ";
printNetBinID(std::cerr, PeerId(), type);
std::cerr << std::endl;
disconnect();
return 1;
}
// Bin Interface.
int NetBinDummy::tick()
{
if (toConnect)
{
if (connectTS < time(NULL))
{
std::cerr << "NetBinDummy::tick() dummyConnected = true ";
printNetBinID(std::cerr, PeerId(), type);
std::cerr << std::endl;
dummyConnected = true;
toConnect = false;
if (parent())
parent()->notifyEvent(this, CONNECT_SUCCESS);
}
else
{
std::cerr << "NetBinDummy::tick() toConnect ";
printNetBinID(std::cerr, PeerId(), type);
std::cerr << std::endl;
}
}
return 0;
}
int NetBinDummy::senddata(void *data, int len)
{
std::cerr << "NetBinDummy::senddata() ";
printNetBinID(std::cerr, PeerId(), type);
std::cerr << std::endl;
if (dummyConnected)
return len;
return 0;
}
int NetBinDummy::readdata(void *data, int len)
{
std::cerr << "NetBinDummy::readdata() ";
printNetBinID(std::cerr, PeerId(), type);
std::cerr << std::endl;
return 0;
}
int NetBinDummy::netstatus()
{
std::cerr << "NetBinDummy::netstatus() ";
printNetBinID(std::cerr, PeerId(), type);
std::cerr << std::endl;
return 1;
}
int NetBinDummy::isactive()
{
std::cerr << "NetBinDummy::isactive() ";
printNetBinID(std::cerr, PeerId(), type);
if (dummyConnected)
std::cerr << " true ";
else
std::cerr << " false ";
std::cerr << std::endl;
return dummyConnected;
}
bool NetBinDummy::moretoread()
{
std::cerr << "NetBinDummy::moretoread() ";
printNetBinID(std::cerr, PeerId(), type);
std::cerr << std::endl;
return false;
}
bool NetBinDummy::cansend()
{
std::cerr << "NetBinDummy::cansend() ";
printNetBinID(std::cerr, PeerId(), type);
std::cerr << std::endl;
return dummyConnected;
}
int NetBinDummy::close()
{
std::cerr << "NetBinDummy::close() ";
printNetBinID(std::cerr, PeerId(), type);
std::cerr << std::endl;
return 1;
}
std::string NetBinDummy::gethash()
{
std::cerr << "NetBinDummy::gethash() ";
printNetBinID(std::cerr, PeerId(), type);
std::cerr << std::endl;
return std::string("");
}