/* * This file is part of rasdaman community. * * Rasdaman community 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 3 of the License, or * (at your option) any later version. * * Rasdaman community 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 rasdaman community. If not, see . * * Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009 Peter Baumann / rasdaman GmbH. * * For more information please see * or contact Peter Baumann via . */ #include "raslib/error.hh" #include "raslib/rminit.hh" #include "httpserver.h" #include "defs.h" #include "protos.h" #include "types.h" #include "server.h" #ifdef PURIFY #include #endif /*--- Global Data Section: ------------------------------------------------*/ /* All we need to remember or may want to know is in this structure */ struct ServerBase Server; struct Logging *LogBase = &Server.Log; /****** main/main ************************************************************ * * NAME * main -- the main function of this program. * * SYNOPSIS * void main( int argc, char *argv[] ); * * FUNCTION * "main" calls "Initialize()" for setting up the program, activates * the main socket with the "listen()" system call, and then waits * forever for a client to connect. If a client connection request is * received, a child process will be spawned and the child will handle * the request while the parent process will wait again for new * connection requests. * * INPUTS * argc - The number of arguments given on the command line. * argv[] - An array of strings, containing the arguments given on the * command line. * * NOTES * The program can only be stopped by sending it the corresponding * signals ("SIGQUIT", "SIGTERM"). * * BUGS * None known. Not here. * * SEE ALSO * Initialize(), Accept(), AddChild(), InitChild(), HandleRequest(). * ****************************************************************************** * */ extern int init_httpserver( int argc, char *argv[] ) { pid_t ChildPId; /* -> Server.ChildInfo */ RMInit::logOut << "Initialising parameters for HTTP server... " << endl; RMInit::logOut.flush(); Initialize( argc, argv, &Server ); RMInit::logOut << "Initialising server socket for HTTP server... " << endl; RMInit::logOut.flush(); listen( Server.SockFD, 5 ); RMInit::logOut << "Waiting for client calls... " << endl; RMInit::logOut.flush(); #ifdef PURIFY purify_printf( "Server Startup Finnished." ); purify_new_leaks(); #endif /* // this is a quick hack for testing */ /* return 0; */ for(;;) { Accept( Server.SockFD, &Server.Client ); strcpy( Server.Client.Host.IPAddrString, inet_ntoa( Server.Client.Socket.sin_addr ) ); if( Server.Client.Host.IPAddrString == NULL ) strcpy( Server.Client.Host.IPAddrString, "0.0.0.0" ); Server.Client.Host.IPAddress = inet_addr( Server.Client.Host.IPAddrString ); Server.Client.Comm.ConnStatus = CONN_UNDEFINED; InitHTTPMsg( &Server.Client.Response ); InitReqInfo( &Server.Client.Request ); LogMsg( LG_SERVER, INFO, "INFO: ====== Connection from %s accepted...", Server.Client.Host.IPAddrString ); HandleRequest( &Server.Client ); LogMsg( LG_SERVER, INFO, "INFO: ====== EOT. Disconnecting." ); close( Server.Client.SockFD ); } // otherwise Exit(OK) should have been called return -1; } /****** main/Exit ************************************************************ * * NAME * Exit -- Cleanup when exiting. * * SYNOPSIS * void Exit( int RC ); * * FUNCTION * This function closes all open socket descriptors and the logging * subsystem. If the calling process is the parent process, it also * deletes the file where the process Id is stored. * After that, it calls the "exit()" function with the return code * "RC". * * INPUTS * RC - return or exit code, indicating the error condition of the * program. * * NOTES * This function is called by the signal handlers for "SIGQUIT", * "SIGTERM", "SIGINT" and "SIGHUP" and the main() function. * In future versions, "SIGHUP" should be changed to reread the * configuration file instead of calling Exit(). * * BUGS * The global variable "SubServer[]" should not be used. * * SEE ALSO * Exit(). * ****************************************************************************** * */ int Exit( int RC ) { int i; // for( i = 0; i < NUM_SUBSERVER; i++ ) // close( SubServer[i].SockFD ); close( Server.SockFD ); if( getpid() == Server.PId ) /* Is this the parent process? */ { unlink( Server.PidFile ); LogMsg( LG_SERVER, DEBUG, "DEBUG: Main process exiting (RC=%d)...", RC ); LogMsg( LG_SERVER, INFO, "INFO: ========= %s terminated. ============", DAEMONNAME ); } else { LogMsg( LG_SERVER, DEBUG, "DEBUG: Exiting (RC=%d)...", RC ); } CloseLog( &Server.Log ); free(Server.Directory); if(RC != OK) throw r_Error( r_Error::r_Error_General ); return RC; }