diff options
Diffstat (limited to 'src/common/core.c')
-rw-r--r-- | src/common/core.c | 447 |
1 files changed, 222 insertions, 225 deletions
diff --git a/src/common/core.c b/src/common/core.c index e1f99885b..efab15dcb 100644 --- a/src/common/core.c +++ b/src/common/core.c @@ -28,7 +28,7 @@ void (*shutdown_callback)(void) = NULL; #if defined(BUILDBOT) - int buildbotflag = 0; +int buildbotflag = 0; #endif int runflag = CORE_ST_RUN; @@ -38,14 +38,14 @@ char **arg_v = NULL; char *SERVER_NAME = NULL; char SERVER_TYPE = ATHENA_SERVER_NONE; -#ifndef MINICORE // minimalist Core +#ifndef MINICORE // minimalist Core // Added by Gabuzomeu // // This is an implementation of signal() using sigaction() for portability. // (sigaction() is POSIX; signal() is not.) Taken from Stevens' _Advanced // Programming in the UNIX Environment_. // -#ifdef WIN32 // windows don't have SIGPIPE +#ifdef WIN32 // windows don't have SIGPIPE #define SIGPIPE SIGINT #endif @@ -54,229 +54,225 @@ char SERVER_TYPE = ATHENA_SERVER_NONE; #else sigfunc *compat_signal(int signo, sigfunc *func) { - struct sigaction sact, oact; + struct sigaction sact, oact; - sact.sa_handler = func; - sigemptyset(&sact.sa_mask); - sact.sa_flags = 0; + sact.sa_handler = func; + sigemptyset(&sact.sa_mask); + sact.sa_flags = 0; #ifdef SA_INTERRUPT - sact.sa_flags |= SA_INTERRUPT; /* SunOS */ + sact.sa_flags |= SA_INTERRUPT; /* SunOS */ #endif - if (sigaction(signo, &sact, &oact) < 0) - return (SIG_ERR); + if (sigaction(signo, &sact, &oact) < 0) + return (SIG_ERR); - return (oact.sa_handler); + return (oact.sa_handler); } #endif /*====================================== - * CORE : Console events for Windows + * CORE : Console events for Windows *--------------------------------------*/ #ifdef _WIN32 static BOOL WINAPI console_handler(DWORD c_event) { - switch(c_event) - { - case CTRL_CLOSE_EVENT: - case CTRL_LOGOFF_EVENT: - case CTRL_SHUTDOWN_EVENT: - if( shutdown_callback != NULL ) - shutdown_callback(); - else - runflag = CORE_ST_STOP;// auto-shutdown - break; - default: - return FALSE; + switch (c_event) { + case CTRL_CLOSE_EVENT: + case CTRL_LOGOFF_EVENT: + case CTRL_SHUTDOWN_EVENT: + if (shutdown_callback != NULL) + shutdown_callback(); + else + runflag = CORE_ST_STOP;// auto-shutdown + break; + default: + return FALSE; } return TRUE; } static void cevents_init() { - if (SetConsoleCtrlHandler(console_handler,TRUE)==FALSE) - ShowWarning ("Unable to install the console handler!\n"); + if (SetConsoleCtrlHandler(console_handler,TRUE)==FALSE) + ShowWarning("Unable to install the console handler!\n"); } #endif /*====================================== - * CORE : Signal Sub Function + * CORE : Signal Sub Function *--------------------------------------*/ static void sig_proc(int sn) { - static int is_called = 0; - - switch (sn) { - case SIGINT: - case SIGTERM: - if (++is_called > 3) - exit(EXIT_SUCCESS); - if( shutdown_callback != NULL ) - shutdown_callback(); - else - runflag = CORE_ST_STOP;// auto-shutdown - break; - case SIGSEGV: - case SIGFPE: - do_abort(); - // Pass the signal to the system's default handler - compat_signal(sn, SIG_DFL); - raise(sn); - break; + static int is_called = 0; + + switch (sn) { + case SIGINT: + case SIGTERM: + if (++is_called > 3) + exit(EXIT_SUCCESS); + if (shutdown_callback != NULL) + shutdown_callback(); + else + runflag = CORE_ST_STOP;// auto-shutdown + break; + case SIGSEGV: + case SIGFPE: + do_abort(); + // Pass the signal to the system's default handler + compat_signal(sn, SIG_DFL); + raise(sn); + break; #ifndef _WIN32 - case SIGXFSZ: - // ignore and allow it to set errno to EFBIG - ShowWarning ("Max file size reached!\n"); - //run_flag = 0; // should we quit? - break; - case SIGPIPE: - //ShowInfo ("Broken pipe found... closing socket\n"); // set to eof in socket.c - break; // does nothing here + case SIGXFSZ: + // ignore and allow it to set errno to EFBIG + ShowWarning("Max file size reached!\n"); + //run_flag = 0; // should we quit? + break; + case SIGPIPE: + //ShowInfo ("Broken pipe found... closing socket\n"); // set to eof in socket.c + break; // does nothing here #endif - } + } } -void signals_init (void) +void signals_init(void) { - compat_signal(SIGTERM, sig_proc); - compat_signal(SIGINT, sig_proc); + compat_signal(SIGTERM, sig_proc); + compat_signal(SIGINT, sig_proc); #ifndef _DEBUG // need unhandled exceptions to debug on Windows - compat_signal(SIGSEGV, sig_proc); - compat_signal(SIGFPE, sig_proc); + compat_signal(SIGSEGV, sig_proc); + compat_signal(SIGFPE, sig_proc); #endif #ifndef _WIN32 - compat_signal(SIGILL, SIG_DFL); - compat_signal(SIGXFSZ, sig_proc); - compat_signal(SIGPIPE, sig_proc); - compat_signal(SIGBUS, SIG_DFL); - compat_signal(SIGTRAP, SIG_DFL); + compat_signal(SIGILL, SIG_DFL); + compat_signal(SIGXFSZ, sig_proc); + compat_signal(SIGPIPE, sig_proc); + compat_signal(SIGBUS, SIG_DFL); + compat_signal(SIGTRAP, SIG_DFL); #endif } #endif #ifdef SVNVERSION - const char *get_svn_revision(void) - { - return EXPAND_AND_QUOTE(SVNVERSION); - } +const char *get_svn_revision(void) +{ + return EXPAND_AND_QUOTE(SVNVERSION); +} #else// not SVNVERSION -const char* get_svn_revision(void) +const char *get_svn_revision(void) { - static char svn_version_buffer[16] = ""; - FILE *fp; - - if( svn_version_buffer[0] != '\0' ) - return svn_version_buffer; - - // subversion 1.7 uses a sqlite3 database - // FIXME this is hackish at best... - // - ignores database file structure - // - assumes the data in NODES.dav_cache column ends with "!svn/ver/<revision>/<path>)" - // - since it's a cache column, the data might not even exist - if( (fp = fopen(".svn"PATHSEP_STR"wc.db", "rb")) != NULL || (fp = fopen(".."PATHSEP_STR".svn"PATHSEP_STR"wc.db", "rb")) != NULL ) - { - #ifndef SVNNODEPATH - //not sure how to handle branches, so i'll leave this overridable define until a better solution comes up - #define SVNNODEPATH trunk - #endif - const char* prefix = "!svn/ver/"; - const char* postfix = "/"EXPAND_AND_QUOTE(SVNNODEPATH)")"; // there should exist only 1 entry like this - size_t prefix_len = strlen(prefix); - size_t postfix_len = strlen(postfix); - size_t i,j,len; - char* buffer; - - // read file to buffer - fseek(fp, 0, SEEK_END); - len = ftell(fp); - buffer = (char*)aMalloc(len + 1); - fseek(fp, 0, SEEK_SET); - len = fread(buffer, 1, len, fp); - buffer[len] = '\0'; - fclose(fp); - - // parse buffer - for( i = prefix_len + 1; i + postfix_len <= len; ++i ) - { - if( buffer[i] != postfix[0] || memcmp(buffer + i, postfix, postfix_len) != 0 ) - continue; // postfix missmatch - for( j = i; j > 0; --j ) - {// skip digits - if( !ISDIGIT(buffer[j - 1]) ) - break; - } - if( memcmp(buffer + j - prefix_len, prefix, prefix_len) != 0 ) - continue; // prefix missmatch - // done - snprintf(svn_version_buffer, sizeof(svn_version_buffer), "%d", atoi(buffer + j)); - break; - } - aFree(buffer); - - if( svn_version_buffer[0] != '\0' ) - return svn_version_buffer; - } - - // subversion 1.6 and older? - if ((fp = fopen(".svn/entries", "r")) != NULL) - { - char line[1024]; - int rev; - // Check the version - if (fgets(line, sizeof(line), fp)) - { - if(!ISDIGIT(line[0])) - { - // XML File format - while (fgets(line,sizeof(line),fp)) - if (strstr(line,"revision=")) break; - if (sscanf(line," %*[^\"]\"%d%*[^\n]", &rev) == 1) { - snprintf(svn_version_buffer, sizeof(svn_version_buffer), "%d", rev); - } - } - else - { - // Bin File format - if ( fgets(line, sizeof(line), fp) == NULL ) { printf("Can't get bin name\n"); } // Get the name - if ( fgets(line, sizeof(line), fp) == NULL ) { printf("Can't get entries kind\n"); } // Get the entries kind - if(fgets(line, sizeof(line), fp)) // Get the rev numver - { - snprintf(svn_version_buffer, sizeof(svn_version_buffer), "%d", atoi(line)); - } - } - } - fclose(fp); - - if( svn_version_buffer[0] != '\0' ) - return svn_version_buffer; - } - - // fallback - snprintf(svn_version_buffer, sizeof(svn_version_buffer), "Unknown"); - return svn_version_buffer; + static char svn_version_buffer[16] = ""; + FILE *fp; + + if (svn_version_buffer[0] != '\0') + return svn_version_buffer; + + // subversion 1.7 uses a sqlite3 database + // FIXME this is hackish at best... + // - ignores database file structure + // - assumes the data in NODES.dav_cache column ends with "!svn/ver/<revision>/<path>)" + // - since it's a cache column, the data might not even exist + if ((fp = fopen(".svn"PATHSEP_STR"wc.db", "rb")) != NULL || (fp = fopen(".."PATHSEP_STR".svn"PATHSEP_STR"wc.db", "rb")) != NULL) { +#ifndef SVNNODEPATH + //not sure how to handle branches, so i'll leave this overridable define until a better solution comes up +#define SVNNODEPATH trunk +#endif + const char *prefix = "!svn/ver/"; + const char *postfix = "/"EXPAND_AND_QUOTE(SVNNODEPATH)")"; // there should exist only 1 entry like this + size_t prefix_len = strlen(prefix); + size_t postfix_len = strlen(postfix); + size_t i,j,len; + char *buffer; + + // read file to buffer + fseek(fp, 0, SEEK_END); + len = ftell(fp); + buffer = (char *)aMalloc(len + 1); + fseek(fp, 0, SEEK_SET); + len = fread(buffer, 1, len, fp); + buffer[len] = '\0'; + fclose(fp); + + // parse buffer + for (i = prefix_len + 1; i + postfix_len <= len; ++i) { + if (buffer[i] != postfix[0] || memcmp(buffer + i, postfix, postfix_len) != 0) + continue; // postfix missmatch + for (j = i; j > 0; --j) { + // skip digits + if (!ISDIGIT(buffer[j - 1])) + break; + } + if (memcmp(buffer + j - prefix_len, prefix, prefix_len) != 0) + continue; // prefix missmatch + // done + snprintf(svn_version_buffer, sizeof(svn_version_buffer), "%d", atoi(buffer + j)); + break; + } + aFree(buffer); + + if (svn_version_buffer[0] != '\0') + return svn_version_buffer; + } + + // subversion 1.6 and older? + if ((fp = fopen(".svn/entries", "r")) != NULL) { + char line[1024]; + int rev; + // Check the version + if (fgets(line, sizeof(line), fp)) { + if (!ISDIGIT(line[0])) { + // XML File format + while (fgets(line,sizeof(line),fp)) + if (strstr(line,"revision=")) break; + if (sscanf(line," %*[^\"]\"%d%*[^\n]", &rev) == 1) { + snprintf(svn_version_buffer, sizeof(svn_version_buffer), "%d", rev); + } + } else { + // Bin File format + if (fgets(line, sizeof(line), fp) == NULL) { + printf("Can't get bin name\n"); // Get the name + } + if (fgets(line, sizeof(line), fp) == NULL) { + printf("Can't get entries kind\n"); // Get the entries kind + } + if (fgets(line, sizeof(line), fp)) { // Get the rev numver + snprintf(svn_version_buffer, sizeof(svn_version_buffer), "%d", atoi(line)); + } + } + } + fclose(fp); + + if (svn_version_buffer[0] != '\0') + return svn_version_buffer; + } + + // fallback + snprintf(svn_version_buffer, sizeof(svn_version_buffer), "Unknown"); + return svn_version_buffer; } #endif /*====================================== - * CORE : Display title + * CORE : Display title * ASCII By CalciumKid 1/12/2011 *--------------------------------------*/ -static void display_title(void) { - //ClearScreen(); // clear screen and go up/left (0, 0 position in text) - - ShowMessage("\n"); - ShowMessage(""CL_PASS" "CL_BOLD" "CL_PASS""CL_CLL""CL_NORMAL"\n"); - ShowMessage(""CL_PASS" "CL_BT_WHITE" rAthena Development Team presents "CL_PASS""CL_CLL""CL_NORMAL"\n"); - ShowMessage(""CL_PASS" "CL_BOLD" ___ __ __ "CL_PASS""CL_CLL""CL_NORMAL"\n"); - ShowMessage(""CL_PASS" "CL_BOLD" _____/ | / /_/ /_ ___ ____ ____ _ "CL_PASS""CL_CLL""CL_NORMAL"\n"); - ShowMessage(""CL_PASS" "CL_BOLD" / ___/ /| |/ __/ __ \\/ _ \\/ __ \\/ __ `/ "CL_PASS""CL_CLL""CL_NORMAL"\n"); - ShowMessage(""CL_PASS" "CL_BOLD" / / / ___ / /_/ / / / __/ / / / /_/ / "CL_PASS""CL_CLL""CL_NORMAL"\n"); - ShowMessage(""CL_PASS" "CL_BOLD" /_/ /_/ |_\\__/_/ /_/\\___/_/ /_/\\__,_/ "CL_PASS""CL_CLL""CL_NORMAL"\n"); - ShowMessage(""CL_PASS" "CL_BOLD" "CL_PASS""CL_CLL""CL_NORMAL"\n"); - ShowMessage(""CL_PASS" "CL_GREEN" http://rathena.org/board/ "CL_PASS""CL_CLL""CL_NORMAL"\n"); - ShowMessage(""CL_PASS" "CL_BOLD" "CL_PASS""CL_CLL""CL_NORMAL"\n"); - - ShowInfo("SVN Revision: '"CL_WHITE"%s"CL_RESET"'.\n", get_svn_revision()); +static void display_title(void) +{ + //ClearScreen(); // clear screen and go up/left (0, 0 position in text) + + ShowMessage("\n"); + ShowMessage(""CL_PASS" "CL_BOLD" "CL_PASS""CL_CLL""CL_NORMAL"\n"); + ShowMessage(""CL_PASS" "CL_BT_WHITE" rAthena Development Team presents "CL_PASS""CL_CLL""CL_NORMAL"\n"); + ShowMessage(""CL_PASS" "CL_BOLD" ___ __ __ "CL_PASS""CL_CLL""CL_NORMAL"\n"); + ShowMessage(""CL_PASS" "CL_BOLD" _____/ | / /_/ /_ ___ ____ ____ _ "CL_PASS""CL_CLL""CL_NORMAL"\n"); + ShowMessage(""CL_PASS" "CL_BOLD" / ___/ /| |/ __/ __ \\/ _ \\/ __ \\/ __ `/ "CL_PASS""CL_CLL""CL_NORMAL"\n"); + ShowMessage(""CL_PASS" "CL_BOLD" / / / ___ / /_/ / / / __/ / / / /_/ / "CL_PASS""CL_CLL""CL_NORMAL"\n"); + ShowMessage(""CL_PASS" "CL_BOLD" /_/ /_/ |_\\__/_/ /_/\\___/_/ /_/\\__,_/ "CL_PASS""CL_CLL""CL_NORMAL"\n"); + ShowMessage(""CL_PASS" "CL_BOLD" "CL_PASS""CL_CLL""CL_NORMAL"\n"); + ShowMessage(""CL_PASS" "CL_GREEN" http://rathena.org/board/ "CL_PASS""CL_CLL""CL_NORMAL"\n"); + ShowMessage(""CL_PASS" "CL_BOLD" "CL_PASS""CL_CLL""CL_NORMAL"\n"); + + ShowInfo("SVN Revision: '"CL_WHITE"%s"CL_RESET"'.\n", get_svn_revision()); } // Warning if executed as superuser (root) @@ -284,72 +280,73 @@ void usercheck(void) { #ifndef _WIN32 if (geteuid() == 0) { - ShowWarning ("You are running rAthena with root privileges, it is not necessary.\n"); + ShowWarning("You are running rAthena with root privileges, it is not necessary.\n"); } #endif } /*====================================== - * CORE : MAINROUTINE + * CORE : MAINROUTINE *--------------------------------------*/ -int main (int argc, char **argv) +int main(int argc, char **argv) { - {// initialize program arguments - char *p1 = SERVER_NAME = argv[0]; - char *p2 = p1; - while ((p1 = strchr(p2, '/')) != NULL || (p1 = strchr(p2, '\\')) != NULL) - { - SERVER_NAME = ++p1; - p2 = p1; - } - arg_c = argc; - arg_v = argv; - } - - malloc_init();// needed for Show* in display_title() [FlavioJS] + { + // initialize program arguments + char *p1 = SERVER_NAME = argv[0]; + char *p2 = p1; + while ((p1 = strchr(p2, '/')) != NULL || (p1 = strchr(p2, '\\')) != NULL) { + SERVER_NAME = ++p1; + p2 = p1; + } + arg_c = argc; + arg_v = argv; + } + + malloc_init();// needed for Show* in display_title() [FlavioJS] #ifdef MINICORE // minimalist Core - display_title(); - usercheck(); - do_init(argc,argv); - do_final(); + display_title(); + usercheck(); + do_init(argc,argv); + do_final(); #else// not MINICORE - set_server_type(); - display_title(); - usercheck(); + set_server_type(); + display_title(); + usercheck(); - rathread_init(); - mempool_init(); - db_init(); - signals_init(); + rathread_init(); + mempool_init(); + db_init(); + signals_init(); #ifdef _WIN32 - cevents_init(); + cevents_init(); #endif - timer_init(); - socket_init(); + timer_init(); + socket_init(); - do_init(argc,argv); + do_init(argc,argv); - {// Main runtime cycle - int next; - while (runflag != CORE_ST_STOP) { - next = do_timer(gettick_nocache()); - do_sockets(next); - } - } + { + // Main runtime cycle + int next; + while (runflag != CORE_ST_STOP) { + next = do_timer(gettick_nocache()); + do_sockets(next); + } + } - do_final(); + do_final(); - timer_final(); - socket_final(); - db_final(); - mempool_final(); - rathread_final(); + timer_final(); + socket_final(); + db_final(); + mempool_final(); + rathread_final(); #endif - malloc_final(); + malloc_final(); - return 0; + return 0; } |