void MainDisplayUsage( char *program, char *errorMsg ) { char *nullString = "<program name>"; LogBanner(); if( errorMsg != NULL ) { fprintf( stderr, "\n%s\n\n", errorMsg ); } if( program == NULL ) { program = nullString; } fprintf( stderr, "\nUsage:\n\t%s [-H host] [-P port] [-u user] " "[-p password] [-d database] [-D] [-v]\n\n", program ); fprintf( stderr, "Options:\n" "\t-H or --host\tMySQL host to connect to (default localhost)\n" "\t-P or --port\tMySQL port to connect to (default 3306)\n" "\t-u or --user\tMySQL user to connect as (default beirdobot)\n" "\t-p or --password\tMySQL password to use (default beirdobot)\n" "\t-d or --database\tMySQL database to use (default beirdobot)\n" "\t-D or --daemon\tRun solely in daemon mode, detached\n" "\t-v or --verbose\tShow verbose information while running\n" "\t-g or --debug\tWrite a debugging logfile\n" "\t-V or --version\tshow the version number and quit\n" "\t-h or --help\tshow this help text\n\n" ); }
void MainDisplayUsage( char *program, char *errorMsg ) { char *nullString = "<program name>"; LogBanner(); if( errorMsg != NULL ) { fprintf( stderr, "\n%s\n\n", errorMsg ); } if( program == NULL ) { program = nullString; } fprintf( stderr, "\nUsage:\n\t%s [-H host] [-P port] [-u user] " "[-p password] [-d database] [-D] [-v]\n\n", program ); fprintf( stderr, "Options:\n" "\t-H or --host\tMySQL host to connect to (default localhost)\n" "\t-P or --port\tMySQL port to connect to (default 3306)\n" "\t-u or --user\tMySQL user to connect as (default beirdobot)\n" "\t-p or --password\tMySQL password to use (default beirdobot)\n" "\t-d or --database\tMySQL database to use (default beirdobot)\n" "\t-V or --version\tshow the version number and quit\n" "\t-h or --help\tshow this help text\n\n" ); }
int main ( int argc, char **argv ) { pthread_mutex_t spinLockMutex; pid_t childPid; struct sigaction sa; sigset_t sigmsk; size_t len; ThreadCallback_t callbacks; GlobalAbort = false; /* Parse the command line options */ MainParseArgs( argc, argv ); #ifndef __CYGWIN__ len = confstr( _CS_GNU_LIBPTHREAD_VERSION, NULL, 0 ); if( len ) { pthreadsVersion = (char *)malloc(len); confstr( _CS_GNU_LIBPTHREAD_VERSION, pthreadsVersion, len ); } if( !pthreadsVersion || strstr( pthreadsVersion, "linuxthreads" ) ) { fprintf( stderr, "beirdobot requires NPTL to operate correctly.\n\n" "The signal handling in linuxthreads is just too " "broken to use.\n\n" ); exit( 1 ); } #else len = 0; #endif /* Do we need to detach? */ if( Daemon ) { childPid = fork(); if( childPid < 0 ) { perror( "Couldn't detach in daemon mode" ); _exit( 1 ); } if( childPid != 0 ) { /* This is still the parent, report the child's pid and exit */ printf( "[Detached as PID %d]\n", childPid ); /* And exit the parent */ _exit( 0 ); } /* After this is in the detached child */ /* Close stdin, stdout, stderr to release the tty */ close(0); close(1); close(2); } mainThreadId = pthread_self(); /* * Setup the sigmasks for this thread (which is the parent to all others). * This will propogate to all children. */ sigfillset( &sigmsk ); sigdelset( &sigmsk, SIGUSR1 ); sigdelset( &sigmsk, SIGUSR2 ); sigdelset( &sigmsk, SIGHUP ); sigdelset( &sigmsk, SIGWINCH ); sigdelset( &sigmsk, SIGINT ); sigdelset( &sigmsk, SIGSEGV ); sigdelset( &sigmsk, SIGILL ); sigdelset( &sigmsk, SIGFPE ); pthread_sigmask( SIG_SETMASK, &sigmsk, NULL ); /* Initialize the non-threadsafe CURL library functionality */ curl_global_init( CURL_GLOBAL_ALL ); /* Start up the Logging thread */ logging_initialize(TRUE); memset( &callbacks, 0, sizeof(ThreadCallback_t) ); callbacks.sighupFunc = mainSighup; thread_register( &mainThreadId, "thread_main", &callbacks ); /* Setup signal handler for SIGUSR1 (toggles Debug) */ sa.sa_sigaction = (sigAction_t)logging_toggle_debug; sigemptyset( &sa.sa_mask ); sa.sa_flags = SA_RESTART; sigaction( SIGUSR1, &sa, NULL ); /* Setup the exit handler */ atexit( MainDelayExit ); /* Setup signal handler for SIGINT (shut down cleanly) */ sa.sa_sigaction = signal_interrupt; sigemptyset( &sa.sa_mask ); sa.sa_flags = SA_RESTART; sigaction( SIGINT, &sa, NULL ); /* Setup signal handlers that are to be propogated to all threads */ sa.sa_sigaction = signal_everyone; sigemptyset( &sa.sa_mask ); sa.sa_flags = SA_RESTART | SA_SIGINFO; sigaction( SIGUSR2, &sa, NULL ); sigaction( SIGHUP, &sa, NULL ); sigaction( SIGWINCH, &sa, NULL ); /* Setup signal handlers for SEGV, ILL, FPE */ sa.sa_sigaction = signal_death; sigemptyset( &sa.sa_mask ); sa.sa_flags = SA_RESTART | SA_SIGINFO; sigaction( SIGSEGV, &sa, NULL ); sigaction( SIGILL, &sa, NULL ); sigaction( SIGFPE, &sa, NULL ); versionTree = BalancedBTreeCreate( BTREE_KEY_STRING ); #ifndef __CYGWIN__ versionAdd( "pthreads", pthreadsVersion ); #endif curses_start(); cursesMenuItemAdd( 2, MENU_SYSTEM, "About", mainAbout, NULL ); cursesMenuItemAdd( 2, MENU_SYSTEM, "Licensing", mainLicensing, NULL ); cursesMenuItemAdd( 2, MENU_SYSTEM, "Versions", mainVersions, NULL ); cursesMenuItemAdd( 2, MENU_SYSTEM, "Reload All", mainReloadAll, NULL ); /* Add the terminal setting as a version */ versionAdd( "TERM", getenv("TERM") ); /* Print the startup log messages */ LogBanner(); LogPrint( LOG_INFO, "CFLAGS: %s", CFLAGS ); LogPrint( LOG_INFO, "LDFLAGS: %s", LDFLAGS ); /* Setup the CLucene indexer */ clucene_init(0); /* Setup the MySQL connection */ db_setup(); db_check_schema_main(); /* Setup the bot commands */ botCmd_initialize(); /* Setup the regexp support */ regexp_initialize(); /* Setup the plugins */ plugins_initialize(); /* Start the notifier thread */ notify_start(); /* Start the authenticate thread */ authenticate_start(); /* Start the bot */ bot_start(); /* Sit on this and rotate - this causes an intentional deadlock, this * thread should stop dead in its tracks */ pthread_mutex_init( &spinLockMutex, NULL ); pthread_mutex_lock( &spinLockMutex ); pthread_mutex_lock( &spinLockMutex ); return(0); }
void MainParseArgs( int argc, char **argv ) { #ifndef __CYGWIN__ extern char *optarg; extern int optind, opterr, optopt; #endif int opt; int optIndex = 0; static struct option longOpts[] = { {"help", 0, 0, 'h'}, {"version", 0, 0, 'V'}, {"host", 1, 0, 'H'}, {"user", 1, 0, 'u'}, {"password", 1, 0, 'p'}, {"port", 1, 0, 'P'}, {"database", 1, 0, 'd'}, {"daemon", 0, 0, 'D'}, {"verbose", 0, 0, 'v'}, {"optimize", 0, 0, 'o'}, {"debug", 0, 0, 'g'}, {0, 0, 0, 0} }; mysql_host = NULL; mysql_portnum = 0; mysql_user = NULL; mysql_password = NULL; mysql_db = NULL; verbose = false; Debug = false; Daemon = false; optimize = false; while( (opt = getopt_long( argc, argv, "hVH:P:u:p:d:Dgov", longOpts, &optIndex )) != -1 ) { switch( opt ) { case 'h': MainDisplayUsage( argv[0], NULL ); exit( 0 ); break; case 'D': Daemon = true; break; case 'g': Debug = true; break; case 'o': optimize = true; break; case 'v': verbose = true; break; case 'H': if( mysql_host != NULL ) { free( mysql_host ); } mysql_host = strdup(optarg); break; case 'P': mysql_portnum = atoi(optarg); break; case 'u': if( mysql_user != NULL ) { free( mysql_user ); } mysql_user = strdup(optarg); break; case 'p': if( mysql_password != NULL ) { free( mysql_password ); } mysql_password = strdup(optarg); break; case 'd': if( mysql_db != NULL ) { free( mysql_db ); } mysql_db = strdup(optarg); break; case 'V': LogBanner(); exit( 0 ); break; case '?': case ':': default: MainDisplayUsage( argv[0], "Unknown option" ); exit( 1 ); break; } } if( mysql_host == NULL ) { mysql_host = strdup("localhost"); } if( mysql_portnum == 0 ) { mysql_portnum = 3306; } if( mysql_user == NULL ) { mysql_user = strdup("beirdobot"); } if( mysql_password == NULL ) { mysql_password = strdup("beirdobot"); } if( mysql_db == NULL ) { mysql_db = strdup("beirdobot"); } if( Daemon ) { verbose = false; } }
void StartThreads( void ) { pthread_mutex_t spinLockMutex; pid_t childPid; struct sigaction sa; sigset_t sigmsk; size_t len; ThreadCallback_t callbacks; GlobalAbort = FALSE; #ifndef __CYGWIN__ len = confstr( _CS_GNU_LIBPTHREAD_VERSION, NULL, 0 ); if( len ) { pthreadsVersion = CREATEN(char, len); confstr( _CS_GNU_LIBPTHREAD_VERSION, pthreadsVersion, len ); } #else (void)len; pthreadsVersion = memstrlink( "Cygwin" ); #endif if( !pthreadsVersion || strstr( pthreadsVersion, "linuxthreads" ) ) { fprintf( stderr, "havokmud requires NPTL to operate correctly.\n\n" "The signal handling in linuxthreads is just too " "broken to use.\n\n" ); exit( 1 ); } /* Do we need to detach? */ if( Daemon ) { childPid = fork(); if( childPid < 0 ) { perror( "Couldn't detach in daemon mode" ); _exit( 1 ); } if( childPid != 0 ) { /* This is still the parent, report the child's pid and exit */ printf( "[Detached as PID %d]\n", childPid ); /* And exit the parent */ _exit( 0 ); } /* After this is in the detached child */ /* Close stdin, stdout, stderr to release the tty */ close(0); close(1); close(2); } LoggingQ = QueueCreate( 1024 ); ConnectInputQ = QueueCreate( 256 ); ConnectDnsQ = QueueCreate( 64 ); InputLoginQ = QueueCreate( 256 ); InputEditorQ = QueueCreate( 256 ); InputPlayerQ = QueueCreate( 256 ); InputImmortQ = QueueCreate( 256 ); MailQ = QueueCreate( 128 ); QueryQ = QueueCreate( 1024 ); ProtobufQ = QueueCreate( 1024 ); mainThreadId = pthread_self(); /* * Setup the sigmasks for this thread (which is the parent to all others). * This will propogate to all children. */ sigfillset( &sigmsk ); sigdelset( &sigmsk, SIGUSR1 ); sigdelset( &sigmsk, SIGUSR2 ); sigdelset( &sigmsk, SIGHUP ); sigdelset( &sigmsk, SIGWINCH ); sigdelset( &sigmsk, SIGINT ); sigdelset( &sigmsk, SIGSEGV ); sigdelset( &sigmsk, SIGILL ); sigdelset( &sigmsk, SIGFPE ); pthread_sigmask( SIG_SETMASK, &sigmsk, NULL ); memset( &callbacks, 0, sizeof(ThreadCallback_t) ); callbacks.sighupFunc = mainSighup; thread_register( &mainThreadId, "MainThread", NULL ); /* Setup signal handler for SIGUSR1 (toggles Debug) */ sa.sa_sigaction = (sigAction_t)logging_toggle_debug; sigemptyset( &sa.sa_mask ); sa.sa_flags = SA_RESTART; sigaction( SIGUSR1, &sa, NULL ); /* Setup the exit handler */ atexit( MainDelayExit ); /* Setup signal handler for SIGINT (shut down cleanly) */ sa.sa_sigaction = (sigAction_t)signal_interrupt; sigemptyset( &sa.sa_mask ); sa.sa_flags = SA_RESTART; sigaction( SIGINT, &sa, NULL ); /* Setup signal handlers that are to be propogated to all threads */ sa.sa_sigaction = (sigAction_t)signal_everyone; sigemptyset( &sa.sa_mask ); sa.sa_flags = SA_RESTART | SA_SIGINFO; sigaction( SIGUSR2, &sa, NULL ); sigaction( SIGHUP, &sa, NULL ); sigaction( SIGWINCH, &sa, NULL ); /* Setup signal handlers for SEGV, ILL, FPE */ sa.sa_sigaction = (sigAction_t)signal_death; sigemptyset( &sa.sa_mask ); sa.sa_flags = SA_RESTART | SA_SIGINFO; sigaction( SIGSEGV, &sa, NULL ); sigaction( SIGILL, &sa, NULL ); sigaction( SIGFPE, &sa, NULL ); versionAdd( "pthreads", pthreadsVersion ); versionAdd( "TERM", getenv("TERM") ); thread_create( &loggingThreadId, LoggingThread, NULL, "LoggingThread", NULL ); #if 0 curses_start(); cursesMenuItemAdd( 2, MENU_SYSTEM, "About", mainAbout, NULL ); cursesMenuItemAdd( 2, MENU_SYSTEM, "Licensing", mainLicensing, NULL ); cursesMenuItemAdd( 2, MENU_SYSTEM, "Versions", mainVersions, NULL ); cursesMenuItemAdd( 2, MENU_SYSTEM, "Reload All", mainReloadAll, NULL ); #endif LogBanner(); db_init(); db_mysql_init(); memset( &callbacks, 0, sizeof(ThreadCallback_t) ); callbacks.sigusr2Func = memoryStats; thread_create( &memoryThreadId, MemoryCoalesceThread, NULL, "MemoryCoalesceThread", &callbacks ); thread_create( &dnsThreadId, DnsThread, NULL, "DnsThread", NULL ); thread_create( &inputThreadId, InputThread, NULL, "InputThread", NULL ); thread_create( &loginThreadId, LoginThread, NULL, "LoginThread", NULL ); thread_create( &editorThreadId, EditorThread, NULL, "EditorThread", NULL ); mortalPlayingArgs.inputQ = InputPlayerQ; thread_create( &mortalPlayingThreadId, PlayingThread, &mortalPlayingArgs, "MortalPlayingThread", NULL ); immortPlayingArgs.inputQ = InputImmortQ; thread_create( &immortPlayingThreadId, PlayingThread, &immortPlayingArgs, "ImmortPlayingThread", NULL ); thread_create( &mysqlThreadId, MysqlThread, NULL, "MySQLThread", NULL ); thread_create( &protobufThreadId, ProtobufThread, NULL, "ProtobufThread", NULL ); pthread_mutex_lock( startupMutex ); pthread_mutex_unlock( startupMutex ); db_check_schema_main(); thread_create( &smtpThreadId, SmtpThread, NULL, "SMTPThread", NULL ); connectThreadArgs.port = mud_port; connectThreadArgs.timeout_sec = 0; connectThreadArgs.timeout_usec = 100000; thread_create( &connectionThreadId, ConnectionThread, &connectThreadArgs, "ConnectionThread", NULL ); pthread_mutex_lock( startupMutex ); pthread_mutex_unlock( startupMutex ); /* Sit on this and rotate - this causes an intentional deadlock, this * thread should stop dead in its tracks */ thread_mutex_init( &spinLockMutex ); pthread_mutex_lock( &spinLockMutex ); pthread_mutex_lock( &spinLockMutex ); }
int main ( int argc, char **argv ) { extern QueueObject_t *IndexQ; struct sigaction sa; sigset_t sigmsk; uint32 count; GlobalAbort = false; /* Parse the command line options */ MainParseArgs( argc, argv ); mainThreadId = pthread_self(); /* * Setup the sigmasks for this thread (which is the parent to all others). * This will propogate to all children. */ sigfillset( &sigmsk ); sigdelset( &sigmsk, SIGUSR1 ); sigdelset( &sigmsk, SIGUSR2 ); sigdelset( &sigmsk, SIGINT ); sigdelset( &sigmsk, SIGSEGV ); sigdelset( &sigmsk, SIGILL ); sigdelset( &sigmsk, SIGFPE ); pthread_sigmask( SIG_SETMASK, &sigmsk, NULL ); /* Start up the Logging thread */ logging_initialize(FALSE); thread_register( &mainThreadId, "thread_main", NULL ); /* Setup signal handler for SIGUSR1 (toggles Debug) */ sa.sa_sigaction = (sigAction_t)logging_toggle_debug; sigemptyset( &sa.sa_mask ); sa.sa_flags = SA_RESTART; sigaction( SIGUSR1, &sa, NULL ); /* Setup the exit handler */ atexit( MainDelayExit ); /* Setup signal handler for SIGINT (shut down cleanly) */ sa.sa_sigaction = signal_interrupt; sigemptyset( &sa.sa_mask ); sa.sa_flags = SA_RESTART; sigaction( SIGINT, &sa, NULL ); /* Setup signal handlers that are to be propogated to all threads */ sa.sa_sigaction = signal_everyone; sigemptyset( &sa.sa_mask ); sa.sa_flags = SA_RESTART | SA_SIGINFO; sigaction( SIGUSR2, &sa, NULL ); /* Setup signal handlers for SEGV, ILL, FPE */ sa.sa_sigaction = signal_death; sigemptyset( &sa.sa_mask ); sa.sa_flags = SA_RESTART | SA_SIGINFO; sigaction( SIGSEGV, &sa, NULL ); sigaction( SIGILL, &sa, NULL ); sigaction( SIGFPE, &sa, NULL ); /* Print the startup log messages */ LogBanner(); /* Setup the CLucene indexer */ clucene_init(1); /* Setup the MySQL connection */ db_setup(); db_check_schema_main(); db_rebuild_clucene(); /* Wait for the clucene thread to finish emptying its queue */ while( (count = QueueUsed( IndexQ )) > 0 ) { LogPrint( LOG_INFO, "%d left", count ); sleep( 1 ); } GlobalAbort = TRUE; return(0); }