diff --git a/relay/Makefile b/relay/Makefile index 938c3c5f4..6e28ef682 100644 --- a/relay/Makefile +++ b/relay/Makefile @@ -15,7 +15,8 @@ # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -CC = g++ +CXX = g++-4.1 +CC=$(CXX) SRC = xwrelay.cpp \ cref.cpp \ ctrl.cpp \ @@ -26,8 +27,10 @@ SRC = xwrelay.cpp \ crefmgr.cpp \ permid.cpp \ +# STATIC ?= -static + OBJ = $(patsubst %.cpp,%.o,$(SRC)) -LDFLAGS += -pthread -g -lmcheck +LDFLAGS += -pthread -g -lmcheck $(STATIC) CPPFLAGS += -DSPAWN_SELF -g -Wall -DSVN_REV=\"$(shell svnversion -n .)\" # turn on semaphore debugging # CPPFLAGS += -DDEBUG_LOCKS @@ -47,3 +50,6 @@ tarball: ../relay/*.{cpp,h} \ ../relay/Makefile \ ../relay/xwrelay.conf + +help: + @echo $(MAKE) [STATIC=\"-static\"] \ No newline at end of file diff --git a/relay/ctrl.cpp b/relay/ctrl.cpp index b285d414e..55073560d 100644 --- a/relay/ctrl.cpp +++ b/relay/ctrl.cpp @@ -52,7 +52,7 @@ extern pthread_rwlock_t gCookieMapRWLock; typedef bool (*CmdPtr)( int socket, const char** args ); typedef struct FuncRec { - char* name; + const char* name; CmdPtr func; } FuncRec; @@ -92,20 +92,20 @@ print_to_sock( int sock, bool addCR, const char* what, ... ) static const FuncRec gFuncs[] = { { "?", cmd_help }, + { "crash", cmd_crash }, + { "eject", cmd_kill_eject }, + { "get", cmd_get }, { "help", cmd_help }, - { "quit", cmd_quit }, - { "print", cmd_print }, + { "kill", cmd_kill_eject }, { "lock", cmd_lock }, + { "print", cmd_print }, + { "quit", cmd_quit }, + { "rev", cmd_rev }, + { "set", cmd_set }, + { "shutdown", cmd_shutdown }, { "start", cmd_start }, { "stop", cmd_stop }, - { "kill", cmd_kill_eject }, - { "eject", cmd_kill_eject }, - { "shutdown", cmd_shutdown }, - { "get", cmd_get }, - { "set", cmd_set }, - { "rev", cmd_rev }, { "uptime", cmd_uptime }, - { "crash", cmd_crash }, }; static bool @@ -184,7 +184,7 @@ cmd_kill_eject( int socket, const char** args ) "silently remove from game" : "remove from game with error to device"; if ( !found ) { - char* msg = + const char* msg = "* %s socket -- %s\n" " %s cref connName \n" " %s cref id " @@ -221,7 +221,7 @@ static bool cmd_set( int socket, const char** args ) { if ( 0 == strcmp( args[1], "help" ) ) { - print_to_sock( socket, true, "* %s loglevel \n", args[0] ); + print_to_sock( socket, true, "* %s loglevel ", args[0] ); } else { const char* attr = args[1]; const char* val = args[2]; @@ -374,7 +374,7 @@ cmd_print( int socket, const char** args ) } if ( !found ) { - char* str = + const char* str = "* %s cref all\n" " %s cref name \n" " %s cref connName \n" diff --git a/relay/states.cpp b/relay/states.cpp index ed002f6df..55db9b9ce 100644 --- a/relay/states.cpp +++ b/relay/states.cpp @@ -153,7 +153,7 @@ getFromTable( XW_RELAY_STATE curState, XW_RELAY_EVENT curEvent, #define CASESTR(s) case s: return #s -char* +const char* stateString( XW_RELAY_STATE state ) { switch( state ) { @@ -178,7 +178,7 @@ stateString( XW_RELAY_STATE state ) return ""; } -char* +const char* eventString( XW_RELAY_EVENT evt ) { switch( evt ) { @@ -204,7 +204,7 @@ eventString( XW_RELAY_EVENT evt ) return ""; } -char* +const char* actString( XW_RELAY_ACTION act ) { switch ( act ) { diff --git a/relay/states.h b/relay/states.h index 817a5b1d9..a4111e4f0 100644 --- a/relay/states.h +++ b/relay/states.h @@ -153,8 +153,8 @@ bool getFromTable( XW_RELAY_STATE curState, XW_RELAY_EVENT curEvent, XW_RELAY_ACTION* takeAction, XW_RELAY_STATE* nextState ); -char* stateString( XW_RELAY_STATE state ); -char* eventString( XW_RELAY_EVENT evt ); -char* actString( XW_RELAY_ACTION act ); +const char* stateString( XW_RELAY_STATE state ); +const char* eventString( XW_RELAY_EVENT evt ); +const char* actString( XW_RELAY_ACTION act ); #endif diff --git a/relay/xwrelay.cpp b/relay/xwrelay.cpp index f1792ab8f..571dbb61e 100644 --- a/relay/xwrelay.cpp +++ b/relay/xwrelay.cpp @@ -47,7 +47,9 @@ #include #include #include +#include #include +#include #if defined(__FreeBSD__) # if (OSVERSION > 500000) @@ -70,15 +72,30 @@ #include "timermgr.h" #include "permid.h" +#define LOG_FILE_PATH "./xwrelay.log" + void logf( XW_LogLevel level, const char* format, ... ) { RelayConfigs* rc = RelayConfigs::GetConfigs(); if ( NULL == rc || level <= rc->GetLogLevel() ) { - FILE* where = stderr; +#ifdef USE_SYSLOG + char buf[256]; + va_list ap; + va_start( ap, format ); + vsnprintf( buf, sizeof(buf), format, ap ); + syslog( LOG_LOCAL0 | LOG_INFO, buf ); + va_end(ap); +#else + static FILE* where = 0; struct tm* timp; struct timeval tv; struct timezone tz; + + if ( !where ) { + where = fopen( LOG_FILE_PATH, "a" ); + } + gettimeofday( &tv, &tz ); timp = localtime( &tv.tv_sec ); @@ -92,6 +109,7 @@ logf( XW_LogLevel level, const char* format, ... ) vfprintf( where, format, ap ); va_end(ap); fprintf( where, "\n" ); +#endif } } /* logf */ @@ -295,7 +313,7 @@ processDisconnect( unsigned char* bufp, int bufLen, int socket ) } /* processDisconnect */ void -killSocket( int socket, char* why ) +killSocket( int socket, const char* why ) { logf( XW_LOGERROR, "killSocket(%d): %s", socket, why ); CRefMgr::Get()->RemoveSocketRefs( socket ); @@ -418,6 +436,7 @@ usage( char* arg0 ) fprintf( stderr, "\t-? (print this help)\\\n" "\t-c (localhost port for control console)\\\n" + "\t-d (don't become daemon)\\\n" "\t-f (config file)\\\n" "\t-h (print this help)\\\n" "\t-i (file where next global id stored)\\\n" @@ -480,6 +499,13 @@ printWhy( int status ) } /* printWhy */ #endif +static void +parentDied( int sig ) +{ + logf( XW_LOGINFO, "%s", __func__ ); + exit(0); +} + int main( int argc, char** argv ) { int port = 0; @@ -488,6 +514,7 @@ int main( int argc, char** argv ) char* conffile = NULL; const char* serverName = NULL; const char* idFileName = NULL; + bool doDaemon = true; /* Verify sizes here... */ assert( sizeof(CookieID) == 2 ); @@ -498,7 +525,7 @@ int main( int argc, char** argv ) first. */ for ( ; ; ) { - int opt = getopt(argc, argv, "h?c:p:n:i:f:t:" ); + int opt = getopt(argc, argv, "h?c:p:n:i:f:t:d" ); if ( opt == -1 ) { break; @@ -511,6 +538,9 @@ int main( int argc, char** argv ) case 'c': ctrlport = atoi( optarg ); break; + case 'd': + doDaemon = false; + break; case 'f': conffile = optarg; break; @@ -556,6 +586,35 @@ int main( int argc, char** argv ) /* add signal handling here */ + /* + The daemon() function is for programs wishing to detach themselves from + the controlling terminal and run in the background as system daemons. + + Unless the argument nochdir is non-zero, daemon() changes the current + working directory to the root ("/"). + + Unless the argument noclose is non-zero, daemon() will redirect standard + input, standard output and standard error to /dev/null. + + (This function forks, and if the fork() succeeds, the parent does + _exit(0), so that further errors are seen by the child only.) On + success zero will be returned. If an error occurs, daemon() returns -1 + and sets the global variable errno to any of the errors specified for + the library functions fork(2) and setsid(2). + */ + if ( doDaemon ) { + if ( 0 != daemon( true, false ) ) { + logf( XW_LOGERROR, "dev() => %s", strerror(errno) ); + exit( -1 ); + } + } + + pid_t pid = getpid(); + FILE* f = fopen( "./xwrelay.pid", "w" ); + assert( f ); + fprintf( f, "%d", pid ); + fclose( f ); + #ifdef SPAWN_SELF /* loop forever, relaunching children as they die. */ for ( ; ; ) { @@ -573,6 +632,9 @@ int main( int argc, char** argv ) } #endif + prctl( PR_SET_PDEATHSIG, SIGUSR1 ); + (void)signal( SIGUSR1, parentDied ); + g_listener = make_socket( INADDR_ANY, port ); if ( g_listener == -1 ) { exit( 1 ); diff --git a/relay/xwrelay_priv.h b/relay/xwrelay_priv.h index d3695c242..15a1df133 100644 --- a/relay/xwrelay_priv.h +++ b/relay/xwrelay_priv.h @@ -16,7 +16,7 @@ typedef enum { void logf( XW_LogLevel level, const char* format, ... ); -void killSocket( int socket, char* why ); +void killSocket( int socket, const char* why ); int send_with_length_unsafe( int socket, unsigned char* buf, int bufLen );