#include "../lib/sstring.h"
+#include "../lib/valgrind.h"
#include "events.h"
#include "schedule.h"
#include "hooks.h"
#include <stdlib.h>
#include <stdio.h>
+#include <string.h>
#include <time.h>
#include <sys/time.h>
-
-int newserv_shutdown_pending;
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <errno.h>
+#include <signal.h>
+#include <unistd.h>
void initseed();
void init_logfile();
+void fini_logfile();
+void siginthandler(int sig);
+void sigusr1handler(int sig);
+void sigsegvhandler(int sig);
+void sighuphandler(int sig);
+void handlecore(void);
+void handlesignals(void);
+
+int newserv_shutdown_pending;
+static int newserv_sigint_pending, newserv_sigusr1_pending, newserv_sighup_pending;
+static void (*oldsegv)(int);
int main(int argc, char **argv) {
+ char *config = "newserv.conf";
+
+ nsinit();
+
initseed();
inithooks();
inithandlers();
init_logfile();
- initsstring();
-
if (argc>1) {
- initconfig(argv[1]);
- } else {
- initconfig("newserv.conf");
+ if (strcmp(argv[1], "--help")==0) {
+ printf("Syntax: %s [config]\n", argv[0]);
+ puts("");
+ printf("Default configuration file unless specified: %s\n", config);
+
+ return 0;
+ }
+
+ config = argv[1];
+ }
+
+ initconfig(config);
+
+ /* modules can rely on this directory always being there */
+ if (mkdir("data", 0700) < 0 && errno != EEXIST) {
+ perror("mkdir");
+ return 1;
}
/* Loading the modules will bring in the bulk of the code */
initmodules();
+ signal(SIGPIPE, SIG_IGN);
+ signal(SIGINT, siginthandler);
+ signal(SIGUSR1, sigusr1handler);
+ signal(SIGHUP, sighuphandler);
+ oldsegv = signal(SIGSEGV, sigsegvhandler);
/* Main loop */
for(;;) {
handleevents(10);
doscheduledevents(time(NULL));
+
if (newserv_shutdown_pending) {
newserv_shutdown();
break;
}
+
+ handlesignals();
}
-
- nsfreeall(POOL_SSTRING);
+
+ freeconfig();
+
+ fini_logfile();
+ finischedule();
+ finihandlers();
+
nsexit();
+
+ if (RUNNING_ON_VALGRIND) {
+ /* We've already manually called _fini for each of the modules. Make sure
+ * it's not getting called again when the libraries are unloaded. */
+ _exit(0);
+ }
+
+ return 0;
+}
+
+void handlesignals(void) {
+ if (newserv_sigusr1_pending) {
+ signal(SIGUSR1, sigusr1handler);
+ Error("core", ERR_INFO, "SIGUSR1 received.");
+ triggerhook(HOOK_CORE_SIGUSR1, NULL);
+ newserv_sigusr1_pending=0;
+ }
+
+ if (newserv_sighup_pending) {
+ signal(SIGHUP, sighuphandler);
+ Error("core", ERR_INFO, "SIGHUP received, rehashing...");
+ triggerhook(HOOK_CORE_REHASH, (void *)1);
+ newserv_sighup_pending=0;
+ }
+
+ if (newserv_sigint_pending) {
+ Error("core", ERR_INFO, "SIGINT received, terminating.");
+ triggerhook(HOOK_CORE_SIGINT, NULL);
+ newserv_sigint_pending=0;
+ newserv_shutdown_pending=1;
+ }
}
/*
gettimeofday(&t, NULL);
srand(t.tv_usec);
}
+
+void siginthandler(int sig) {
+ newserv_sigint_pending = 1;
+}
+
+void sigusr1handler(int sig) {
+ newserv_sigusr1_pending = 1;
+}
+
+void sighuphandler(int sig) {
+ newserv_sighup_pending = 1;
+}
+
+void sigsegvhandler(int sig) {
+ handlecore();
+
+ oldsegv(sig);
+}