]> jfr.im git - irc/quakenet/newserv.git/blob - core/main.c
core: Create the data directory if it doesn't already exist.
[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(SIGINT, siginthandler);
71 signal(SIGUSR1, sigusr1handler);
72 signal(SIGHUP, sighuphandler);
73 oldsegv = signal(SIGSEGV, sigsegvhandler);
74
75 /* Main loop */
76 for(;;) {
77 handleevents(10);
78 doscheduledevents(time(NULL));
79
80 if (newserv_shutdown_pending) {
81 newserv_shutdown();
82 break;
83 }
84
85 handlesignals();
86 }
87
88 freeconfig();
89
90 fini_logfile();
91 finischedule();
92 finihandlers();
93
94 nsexit();
95
96 if (RUNNING_ON_VALGRIND) {
97 /* We've already manually called _fini for each of the modules. Make sure
98 * it's not getting called again when the libraries are unloaded. */
99 _exit(0);
100 }
101
102 return 0;
103 }
104
105 void handlesignals(void) {
106 if (newserv_sigusr1_pending) {
107 signal(SIGUSR1, sigusr1handler);
108 Error("core", ERR_INFO, "SIGUSR1 received.");
109 triggerhook(HOOK_CORE_SIGUSR1, NULL);
110 newserv_sigusr1_pending=0;
111 }
112
113 if (newserv_sighup_pending) {
114 signal(SIGHUP, sighuphandler);
115 Error("core", ERR_INFO, "SIGHUP received, rehashing...");
116 triggerhook(HOOK_CORE_REHASH, (void *)1);
117 newserv_sighup_pending=0;
118 }
119
120 if (newserv_sigint_pending) {
121 Error("core", ERR_INFO, "SIGINT received, terminating.");
122 triggerhook(HOOK_CORE_SIGINT, NULL);
123 newserv_sigint_pending=0;
124 newserv_shutdown_pending=1;
125 }
126 }
127
128 /*
129 * seed the pseudo-random number generator, rand()
130 */
131 void initseed() {
132 struct timeval t;
133
134 gettimeofday(&t, NULL);
135 srand(t.tv_usec);
136 }
137
138 void siginthandler(int sig) {
139 newserv_sigint_pending = 1;
140 }
141
142 void sigusr1handler(int sig) {
143 newserv_sigusr1_pending = 1;
144 }
145
146 void sighuphandler(int sig) {
147 newserv_sighup_pending = 1;
148 }
149
150 void sigsegvhandler(int sig) {
151 handlecore();
152
153 oldsegv(sig);
154 }