#define DEFAULT_PID_FILE "neonserv.pid"
#define DEFAULT_CONF_FILE "neonserv.conf"
-#define DEFAULT_LOG_FILE "neonserv.log"
#include "main.h"
#include "signal.h"
#include "ModuleFunctions.h"
#include "IOHandler.h"
#include "statistics.h"
+#include "log.h"
-static struct {
- time_t start_time;
- int running : 1;
- int restart : 1;
- int run_as_daemon : 1;
- int daemonized : 1;
- int loglevel : 8;
- int loaded_config : 1;
- int running_threads : 8;
-
- int argc;
- char **argv;
-
- char config[MAXLEN];
- char pidfile[MAXLEN];
-} process_state;
-
-static FILE *log_fptr = NULL;
+struct ProcessState process_state;
#ifdef HAVE_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 void *main_tread(void *empty);
static TIMEQ_CALLBACK(clear_cache);
static TIMEQ_CALLBACK(main_checkauths);
static void check_firstrun();
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);
+ printf_log("main", LOG_INFO, "Forking into the background (pid: %d)...\n", pid);
exit(0);
}
setsid();
FILE *pidfile = fopen(process_state.pidfile, "w");
if (pidfile == NULL) {
fprintf(stderr, "Unable to create PID file: %s\n", strerror(errno));
- putlog(LOGLEVEL_ERROR, "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);
}
static int reload_configuration() {
- if(!loadConfig(process_state.config))
+ 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;
+ }
if(process_state.loaded_config) {
if(!reload_mysql())
return 2;
/* 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_bind();
init_modcmd();
register_module_commands();
init_handleinfohandler();
}
void shutdown_subsystems() {
+ printf_log("main", LOG_INFO, "stopping NeonServ subsystems...");
free_sockets(1);
- usleep(10000); //wait for disconnect (10ms)
+ //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 {
+ timeout.tv_sec = 0;
+ timeout.tv_usec = 10000;
+ iohandler_poll_timeout(timeout);
+ gettimeofday(&ctime2, NULL);
+ } while(timeval_is_bigger(ctime1, ctime2));
+ }
stop_modules();
free_sockets(0);
qserver_free();
}
static void main_start_threads() {
- int tid_id = 0;
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++) {
/* MAIN FUNCTION(S) */
-static void main_tread(void *empty) {
+static void *main_tread(void *empty) {
while(process_state.running) {
iohandler_poll();
}
+ return NULL;
}
static void main_restart_process() {
initMemoryDebug();
#endif
+ //initialize mutex debugger BEFORE using any mutexes
+ #ifdef ENABLE_MUTEX_DEBUG
+ initMutexDebug();
+ #endif
+
//deny root startup
#ifndef WIN32
if(geteuid() == 0 || getuid() == 0) {
//load configuration
int errid;
- if(errid = reload_configuration()) {
+ if((errid = reload_configuration())) {
fprintf(stderr, "Unable to load configuration file `%s`. (errid: %d)\n", process_state.config, errid);
exit(0);
}
free(modulelist);
#if HAVE_THREADS
- THREAD_MUTEX_INIT(log_sync);
THREAD_MUTEX_INIT(cache_sync);
THREAD_MUTEX_INIT(whohandler_sync);
THREAD_MUTEX_INIT(whohandler_mass_sync);
timeq_add(next_call, 0, main_checkauths, NULL);
}
-/* LOG BACKEND */
-
-void write_log(int loglevel, const char *line, int len) {
- SYNCHRONIZE(log_sync);
- if(!process_state.daemonized && (process_state.loglevel & loglevel)) {
- printf("%s", line);
- } else if(!process_state.daemonized && loglevel == LOGLEVEL_ERROR) {
- fprintf(stderr, "%s", line);
- }
- if(get_int_field("log.loglevel") & loglevel) {
- if(!log_fptr) {
- log_fptr = fopen(DEFAULT_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() {