X-Git-Url: http://git.pk910.de/?p=NeonServV5.git;a=blobdiff_plain;f=src%2Fmain.c;h=fb16300da97ac5697e13adfcc59b85811a8468d3;hp=dc76d7a661043e0fe36f98114a7a8744268f92f2;hb=HEAD;hpb=a0f5e337ee57df78939e9ddaccf9a18bcf811435 diff --git a/src/main.c b/src/main.c index dc76d7a..fb16300 100644 --- a/src/main.c +++ b/src/main.c @@ -1,4 +1,4 @@ -/* main.c - NeonServ v5.3 +/* main.c - NeonServ v5.6 * Copyright (C) 2011-2012 Philipp Kreil (pk910) * * This program is free software: you can redistribute it and/or modify @@ -15,6 +15,9 @@ * along with this program. If not, see . */ +#define DEFAULT_PID_FILE "neonserv.pid" +#define DEFAULT_CONF_FILE "neonserv.conf" + #include "main.h" #include "signal.h" #include "ClientSocket.h" @@ -34,105 +37,192 @@ #include "ModeNode.h" #include "IRCQueue.h" #include "DBHelper.h" -#include "commands.h" #include "ConfigParser.h" -#include "ssl.h" #include "QServer.h" #include "version.h" +#include "modules.h" +#include "module_commands.h" +#include "ModuleFunctions.h" +#include "IOHandler.h" +#include "statistics.h" +#include "log.h" + +struct ProcessState process_state; -time_t start_time; -static int running, hard_restart; -static int statistics_requested_lusers = 0; -int statistics_enabled; -TIMEQ_CALLBACK(main_statistics); -TIMEQ_CALLBACK(main_checkauths); -static int daemonized = 0; -static int print_loglevel = 0; -static FILE *log_fptr = NULL; -static int process_argc; -static char **process_argv; #ifdef HAVE_THREADS -int running_threads; pthread_mutex_t cache_sync; pthread_mutex_t whohandler_sync, whohandler_mass_sync; -static pthread_mutex_t log_sync; +static pthread_t *current_threads = NULL; #endif +static void *main_tread(void *empty); +static TIMEQ_CALLBACK(clear_cache); +static TIMEQ_CALLBACK(main_checkauths); static void check_firstrun(); -void cleanup() { - free_sockets(); - qserver_free(); - free_parser(); - free_UserNode(); - free_ChanNode(); - free_bind(); - free_modcmd(); - free_whoqueue(); - free_bots(); - free_mysql(); - free_handleinfohandler(); - free_lang(); + +static void main_parse_arguments() { + int c; + struct option options[] = { + {"show", 1, 0, 's'}, + {"foreground", 0, 0, 'f'}, + {"config", 1, 0, 'c'}, + {"pid", 1, 0, 'p'}, + {"help", 0, 0, 'h'}, + {"version", 0, 0, 'v'}, + {0, 0, 0, 0} + }; + while ((c = getopt_long(process_state.argc, process_state.argv, "s:fvh", options, NULL)) != -1) { + switch (c) { + case 'c': + strncpy(process_state.config, optarg, MAXLEN-1); + break; + case 'p': + strncpy(process_state.pidfile, optarg, MAXLEN-1); + break; + case 's': + process_state.loglevel = atoi(optarg); + break; + case 'f': + process_state.run_as_daemon = 0; + break; + case 'v': + printf("Version: %s.%d (%s)\n", NEONSERV_VERSION, patchlevel, (strcmp(revision, "") ? revision : "-")); + printf("Build: #%s %s (%s lines, " COMPILER ")\n", compilation, creation, codelines); + exit(0); + break; + case 'h': + printf("Usage: ./neonserv [-c neonserv.conf] [-p neonserv.pid] [-s loglevel] [-f] [-h|-v]\n"); + printf(" -c, --config use this configuration file.\n"); + printf(" -f, --foreground run NeonServ in the foreground.\n"); + printf(" -h, --help prints this usage message.\n"); + printf(" -p, --pid use this pid file.\n"); + printf(" -s, --show show log lines matching loglevel in stdout.\n"); + printf(" -v, --version prints this program's version.\n"); + exit(0); + break; + } + } } -static int load_mysql_config() { - char *mysql_host, *mysql_user, *mysql_pass, *mysql_base; - int mysql_serverport; - - mysql_host = get_string_field("MySQL.host"); - if(!mysql_host) { - perror("invalid neonserv.conf: missing MySQL.host"); - return 0; +static void main_daemon_exit() { + remove(process_state.pidfile); +} + +static void main_daemonize() { + #ifndef WIN32 + /* Attempt to fork into the background if daemon mode is on. */ + pid_t pid = fork(); + if (pid < 0) { + fprintf(stderr, "Unable to fork: %s\n", strerror(errno)); + } else if (pid > 0) { + printf("Forking into the background (pid: %d)...\n", pid); + printf_log("main", LOG_INFO, "Forking into the background (pid: %d)...\n", pid); + exit(0); } - mysql_serverport = get_int_field("MySQL.port"); - if(!mysql_serverport) - mysql_serverport = 3306; - mysql_user = get_string_field("MySQL.user"); - if(!mysql_user) { - perror("invalid neonserv.conf: missing MySQL.user"); - return 0; + setsid(); + process_state.daemonized = 1; + atexit(main_daemon_exit); + FILE *pidfile = fopen(process_state.pidfile, "w"); + if (pidfile == NULL) { + fprintf(stderr, "Unable to create PID file: %s\n", strerror(errno)); + printf_log("main", LOG_ERROR, "Unable to create PID file: %s\n", strerror(errno)); + } else { + fprintf(pidfile, "%i\n", (int)getpid()); + fclose(pidfile); } - mysql_pass = get_string_field("MySQL.pass"); - if(!mysql_pass) { - perror("invalid neonserv.conf: missing MySQL.pass"); - return 0; + FILE *retn; + fclose(stdin); retn = fopen("/dev/null", "r"); + fclose(stdout); retn = fopen("/dev/null", "w"); + fclose(stderr); retn = fopen("/dev/null", "w"); + #endif +} + +static int reload_configuration() { + printf_log("main", LOG_DEBUG, "reloading configuration file: %s", process_state.config); + if(!loadConfig(process_state.config)) { + printf_log("main", LOG_ERROR, "could not reload configuration file: %s", process_state.config); + return 1; } - mysql_base = get_string_field("MySQL.base"); - if(!mysql_base) { - perror("invalid neonserv.conf: missing MySQL base"); - return 0; + if(process_state.loaded_config) { + if(!reload_mysql()) + return 2; + char **modulelist = get_all_fieldnames("modules"); + if(!modulelist || !modulelist[0]) { + free(modulelist); + return 3; + } + free(modulelist); + event_reload(0); } - init_mysql(mysql_host, mysql_serverport, mysql_user, mysql_pass, mysql_base); - return 1; + process_state.loaded_config = 1; + return 0; } -#ifdef HAVE_THREADS -pthread_t *current_threads = NULL; -void * thread_main(void *arg) { - time_t socket_wait; - while(running) { - socket_wait = time(0) + SOCKET_SELECT_TIME; +/* INITIALISATION OF SUBSYSTEMS */ +void initialize_subsystems() { + init_bind(); + init_log(); + printf_log("main", LOG_INFO, "starting up NeonServ %s subsystems...", NEONSERV_VERSION); + init_lang(); + init_parser(); + init_UserNode(); + init_ChanNode(); + init_ModeNode(); + init_modcmd(); + register_module_commands(); + init_handleinfohandler(); + init_tools(); + init_modulefunctions(); + loadModules(); + init_bots(); + init_DBHelper(); + qserver_init(); + load_languages(); + init_statistics(); +} + +void shutdown_subsystems() { + printf_log("main", LOG_INFO, "stopping NeonServ subsystems..."); + free_sockets(1); + //wait 50ms (run iohandler) + { + struct timeval timeout, ctime1, ctime2; + gettimeofday(&ctime1, NULL); + ctime1.tv_usec += 50000; + if(ctime1.tv_usec > 1000000) { + ctime1.tv_usec -= 1000000; + ctime1.tv_sec++; + } do { - if(!socket_loop(SOCKET_SELECT_TIME)) { - putlog(LOGLEVEL_ERROR, "No more active Bots... shutting down."); - cleanup(); - exit(0); - } - } while(time(0) < socket_wait); - clearTempUsers(); - destroyEvents(); - mysql_free(); + timeout.tv_sec = 0; + timeout.tv_usec = 10000; + iohandler_poll_timeout(timeout); + gettimeofday(&ctime2, NULL); + } while(timeval_is_bigger(ctime1, ctime2)); } - running_threads--; - return NULL; + stop_modules(); + free_sockets(0); + qserver_free(); + free_parser(); + free_UserNode(); + free_ChanNode(); + free_bind(); + free_modcmd(); + free_whoqueue(); + free_mysql(); + free_handleinfohandler(); + free_lang(); } +/* THREAD CONTROL */ +#ifdef HAVE_THREADS int getCurrentThreadID() { if(!current_threads) return 0; int i; unsigned int my_tid = (unsigned int) pthread_self_tid(); - for(i = 0; i < running_threads; i++) { + for(i = 0; i < process_state.running_threads; i++) { #ifdef WIN32 if((unsigned int) current_threads[i].p == my_tid) #else @@ -142,255 +232,188 @@ int getCurrentThreadID() { } return 0; } - #endif -void exit_daemon() { - if(daemonized) { - remove(PID_FILE); - } +int getRunningThreads() { + #ifdef HAVE_THREADS + return process_state.running_threads; + #else + return 1; + #endif } -int main(int argc, char *argv[]) { - int run_as_daemon = 1; - int argi; - process_argv = argv; - process_argc = argc; - printf("NeonServ v%s\n\n", NEONSERV_VERSION); - for(argi = 1; argi < argc; argi++) { - if(!strcmp(argv[argi], "-f") || !strcmp(argv[argi], "--foreground")) { - run_as_daemon = 0; - } else if(!strcmp(argv[argi], "-s") || !strcmp(argv[argi], "--show")) { - if(argi+1 == argc) break; - argi++; - print_loglevel = atoi(argv[argi]); - } else if(!strcmp(argv[argi], "-v") || !strcmp(argv[argi], "--version")) { - printf("Version: %s.%d (%s)\n", NEONSERV_VERSION, patchlevel, (strcmp(revision, "") ? revision : "-")); - printf("Build: #%s %s (%s lines, " COMPILER ")\n", compilation, creation, codelines); - exit(0); - } else if(!strcmp(argv[argi], "-h") || !strcmp(argv[argi], "--help")) { - printf("Usage: ./neonserv [-s loglevel] [-f] [-h|-v]\n"); - printf(" -s, --show show log lines matching loglevel in stdout.\n"); - printf(" -f, --foreground run NeonServ in the foreground.\n"); - printf(" -h, --help prints this usage message.\n"); - printf(" -v, --version prints this program's version.\n"); - exit(0); +static void main_start_threads() { + int worker_threads = get_int_field("General.worker_threads"); + if(!worker_threads) worker_threads = 1; + #ifdef HAVE_THREADS + int tid_id = 0; + { + current_threads = calloc(worker_threads, sizeof(*current_threads)); + for(tid_id = 0; tid_id < worker_threads; tid_id++) { + process_state.running_threads++; + pthread_create(¤t_threads[tid_id], NULL, main_tread, NULL); } } - if(geteuid() == 0 || getuid() == 0) { - fprintf(stderr, "NeonServ may not be run with super user privileges.\n"); - exit(0); - } - if(!loadConfig(CONF_FILE)) { - fprintf(stderr, "Unable to load " CONF_FILE "\n"); - exit(0); - } - #if HAVE_THREADS - THREAD_MUTEX_INIT(log_sync); #endif - if(!load_mysql_config()) { - fprintf(stderr, "Unable to connect to MySQL\n"); - exit(0); - } - check_firstrun(); - if (run_as_daemon) { - /* Attempt to fork into the background if daemon mode is on. */ - pid_t pid = fork(); - if (pid < 0) { - fprintf(stderr, "Unable to fork: %s\n", strerror(errno)); - } else if (pid > 0) { - printf("Forking into the background (pid: %d)...\n", pid); - putlog(LOGLEVEL_INFO, "Forking into the background (pid: %d)...\n", pid); - exit(0); - } - setsid(); - daemonized = 1; - atexit(exit_daemon); - FILE *pidfile = fopen(PID_FILE, "w"); - if (pidfile == NULL) { - fprintf(stderr, "Unable to create PID file: %s", strerror(errno)); - putlog(LOGLEVEL_ERROR, "Unable to create PID file: %s", strerror(errno)); - } else { - fprintf(pidfile, "%i\n", (int)getpid()); - fclose(pidfile); + main_tread(NULL); + #ifdef HAVE_THREADS + { + for(tid_id = 0; tid_id < worker_threads; tid_id++) { + pthread_join(current_threads[tid_id], NULL); } - fclose(stdin); - fclose(stdout); - fclose(stderr); + process_state.running_threads = 0; + } + #endif +} + +/* MAIN FUNCTION(S) */ + +static void *main_tread(void *empty) { + while(process_state.running) { + iohandler_poll(); } + return NULL; +} + +static void main_restart_process() { + /* Append a NULL to the end of argv[]. */ + char **restart_argv = (char **)alloca((process_state.argc + 1) * sizeof(char *)); + memcpy(restart_argv, process_state.argv, process_state.argc * sizeof(char *)); + restart_argv[process_state.argc] = NULL; + #ifdef WIN32 + execv(process_state.argv[0], (const char * const*)restart_argv); + #else + execv(process_state.argv[0], restart_argv); + #endif +} + +int main(int argc, char *argv[]) { + memset(&process_state, 0, sizeof(process_state)); + printf("NeonServ v%s\n\n", NEONSERV_VERSION); -main: - signal(SIGABRT, sighandler); - signal(SIGFPE, sighandler); - signal(SIGILL, sighandler); - signal(SIGINT, sighandler); - signal(SIGSEGV, sighandler); - signal(SIGTERM, sighandler); + process_state.argv = argv; + process_state.argc = argc; + process_state.run_as_daemon = 1; + strcpy(process_state.config, DEFAULT_CONF_FILE); + strcpy(process_state.pidfile, DEFAULT_PID_FILE); + + //parse argv + main_parse_arguments(); + //initialize memory debugger BEFORE allocating memory #ifdef ENABLE_MEMORY_DEBUG initMemoryDebug(); #endif - start_time = time(0); + //initialize mutex debugger BEFORE using any mutexes + #ifdef ENABLE_MUTEX_DEBUG + initMutexDebug(); + #endif - #ifdef WIN32 - int res; - WSADATA wsadata; - // Start Windows Sockets. - res = WSAStartup(MAKEWORD(2, 0), &wsadata); - if (res) - { - perror("Unable to start Windows Sockets"); - return 0; + //deny root startup + #ifndef WIN32 + if(geteuid() == 0 || getuid() == 0) { + fprintf(stderr, "NeonServ may not be run with super user privileges.\n"); + exit(0); } #endif - statistics_enabled = get_int_field("statistics.enable"); + //load configuration + int errid; + if((errid = reload_configuration())) { + fprintf(stderr, "Unable to load configuration file `%s`. (errid: %d)\n", process_state.config, errid); + exit(0); + } - #ifdef HAVE_THREADS + //check mysql configuration + if(!reload_mysql()) { + fprintf(stderr, "Unable to load MySQL configuration.\n"); + exit(0); + } + + //check module configuration + char **modulelist = get_all_fieldnames("modules"); + if(!modulelist || !modulelist[0]) { + fprintf(stderr, "Unable to load Module configuration.\n"); + exit(0); + } + free(modulelist); + + #if HAVE_THREADS THREAD_MUTEX_INIT(cache_sync); THREAD_MUTEX_INIT(whohandler_sync); THREAD_MUTEX_INIT(whohandler_mass_sync); #endif - queue_init(); - init_sockets(); - init_timeq(); - init_lang(); - ssl_init(); - init_parser(); - init_UserNode(); - init_ChanNode(); - init_ModeNode(); - init_bind(); - init_modcmd(); - init_handleinfohandler(); - init_tools(); - register_commands(); - init_bots(); - init_DBHelper(); - qserver_init(); + //connect to mysql and check if it's the frst bot startup + init_mysql(); + check_firstrun(); - load_languages(); - int update_minutes = get_int_field("statistics.frequency"); - if(!update_minutes) update_minutes = 2; - timeq_add(update_minutes * 60 + 10, main_statistics, NULL); + //deamonize if wanted + if(process_state.run_as_daemon) + main_daemonize(); - timeq_add(90, main_checkauths, NULL); + //set signal handlers + signal(SIGABRT, sighandler); + signal(SIGFPE, sighandler); + signal(SIGILL, sighandler); + signal(SIGINT, sighandler); + signal(SIGSEGV, sighandler); + signal(SIGTERM, sighandler); - int worker_threads = get_int_field("General.worker_threads"); - if(!worker_threads) worker_threads = 1; - running = 1; - #ifdef HAVE_THREADS - int tid_id = 0; - current_threads = calloc(worker_threads, sizeof(*current_threads)); - for(tid_id = 0; tid_id < worker_threads; tid_id++) { - running_threads++; - pthread_create(¤t_threads[tid_id], NULL, thread_main, NULL); - } - int usleep_delay = 1000000 / TICKS_PER_SECOND; - while(running) { - timeq_tick(); - loop_bots(); - qserver_loop(); - queue_loop(); - mysql_free(); - usleep(usleep_delay); - } - for(tid_id = 0; tid_id < worker_threads; tid_id++) { - pthread_join(current_threads[tid_id], NULL); - } - running_threads = 0; - #else - time_t socket_wait; - while(running) { - socket_wait = time(0) + SOCKET_SELECT_TIME; - do { - if(!socket_loop(SOCKET_SELECT_TIME)) { - putlog(LOGLEVEL_ERROR, "No more active Bots... shutting down."); - cleanup(); - exit(0); - } - } while(time(0) < socket_wait); - timeq_tick(); - loop_bots(); - clearTempUsers(); - destroyEvents(); - qserver_loop(); - queue_loop(); - mysql_free(); - } - #endif - cleanup(); - if(hard_restart) { - restart_process(); - } - goto main; -} - -void restart_process() { - /* Append a NULL to the end of argv[]. */ - char **restart_argv = (char **)alloca((process_argc + 1) * sizeof(char *)); - memcpy(restart_argv, process_argv, process_argc * sizeof(char *)); - restart_argv[process_argc] = NULL; - #ifdef WIN32 - execv(process_argv[0], (const char * const*)restart_argv); - #else - execv(process_argv[0], restart_argv); - #endif -} - -int stricmp (const char *s1, const char *s2) -{ - if (s1 == NULL) return s2 == NULL ? 0 : -(*s2); - if (s2 == NULL) return *s1; - char c1, c2; - while ((c1 = tolower (*s1)) == (c2 = tolower (*s2))) - { - if (*s1 == '\0') break; - ++s1; ++s2; - } - return c1 - c2; + //set start time and initialize other code parts + process_state.running = 1; + process_state.start_time = time(0); + initialize_subsystems(); + + //start timers + timeq_add(CLEAR_CACHE_INTERVAL, 0, clear_cache, NULL); + timeq_add(90, 0, main_checkauths, NULL); + + //start worker threads + main_start_threads(); //BLOCKING + + //shutdown sequence... + shutdown_subsystems(); + if(process_state.restart) + main_restart_process(); //terminates the current process on success + + //eop (end of program :P) + //trust me, thats the end! + exit(0); } -int stricmplen (const char *s1, const char *s2, int len) -{ - if (s1 == NULL) return s2 == NULL ? 0 : -(*s2); - if (s2 == NULL) return *s1; - char c1, c2; - int i = 0; - while ((c1 = tolower (*s1)) == (c2 = tolower (*s2))) - { - i++; - if (*s1 == '\0') break; - ++s1; ++s2; - if(i == len) break; - } - return c1 - c2; +/* BOT INFORMATION */ +time_t getStartTime() { + return process_state.start_time; } -void restart_bot(int do_hard_restart) { - hard_restart = do_hard_restart; - running = 0; +/* BOT CONTROL */ +void restart_bot(int crash) { + if(crash) { + main_daemon_exit(); + main_restart_process(); + } else { + process_state.restart = 1; + process_state.running = 0; + } } void stop_bot() { - cleanup(); - exit(0); + process_state.running = 0; } void reload_config() { - loadConfig(CONF_FILE); + reload_configuration(); } -static int getCurrentSecondsOfDay() { - time_t now = time(0); - struct tm *timeofday = localtime(&now); - int seconds = 0; - seconds += timeofday->tm_hour * 3600; - seconds += timeofday->tm_min * 60; - seconds += timeofday->tm_sec; - return seconds; +/* TIMER FUNCTIONS */ + +static TIMEQ_CALLBACK(clear_cache) { + timeq_add(CLEAR_CACHE_INTERVAL, 0, clear_cache, NULL); + clearTempUsers(); + destroyEvents(); + mysql_free(); } static AUTHLOOKUP_CALLBACK(main_checkauths_callback) { @@ -400,15 +423,24 @@ static AUTHLOOKUP_CALLBACK(main_checkauths_callback) { printf_mysql_query("SELECT `user_id`, `user_registered` FROM `users` WHERE `user_user` = '%s'", escape_string(auth)); res = mysql_use(); if ((row = mysql_fetch_row(res)) != NULL) { - if(!exists || (strcmp(row[1], "0") && registered != atoi(row[1]))) { + int diff = registered - atoi(row[1]); + if(diff < 0) + diff *= -1; + if(!exists || (strcmp(row[1], "0") && diff > 86400)) { //User is no longer valid! Delete it... deleteUser(atoi(row[0])); char *alertchan = get_string_field("General.CheckAuths.alertchan"); if(alertchan) { + char reason[MAXLEN]; + if(!exists) { + strcpy(reason, "USER_NOT_EXISTS"); + } else { + sprintf(reason, "USER_REGISTERED_MISSMATCH: %lu, expected %d (diff: %d)", (unsigned long) registered, atoi(row[1]), diff); + } struct ChanNode *alertchan_chan = getChanByName(alertchan); struct ClientSocket *alertclient; if(alertchan_chan && (alertclient = getChannelBot(alertchan_chan, 0)) != NULL) { - putsock(alertclient, "PRIVMSG %s :Deleted User %s", alertchan_chan->name, auth); + putsock(alertclient, "PRIVMSG %s :Deleted User %s (%s)", alertchan_chan->name, auth, reason); } } } else if(exists && !strcmp(row[1], "0")) { @@ -419,7 +451,7 @@ static AUTHLOOKUP_CALLBACK(main_checkauths_callback) { } } -TIMEQ_CALLBACK(main_checkauths) { +static TIMEQ_CALLBACK(main_checkauths) { int next_call = 600; if(get_int_field("General.CheckAuths.enabled")) { int check_start_time = get_int_field("General.CheckAuths.start_time") * 3600; @@ -441,7 +473,7 @@ TIMEQ_CALLBACK(main_checkauths) { if ((row = mysql_fetch_row(res)) != NULL) { lastcheck = atoi(row[1]); if(!lastcheck || unixtime - lastcheck >= min_unckecked) { - lookup_authname(row[0], main_checkauths_callback, NULL); + lookup_authname(row[0], 0, main_checkauths_callback, NULL); } else next_call = 300; } @@ -456,89 +488,10 @@ TIMEQ_CALLBACK(main_checkauths) { } } - timeq_add(next_call, main_checkauths, NULL); -} - -TIMEQ_CALLBACK(main_statistics) { - int update_minutes = get_int_field("statistics.frequency"); - if(!update_minutes) update_minutes = 2; - timeq_add(update_minutes * 60, main_statistics, NULL); - if(get_int_field("statistics.enable")) { - statistics_enabled = 1; - statistics_requested_lusers = 1; - if(get_int_field("statistics.include_lusers")) { - struct ClientSocket *bot, *lusersbot = NULL; - for(bot = getBots(SOCKET_FLAG_READY, NULL); bot; bot = getBots(SOCKET_FLAG_READY, bot)) { - if(bot->flags & SOCKET_FLAG_PREFERRED) - lusersbot = bot; - } - bot = lusersbot; - if(bot == NULL) bot = getBots(SOCKET_FLAG_READY, NULL); - putsock(bot, "LUSERS"); - } else { - statistics_update(); - } - } else - statistics_enabled = 0; -} - -void statistics_update() { - if(get_int_field("statistics.enable") && statistics_requested_lusers && get_string_field("statistics.execute")) { - statistics_requested_lusers = 0; - char command[MAXLEN]; - /* parameters: - - visible users - - visible chanusers - - visible channels - - privmsg per minute - - commands per minute - - network users - - network channels - */ - sprintf(command, "%s %d %d %d %d %d %d %d", get_string_field("statistics.execute"), getUserCount(), getChanUserCount(), getChannelCount(), statistics_privmsg, statistics_commands, statistics_network_users, statistics_network_channels); - statistics_privmsg = 0; - statistics_commands = 0; - system(command); - } + timeq_add(next_call, 0, main_checkauths, NULL); } -void write_log(int loglevel, const char *line, int len) { - SYNCHRONIZE(log_sync); - if(!daemonized && (print_loglevel & loglevel)) { - printf("%s", line); - } else if(!daemonized && loglevel == LOGLEVEL_ERROR) { - fprintf(stderr, "%s", line); - } - if(get_int_field("log.loglevel") & loglevel) { - if(!log_fptr) { - log_fptr = fopen(LOG_FILE, "a"); - if(!log_fptr) goto write_log_end; - } - time_t rawtime; - struct tm *timeinfo; - time(&rawtime); - timeinfo = localtime(&rawtime); - char timestr[20]; - int timepos = strftime(timestr, 20, "%x %X ", timeinfo); - fwrite(timestr, 1, timepos, log_fptr); - fwrite(line, 1, len, log_fptr); - } - write_log_end: - DESYNCHRONIZE(log_sync); -} - -void putlog(int loglevel, const char *text, ...) { - va_list arg_list; - char logBuf[MAXLOGLEN]; - int pos; - logBuf[0] = '\0'; - va_start(arg_list, text); - pos = vsnprintf(logBuf, MAXLOGLEN - 1, text, arg_list); - va_end(arg_list); - if (pos < 0 || pos > (MAXLOGLEN - 1)) pos = MAXLOGLEN - 1; - logBuf[pos] = '\0'; - write_log(loglevel, logBuf, pos); -} +/* INSTALLATION SCRIPT */ static void check_firstrun() { MYSQL_RES *res; @@ -552,7 +505,7 @@ static void check_firstrun() { printf("AuthServ account name of admin user: "); char *ptr; char adminuser[31]; - fgets(adminuser, 30, stdin); + ptr = fgets(adminuser, 30, stdin); for(ptr = adminuser; *ptr; ptr++) { if(*ptr == '\n' || *ptr == '\r') *ptr = '\0'; } if(strlen(adminuser) < 2) goto check_firstrun_admin; printf_mysql_query("SELECT `user_id` FROM `users` WHERE `user_user` = '%s'", escape_string(adminuser)); @@ -572,25 +525,25 @@ static void check_firstrun() { char bot_nick[31]; check_firstrun_bot_nick: printf("Nick: "); - fgets(bot_nick, 30, stdin); + ptr = fgets(bot_nick, 30, stdin); for(ptr = bot_nick; *ptr; ptr++) { if(*ptr == '\n' || *ptr == '\r') *ptr = '\0'; } if(strlen(bot_nick) < 2) goto check_firstrun_bot_nick; char bot_ident[16]; check_firstrun_bot_ident: printf("Ident: "); - fgets(bot_ident, 15, stdin); + ptr = fgets(bot_ident, 15, stdin); for(ptr = bot_ident; *ptr; ptr++) { if(*ptr == '\n' || *ptr == '\r') *ptr = '\0'; } if(strlen(bot_ident) < 2) goto check_firstrun_bot_ident; char bot_realname[101]; check_firstrun_bot_realname: printf("Realname: "); - fgets(bot_realname, 100, stdin); + ptr = fgets(bot_realname, 100, stdin); for(ptr = bot_realname; *ptr; ptr++) { if(*ptr == '\n' || *ptr == '\r') *ptr = '\0'; } if(strlen(bot_realname) < 2) goto check_firstrun_bot_realname; char bot_server[101]; check_firstrun_bot_server: printf("Server: [irc.onlinegamesnet.net] "); - fgets(bot_server, 100, stdin); + ptr = fgets(bot_server, 100, stdin); for(ptr = bot_server; *ptr; ptr++) { if(*ptr == '\n' || *ptr == '\r') *ptr = '\0'; } if(*bot_server && strlen(bot_nick) < 5) goto check_firstrun_bot_server; if(!*bot_server) @@ -598,7 +551,7 @@ static void check_firstrun() { int bot_port; char bot_port_buf[7]; printf("Port: [6667] "); - fgets(bot_port_buf, 6, stdin); + ptr = fgets(bot_port_buf, 6, stdin); for(ptr = bot_port_buf; *ptr; ptr++) { if(*ptr == '\n' || *ptr == '\r') *ptr = '\0'; } if(!*bot_port_buf) bot_port = 6667; @@ -608,7 +561,7 @@ static void check_firstrun() { char bot_ssl_buf[5]; check_firstrun_bot_ssl: printf("SSL: [y/N] "); - fgets(bot_ssl_buf, 4, stdin); + ptr = fgets(bot_ssl_buf, 4, stdin); for(ptr = bot_ssl_buf; *ptr; ptr++) { if(*ptr == '\n' || *ptr == '\r') *ptr = '\0'; } if(!*bot_ssl_buf || tolower(*bot_ssl_buf) == 'n') bot_ssl = 0; @@ -618,12 +571,12 @@ static void check_firstrun() { goto check_firstrun_bot_ssl; char bot_pass[101]; printf("Server Password: [] "); - fgets(bot_pass, 100, stdin); + ptr = fgets(bot_pass, 100, stdin); for(ptr = bot_pass; *ptr; ptr++) { if(*ptr == '\n' || *ptr == '\r') *ptr = '\0'; } int bot_maxchan; char bot_maxchan_buf[5]; printf("MaxChannel: [20] "); - fgets(bot_maxchan_buf, 5, stdin); + ptr = fgets(bot_maxchan_buf, 5, stdin); for(ptr = bot_maxchan_buf; *ptr; ptr++) { if(*ptr == '\n' || *ptr == '\r') *ptr = '\0'; } if(*bot_maxchan_buf) bot_maxchan = atoi(bot_maxchan_buf); @@ -633,7 +586,7 @@ static void check_firstrun() { char bot_queue_buf[5]; check_firstrun_bot_queue: printf("Queue (prevents excess floods): [Y/n] "); - fgets(bot_queue_buf, 4, stdin); + ptr = fgets(bot_queue_buf, 4, stdin); for(ptr = bot_queue_buf; *ptr; ptr++) { if(*ptr == '\n' || *ptr == '\r') *ptr = '\0'; } if(!*bot_queue_buf || tolower(*bot_queue_buf) == 'y') bot_queue = 1;