]>
jfr.im git - irc/evilnet/x3.git/blob - src/main.c
2 * Copyright 2000-2006 srvx Development Team
4 * This file is part of X3.
6 * srvx is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 3 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with srvx; if not, write to the Free Software Foundation,
18 * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
21 #define PID_FILE "x3.pid"
44 #ifdef HAVE_SYS_RESOURCE_H
45 #include <sys/resource.h>
47 #ifdef HAVE_NETINET_IN_H
48 #include <netinet/in.h>
50 #ifdef HAVE_SYS_SOCKET_H
51 #include <sys/socket.h>
53 #ifdef HAVE_SYS_WAIT_H
57 #include "main-common.c"
59 void sigaction_writedb(int x
)
61 #ifndef HAVE_STRSIGNAL
62 log_module(MAIN_LOG
, LOG_INFO
, "Signal %d -- writing databases.", x
);
64 log_module(MAIN_LOG
, LOG_INFO
, "%s -- writing databases.", strsignal(x
));
69 void sigaction_exit(int x
)
71 #ifndef HAVE_STRSIGNAL
72 log_module(MAIN_LOG
, LOG_INFO
, "Signal %d -- exiting.", x
);
74 log_module(MAIN_LOG
, LOG_INFO
, "%s -- exiting.", strsignal(x
));
76 irc_squit(self
, "Exiting on signal from console.", NULL
);
80 void sigaction_wait(UNUSED_ARG(int x
))
83 wait4(-1, &code
, WNOHANG
, NULL
);
86 void sigaction_rehash(int x
)
88 #ifndef HAVE_STRSIGNAL
89 log_module(MAIN_LOG
, LOG_INFO
, "Signal %d -- rehashing.", x
);
91 log_module(MAIN_LOG
, LOG_INFO
, "%s -- rehashing.", strsignal(x
));
96 #if WITH_MALLOC_BOEHM_GC
98 gc_warn_proc(char *msg
, GC_word arg
)
100 log_module(MAIN_LOG
, LOG_ERROR
, "GC(%p): %s", (void*)arg
, msg
);
104 int main(int argc
, char *argv
[])
112 #if WITH_MALLOC_BOEHM_GC
114 GC_set_warn_proc(gc_warn_proc
);
115 GC_enable_incremental();
119 log_module(MAIN_LOG
, LOG_INFO
, "changed to %s\n", PREFIX
);
121 log_module(MAIN_LOG
, LOG_WARNING
, "unable to change directory to %s, using current directory instead\n", PREFIX
);
126 /* set up some signal handlers */
127 memset(&sv
, 0, sizeof(sv
));
128 sigemptyset(&sv
.sa_mask
);
129 sv
.sa_handler
= SIG_IGN
;
130 sigaction(SIGPIPE
, &sv
, NULL
);
131 sv
.sa_handler
= sigaction_rehash
;
132 sigaction(SIGHUP
, &sv
, NULL
);
133 sv
.sa_handler
= sigaction_writedb
;
134 sigaction(SIGINT
, &sv
, NULL
);
135 sv
.sa_handler
= sigaction_exit
;
136 sigaction(SIGQUIT
, &sv
, NULL
);
137 sv
.sa_handler
= sigaction_wait
;
138 sigaction(SIGCHLD
, &sv
, NULL
);
140 if (argc
> 1) { /* parse command line, if any */
142 struct option options
[] =
144 {"config", 1, 0, 'c'},
145 {"debug", 0, 0, 'd'},
146 {"foreground", 0, 0, 'f'},
148 {"check", 0, 0, 'k'},
149 {"replay", 1, 0, 'r'},
150 {"version", 0, 0, 'v'},
154 while ((c
= getopt_long(argc
, argv
, "c:dfhkr:v", options
, NULL
)) != -1) {
157 services_config
= optarg
;
160 if (conf_read(services_config
)) {
161 printf("%s appears to be a valid configuration file.\n", services_config
);
163 printf("%s is an invalid configuration file.\n", services_config
);
167 replay_file
= fopen(optarg
, "r");
169 fprintf(stderr
, "Could not open %s for reading: %s (%d)\n",
170 optarg
, strerror(errno
), errno
);
195 /* We read a line here to "prime" the replay file parser, but
196 * mostly to get the right value of "now" for when we do the
204 fprintf(stdout
, "Initializing daemon...\n");
205 if (!conf_read(services_config
)) {
206 fprintf(stderr
, "Unable to read %s.\n", services_config
);
210 conf_register_reload(uplink_compile
);
213 /* Attempt to fork into the background if daemon mode is on. */
216 fprintf(stderr
, "Unable to fork: %s\n", strerror(errno
));
217 } else if (pid
> 0) {
218 fprintf(stdout
, "Forking into the background (pid: %d)...\n", pid
);
224 file_out
= fopen(PID_FILE
, "w");
225 if (file_out
== NULL
) {
226 /* Create the main process' pid file */
227 fprintf(stderr
, "Unable to create PID file: %s", strerror(errno
));
229 fprintf(file_out
, "%i\n", (int)getpid());
234 /* Close these since we should not use them from now on. */
240 services_argc
= argc
;
241 services_argv
= argv
;
243 atexit(call_exit_funcs
);
244 reg_exit_func(main_shutdown
, NULL
);
247 MAIN_LOG
= log_register_type("x3", "file:main.log");
260 conf_globals(); /* initializes the core services */
263 message_register_table(msgtab
);
269 /* The first exit func to be called *should* be saxdb_write_all(). */
270 reg_exit_func(saxdb_write_all
, NULL
);
273 log_module(MAIN_LOG
, LOG_INFO
, "Beginning replay...");
276 if ((msg
= dict_sanity_check(clients
))) {
277 log_module(MAIN_LOG
, LOG_ERROR
, "Clients insanity: %s", msg
);
280 if ((msg
= dict_sanity_check(channels
))) {
281 log_module(MAIN_LOG
, LOG_ERROR
, "Channels insanity: %s", msg
);
284 if ((msg
= dict_sanity_check(servers
))) {
285 log_module(MAIN_LOG
, LOG_ERROR
, "Servers insanity: %s", msg
);