]> jfr.im git - solanum.git/blob - ircd/ircd.c
Merge branch 'authd-framework' of github.com:charybdis-ircd/charybdis into authd...
[solanum.git] / ircd / ircd.c
1 /*
2 * charybdis: A slightly useful ircd.
3 * ircd.c: Starts up and runs the ircd.
4 *
5 * Copyright (C) 1990 Jarkko Oikarinen and University of Oulu, Co Center
6 * Copyright (C) 1996-2002 Hybrid Development Team
7 * Copyright (C) 2002-2008 ircd-ratbox development team
8 * Copyright (C) 2005-2013 charybdis development team
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
23 * USA
24 */
25
26 #include "rb_lib.h"
27 #include "stdinc.h"
28 #include "setup.h"
29 #include "defaults.h"
30 #include "ircd.h"
31 #include "channel.h"
32 #include "class.h"
33 #include "client.h"
34 #include "hash.h"
35 #include "match.h"
36 #include "ircd_signal.h"
37 #include "msg.h" /* msgtab */
38 #include "hostmask.h"
39 #include "numeric.h"
40 #include "parse.h"
41 #include "restart.h"
42 #include "s_conf.h"
43 #include "logger.h"
44 #include "s_serv.h" /* try_connections */
45 #include "s_user.h"
46 #include "s_stats.h"
47 #include "scache.h"
48 #include "send.h"
49 #include "supported.h"
50 #include "whowas.h"
51 #include "modules.h"
52 #include "hook.h"
53 #include "ircd_getopt.h"
54 #include "newconf.h"
55 #include "reject.h"
56 #include "s_conf.h"
57 #include "s_newconf.h"
58 #include "cache.h"
59 #include "monitor.h"
60 #include "patchlevel.h"
61 #include "serno.h"
62 #include "sslproc.h"
63 #include "chmode.h"
64 #include "privilege.h"
65 #include "bandbi.h"
66 #include "authd.h"
67 #include "operhash.h"
68
69 /* /quote set variables */
70 struct SetOptions GlobalSetOptions;
71
72 /* configuration set from ircd.conf */
73 struct config_file_entry ConfigFileEntry;
74 /* server info set from ircd.conf */
75 struct server_info ServerInfo;
76 /* admin info set from ircd.conf */
77 struct admin_info AdminInfo;
78
79 struct Counter Count;
80 struct ServerStatistics ServerStats;
81
82 int maxconnections;
83 struct Client me; /* That's me */
84 struct LocalUser meLocalUser; /* That's also part of me */
85
86 rb_dlink_list global_client_list;
87
88 /* unknown/client pointer lists */
89 rb_dlink_list unknown_list; /* unknown clients ON this server only */
90 rb_dlink_list lclient_list; /* local clients only ON this server */
91 rb_dlink_list serv_list; /* local servers to this server ONLY */
92 rb_dlink_list global_serv_list; /* global servers on the network */
93 rb_dlink_list local_oper_list; /* our opers, duplicated in lclient_list */
94 rb_dlink_list oper_list; /* network opers */
95
96 char **myargv;
97 bool dorehash = false;
98 bool dorehashbans = false;
99 bool doremotd = false;
100 bool kline_queued = false;
101 bool server_state_foreground = false;
102 bool opers_see_all_users = false;
103 bool ircd_ssl_ok = false;
104 bool ircd_zlib_ok = true;
105
106 int testing_conf = 0;
107 time_t startup_time;
108
109 int default_server_capabs;
110
111 int splitmode;
112 int splitchecking;
113 int split_users;
114 int split_servers;
115 int eob_count;
116
117 const char *ircd_paths[IRCD_PATH_COUNT] = {
118 [IRCD_PATH_PREFIX] = DPATH,
119 [IRCD_PATH_MODULES] = MODPATH,
120 [IRCD_PATH_AUTOLOAD_MODULES] = AUTOMODPATH,
121 [IRCD_PATH_ETC] = ETCPATH,
122 [IRCD_PATH_LOG] = LOGPATH,
123 [IRCD_PATH_USERHELP] = UHPATH,
124 [IRCD_PATH_OPERHELP] = HPATH,
125 [IRCD_PATH_IRCD_EXEC] = SPATH,
126 [IRCD_PATH_IRCD_CONF] = CPATH,
127 [IRCD_PATH_IRCD_MOTD] = MPATH,
128 [IRCD_PATH_IRCD_LOG] = LPATH,
129 [IRCD_PATH_IRCD_PID] = PPATH,
130 [IRCD_PATH_IRCD_OMOTD] = OPATH,
131 [IRCD_PATH_BANDB] = DBPATH,
132 [IRCD_PATH_BIN] = BINPATH,
133 [IRCD_PATH_LIBEXEC] = PKGLIBEXECDIR,
134 };
135
136 const char *logFileName = NULL;
137 const char *pidFileName = NULL;
138
139 void
140 ircd_shutdown(const char *reason)
141 {
142 struct Client *target_p;
143 rb_dlink_node *ptr;
144
145 RB_DLINK_FOREACH(ptr, lclient_list.head)
146 {
147 target_p = ptr->data;
148
149 sendto_one(target_p, ":%s NOTICE %s :Server Terminating. %s",
150 me.name, target_p->name, reason);
151 }
152
153 RB_DLINK_FOREACH(ptr, serv_list.head)
154 {
155 target_p = ptr->data;
156
157 sendto_one(target_p, ":%s ERROR :Terminated by %s",
158 me.name, reason);
159 }
160
161 ilog(L_MAIN, "Server Terminating. %s", reason);
162 close_logfiles();
163
164 unlink(pidFileName);
165 exit(0);
166 }
167
168 /*
169 * print_startup - print startup information
170 */
171 static void
172 print_startup(int pid)
173 {
174 int fd;
175
176 #ifndef _WIN32
177 close(1);
178 fd = open("/dev/null", O_RDWR);
179 if (fd == -1) {
180 perror("open /dev/null");
181 exit(EXIT_FAILURE);
182 }
183 if (fd == 0)
184 fd = dup(fd);
185 if (fd != 1)
186 abort();
187 #endif
188 inotice("runtime path: %s", rb_path_to_self());
189 inotice("now running in %s mode from %s as pid %d ...",
190 !server_state_foreground ? "background" : "foreground",
191 ConfigFileEntry.dpath, pid);
192
193 #ifndef _WIN32
194 /* let the parent process know the initialization was successful
195 * -- jilles */
196 if (!server_state_foreground)
197 {
198 /* GCC complains on Linux if we don't check the value of write pedantically.
199 * Technically you're supposed to check the value, yes, but it probably can't fail.
200 * No, casting to void is of no use to shut the warning up. You HAVE to use the value.
201 * --Elizfaox
202 */
203 if(write(0, ".", 1) < 1)
204 abort();
205 }
206 if (dup2(1, 0) == -1)
207 abort();
208 if (dup2(1, 2) == -1)
209 abort();
210 #endif
211 }
212
213 /*
214 * init_sys
215 *
216 * inputs - boot_daemon flag
217 * output - none
218 * side effects - if boot_daemon flag is not set, don't daemonize
219 */
220 static void
221 init_sys(void)
222 {
223 #if !defined(_WIN32) && defined(RLIMIT_NOFILE) && defined(HAVE_SYS_RESOURCE_H)
224 struct rlimit limit;
225
226 if(!getrlimit(RLIMIT_NOFILE, &limit))
227 {
228 maxconnections = limit.rlim_cur;
229 if(maxconnections <= MAX_BUFFER)
230 {
231 fprintf(stderr, "ERROR: Shell FD limits are too low.\n");
232 fprintf(stderr, "ERROR: charybdis reserves %d FDs, shell limits must be above this\n", MAX_BUFFER);
233 exit(EXIT_FAILURE);
234 }
235 return;
236 }
237 #endif /* RLIMIT_FD_MAX */
238 maxconnections = MAXCONNECTIONS;
239 }
240
241 static int
242 make_daemon(void)
243 {
244 #ifndef _WIN32
245 int pid;
246 int pip[2];
247 char c;
248
249 if (pipe(pip) < 0)
250 {
251 perror("pipe");
252 exit(EXIT_FAILURE);
253 }
254 dup2(pip[1], 0);
255 close(pip[1]);
256 if((pid = fork()) < 0)
257 {
258 perror("fork");
259 exit(EXIT_FAILURE);
260 }
261 else if(pid > 0)
262 {
263 close(0);
264 /* Wait for initialization to finish, successfully or
265 * unsuccessfully. Until this point the child may still
266 * write to stdout/stderr.
267 * -- jilles */
268 if (read(pip[0], &c, 1) > 0)
269 exit(EXIT_SUCCESS);
270 else
271 exit(EXIT_FAILURE);
272 }
273
274 close(pip[0]);
275 setsid();
276 /* fclose(stdin);
277 fclose(stdout);
278 fclose(stderr); */
279 #endif
280 return 0;
281 }
282
283 static int printVersion = 0;
284
285 struct lgetopt myopts[] = {
286 {"configfile", &ConfigFileEntry.configfile,
287 STRING, "File to use for ircd.conf"},
288 {"logfile", &logFileName,
289 STRING, "File to use for ircd.log"},
290 {"pidfile", &pidFileName,
291 STRING, "File to use for process ID"},
292 {"foreground", &server_state_foreground,
293 YESNO, "Run in foreground (don't detach)"},
294 {"version", &printVersion,
295 YESNO, "Print version and exit"},
296 {"conftest", &testing_conf,
297 YESNO, "Test the configuration files and exit"},
298 {"help", NULL, USAGE, "Print this text"},
299 {NULL, NULL, STRING, NULL},
300 };
301
302 static void
303 check_rehash(void *unused)
304 {
305 /*
306 * Check to see whether we have to rehash the configuration ..
307 */
308 if(dorehash)
309 {
310 rehash(true);
311 dorehash = false;
312 }
313
314 if(dorehashbans)
315 {
316 rehash_bans();
317 dorehashbans = false;
318 }
319
320 if(doremotd)
321 {
322 sendto_realops_snomask(SNO_GENERAL, L_ALL,
323 "Got signal SIGUSR1, reloading ircd motd file");
324 cache_user_motd();
325 doremotd = false;
326 }
327 }
328
329 /*
330 * initalialize_global_set_options
331 *
332 * inputs - none
333 * output - none
334 * side effects - This sets all global set options needed
335 */
336 static void
337 initialize_global_set_options(void)
338 {
339 memset(&GlobalSetOptions, 0, sizeof(GlobalSetOptions));
340 /* memset( &ConfigFileEntry, 0, sizeof(ConfigFileEntry)); */
341
342 GlobalSetOptions.maxclients = ServerInfo.default_max_clients;
343
344 if(GlobalSetOptions.maxclients > (maxconnections - MAX_BUFFER) || (GlobalSetOptions.maxclients <= 0))
345 GlobalSetOptions.maxclients = maxconnections - MAX_BUFFER;
346
347 GlobalSetOptions.autoconn = 1;
348
349 GlobalSetOptions.spam_time = MIN_JOIN_LEAVE_TIME;
350 GlobalSetOptions.spam_num = MAX_JOIN_LEAVE_COUNT;
351
352 GlobalSetOptions.floodcount = ConfigFileEntry.default_floodcount;
353
354 split_servers = ConfigChannel.default_split_server_count;
355 split_users = ConfigChannel.default_split_user_count;
356
357 if(split_users && split_servers
358 && (ConfigChannel.no_create_on_split || ConfigChannel.no_join_on_split))
359 {
360 splitmode = 1;
361 splitchecking = 1;
362 }
363
364 GlobalSetOptions.ident_timeout = ConfigFileEntry.default_ident_timeout;
365
366 rb_strlcpy(GlobalSetOptions.operstring,
367 ConfigFileEntry.default_operstring,
368 sizeof(GlobalSetOptions.operstring));
369 rb_strlcpy(GlobalSetOptions.adminstring,
370 ConfigFileEntry.default_adminstring,
371 sizeof(GlobalSetOptions.adminstring));
372
373 /* memset( &ConfigChannel, 0, sizeof(ConfigChannel)); */
374
375 /* End of global set options */
376
377 }
378
379 /*
380 * initialize_server_capabs
381 *
382 * inputs - none
383 * output - none
384 */
385 static void
386 initialize_server_capabs(void)
387 {
388 default_server_capabs &= ~CAP_ZIP;
389 }
390
391 /*
392 * relocate_paths
393 *
394 * inputs - none
395 * output - none
396 * side effects - items in ircd_paths[] array are relocated
397 */
398 #ifdef _WIN32
399 static void
400 relocate_paths(void)
401 {
402 char prefix[PATH_MAX], workbuf[PATH_MAX];
403 char *p;
404
405 rb_strlcpy(prefix, rb_path_to_self(), sizeof prefix);
406
407 ircd_paths[IRCD_PATH_IRCD_EXEC] = rb_strdup(prefix);
408
409 /* if we're running from inside the source tree, we probably do not want to relocate any other paths */
410 if (strstr(prefix, ".libs") != NULL)
411 return;
412
413 /* prefix = /home/kaniini/ircd/bin/ircd */
414 p = strrchr(prefix, RB_PATH_SEPARATOR);
415 if (rb_unlikely(p == NULL))
416 return;
417 *p = 0;
418
419 /* prefix = /home/kaniini/ircd/bin */
420 p = strrchr(prefix, RB_PATH_SEPARATOR);
421 if (rb_unlikely(p == NULL))
422 return;
423 *p = 0;
424
425 /* prefix = /home/kaniini/ircd */
426 ircd_paths[IRCD_PATH_PREFIX] = rb_strdup(prefix);
427
428 /* now that we have our prefix, we can relocate the other paths... */
429 snprintf(workbuf, sizeof workbuf, "%s%cmodules", prefix, RB_PATH_SEPARATOR);
430 ircd_paths[IRCD_PATH_MODULES] = rb_strdup(workbuf);
431
432 snprintf(workbuf, sizeof workbuf, "%s%cmodules%cautoload", prefix, RB_PATH_SEPARATOR, RB_PATH_SEPARATOR);
433 ircd_paths[IRCD_PATH_AUTOLOAD_MODULES] = rb_strdup(workbuf);
434
435 snprintf(workbuf, sizeof workbuf, "%s%cetc", prefix, RB_PATH_SEPARATOR);
436 ircd_paths[IRCD_PATH_ETC] = rb_strdup(workbuf);
437
438 snprintf(workbuf, sizeof workbuf, "%s%clog", prefix, RB_PATH_SEPARATOR);
439 ircd_paths[IRCD_PATH_LOG] = rb_strdup(workbuf);
440
441 snprintf(workbuf, sizeof workbuf, "%s%chelp%cusers", prefix, RB_PATH_SEPARATOR, RB_PATH_SEPARATOR);
442 ircd_paths[IRCD_PATH_USERHELP] = rb_strdup(workbuf);
443
444 snprintf(workbuf, sizeof workbuf, "%s%chelp%copers", prefix, RB_PATH_SEPARATOR, RB_PATH_SEPARATOR);
445 ircd_paths[IRCD_PATH_OPERHELP] = rb_strdup(workbuf);
446
447 snprintf(workbuf, sizeof workbuf, "%s%cetc%circd.conf", prefix, RB_PATH_SEPARATOR, RB_PATH_SEPARATOR);
448 ircd_paths[IRCD_PATH_IRCD_CONF] = rb_strdup(workbuf);
449
450 snprintf(workbuf, sizeof workbuf, "%s%cetc%circd.motd", prefix, RB_PATH_SEPARATOR, RB_PATH_SEPARATOR);
451 ircd_paths[IRCD_PATH_IRCD_MOTD] = rb_strdup(workbuf);
452
453 snprintf(workbuf, sizeof workbuf, "%s%cetc%copers.motd", prefix, RB_PATH_SEPARATOR, RB_PATH_SEPARATOR);
454 ircd_paths[IRCD_PATH_IRCD_OMOTD] = rb_strdup(workbuf);
455
456 snprintf(workbuf, sizeof workbuf, "%s%cetc%cban.db", prefix, RB_PATH_SEPARATOR, RB_PATH_SEPARATOR);
457 ircd_paths[IRCD_PATH_BANDB] = rb_strdup(workbuf);
458
459 snprintf(workbuf, sizeof workbuf, "%s%cetc%circd.pid", prefix, RB_PATH_SEPARATOR, RB_PATH_SEPARATOR);
460 ircd_paths[IRCD_PATH_IRCD_PID] = rb_strdup(workbuf);
461
462 snprintf(workbuf, sizeof workbuf, "%s%clogs%circd.log", prefix, RB_PATH_SEPARATOR, RB_PATH_SEPARATOR);
463 ircd_paths[IRCD_PATH_IRCD_LOG] = rb_strdup(workbuf);
464
465 snprintf(workbuf, sizeof workbuf, "%s%cbin", prefix, RB_PATH_SEPARATOR);
466 ircd_paths[IRCD_PATH_BIN] = rb_strdup(workbuf);
467 ircd_paths[IRCD_PATH_LIBEXEC] = rb_strdup(workbuf);
468 }
469 #endif
470
471 /*
472 * write_pidfile
473 *
474 * inputs - filename+path of pid file
475 * output - none
476 * side effects - write the pid of the ircd to filename
477 */
478 static void
479 write_pidfile(const char *filename)
480 {
481 FILE *fb;
482 char buff[32];
483 if((fb = fopen(filename, "w")))
484 {
485 unsigned int pid = (unsigned int) getpid();
486
487 snprintf(buff, sizeof(buff), "%u\n", pid);
488 if((fputs(buff, fb) == -1))
489 {
490 ilog(L_MAIN, "Error writing %u to pid file %s (%s)",
491 pid, filename, strerror(errno));
492 }
493 fclose(fb);
494 return;
495 }
496 else
497 {
498 ilog(L_MAIN, "Error opening pid file %s", filename);
499 }
500 }
501
502 /*
503 * check_pidfile
504 *
505 * inputs - filename+path of pid file
506 * output - none
507 * side effects - reads pid from pidfile and checks if ircd is in process
508 * list. if it is, gracefully exits
509 * -kre
510 */
511 static void
512 check_pidfile(const char *filename)
513 {
514 FILE *fb;
515 char buff[32];
516 pid_t pidfromfile;
517
518 /* Don't do logging here, since we don't have log() initialised */
519 if((fb = fopen(filename, "r")))
520 {
521 if(fgets(buff, 20, fb) != NULL)
522 {
523 pidfromfile = atoi(buff);
524 if(!rb_kill(pidfromfile, 0))
525 {
526 printf("ircd: daemon is already running\n");
527 exit(-1);
528 }
529 }
530 fclose(fb);
531 }
532 }
533
534 /*
535 * setup_corefile
536 *
537 * inputs - nothing
538 * output - nothing
539 * side effects - setups corefile to system limits.
540 * -kre
541 */
542 static void
543 setup_corefile(void)
544 {
545 #ifdef HAVE_SYS_RESOURCE_H
546 struct rlimit rlim; /* resource limits */
547
548 /* Set corefilesize to maximum */
549 if(!getrlimit(RLIMIT_CORE, &rlim))
550 {
551 rlim.rlim_cur = rlim.rlim_max;
552 setrlimit(RLIMIT_CORE, &rlim);
553 }
554 #endif
555 }
556
557 static void
558 ircd_log_cb(const char *str)
559 {
560 ilog(L_MAIN, "librb reports: %s", str);
561 }
562
563 static void
564 ircd_restart_cb(const char *str)
565 {
566 inotice("librb has called the restart callback: %s", str);
567 restart(str);
568 }
569
570 /*
571 * Why EXIT_FAILURE here?
572 * Because if ircd_die_cb() is called it's because of a fatal
573 * error inside libcharybdis, and we don't know how to handle the
574 * exception, so it is logical to return a FAILURE exit code here.
575 * --nenolod
576 */
577 static void
578 ircd_die_cb(const char *str)
579 {
580 if(str != NULL)
581 {
582 /* Try to get the message out to currently logged in operators. */
583 sendto_realops_snomask(SNO_GENERAL, L_NETWIDE, "librb has called the die callback..aborting: %s", str);
584 inotice("librb has called the die callback..aborting: %s", str);
585 }
586 else
587 inotice("librb has called the die callback..aborting");
588
589 unlink(pidFileName);
590 exit(EXIT_FAILURE);
591 }
592
593 struct ev_entry *check_splitmode_ev = NULL;
594
595 static int
596 seed_with_urandom(void)
597 {
598 unsigned int seed;
599 int fd;
600
601 fd = open("/dev/urandom", O_RDONLY);
602 if(fd >= 0)
603 {
604 if(read(fd, &seed, sizeof(seed)) == sizeof(seed))
605 {
606 close(fd);
607 srand(seed);
608 return 1;
609 }
610 close(fd);
611 }
612 return 0;
613 }
614
615 static void
616 seed_with_clock(void)
617 {
618 const struct timeval *tv;
619 rb_set_time();
620 tv = rb_current_time_tv();
621 srand(tv->tv_sec ^ (tv->tv_usec | (getpid() << 20)));
622 }
623
624 static void
625 seed_random(void *unused)
626 {
627 unsigned int seed;
628 if(rb_get_random(&seed, sizeof(seed)) == -1)
629 {
630 if(!seed_with_urandom())
631 seed_with_clock();
632 return;
633 }
634 srand(seed);
635 }
636
637 /*
638 * main
639 *
640 * Initializes the IRCd.
641 *
642 * Inputs - number of commandline args, args themselves
643 * Outputs - none
644 * Side Effects - this is where the ircd gets going right now
645 */
646 int
647 charybdis_main(int argc, char *argv[])
648 {
649 int fd;
650
651 #ifndef _WIN32
652 /* Check to see if the user is running us as root, which is a nono */
653 if(geteuid() == 0)
654 {
655 fprintf(stderr, "Don't run ircd as root!!!\n");
656 return -1;
657 }
658 #endif
659
660 #ifdef _WIN32
661 relocate_paths();
662 #endif
663
664 logFileName = ircd_paths[IRCD_PATH_IRCD_LOG];
665 pidFileName = ircd_paths[IRCD_PATH_IRCD_PID];
666
667 ConfigFileEntry.dpath = ircd_paths[IRCD_PATH_PREFIX];
668 ConfigFileEntry.configfile = ircd_paths[IRCD_PATH_IRCD_CONF]; /* Server configuration file */
669 ConfigFileEntry.connect_timeout = 30; /* Default to 30 */
670
671 init_sys();
672
673 umask(077); /* better safe than sorry --SRB */
674
675 myargv = argv;
676 parseargs(&argc, &argv, myopts);
677
678 if(chdir(ConfigFileEntry.dpath))
679 {
680 fprintf(stderr, "Unable to chdir to %s: %s\n", ConfigFileEntry.dpath, strerror(errno));
681 exit(EXIT_FAILURE);
682 }
683
684 rb_set_time();
685
686 /*
687 * Setup corefile size immediately after boot -kre
688 */
689 setup_corefile();
690
691 /* initialise operhash fairly early. */
692 init_operhash();
693
694 memset(&me, 0, sizeof(me));
695 memset(&meLocalUser, 0, sizeof(meLocalUser));
696 me.localClient = &meLocalUser;
697
698 /* Make sure all lists are zeroed */
699 memset(&unknown_list, 0, sizeof(unknown_list));
700 memset(&lclient_list, 0, sizeof(lclient_list));
701 memset(&serv_list, 0, sizeof(serv_list));
702 memset(&global_serv_list, 0, sizeof(global_serv_list));
703 memset(&local_oper_list, 0, sizeof(local_oper_list));
704 memset(&oper_list, 0, sizeof(oper_list));
705
706 rb_dlinkAddTail(&me, &me.node, &global_client_list);
707
708 memset(&Count, 0, sizeof(Count));
709 memset(&ServerInfo, 0, sizeof(ServerInfo));
710 memset(&AdminInfo, 0, sizeof(AdminInfo));
711 memset(&ServerStats, 0, sizeof(struct ServerStatistics));
712
713 if(printVersion)
714 {
715 printf("ircd: version %s(%s)\n", ircd_version, serno);
716 #ifdef CUSTOM_BRANDING
717 printf("ircd: based on %s-%s\n", PACKAGE_NAME, PACKAGE_VERSION);
718 #endif
719 printf("ircd: %s\n", rb_lib_version());
720 exit(EXIT_SUCCESS);
721 }
722
723 setup_signals();
724
725 if (testing_conf)
726 server_state_foreground = true;
727
728 #ifndef _WIN32
729 /* Make sure fd 0, 1 and 2 are in use -- jilles */
730 do
731 {
732 fd = open("/dev/null", O_RDWR);
733 } while (fd < 2 && fd != -1);
734 if (fd > 2)
735 close(fd);
736 else if (fd == -1)
737 exit(1);
738 #endif
739
740 /* Check if there is pidfile and daemon already running */
741 if(!testing_conf)
742 {
743 check_pidfile(pidFileName);
744
745 if(!server_state_foreground)
746 make_daemon();
747 inotice("starting %s ...", ircd_version);
748 inotice("%s", rb_lib_version());
749 }
750
751 /* Init the event subsystem */
752 rb_lib_init(ircd_log_cb, ircd_restart_cb, ircd_die_cb, !server_state_foreground, maxconnections, DNODE_HEAP_SIZE, FD_HEAP_SIZE);
753 rb_linebuf_init(LINEBUF_HEAP_SIZE);
754
755 rb_init_prng(NULL, RB_PRNG_DEFAULT);
756
757 seed_random(NULL);
758
759 init_builtin_capabs();
760 default_server_capabs = CAP_MASK;
761
762 init_main_logfile();
763 newconf_init();
764 init_s_conf();
765 init_s_newconf();
766 init_hash();
767 clear_scache_hash_table(); /* server cache name table */
768 init_host_hash();
769 clear_hash_parse();
770 init_client();
771 init_hook();
772 init_channels();
773 initclass();
774 whowas_init();
775 init_reject();
776 init_cache();
777 init_monitor();
778
779 construct_cflags_strings();
780
781 load_all_modules(1);
782 load_core_modules(1);
783
784 init_authd(); /* Start up authd. */
785 init_dns(); /* Start up DNS query system */
786
787 privilegeset_set_new("default", "", 0);
788
789 if (testing_conf)
790 fprintf(stderr, "\nBeginning config test\n");
791 read_conf_files(true); /* cold start init conf files */
792
793 mod_add_path(MODULE_DIR);
794 mod_add_path(MODULE_DIR "/autoload");
795
796 init_isupport();
797
798 init_bandb();
799 init_ssld();
800
801 rehash_bans();
802
803 initialize_server_capabs(); /* Set up default_server_capabs */
804 initialize_global_set_options();
805
806 if(ServerInfo.name == NULL)
807 {
808 ierror("no server name specified in serverinfo block.");
809 return -1;
810 }
811 rb_strlcpy(me.name, ServerInfo.name, sizeof(me.name));
812
813 if(ServerInfo.sid[0] == '\0')
814 {
815 ierror("no server sid specified in serverinfo block.");
816 return -2;
817 }
818 strcpy(me.id, ServerInfo.sid);
819 init_uid();
820
821 /* serverinfo{} description must exist. If not, error out. */
822 if(ServerInfo.description == NULL)
823 {
824 ierror("no server description specified in serverinfo block.");
825 return -3;
826 }
827 rb_strlcpy(me.info, ServerInfo.description, sizeof(me.info));
828
829 if(ServerInfo.ssl_cert != NULL && ServerInfo.ssl_private_key != NULL)
830 {
831 /* just do the rb_setup_ssl_server to validate the config */
832 if(!rb_setup_ssl_server(ServerInfo.ssl_cert, ServerInfo.ssl_private_key, ServerInfo.ssl_dh_params, ServerInfo.ssl_cipher_list))
833 {
834 ilog(L_MAIN, "WARNING: Unable to setup SSL.");
835 ircd_ssl_ok = false;
836 }
837 else
838 ircd_ssl_ok = true;
839 }
840
841 if (testing_conf)
842 {
843 fprintf(stderr, "\nConfig testing complete.\n");
844 fflush(stderr);
845 return 0; /* Why? We want the launcher to exit out. */
846 }
847
848 configure_authd();
849
850 me.from = &me;
851 me.servptr = &me;
852 SetMe(&me);
853 make_server(&me);
854 startup_time = rb_current_time();
855 add_to_client_hash(me.name, &me);
856 add_to_id_hash(me.id, &me);
857 me.serv->nameinfo = scache_connect(me.name, me.info, 0);
858
859 rb_dlinkAddAlloc(&me, &global_serv_list);
860
861 construct_umodebuf();
862
863 check_class();
864 write_pidfile(pidFileName);
865 load_help();
866 open_logfiles();
867
868 ilog(L_MAIN, "Server Ready");
869
870 /* We want try_connections to be called as soon as possible now! -- adrian */
871 /* No, 'cause after a restart it would cause all sorts of nick collides */
872 /* um. by waiting even longer, that just means we have even *more*
873 * nick collisions. what a stupid idea. set an event for the IO loop --fl
874 */
875 rb_event_addish("try_connections", try_connections, NULL, STARTUP_CONNECTIONS_TIME);
876 rb_event_addonce("try_connections_startup", try_connections, NULL, 2);
877 rb_event_add("check_rehash", check_rehash, NULL, 3);
878 rb_event_addish("reseed_srand", seed_random, NULL, 300); /* reseed every 10 minutes */
879
880 if(splitmode)
881 check_splitmode_ev = rb_event_add("check_splitmode", check_splitmode, NULL, 5);
882
883 print_startup(getpid());
884
885 rb_lib_loop(0);
886
887 return 0;
888 }