]> jfr.im git - irc/quakenet/newserv.git/blob - core/main.c
Merge default.
[irc/quakenet/newserv.git] / core / main.c
1 #include "../lib/sstring.h"
2 #include "../lib/valgrind.h"
3 #include "events.h"
4 #include "schedule.h"
5 #include "hooks.h"
6 #include "modules.h"
7 #include "config.h"
8 #include "error.h"
9 #include "nsmalloc.h"
10
11 #include <stdlib.h>
12 #include <stdio.h>
13 #include <string.h>
14 #include <time.h>
15 #include <sys/time.h>
16 #include <signal.h>
17 #include <unistd.h>
18
19 void initseed();
20 void init_logfile();
21 void fini_logfile();
22 void siginthandler(int sig);
23 void sigusr1handler(int sig);
24 void sigsegvhandler(int sig);
25 void sighuphandler(int sig);
26 void handlecore(void);
27 void handlesignals(void);
28
29 int newserv_shutdown_pending;
30 static int newserv_sigint_pending, newserv_sigusr1_pending, newserv_sighup_pending;
31 static void (*oldsegv)(int);
32
33 int main(int argc, char **argv) {
34 char *config = "newserv.conf";
35
36 nsinit();
37
38 initseed();
39 inithooks();
40 inithandlers();
41 initschedule();
42
43 init_logfile();
44
45 if (argc>1) {
46 if (strcmp(argv[1], "--help")==0) {
47 printf("Syntax: %s [config]\n", argv[0]);
48 puts("");
49 printf("Default configuration file unless specified: %s\n", config);
50
51 return 0;
52 }
53
54 config = argv[1];
55 }
56
57 initconfig(config);
58
59 /* Loading the modules will bring in the bulk of the code */
60 initmodules();
61 signal(SIGINT, siginthandler);
62 signal(SIGUSR1, sigusr1handler);
63 signal(SIGHUP, sighuphandler);
64 oldsegv = signal(SIGSEGV, sigsegvhandler);
65
66 /* Main loop */
67 for(;;) {
68 handleevents(10);
69 doscheduledevents(time(NULL));
70
71 if (newserv_shutdown_pending) {
72 newserv_shutdown();
73 break;
74 }
75
76 handlesignals();
77 }
78
79 freeconfig();
80
81 fini_logfile();
82 finischedule();
83 finihandlers();
84
85 nsexit();
86
87 if (RUNNING_ON_VALGRIND) {
88 /* We've already manually called _fini for each of the modules. Make sure
89 * it's not getting called again when the libraries are unloaded. */
90 _exit(0);
91 }
92
93 return 0;
94 }
95
96 void handlesignals(void) {
97 if (newserv_sigusr1_pending) {
98 signal(SIGUSR1, sigusr1handler);
99 Error("core", ERR_INFO, "SIGUSR1 received.");
100 triggerhook(HOOK_CORE_SIGUSR1, NULL);
101 newserv_sigusr1_pending=0;
102 }
103
104 if (newserv_sighup_pending) {
105 signal(SIGHUP, sighuphandler);
106 Error("core", ERR_INFO, "SIGHUP received, rehashing...");
107 triggerhook(HOOK_CORE_REHASH, (void *)1);
108 newserv_sighup_pending=0;
109 }
110
111 if (newserv_sigint_pending) {
112 Error("core", ERR_INFO, "SIGINT received, terminating.");
113 triggerhook(HOOK_CORE_SIGINT, NULL);
114 newserv_sigint_pending=0;
115 newserv_shutdown_pending=1;
116 }
117 }
118
119 /*
120 * seed the pseudo-random number generator, rand()
121 */
122 void initseed() {
123 struct timeval t;
124
125 gettimeofday(&t, NULL);
126 srand(t.tv_usec);
127 }
128
129 void siginthandler(int sig) {
130 newserv_sigint_pending = 1;
131 }
132
133 void sigusr1handler(int sig) {
134 newserv_sigusr1_pending = 1;
135 }
136
137 void sighuphandler(int sig) {
138 newserv_sighup_pending = 1;
139 }
140
141 void sigsegvhandler(int sig) {
142 handlecore();
143
144 oldsegv(sig);
145 }