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