#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_ */