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 #include <grp.h>
00036 #include <pwd.h>
00037
00038 #include <iostream>
00039 #include <fstream>
00040
00041 using std::cout ;
00042 using std::cerr ;
00043 using std::endl ;
00044 using std::ios ;
00045 using std::ofstream ;
00046
00047 #include "config.h"
00048
00049 #include "ServerApp.h"
00050 #include "ServerExitConditions.h"
00051 #include "TheBESKeys.h"
00052 #include "SocketListener.h"
00053 #include "TcpSocket.h"
00054 #include "UnixSocket.h"
00055 #include "BESServerHandler.h"
00056 #include "BESException.h"
00057 #include "PPTException.h"
00058 #include "PPTServer.h"
00059 #include "PPTException.h"
00060 #include "SocketException.h"
00061 #include "BESMemoryManager.h"
00062 #include "BESDebug.h"
00063 #include "BESServerUtils.h"
00064
00065 #include "BESDefaultModule.h"
00066 #include "BESDefaultCommands.h"
00067
00068 ServerApp::ServerApp()
00069 : BESModuleApp(),
00070 _portVal( 0 ),
00071 _gotPort( false ),
00072 _unixSocket( "" ),
00073 _secure( false ),
00074 _mypid( 0 ),
00075 _ts( 0 ),
00076 _us( 0 ),
00077 _ps( 0 )
00078 {
00079 _mypid = getpid() ;
00080 }
00081
00082 ServerApp::~ServerApp()
00083 {
00084 }
00085
00086 void
00087 ServerApp::signalTerminate( int sig )
00088 {
00089 if( sig == SIGTERM )
00090 {
00091 BESApp::TheApplication()->terminate( sig ) ;
00092 exit( SERVER_EXIT_NORMAL_SHUTDOWN ) ;
00093 }
00094 }
00095
00096 void
00097 ServerApp::signalInterrupt( int sig )
00098 {
00099 if( sig == SIGINT )
00100 {
00101 BESApp::TheApplication()->terminate( sig ) ;
00102 exit( SERVER_EXIT_NORMAL_SHUTDOWN ) ;
00103 }
00104 }
00105
00106 void
00107 ServerApp::signalRestart( int sig )
00108 {
00109 if( sig == SIGUSR1 )
00110 {
00111 BESApp::TheApplication()->terminate( sig ) ;
00112 exit( SERVER_EXIT_RESTART ) ;
00113 }
00114 }
00115
00116 void
00117 ServerApp::set_group_id()
00118 {
00119 #if !defined(OS2) && !defined(TPF)
00120
00121
00122
00123
00124
00125 BESDEBUG( "server", "ServerApp: Setting group id ... " )
00126 bool found = false ;
00127 string key = "BES.Group" ;
00128 string group_str = TheBESKeys::TheKeys()->get_key( key, found ) ;
00129 if( !found || group_str.empty() )
00130 {
00131 BESDEBUG( "server", "FAILED" << endl ) ;
00132 cerr << "FAILED: Group not specified in BES configuration file"
00133 << endl ;
00134 exit( SERVER_EXIT_FATAL_CAN_NOT_START ) ;
00135 }
00136 BESDEBUG( "server", "to " << group_str << " ... " )
00137
00138 gid_t new_gid = 0 ;
00139 if( group_str[0] == '#' )
00140 {
00141
00142 const char *group_c = group_str.c_str() ;
00143 group_c++ ;
00144 new_gid = atoi( group_c ) ;
00145 }
00146 else
00147 {
00148
00149 struct group *ent ;
00150 ent = getgrnam( group_str.c_str() ) ;
00151 if( !ent )
00152 {
00153 BESDEBUG( "server", "FAILED" << endl ) ;
00154 cerr << "FAILED: Group " << group_str << " does not exist" << endl ;
00155 exit( SERVER_EXIT_FATAL_CAN_NOT_START ) ;
00156 }
00157 new_gid = ent->gr_gid ;
00158 }
00159
00160 if( new_gid < 1 )
00161 {
00162 BESDEBUG( "server", "FAILED" << endl ) ;
00163 cerr << "FAILED: Group id " << new_gid
00164 << " not a valid group id for BES" << endl ;
00165 exit( SERVER_EXIT_FATAL_CAN_NOT_START ) ;
00166 }
00167
00168 BESDEBUG( "server", "to id " << new_gid << " ... " )
00169 if( setgid( new_gid ) == -1 )
00170 {
00171 BESDEBUG( "server", "FAILED" << endl ) ;
00172 cerr << "FAILED: unable to set the group id to " << new_gid << endl ;
00173 exit( SERVER_EXIT_FATAL_CAN_NOT_START ) ;
00174 }
00175
00176 BESDEBUG( "server", "OK" << endl ) ;
00177 #else
00178 BESDEBUG( "server", "ServerApp: Groups not supported in this OS" )
00179 #endif
00180 }
00181
00182 void
00183 ServerApp::set_user_id()
00184 {
00185 BESDEBUG( "server", "ServerApp: Setting user id ... " )
00186
00187
00188
00189
00190
00191 bool found = false ;
00192 string key = "BES.User" ;
00193 string user_str = TheBESKeys::TheKeys()->get_key( key, found ) ;
00194 if( !found || user_str.empty() )
00195 {
00196 BESDEBUG( "server", "FAILED" << endl ) ;
00197 cerr << "FAILED: User not specified in BES configuration file"
00198 << endl ;
00199 exit( SERVER_EXIT_FATAL_CAN_NOT_START ) ;
00200 }
00201 BESDEBUG( "server", "to " << user_str << " ... " )
00202
00203 uid_t new_id = 0 ;
00204 if( user_str[0] == '#' )
00205 {
00206 const char *user_str_c = user_str.c_str() ;
00207 user_str_c++ ;
00208 new_id = atoi( user_str_c ) ;
00209 }
00210 else
00211 {
00212 struct passwd *ent ;
00213 ent = getpwnam( user_str.c_str() ) ;
00214 if( !ent )
00215 {
00216 BESDEBUG( "server", "FAILED" << endl ) ;
00217 cerr << "FAILED: Bad user name specified: "
00218 << user_str << endl ;
00219 exit( SERVER_EXIT_FATAL_CAN_NOT_START ) ;
00220 }
00221 new_id = ent->pw_uid ;
00222 }
00223
00224
00225 if( !new_id )
00226 {
00227 BESDEBUG( "server", "FAILED" << endl ) ;
00228 cerr << "FAILED: BES can not run as root" << endl ;
00229 exit( SERVER_EXIT_FATAL_CAN_NOT_START ) ;
00230 }
00231
00232 BESDEBUG( "server", "to " << new_id << " ... " )
00233 if( setuid( new_id ) == -1 )
00234 {
00235 BESDEBUG( "server", "FAILED" << endl ) ;
00236 cerr << "FAILED: Unable to set user id to "
00237 << new_id << endl ;
00238 exit( SERVER_EXIT_FATAL_CAN_NOT_START ) ;
00239 }
00240 }
00241
00242 int
00243 ServerApp::initialize( int argc, char **argv )
00244 {
00245
00246 uid_t curr_euid = geteuid() ;
00247 if( curr_euid )
00248 {
00249 cerr << "FAILED: Must be root to run BES" << endl ;
00250 exit( SERVER_EXIT_FATAL_CAN_NOT_START ) ;
00251 }
00252
00253 int c = 0 ;
00254 bool needhelp = false ;
00255 string dashi ;
00256 string dashc ;
00257
00258
00259
00260 while( ( c = getopt( argc, argv, "hvsd:c:p:u:i:r:" ) ) != EOF )
00261 {
00262 switch( c )
00263 {
00264 case 'i':
00265 dashi = optarg ;
00266 break ;
00267 case 'c':
00268 dashc = optarg ;
00269 break ;
00270 case 'r':
00271 break ;
00272 case 'p':
00273 _portVal = atoi( optarg ) ;
00274 _gotPort = true ;
00275 break ;
00276 case 'u':
00277 _unixSocket = optarg ;
00278 break ;
00279 case 'd':
00280 BESDebug::SetUp( optarg ) ;
00281 break ;
00282 case 'v':
00283 BESServerUtils::show_version( BESApp::TheApplication()->appName() ) ;
00284 break ;
00285 case 's':
00286 _secure = true ;
00287 break ;
00288 case 'h':
00289 case '?':
00290 default:
00291 needhelp = true ;
00292 break ;
00293 }
00294 }
00295
00296
00297
00298 if( !dashc.empty() )
00299 {
00300 TheBESKeys::ConfigFile = dashc ;
00301 }
00302
00303
00304
00305
00306 if( dashc.empty() && !dashi.empty() )
00307 {
00308 if( dashi[dashi.length()-1] != '/' )
00309 {
00310 dashi += '/' ;
00311 }
00312 string conf_file = dashi + "etc/bes/bes.conf" ;
00313 TheBESKeys::ConfigFile = conf_file ;
00314 }
00315
00316 bool found = false ;
00317 string port_key = "BES.ServerPort" ;
00318 if( !_gotPort )
00319 {
00320 string sPort = TheBESKeys::TheKeys()->get_key( port_key, found ) ;
00321 if( found )
00322 {
00323 _portVal = atoi( sPort.c_str() ) ;
00324 if( _portVal != 0 )
00325 {
00326 _gotPort = true ;
00327 }
00328 }
00329 }
00330
00331 found = false ;
00332 string socket_key = "BES.ServerUnixSocket" ;
00333 if( _unixSocket == "" )
00334 {
00335 _unixSocket = TheBESKeys::TheKeys()->get_key( socket_key, found ) ;
00336 }
00337
00338 if( !_gotPort && _unixSocket == "" )
00339 {
00340 cout << endl << "Must specify either a tcp port"
00341 << " or a unix socket or both" << endl ;
00342 cout << "Please specify on the command line with"
00343 << " -p <port> -u <unix_socket> "
00344 << endl
00345 << "Or specify in the bes configuration file with "
00346 << port_key << " and/or " << socket_key
00347 << endl << endl ;
00348 BESServerUtils::show_usage( BESApp::TheApplication()->appName() ) ;
00349 }
00350
00351 found = false ;
00352 if( _secure == false )
00353 {
00354 string key = "BES.ServerSecure" ;
00355 string isSecure = TheBESKeys::TheKeys()->get_key( key, found ) ;
00356 if( isSecure == "Yes" || isSecure == "YES" || isSecure == "yes" )
00357 {
00358 _secure = true ;
00359 }
00360 }
00361
00362 BESDEBUG( "server", "ServerApp: Registering signal SIGTERM ... " )
00363 if( signal( SIGTERM, signalTerminate ) == SIG_ERR )
00364 {
00365 BESDEBUG( "server", "FAILED" << endl ) ;
00366 cerr << "FAILED: Can not register SIGTERM signal handler" << endl ;
00367 exit( SERVER_EXIT_FATAL_CAN_NOT_START ) ;
00368 }
00369 BESDEBUG( "server", "OK" << endl ) ;
00370
00371 BESDEBUG( "server", "ServerApp: Registering signal SIGINT ... " )
00372 if( signal( SIGINT, signalInterrupt ) == SIG_ERR )
00373 {
00374 BESDEBUG( "server", "FAILED" << endl ) ;
00375 cerr << "FAILED: Can not register SIGINT signal handler" << endl ;
00376 exit( SERVER_EXIT_FATAL_CAN_NOT_START ) ;
00377 }
00378 BESDEBUG( "server", "OK" << endl ) ;
00379
00380 BESDEBUG( "server", "ServerApp: Registering signal SIGUSR1 ... " )
00381 if( signal( SIGUSR1, signalRestart ) == SIG_ERR )
00382 {
00383 BESDEBUG( "server", "FAILED" << endl ) ;
00384 cerr << "FAILED: Can not register SIGUSR1 signal handler" << endl ;
00385 exit( SERVER_EXIT_FATAL_CAN_NOT_START ) ;
00386 }
00387 BESDEBUG( "server", "OK" << endl ) ;
00388
00389 BESDEBUG( "server", "ServerApp: initializing default module ... " )
00390 BESDefaultModule::initialize( argc, argv ) ;
00391 BESDEBUG( "server", "OK" << endl ) ;
00392
00393 BESDEBUG( "server", "ServerApp: initializing default commands ... " )
00394 BESDefaultCommands::initialize( argc, argv ) ;
00395 BESDEBUG( "server", "OK" << endl ) ;
00396
00397 int ret = BESModuleApp::initialize( argc, argv ) ;
00398
00399 BESDEBUG( "server", "ServerApp: initialized settings:" << *this ) ;
00400
00401 if( needhelp )
00402 {
00403 BESServerUtils::show_usage( BESApp::TheApplication()->appName() ) ;
00404 }
00405
00406
00407
00408
00409 set_group_id() ;
00410 set_user_id() ;
00411
00412 return ret ;
00413 }
00414
00415 int
00416 ServerApp::run()
00417 {
00418 try
00419 {
00420 BESDEBUG( "server", "ServerApp: initializing memory pool ... " )
00421 BESMemoryManager::initialize_memory_pool() ;
00422 BESDEBUG( "server", "OK" << endl ) ;
00423
00424 SocketListener listener ;
00425
00426 if( _portVal )
00427 {
00428 _ts = new TcpSocket( _portVal ) ;
00429 listener.listen( _ts ) ;
00430 BESDEBUG( "server", "ServerApp: listening on port (" << _portVal << ")" << endl )
00431 }
00432
00433 if( !_unixSocket.empty() )
00434 {
00435 _us = new UnixSocket( _unixSocket ) ;
00436 listener.listen( _us ) ;
00437 BESDEBUG( "server", "ServerApp: listening on unix socket (" << _unixSocket << ")" << endl )
00438 }
00439
00440 BESServerHandler handler ;
00441
00442 _ps = new PPTServer( &handler, &listener, _secure ) ;
00443 _ps->initConnection() ;
00444 }
00445 catch( SocketException &se )
00446 {
00447 cerr << "caught SocketException" << endl ;
00448 cerr << se.getMessage() << endl ;
00449 return 1 ;
00450 }
00451 catch( PPTException &pe )
00452 {
00453 cerr << "caught PPTException" << endl ;
00454 cerr << pe.getMessage() << endl ;
00455 return 1 ;
00456 }
00457 catch( ... )
00458 {
00459 cerr << "caught unknown exception" << endl ;
00460 return 1 ;
00461 }
00462
00463 return 0 ;
00464 }
00465
00466 int
00467 ServerApp::terminate( int sig )
00468 {
00469 pid_t apppid = getpid() ;
00470 if( apppid == _mypid )
00471 {
00472 if( _ps )
00473 {
00474 _ps->closeConnection() ;
00475 delete _ps ;
00476 }
00477 if( _ts )
00478 {
00479 _ts->close() ;
00480 delete _ts ;
00481 }
00482 if( _us )
00483 {
00484 _us->close() ;
00485 delete _us ;
00486 }
00487
00488 BESDEBUG( "server", "ServerApp: terminating default module ... " )
00489 BESDefaultModule::terminate( ) ;
00490 BESDEBUG( "server", "OK" << endl ) ;
00491
00492 BESDEBUG( "server", "ServerApp: terminating default commands ... " )
00493 BESDefaultCommands::terminate( ) ;
00494 BESDEBUG( "server", "OK" << endl ) ;
00495
00496 BESModuleApp::terminate( sig ) ;
00497 }
00498 return sig ;
00499 }
00500
00507 void
00508 ServerApp::dump( ostream &strm ) const
00509 {
00510 strm << BESIndent::LMarg << "ServerApp::dump - ("
00511 << (void *)this << ")" << endl ;
00512 BESIndent::Indent() ;
00513 strm << BESIndent::LMarg << "got port? " << _gotPort << endl ;
00514 strm << BESIndent::LMarg << "port: " << _portVal << endl ;
00515 strm << BESIndent::LMarg << "unix socket: " << _unixSocket << endl ;
00516 strm << BESIndent::LMarg << "is secure? " << _secure << endl ;
00517 strm << BESIndent::LMarg << "pid: " << _mypid << endl ;
00518 if( _ts )
00519 {
00520 strm << BESIndent::LMarg << "tcp socket:" << endl ;
00521 BESIndent::Indent() ;
00522 _ts->dump( strm ) ;
00523 BESIndent::UnIndent() ;
00524 }
00525 else
00526 {
00527 strm << BESIndent::LMarg << "tcp socket: null" << endl ;
00528 }
00529 if( _us )
00530 {
00531 strm << BESIndent::LMarg << "unix socket:" << endl ;
00532 BESIndent::Indent() ;
00533 _us->dump( strm ) ;
00534 BESIndent::UnIndent() ;
00535 }
00536 else
00537 {
00538 strm << BESIndent::LMarg << "unix socket: null" << endl ;
00539 }
00540 if( _ps )
00541 {
00542 strm << BESIndent::LMarg << "ppt server:" << endl ;
00543 BESIndent::Indent() ;
00544 _ps->dump( strm ) ;
00545 BESIndent::UnIndent() ;
00546 }
00547 else
00548 {
00549 strm << BESIndent::LMarg << "ppt server: null" << endl ;
00550 }
00551 BESModuleApp::dump( strm ) ;
00552 BESIndent::UnIndent() ;
00553 }
00554
00555 int
00556 main( int argc, char **argv )
00557 {
00558 try
00559 {
00560 ServerApp app ;
00561 return app.main( argc, argv ) ;
00562 }
00563 catch( BESException &e )
00564 {
00565 cerr << "Caught unhandled exception: " << endl ;
00566 cerr << e.get_message() << endl ;
00567 return 1 ;
00568 }
00569 catch( ... )
00570 {
00571 cerr << "Caught unhandled, unknown exception" << endl ;
00572 return 1 ;
00573 }
00574 return 0 ;
00575 }
00576