From 34b70b0b46e34a73308a4034cc9b1c70209b9eb4 Mon Sep 17 00:00:00 2001 From: Fritz Elfert Date: Mon, 28 Jun 1999 08:56:01 +0000 Subject: First import. --- lib/Makefile.am | 3 + lib/bool.h | 20 ++ lib/bufferarray.cc | 68 +++++ lib/bufferarray.h | 25 ++ lib/bufferstore.cc | 166 +++++++++++ lib/bufferstore.h | 50 ++++ lib/iowatch.cc | 77 +++++ lib/iowatch.h | 21 ++ lib/ppsocket.cc | 863 +++++++++++++++++++++++++++++++++++++++++++++++++++++ lib/ppsocket.h | 117 ++++++++ 10 files changed, 1410 insertions(+) create mode 100644 lib/Makefile.am create mode 100644 lib/bool.h create mode 100644 lib/bufferarray.cc create mode 100644 lib/bufferarray.h create mode 100644 lib/bufferstore.cc create mode 100644 lib/bufferstore.h create mode 100644 lib/iowatch.cc create mode 100644 lib/iowatch.h create mode 100644 lib/ppsocket.cc create mode 100644 lib/ppsocket.h (limited to 'lib') diff --git a/lib/Makefile.am b/lib/Makefile.am new file mode 100644 index 0000000..ec2faee --- /dev/null +++ b/lib/Makefile.am @@ -0,0 +1,3 @@ +noinst_LIBRARIES = libutils.a + +libutils_a_SOURCES = bufferarray.cc bufferstore.cc iowatch.cc ppsocket.cc diff --git a/lib/bool.h b/lib/bool.h new file mode 100644 index 0000000..7525d6c --- /dev/null +++ b/lib/bool.h @@ -0,0 +1,20 @@ +#ifndef _bool_h_ +#define _bool_h_ + +#ifndef __GNUC__ + +#ifndef bool +#define bool int +#endif + +#ifndef true +#define true 1 +#endif + +#ifndef false +#define false 0 +#endif + +#endif + +#endif diff --git a/lib/bufferarray.cc b/lib/bufferarray.cc new file mode 100644 index 0000000..4dc3971 --- /dev/null +++ b/lib/bufferarray.cc @@ -0,0 +1,68 @@ +// +// PLP - An implementation of the PSION link protocol +// +// Copyright (C) 1999 Philip Proudman +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program 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 General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// e-mail philip.proudman@btinternet.com + + +#include + +#include "bufferstore.h" +#include "bufferarray.h" + +bufferArray::bufferArray() { + len = 0; + lenAllocd = 5; + buff = new bufferStore [lenAllocd]; +} + +bufferArray::bufferArray(const bufferArray &a) { + len = a.len; + lenAllocd = a.lenAllocd; + buff = new bufferStore [lenAllocd]; + for (int i=0; i < len; i++) buff[i] = a.buff[i]; +} + +bufferArray::~bufferArray() { + delete [] buff; +} + +bufferStore bufferArray::popBuffer() { + bufferStore ret; + if (len > 0) { + ret = buff[0]; + len--; + for (long i=0; i +#include +#include + +#include "bufferstore.h" + +bufferStore::bufferStore() { + lenAllocd = 0; + buff = NULL; + len = 0; + start = 0; +} + +bufferStore::bufferStore(const bufferStore &a) { + lenAllocd = (a.getLen() > MIN_LEN) ? a.getLen() : MIN_LEN; + buff = new unsigned char [lenAllocd]; + len = a.getLen(); + for (long i=0; i MIN_LEN) ? _len : MIN_LEN; + buff = new unsigned char [lenAllocd]; + len = _len; + for (long i=0; i len) return 0; + return len - start; +} + +unsigned char bufferStore::getByte(long pos) const { + return buff[pos+start]; +} + +unsigned int bufferStore::getWord(long pos) const { + return buff[pos+start] + (buff[pos+start+1] << 8); +} + +unsigned int bufferStore::getDWord(long pos) const { + return buff[pos+start] + + (buff[pos+start+1] << 8) + + (buff[pos+start+2] << 16) + + (buff[pos+start+3] << 24); +} + +const char* bufferStore::getString(long pos) const { + return (const char*)buff+pos+start; +} + +ostream &operator<<(ostream &s, const bufferStore &m) { + { + for (int i = m.start; i < m.len; i++) + s << hex << setw(2) << setfill('0') << (int)m.buff[i] << " "; + } + s << "("; + { + for (int i = m.start; i < m.len; i++) { + unsigned char c = m.buff[i]; + if (c>=' ' && c <= 'z') s << c; + } + } + s<< ")"; + return s; +} + +void bufferStore::discardFirstBytes(int n) { + start += n; + if (start > len) start = len; +} + +void bufferStore::checkAllocd(long newLen) { + if (newLen >= lenAllocd) { + do { + if (lenAllocd < MIN_LEN) + lenAllocd = MIN_LEN; + else + lenAllocd *= 2; + } while (newLen >= lenAllocd); + unsigned char* newBuff = new unsigned char [lenAllocd]; + for (int i=start; i>8) & 0xff; +} + +void bufferStore::addDWord(long a) { + checkAllocd(len + 4); + buff[len++] = a & 0xff; + buff[len++] = (a>>8) & 0xff; + buff[len++] = (a>>16) & 0xff; + buff[len++] = (a>>24) & 0xff; +} diff --git a/lib/bufferstore.h b/lib/bufferstore.h new file mode 100644 index 0000000..4840689 --- /dev/null +++ b/lib/bufferstore.h @@ -0,0 +1,50 @@ +#ifndef _bufferstore_h +#define _bufferstore_h + +#include "bool.h" +class ostream; + +class bufferStore { +public: + bufferStore(); + bufferStore(const unsigned char*buff, long len); + ~bufferStore(); + bufferStore(const bufferStore &a); + void operator =(const bufferStore &a); + + // Reading Utils + unsigned long getLen() const; + unsigned char getByte(long pos) const; + unsigned int getWord(long pos) const; + unsigned int getDWord(long pos) const; + const char* getString(long pos=0) const; + void discardFirstBytes(int n); + friend ostream &operator<<(ostream &s, const bufferStore &m); + bool empty() const; + + // Writing utils + void init(); + void init(const unsigned char*buff, long len); + void addByte(unsigned char c); + void addWord(int a); + void addDWord(long a); + void addString(const char* s); + void addStringT(const char* s); + void addBuff(const bufferStore &s, long maxLen=-1); + +private: + void checkAllocd(long newLen); + + long len; + long lenAllocd; + long start; + unsigned char* buff; + + enum c { MIN_LEN = 300 }; +}; + +inline bool bufferStore::empty() const { + return (len-start) == 0; +} + +#endif diff --git a/lib/iowatch.cc b/lib/iowatch.cc new file mode 100644 index 0000000..15e8ecf --- /dev/null +++ b/lib/iowatch.cc @@ -0,0 +1,77 @@ +// +// PLP - An implementation of the PSION link protocol +// +// Copyright (C) 1999 Philip Proudman +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program 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 General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// e-mail philip.proudman@btinternet.com + +#include +#include +#include +#include +#include +#include + +#include "bool.h" +#include "iowatch.h" + +IOWatch::IOWatch() { + num = 0; + io = new int [MAX_IO]; +} + +IOWatch::~IOWatch() { + delete [] io; +} + +void IOWatch::addIO(int a) { + int pos; + for (pos = 0; pos < num && a < io[pos]; pos++); + for (int i = num; i > pos; i--) io[i] = io[i-1]; + io[pos] = a; + num++; +} + +void IOWatch::remIO(int a) { + int pos; + for (pos = 0; pos < num && a != io[pos]; pos++); + if (pos != num) { + num--; + for (int i = pos; i 0) { + fd_set iop; + FD_ZERO(&iop); + for (int i=0; i +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../defaults.h" +#include "bool.h" +#include "bufferstore.h" +#include "ppsocket.h" + +//********************************************************************** +// For unix we need a few definitions +//********************************************************************** + +#ifndef MAKEWORD +#define MAKEWORD(a, b) ((WORD)(((BYTE)(a)) | ((WORD)((BYTE)(b))) << 8)) +#endif +#ifndef SHORT +#define SHORT int +#endif + +//This constructor is useful when converting a socket +//to a derived class of socket +ppsocket::ppsocket(const ppsocket& another) +{ + m_Socket = another.m_Socket; + m_HostAddr = another.m_HostAddr; + m_PeerAddr = another.m_PeerAddr; + m_Bound = another.m_Bound; + m_Timeout = another.m_Timeout; + m_LastError = another.m_LastError; + + m_Timeout = INFINITE; +} + + +ppsocket::ppsocket() +{ + m_Socket = INVALID_SOCKET; + + memset(&m_HostAddr, 0, sizeof(m_HostAddr)); + memset(&m_PeerAddr, 0, sizeof(m_PeerAddr)); + + + ((struct sockaddr_in*) &m_HostAddr)->sin_family = AF_INET; + ((struct sockaddr_in*) &m_PeerAddr)->sin_family = AF_INET; + + m_Bound = false; + + m_Timeout = INFINITE; +} + + +ppsocket::~ppsocket() +{ + if (m_Socket != INVALID_SOCKET) + { + close(m_Socket); + } +} + + +bool ppsocket::startup(void) +{ +#ifdef WIN32 + WSADATA wd; + m_LastError = WSAStartup(MAKEWORD(1, 1), &wd); +#else + m_LastError = 0; +#endif + + return(m_LastError == 0 ? true : false); +} + +//pre : must be bound and peer info set +bool ppsocket::reconnect() +{ + printPeer(); + if (::connect(m_Socket, &m_PeerAddr, sizeof(m_PeerAddr)) != 0) + { + m_LastError = lastErrorCode(); + cout << "Reconnect failed : status : " << m_LastError << endl << flush; + return(false); + } + return(true); +} + + +void ppsocket::printPeer() +{ + char* pPeer = 0; + int port; + + pPeer = inet_ntoa(((struct sockaddr_in*) &m_PeerAddr)->sin_addr); + if (pPeer) + { + port = ntohs(((struct sockaddr_in*) &m_PeerAddr)->sin_port); + cout << "Peer : " << pPeer << " Port : " << port << endl; + } + else + { + cout << "Error getting Peer details\n"; + } +} + +bool ppsocket::connect(char* Peer, int PeerPort, char* Host, int HostPort) +{ + + //**************************************************** + //* If we aren't already bound set the host and bind * + //**************************************************** + + if (!bindSocket(Host, HostPort)) + { + if (m_LastError != 0) + { + return(false); + } + } + + //**************** + //* Set the peer * + //**************** + if (!setPeer(Peer, PeerPort)) + { + return(false); + } + + //*********** + //* Connect * + //*********** + if (::connect(m_Socket, &m_PeerAddr, sizeof(m_PeerAddr)) != 0) + { + m_LastError = lastErrorCode(); + return(false); + } + + return(true); +} + + + +bool ppsocket::listen(char* Host, int Port) +{ + //**************************************************** + //* If we aren't already bound set the host and bind * + //**************************************************** + + if (!bindSocket(Host, Port)) + { + if (m_LastError != 0) + { + return(false); + } + } + + //********************** + //* Listen on the port * + //********************** + + if (::listen(m_Socket, 5) != 0) + { + m_LastError = lastErrorCode(); + return(false); + } + + return(true); +} + + +ppsocket* ppsocket::accept(char* Peer, int MaxLen) +{ + unsigned int len; + ppsocket* accepted; + char* peer; + + //***************************************************** + //* Allocate a new object to hold the accepted socket * + //***************************************************** + + accepted = new ppsocket; + + if (!accepted) + { + m_LastError = lastErrorCode(); + return(NULL); + } + + //*********************** + //* Accept a connection * + //*********************** + + len = sizeof(struct sockaddr); + fcntl(m_Socket, F_SETFL, O_NONBLOCK); + accepted->m_Socket = ::accept(m_Socket, &accepted->m_PeerAddr, &len); + + if (accepted->m_Socket == INVALID_SOCKET) + { + m_LastError = lastErrorCode(); + delete accepted; + return (NULL); + } + + //**************************************************** + //* Got a connection so fill in the other attributes * + //**************************************************** + + accepted->m_HostAddr = m_HostAddr; + accepted->m_Bound = true; + + //**************************************************** + //* If required get the name of the connected client * + //**************************************************** + + if (Peer) + { + peer = inet_ntoa(((struct sockaddr_in*) &accepted->m_PeerAddr)->sin_addr); + if (peer) + { + strncpy(Peer, peer, MaxLen); + Peer[MaxLen] = '\0'; + } + } + else + { + strcpy(Peer, ""); + } + + return(accepted); +} + + +int ppsocket::printf(const char* Format, ...) +{ int i; +va_list ap; +char s[512]; + +va_start(ap, Format); +vsprintf(s, Format, ap); +va_end(ap); + +i = writeTimeout(s, strlen(s), 0); + +return(i); +} + +bool ppsocket::dataToGet() const { + fd_set io; + FD_ZERO(&io); + FD_SET(m_Socket, &io); + struct timeval t; + t.tv_usec = 0; + t.tv_sec = 0; + return (select(m_Socket+1, &io, NULL, NULL, &t) != 0) ? true : false; +} + +int ppsocket::getBufferStore(bufferStore &a, bool wait) { + /* Returns a 0 for for no message, 1 for message OK, and -1 for socket problem */ + if (!wait && !dataToGet()) return 0; + a.init(); + bool hadEscape = false; + do { + char data; + int j = readTimeout(&data, 1, 0); + if (j == SOCKET_ERROR || j == 0) { + return -1; + } + if (hadEscape) { + a.addByte(data); + hadEscape = false; + } + else { + if (data == '\\') + hadEscape = true; + else if (data == '\0') + break; + else + a.addByte(data); + } + } while (true); +#ifdef SOCKET_DIAGNOSTICS + cout << "ppsocket got " << a << endl; +#endif + return (a.getLen() == 0) ? 0 : 1; +} + +bool ppsocket::sendBufferStore(const bufferStore &a) { +#ifdef SOCKET_DIAGNOSTICS + cout << "ppsocket sending " << a << endl; +#endif + bufferStore s; + long l = a.getLen(); + for (long i = 0; i 0) + { + i = writeTimeout(s.getString(sent), tosend, 0); + + if (i == SOCKET_ERROR || i == 0) + return( false); + + sent += i; + tosend -= i; + + if (++retries > 5) + { + m_LastError = 0; + return(false); + } + } + } + return true; +} + +int ppsocket::readEx(char* Data, int cTerm, int MaxLen) +{ + int i, j; + + for (i = 0; i < MaxLen; i++) + { + j = readTimeout(Data + i, 1, 0); + + if (j == SOCKET_ERROR || j == 0) + { + Data[i] = '\0'; + return(i > 0 ? i : 0); + } + + if (Data[i] == cTerm) + break; + } + + return(i+1); +} + +bool ppsocket::puts(const char* Data) +{ + int tosend, sent, retries, i; + + tosend = strlen(Data); + sent = retries = 0; + + while (tosend > 0) + { + i = writeTimeout(Data + sent, tosend, 0); + + if (i == SOCKET_ERROR || i == 0) + return(sent > 0 ? true : false); + + sent += i; + tosend -= i; + + if (++retries > 5) + { + m_LastError = 0; + return(false); + } + } + + return(true); +} + + + +char ppsocket::sgetc(void) +{ + int i; + char c; + + i = readTimeout(&c, 1, 0); + if (i == SOCKET_ERROR || i == 0) + { + return(0); + } + return(c); +} + + +bool ppsocket::sputc(char c) +{ + int i; + + cout << hex << (int)c << endl; + + i = writeTimeout(&c, 1, 0); + + if (i == SOCKET_ERROR || i == 0) + { + return(false); + } + + return(true); +} + + +int ppsocket::read(void* Data, size_t Size, size_t NumObj) +{ + int i = readTimeout((char*) Data, Size*NumObj, 0); + + return(i); +} + + +int ppsocket::write(const void* Data, size_t Size, size_t NumObj) +{ + int i = writeTimeout((char*) Data, Size*NumObj, 0); + + return(i); +} + + +int ppsocket::recv(char* buf, int len, int flags) +{ + int i = ::recv(m_Socket, buf, len, flags); + + if (i < 0) + m_LastError = lastErrorCode(); + + return(i); +} + + +int ppsocket::send(const char* buf, int len, int flags) +{ + int i = ::send(m_Socket, buf, len, flags); + + if (i < 0) + m_LastError = lastErrorCode(); + + return(i); +} + + +int ppsocket::readTimeout(char* buf, int len, int flags) +{ + int i; + + //********************************************************* + //* If there is no timeout use the Berkeley recv function * + //********************************************************* + + if (m_Timeout == INFINITE) + { + i = ::recv(m_Socket, buf, len, flags); + + if (i == SOCKET_ERROR) + { + m_LastError = lastErrorCode(); + } + } + + //******************************************** + //* If there is a timeout use overlapped i/o * + //******************************************** + + else + { + i = SOCKET_ERROR; + } + + + return(i); +} + + +int ppsocket::writeTimeout(const char* buf, int len, int flags) +{ + int i; + // If there is no timeout use the Berkeley send function + + if (m_Timeout == INFINITE) + { + i = ::send(m_Socket, buf, len, flags); + + if (i == SOCKET_ERROR) + { + m_LastError = lastErrorCode(); + } + } + else + { + // If there is a timeout use overlapped i/o + i = SOCKET_ERROR; + } + + return(i); +} + +bool ppsocket::closeSocket(void) +{ + if (close(m_Socket) != 0) + { + m_LastError = lastErrorCode(); + return(false); + } + + m_Socket = INVALID_SOCKET; + + return(true); +} + + +bool ppsocket::bindSocket(char* Host, int Port) +{ + + // If we are already bound return FALSE but with no last error + + m_LastError = 0; + + if (m_Bound) + { + return(false); + } + + // If the socket hasn't been created create it now + + if (m_Socket == INVALID_SOCKET) + { + if (!createSocket()) + { + return(false); + } + } + + // If a host name was supplied then use it + if (!setHost(Host, Port)) + { + return(false); + } + + // Now bind the socket + if (::bind(m_Socket, &m_HostAddr, sizeof(m_HostAddr)) != 0) + { + m_LastError = lastErrorCode(); + return(false); + } + + m_Bound = true; + + return(true); +} + + +bool ppsocket::bindInRange(char* Host, int Low, int High, int Retries) +{ + int port, i; + + // If we are already bound return FALSE but with no last error + + m_LastError = 0; + + if (m_Bound) + { + return(false); + } + + // If the socket hasn't been created create it now + + if (m_Socket == INVALID_SOCKET) + { + if (!createSocket()) + { + return(false); + } + } + // If the number of retries is greater than the range then work through the + // range sequentially. + + if (Retries > High - Low) + { + for (port = Low; port <= High; port++) + { + if (!setHost(Host, port)) + return(false); + + if (::bind(m_Socket, &m_HostAddr, sizeof(m_HostAddr)) == 0) + break; + } + + if (port > High) + { + m_LastError = lastErrorCode(); + return(false); + } + } + + // Else select numbers within the range at random + + else + { + for (i = 0; i < Retries; i++) + { + port = Low + (rand() % (High - Low)); + + if (!setHost(Host, port)) + return(false); + + if (::bind(m_Socket, &m_HostAddr, sizeof(m_HostAddr)) == 0) + break; + } + + if (i >= Retries) + { + m_LastError = lastErrorCode(); + return(false); + } + } + + m_Bound = true; + + return(true); +} + +bool ppsocket::linger(bool LingerOn, int LingerTime) +{ + int i; + struct linger l; + + // If the socket hasn't been created create it now + + if (m_Socket == INVALID_SOCKET) + { + if (!createSocket()) + { + return(false); + } + } + // Set the lingering + + if (LingerOn) + { + l.l_onoff = 1; + l.l_linger = LingerTime; + } + else + { + l.l_onoff = 0; + l.l_linger = 0; + } + i = setsockopt(m_Socket, SOL_SOCKET, SO_LINGER, (const char*) &l, sizeof(l)); + + // Check for errors + + if (i != 0) + { + m_LastError = lastErrorCode(); + return(false); + } + + // Return indicating success + + return(true); +} + + +bool ppsocket::createSocket(void) +{ + // If the socket has already been created just return true + if (m_Socket != INVALID_SOCKET) + { + return(true); + } + + // Create the socket + m_Socket = ::socket(PF_INET, SOCK_STREAM, 0); + + if (m_Socket == INVALID_SOCKET) + { + m_LastError = lastErrorCode(); + return(false); + } + + // By default set no lingering + + linger(FALSE, 0); + + // Return indicating success + + return(true); +} + +bool ppsocket::setPeer(char* Peer, int Port) +{ + struct hostent* he; + + // If a peer name was supplied then use it + if (Peer) + { + he = gethostbyname(Peer); + if (!he) + { + unsigned long ipaddress = inet_addr(Peer); + if (ipaddress == INADDR_NONE) + { + m_LastError = lastErrorCode(); + return(false); + } + + he = gethostbyaddr((const char*) &ipaddress, 4, PF_INET); + if (!he) + { + m_LastError = lastErrorCode(); + return(false); + } + } + memcpy((void*) &((struct sockaddr_in*) &m_PeerAddr)->sin_addr, (void*) he->h_addr_list[0], 4); + } + + // If a port name was supplied use it + + if (Port > 0) + { + ((struct sockaddr_in*) &m_PeerAddr)->sin_port = htons((SHORT) Port); + } + + return(true); +} + + +bool ppsocket::getPeer(char* Peer, int MaxLen, int* Port) +{ + char* peer; + + if (Peer) + { + peer = inet_ntoa(((struct sockaddr_in*) &m_PeerAddr)->sin_addr); + + if (!peer) + { + m_LastError = lastErrorCode(); + return(false); + } + + strncpy(Peer, peer, MaxLen); + Peer[MaxLen] = '\0'; + } + + if (Port) + { + *Port = ntohs(((struct sockaddr_in*) &m_PeerAddr)->sin_port); + } + + return(false); +} + + +bool ppsocket::setHost(char* Host, int Port) +{ + struct hostent* he; + + // If a host name was supplied then use it + if (Host) + { + he = gethostbyname(Host); + + if (!he) + { + unsigned long ipaddress = inet_addr(Host); + if (ipaddress == INADDR_NONE) + { + m_LastError = lastErrorCode(); + return(false); + } + + he = gethostbyaddr((const char*) &ipaddress, 4, PF_INET); + + if (!he) + { + m_LastError = lastErrorCode(); + return(false); + } + } + + memcpy((void*) &((struct sockaddr_in*) &m_HostAddr)->sin_addr, (void*) he->h_addr_list[0], 4); + } + + + // If a port name was supplied use it + + if (Port > 0) + { + ((struct sockaddr_in*) &m_HostAddr)->sin_port = htons((SHORT) Port); + } + + return(true); +} + + +bool ppsocket::getHost(char* Host, int MaxLen, int* Port) +{ + char* host; + + if (Host) + { + host = inet_ntoa(((struct sockaddr_in*) &m_HostAddr)->sin_addr); + + if (!host) + { + m_LastError = lastErrorCode(); + return(false); + } + + strncpy(Host, host, MaxLen); + Host[MaxLen] = '\0'; + } + + if (Port) + { + *Port = ntohs(((struct sockaddr_in*) &m_HostAddr)->sin_port); + } + return(false); +} + +DWORD ppsocket::lastErrorCode() +{ + return errno; +} + +void ppsocket::setSocketInvalid() +{ + m_Socket = INVALID_SOCKET; +} diff --git a/lib/ppsocket.h b/lib/ppsocket.h new file mode 100644 index 0000000..b93ee25 --- /dev/null +++ b/lib/ppsocket.h @@ -0,0 +1,117 @@ +#if !defined(AFX_ppsocket_H__5611BC0C_3E39_11D1_8E4B_00805F2AB205__INCLUDED_) +#define AFX_ppsocket_H__5611BC0C_3E39_11D1_8E4B_00805F2AB205__INCLUDED_ + +#if _MSC_VER >= 1000 +#pragma once +#endif // _MSC_VER >= 1000 + +#include +#include +#include +#include + +#ifndef TRUE +#define TRUE -1 +#define FALSE 0 +#endif +#define DWORD unsigned int +#define SOCKET int + +#ifndef INADDR_NONE +#define INADDR_NONE (in_addr_t)-1 +#endif +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 +#define INFINITE 0 + +extern int errno; + +#include "bool.h" +class bufferStore; + +class ppsocket +{ + +public: + ppsocket(); + virtual ~ppsocket(); + + virtual bool startup(void); + + virtual bool connect(char* Peer, int PeerPort, char* Host = NULL, int HostPort = 0); + virtual bool reconnect(); + + virtual void printPeer(); + + virtual bool listen(char* Host, int Port); + + ppsocket* accept(char* Peer, int MaxLen); + + bool dataToGet() const; + int getBufferStore(bufferStore &a, bool wait = true); + bool sendBufferStore(const bufferStore &a); + + int printf(const char* Format, ...); + + int readEx(char* Data, int cTerm, int MaxLen); + bool puts(const char* Data); + + char sgetc(void); + bool sputc(char c); + + int read(void* Data, size_t Size, size_t NumObj); + virtual int write(const void* Data, size_t Size, size_t NumObj); + + int recv(char* buf, int len, int flags); + int send(const char* buf, int len, int flags); + + int readTimeout(char* buf, int len, int flags); + int writeTimeout(const char* buf, int len, int flags); + + inline void timeout(DWORD t) { m_Timeout = t; } + inline DWORD timeout(void) { return(m_Timeout); } + + bool closeSocket(void); + bool bindSocket(char* Host, int Port); + bool bindInRange(char* Host, int Low, int High, int Retries); + bool linger(bool LingerOn, int LingerTime = 0); + + virtual bool createSocket(void); + + bool setPeer(char* Peer, int Port); + bool getPeer(char* Peer, int MaxLen, int* Port); + bool setHost(char* Host, int Port); + bool getHost(char* Host, int MaxLen, int* Port); + + DWORD getLastError(void) { return(m_LastError); } + inline SOCKET socket(void) const { return(m_Socket); } + DWORD lastErrorCode(); + + //set the current socket to invalid + //useful when deleting if the socket has been + //copied to another and should not be closed + //when this instance is destructed + void setSocketInvalid(); + +protected: + ppsocket(const ppsocket&); + + struct sockaddr* getPeerAddrStruct() { return &m_PeerAddr; } + struct sockaddr* getHostAddrStruct() { return &m_HostAddr; } + void setHostAddrStruct(struct sockaddr* pHostStruct) { m_HostAddr = *pHostStruct; } + void setSocket(SOCKET& sock) { m_Socket = sock; } + void setBound() { m_Bound = true;} + void updateLastError() {m_LastError = lastErrorCode(); } + +private: + SOCKET m_Socket; + struct sockaddr m_HostAddr, m_PeerAddr; + bool m_Bound; +#ifdef WIN32 + OVERLAPPED m_ReadOverlapped, m_WriteOverlapped; +#endif + DWORD m_Timeout; + DWORD m_LastError; +}; + +#endif -- cgit v1.2.3