00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033 #include <signal.h>
00034 #include <unistd.h>
00035
00036 #include <iostream>
00037 #include <fstream>
00038
00039 using std::cout ;
00040 using std::cerr ;
00041 using std::endl ;
00042 using std::ofstream ;
00043
00044 #include "config.h"
00045
00046 #include "ServerApp.h"
00047 #include "ServerExitConditions.h"
00048 #include "TheBESKeys.h"
00049 #include "SocketListener.h"
00050 #include "TcpSocket.h"
00051 #include "UnixSocket.h"
00052 #include "BESServerHandler.h"
00053 #include "BESException.h"
00054 #include "PPTException.h"
00055 #include "PPTServer.h"
00056 #include "PPTException.h"
00057 #include "SocketException.h"
00058 #include "BESMemoryManager.h"
00059 #include "BESDebug.h"
00060 #include "BESServerUtils.h"
00061
00062 #include "BESDefaultModule.h"
00063 #include "BESDefaultCommands.h"
00064
00065 ServerApp::ServerApp()
00066 : BESModuleApp(),
00067 _portVal( 0 ),
00068 _gotPort( false ),
00069 _unixSocket( "" ),
00070 _secure( false ),
00071 _mypid( 0 ),
00072 _ts( 0 ),
00073 _us( 0 ),
00074 _ps( 0 )
00075 {
00076 _mypid = getpid() ;
00077 }
00078
00079 ServerApp::~ServerApp()
00080 {
00081 }
00082
00083 void
00084 ServerApp::signalTerminate( int sig )
00085 {
00086 if( sig == SIGTERM )
00087 {
00088 BESApp::TheApplication()->terminate( sig ) ;
00089 exit( SERVER_EXIT_NORMAL_SHUTDOWN ) ;
00090 }
00091 }
00092
00093 void
00094 ServerApp::signalInterrupt( int sig )
00095 {
00096 if( sig == SIGINT )
00097 {
00098 BESApp::TheApplication()->terminate( sig ) ;
00099 exit( SERVER_EXIT_NORMAL_SHUTDOWN ) ;
00100 }
00101 }
00102
00103 void
00104 ServerApp::signalRestart( int sig )
00105 {
00106 if( sig == SIGUSR1 )
00107 {
00108 BESApp::TheApplication()->terminate( sig ) ;
00109 exit( SERVER_EXIT_RESTART ) ;
00110 }
00111 }
00112
00113 int
00114 ServerApp::initialize( int argc, char **argv )
00115 {
00116 int c = 0 ;
00117
00118
00119
00120 while( ( c = getopt( argc, argv, "hvsd:c:p:u:" ) ) != EOF )
00121 {
00122 switch( c )
00123 {
00124 case 'c':
00125 TheBESKeys::ConfigFile = optarg ;
00126 break ;
00127 case 'p':
00128 _portVal = atoi( optarg ) ;
00129 _gotPort = true ;
00130 break ;
00131 case 'u':
00132 _unixSocket = optarg ;
00133 break ;
00134 case 'd':
00135 {
00136 string dbgstrm = optarg ;
00137 if( dbgstrm[0] == '-' )
00138 {
00139 cout << "Debug filename or stream can not start "
00140 << "with a -" << endl << endl ;
00141 BESServerUtils::show_usage( BESApp::TheApplication()->appName() ) ;
00142 }
00143 if( dbgstrm == "cerr" )
00144 {
00145 BESDebug::Set_debugger( new BESDebug( &cerr ) ) ;
00146 }
00147 else
00148 {
00149 ostream *fstrm = new ofstream( dbgstrm.c_str() ) ;
00150 if( !(*fstrm) )
00151 {
00152 cerr << "Unable to open debug file" << endl ;
00153 BESServerUtils::show_usage( BESApp::TheApplication()->appName() ) ;
00154 }
00155 BESDebug::Set_debugger( new BESDebug( fstrm ) ) ;
00156 }
00157 BESDebug::Begin_debug() ;
00158 }
00159 break ;
00160 case 'v':
00161 BESServerUtils::show_version( BESApp::TheApplication()->appName() ) ;
00162 break ;
00163 case 's':
00164 _secure = true ;
00165 break ;
00166 case 'h':
00167 case '?':
00168 default:
00169 BESServerUtils::show_usage( BESApp::TheApplication()->appName() ) ;
00170 break ;
00171 }
00172 }
00173
00174 bool found = false ;
00175 string port_key = "BES.ServerPort" ;
00176 if( !_gotPort )
00177 {
00178 string sPort = TheBESKeys::TheKeys()->get_key( port_key, found ) ;
00179 if( found )
00180 {
00181 _portVal = atoi( sPort.c_str() ) ;
00182 if( _portVal != 0 )
00183 {
00184 _gotPort = true ;
00185 }
00186 }
00187 }
00188
00189 found = false ;
00190 string socket_key = "BES.ServerUnixSocket" ;
00191 if( _unixSocket == "" )
00192 {
00193 _unixSocket = TheBESKeys::TheKeys()->get_key( socket_key, found ) ;
00194 }
00195
00196 if( !_gotPort && _unixSocket == "" )
00197 {
00198 cout << endl << "Must specify either a tcp port"
00199 << " or a unix socket or both" << endl ;
00200 cout << "Please specify on the command line with"
00201 << " -p <port> -u <unix_socket> "
00202 << endl
00203 << "Or specify in the bes configuration file with "
00204 << port_key << " and/or " << socket_key
00205 << endl << endl ;
00206 BESServerUtils::show_usage( BESApp::TheApplication()->appName() ) ;
00207 }
00208
00209 found = false ;
00210 if( _secure == false )
00211 {
00212 string key = "BES.ServerSecure" ;
00213 string isSecure = TheBESKeys::TheKeys()->get_key( key, found ) ;
00214 if( isSecure == "Yes" || isSecure == "YES" || isSecure == "yes" )
00215 {
00216 _secure = true ;
00217 }
00218 }
00219
00220 BESDEBUG( "ServerApp: Registering signal SIGTERM ... " )
00221 if( signal( SIGTERM, signalTerminate ) == SIG_ERR )
00222 {
00223 BESDEBUG( "FAILED" << endl ) ;
00224 cerr << "FAILED: Can not register SIGTERM signal handler" << endl ;
00225 exit( SERVER_EXIT_FATAL_CAN_NOT_START ) ;
00226 }
00227 BESDEBUG( "OK" << endl ) ;
00228
00229 BESDEBUG( "ServerApp: Registering signal SIGINT ... " )
00230 if( signal( SIGINT, signalInterrupt ) == SIG_ERR )
00231 {
00232 BESDEBUG( "FAILED" << endl ) ;
00233 cerr << "FAILED: Can not register SIGINT signal handler" << endl ;
00234 exit( SERVER_EXIT_FATAL_CAN_NOT_START ) ;
00235 }
00236 BESDEBUG( "OK" << endl ) ;
00237
00238 BESDEBUG( "ServerApp: Registering signal SIGUSR1 ... " )
00239 if( signal( SIGUSR1, signalRestart ) == SIG_ERR )
00240 {
00241 BESDEBUG( "FAILED" << endl ) ;
00242 cerr << "FAILED: Can not register SIGUSR1 signal handler" << endl ;
00243 exit( SERVER_EXIT_FATAL_CAN_NOT_START ) ;
00244 }
00245 BESDEBUG( "OK" << endl ) ;
00246
00247 BESDEBUG( "ServerApp: initializing default module ... " )
00248 BESDefaultModule::initialize( argc, argv ) ;
00249 BESDEBUG( "OK" << endl ) ;
00250
00251 BESDEBUG( "ServerApp: initializing default commands ... " )
00252 BESDefaultCommands::initialize( argc, argv ) ;
00253 BESDEBUG( "OK" << endl ) ;
00254
00255 int ret = BESModuleApp::initialize( argc, argv ) ;
00256
00257 BESDEBUG( "ServerApp: initialized settings:" << *this ) ;
00258
00259 return ret ;
00260 }
00261
00262 int
00263 ServerApp::run()
00264 {
00265 try
00266 {
00267 BESDEBUG( "ServerApp: initializing memory pool ... " )
00268 BESMemoryManager::initialize_memory_pool() ;
00269 BESDEBUG( "OK" << endl ) ;
00270
00271 SocketListener listener ;
00272
00273 if( _portVal )
00274 {
00275 _ts = new TcpSocket( _portVal ) ;
00276 listener.listen( _ts ) ;
00277 BESDEBUG( "ServerApp: listening on port (" << _portVal << ")" << endl )
00278 }
00279
00280 if( !_unixSocket.empty() )
00281 {
00282 _us = new UnixSocket( _unixSocket ) ;
00283 listener.listen( _us ) ;
00284 BESDEBUG( "ServerApp: listening on unix socket (" << _unixSocket << ")" << endl )
00285 }
00286
00287 BESServerHandler handler ;
00288
00289 _ps = new PPTServer( &handler, &listener, _secure ) ;
00290 _ps->initConnection() ;
00291 }
00292 catch( SocketException &se )
00293 {
00294 cerr << "caught SocketException" << endl ;
00295 cerr << se.getMessage() << endl ;
00296 return 1 ;
00297 }
00298 catch( PPTException &pe )
00299 {
00300 cerr << "caught PPTException" << endl ;
00301 cerr << pe.getMessage() << endl ;
00302 return 1 ;
00303 }
00304 catch( ... )
00305 {
00306 cerr << "caught unknown exception" << endl ;
00307 return 1 ;
00308 }
00309
00310 return 0 ;
00311 }
00312
00313 int
00314 ServerApp::terminate( int sig )
00315 {
00316 pid_t apppid = getpid() ;
00317 if( apppid == _mypid )
00318 {
00319 if( _ps )
00320 {
00321 _ps->closeConnection() ;
00322 delete _ps ;
00323 }
00324 if( _ts )
00325 {
00326 _ts->close() ;
00327 delete _ts ;
00328 }
00329 if( _us )
00330 {
00331 _us->close() ;
00332 delete _us ;
00333 }
00334
00335 BESDEBUG( "ServerApp: terminating default module ... " )
00336 BESDefaultModule::terminate( ) ;
00337 BESDEBUG( "OK" << endl ) ;
00338
00339 BESDEBUG( "ServerApp: terminating default commands ... " )
00340 BESDefaultCommands::terminate( ) ;
00341 BESDEBUG( "OK" << endl ) ;
00342
00343 BESModuleApp::terminate( sig ) ;
00344 }
00345 return sig ;
00346 }
00347
00354 void
00355 ServerApp::dump( ostream &strm ) const
00356 {
00357 strm << BESIndent::LMarg << "ServerApp::dump - ("
00358 << (void *)this << ")" << endl ;
00359 BESIndent::Indent() ;
00360 strm << BESIndent::LMarg << "got port? " << _gotPort << endl ;
00361 strm << BESIndent::LMarg << "port: " << _portVal << endl ;
00362 strm << BESIndent::LMarg << "unix socket: " << _unixSocket << endl ;
00363 strm << BESIndent::LMarg << "is secure? " << _secure << endl ;
00364 strm << BESIndent::LMarg << "pid: " << _mypid << endl ;
00365 if( _ts )
00366 {
00367 strm << BESIndent::LMarg << "tcp socket:" << endl ;
00368 BESIndent::Indent() ;
00369 _ts->dump( strm ) ;
00370 BESIndent::UnIndent() ;
00371 }
00372 else
00373 {
00374 strm << BESIndent::LMarg << "tcp socket: null" << endl ;
00375 }
00376 if( _us )
00377 {
00378 strm << BESIndent::LMarg << "unix socket:" << endl ;
00379 BESIndent::Indent() ;
00380 _us->dump( strm ) ;
00381 BESIndent::UnIndent() ;
00382 }
00383 else
00384 {
00385 strm << BESIndent::LMarg << "unix socket: null" << endl ;
00386 }
00387 if( _ps )
00388 {
00389 strm << BESIndent::LMarg << "ppt server:" << endl ;
00390 BESIndent::Indent() ;
00391 _ps->dump( strm ) ;
00392 BESIndent::UnIndent() ;
00393 }
00394 else
00395 {
00396 strm << BESIndent::LMarg << "ppt server: null" << endl ;
00397 }
00398 BESModuleApp::dump( strm ) ;
00399 BESIndent::UnIndent() ;
00400 }
00401
00402 int
00403 main( int argc, char **argv )
00404 {
00405 try
00406 {
00407 ServerApp app ;
00408 return app.main( argc, argv ) ;
00409 }
00410 catch( BESException &e )
00411 {
00412 cerr << "Caught unhandled exception: " << endl ;
00413 cerr << e.get_message() << endl ;
00414 return 1 ;
00415 }
00416 catch( ... )
00417 {
00418 cerr << "Caught unhandled, unknown exception" << endl ;
00419 return 1 ;
00420 }
00421 return 0 ;
00422 }
00423