/* ** SOCKET LISTEN TOOL ** ** (c) COPRIGHT MIT 1995. ** Please first read the full copyright statement in the file COPYRIGH. ** ** Authors: ** HFN Henrik Frystyk Nielsen (frystyk@w3.org) ** ** History: ** Nov 24 95 First version */ #include "WWWLib.h" /* Global Library Include file */ #include "WWWTrans.h" #include "WWWInit.h" #include "WWWApp.h" #include "HTListen.h" /* Implemented here */ #ifndef W3C_VERSION #define W3C_VERSION "unspecified" #endif #define APP_NAME "W3CListenTool" #define APP_VERSION W3C_VERSION /* Default page for "-help" command line option */ #define HELP "http://www.w3.org/pub/WWW/Listen/User/CommandLine.html" #define DEFAULT_PORT 80 #define DEFAULT_FORMAT WWW_RAW #define DEFAULT_BACKLOG HT_BACKLOG #if defined(__svr4__) #define CATCH_SIG #endif typedef struct _ListenTool { HTRequest * request; SOCKET port; int backlog; /* Backlog for listen */ } ListenTool; /* ------------------------------------------------------------------------- */ /* Standard (non-error) Output ** --------------------------- */ PUBLIC int OutputData(const char * fmt, ...) { int ret; va_list pArgs; va_start(pArgs, fmt); ret = vfprintf(stdout, fmt, pArgs); va_end(pArgs); return ret; } /* Create a Listen Tool Object ** --------------------------- */ PRIVATE ListenTool * ListenTool_new (void) { ListenTool * me; if ((me = (ListenTool *) HT_CALLOC(1, sizeof(ListenTool))) == NULL) HT_OUTOFMEM("ListenTool_new"); me->request = HTRequest_new(); me->port = DEFAULT_PORT; me->backlog = DEFAULT_BACKLOG; HTRequest_setPreemptive(me->request, YES); HTRequest_setOutputFormat(me->request, DEFAULT_FORMAT); HTRequest_setOutputStream(me->request, HTFWriter_new(me->request, OUTPUT, YES)); return me; } /* Delete a Listen Tool Object ** --------------------------- */ PRIVATE BOOL ListenTool_delete (ListenTool * me) { if (me) { HTRequest_delete(me->request); HT_FREE(me); return YES; } return NO; } PRIVATE void Cleanup (ListenTool * me, int status) { ListenTool_delete(me); HTEventTerminate(); HTLibTerminate(); #ifdef VMS exit(status ? status : 1); #else exit(status ? status : 0); #endif } #ifdef CATCH_SIG #include /* SetSignal ** This function sets up signal handlers. This might not be necessary to ** call if the application has its own handlers. */ PRIVATE void SetSignal (void) { /* On some systems (SYSV) it is necessary to catch the SIGPIPE signal ** when attemting to connect to a remote host where you normally should ** get `connection refused' back */ if (signal(SIGPIPE, SIG_IGN) == SIG_ERR) { if (WWWTRACE) HTTrace("HTSignal.... Can't catch SIGPIPE\n"); } else { if (WWWTRACE) HTTrace("HTSignal.... Ignoring SIGPIPE\n"); } } #endif /* CATCH_SIG */ PRIVATE void VersionInfo (void) { OutputData("\n\nW3C Reference Software\n\n"); OutputData("\tW3C W3C Listen Tool (%s) version %s.\n", APP_NAME,APP_VERSION); OutputData("\tW3C Reference Library version %s.\n\n",HTLib_version()); OutputData("Please send feedback to \n"); } /* ------------------------------------------------------------------------- */ /* MAIN PROGRAM */ /* ------------------------------------------------------------------------- */ int main (int argc, char ** argv) { int arg; ListenTool * ms = ListenTool_new(); /* Set up the application's event loop. We use the example event loop that comes with the Library. */ HTEventInit(); /* Initiate W3C Reference Library */ HTLibInit(APP_NAME, APP_VERSION); HTMIMEInit(); /* Scan command Line for parameters */ for (arg=1; argport = (arg+1 < argc && *argv[arg+1] != '-') ? atoi(argv[++arg]) : DEFAULT_PORT; /* backlog for listen() */ } else if (!strcmp(argv[arg], "-backlog")) { ms->backlog = (arg+1 < argc && *argv[arg+1] != '-') ? atoi(argv[++arg]) : DEFAULT_BACKLOG; /* Print version and exit */ } else if (!strcmp(argv[arg], "-version")) { VersionInfo(); Cleanup(ms, 0); #ifdef WWWTRACE /* trace flags */ } else if (!strncmp(argv[arg], "-v", 2)) { HTSetTraceMessageMask(argv[arg]+2); #endif } else { if (WWWTRACE) HTTrace("Bad Argument (%s)\n",argv[arg]); } } else { if (WWWTRACE) HTTrace("Bad Argument (%s)\n",argv[arg]); } } #ifdef CATCH_SIG SetSignal(); #endif /* Set up a tool to listen on this port */ if (ms->port >= 0) { /* Create a Net object */ HTNet * net = HTNet_new(ms->request); /* This is the "accepted" Net object */ HTNet * accepted = NULL; /* Register TCP as the transport */ HTTransport_add("tcp", HT_TP_SINGLE, HTReader_new, NULL); /* Register the "noop" application layer protocol for reading */ HTProtocol_add("noop", "tcp", ms->port, YES, HTLoadSocket, NULL); /* Start listening on the socket */ if (net && HTDoListen(net, ms->port, INVSOC, ms->backlog) == HT_OK && HTDoAccept(net, &accepted) == HT_OK) { HTNet_newServer(ms->request, accepted, "noop"); } else { if (WWWTRACE) HTTrace("Can't listen on port %d\n",ms->port); Cleanup(ms, -1); } } Cleanup(ms, 0); return 0; }