Files
2022-12-13 12:44:04 +01:00

275 lines
5.7 KiB
C++
Executable File

#if !defined (_SIMPLE_SERVER_HANDLER_H_)
#define _SIMPLE_SERVER_HANDLER_H_
#include "cdevEventHandler.h"
#include "cdevAddr.h"
#include "cdevSocketConnector.h"
#include "cdevReactor.h"
#include "ErrorReporter.h"
#include "SocketUtil.h"
#include "fifo.h"
#include "clipMagicNumber.h"
#include "cdevMessageBinary.h"
#include "cdevMessage.h"
#include "ClientInfo.h"
const int _CDEV_CONNECTION_RETRIES = 5;
const int MAX_SERVERS = 1024;
extern FifoQueue results [MAX_SERVERS];
extern int completionCodes[MAX_SERVERS];
class DumpAllHandler : public cdevEventHandler,
public SocketReader,
public SocketWriter
{
protected:
char hostName [MAXHOSTNAMELEN + 1];
FifoQueue queue;
cdevSocketConnector stream;
int serverQuitFlag;
cdevReactor & Reactor;
int index;
ClientInfo info;
public:
DumpAllHandler (char * Host, unsigned short Port, cdevReactor & LocalReactor, int Index)
: info(),
SocketReader(CLIP_MAGIC_NUMBER),
SocketWriter(CLIP_MAGIC_NUMBER),
index(Index),
Reactor(LocalReactor),
serverQuitFlag(0)
{
cdevInetAddr addr;
hostName[0] = 0;
addr.set (Port, Host);
if(open(addr)!=0)
{
outputError(CDEV_SEVERITY_ERROR,
"DumpAllHandler::connect",
"Failed to connect to %s on port %i",
Host,
Port);
completionCodes[index]=-1;
}
completionCodes[index] = 0;
cdevData tagMap;
int * tags;
char ** ctags;
int ntags;
char * binary = NULL;
size_t binaryLen = 0;
cdevData::readTagTable(tags, ctags, ntags);
tagMap.insert(1, tags, ntags);
tagMap.insert(2, ctags, ntags);
delete tags;
delete ctags;
cdevMessageBinary packet0(index, 0, 0, 0, 0, CDEV_SERVER_OP, 0, 0,
NULL, "set ClientInfo", &info.getClientData(),
NULL, &tagMap);
packet0.streamOut(&binary, &binaryLen);
packet0.detachData();
enqueue(binary, binaryLen);
cdevMessageBinary packet1(index, 1, 0, 0, 0, CDEV_SERVER_OP, 0, 0,
NULL, "get ServerInfo", NULL, NULL, &tagMap);
packet1.streamOut(&binary, &binaryLen);
packet1.detachData();
enqueue(binary, binaryLen);
cdevMessageBinary packet2(index, 2, 0, 0, 0, CDEV_SERVER_OP, 0, 0,
NULL, "get ClientInfo", NULL, NULL, &tagMap);
packet2.streamOut(&binary, &binaryLen);
packet2.detachData();
enqueue(binary, binaryLen);
}
~DumpAllHandler (void)
{
if(completionCodes[index]!=1) completionCodes[index]=-1;
if(stream.getHandle()>0 && serverQuitFlag==0)
{
writeGoodbye();
}
if(reactor) reactor->extractHandler(this);
handleClose();
}
int open (const cdevAddr &addr)
{
int result = 0;
int count = 0;
result = stream.connect (addr);
if (result != -1)
{
if((result = Reactor.registerHandler(this, READ_MASK|WRITE_MASK|EXCEPT_MASK))==-1)
{
handleClose();
}
}
return result;
}
char * getHostName ( void )
{
if(*hostName==0)
{
cdevInetAddr addr;
if(stream.getRemoteAddress (addr)==0)
{
const char * ptr=addr.getHostName();
if(ptr) strncpy (hostName, ptr, MAXHOSTNAMELEN+1);
}
}
return hostName;
}
char * getName (void) const
{
return "DumpAllHandler";
}
int getHandle (void) const
{
return stream.getHandle();
}
void enqueue (char * buf, size_t len)
{
queue.enqueue(buf, len);
setMask(WRITE_MASK|EXCEPT_MASK);
}
void undequeue (char * buf, size_t len)
{
queue.undequeue(buf, len);
}
int dequeue (char **buf, size_t *len)
{
return queue.dequeue(buf, len);
}
int empty (void)
{
return queue.empty();
}
int handleClose (void)
{
stream.close();
return 0;
}
int handleInput (void)
{
int retval = 0;
char * buf = NULL;
size_t len = 0;
int result = 1;
while(result>0)
{
result = read(&buf, (int *)&len);
switch(result)
{
case SHUTDOWN_CODE:
outputError(CDEV_SEVERITY_INFO, (char *)getName(),
"Connection to %s terminated by client", getHostName());
retval = -1;
break;
case -1:
outputError(CDEV_SEVERITY_WARN, (char *)getName(),
"Error reading from connection to client %s", getHostName());
retval = -1;
break;
case 0:
break;
default:
{
cdevMessage *message = new cdevMessage;
unsigned transIndex = 0;
unsigned clientID = 0;
if(message->streamIn(buf, len)==0 &&
(clientID=message->getClientID())==index &&
(transIndex=message->getTransIndex())>0 &&
transIndex<3)
{
results[index].enqueue((void *)message);
if(transIndex==2) completionCodes[index] = 1;
}
else delete message;
}
break;
}
}
return retval;
}
int handleOutput (void)
{
int retval = 0;
char * buf = NULL;
size_t len = 0;
if(!writing() && dequeue(&buf, &len)==0)
{
int full = 0;
while(!full)
{
if(!(full = writeEnqueue(buf, len)))
{
delete buf;
full = dequeue(&buf, &len);
}
else undequeue(buf, len);
}
if(writeContinue()<0) retval = -1;
}
else if(writing())
{
if(writeContinue()<0) retval = -1;
}
if(retval!=0)
{
outputError(CDEV_SEVERITY_WARN, (char *)getName(),
"Error transmitting to %s", getHostName());
}
if(empty() && !writing())
{
setMask(READ_MASK|EXCEPT_MASK);
}
return retval;
}
int handleExcept (void)
{
stream.close();
serverQuitFlag=1;
return -1;
}
};
#endif /* _SIMPLE_SERVER_HANDLER_H_ */