]> jfr.im git - solanum.git/blame - ircd/ircd.c
authd: remove some whitespace
[solanum.git] / ircd / ircd.c
CommitLineData
212380e3 1/*
6fce54ff 2 * charybdis: A slightly useful ircd.
212380e3
AC
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
6fce54ff 7 * Copyright (C) 2002-2008 ircd-ratbox development team
adef4da1 8 * Copyright (C) 2005-2013 charybdis development team
212380e3
AC
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
212380e3
AC
24 */
25
fe037171 26#include "rb_lib.h"
212380e3
AC
27#include "stdinc.h"
28#include "setup.h"
9b8e9eb3 29#include "defaults.h"
212380e3
AC
30#include "ircd.h"
31#include "channel.h"
32#include "class.h"
33#include "client.h"
212380e3 34#include "hash.h"
4562c604 35#include "match.h"
212380e3 36#include "ircd_signal.h"
212380e3
AC
37#include "msg.h" /* msgtab */
38#include "hostmask.h"
39#include "numeric.h"
40#include "parse.h"
212380e3 41#include "restart.h"
212380e3 42#include "s_conf.h"
4016731b 43#include "logger.h"
212380e3
AC
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"
212380e3
AC
52#include "hook.h"
53#include "ircd_getopt.h"
212380e3 54#include "newconf.h"
212380e3
AC
55#include "reject.h"
56#include "s_conf.h"
57#include "s_newconf.h"
58#include "cache.h"
59#include "monitor.h"
212380e3
AC
60#include "patchlevel.h"
61#include "serno.h"
c6d72037 62#include "sslproc.h"
efccc22c 63#include "chmode.h"
39a68b53 64#include "privilege.h"
6eebc373 65#include "bandbi.h"
6d063f05 66#include "authd.h"
b02a913b 67#include "operhash.h"
212380e3 68
8bd5767b 69/* /quote set variables */
2af8c7ff 70struct SetOptions GlobalSetOptions;
8bd5767b
JT
71
72/* configuration set from ircd.conf */
73struct config_file_entry ConfigFileEntry;
74/* server info set from ircd.conf */
75struct server_info ServerInfo;
76/* admin info set from ircd.conf */
1aad9782
VY
77struct admin_info AdminInfo;
78
8bd5767b 79struct Counter Count;
47adde3d
VY
80struct ServerStatistics ServerStats;
81
1aad9782 82int maxconnections;
8bd5767b 83struct Client me; /* That's me */
1aad9782
VY
84struct LocalUser meLocalUser; /* That's also part of me */
85
3d3d1a95 86rb_dlink_list global_client_list;
8bd5767b 87
3d3d1a95 88/* unknown/client pointer lists */
8bd5767b 89rb_dlink_list unknown_list; /* unknown clients ON this server only */
3d3d1a95 90rb_dlink_list lclient_list; /* local clients only ON this server */
8bd5767b
JT
91rb_dlink_list serv_list; /* local servers to this server ONLY */
92rb_dlink_list global_serv_list; /* global servers on the network */
93rb_dlink_list local_oper_list; /* our opers, duplicated in lclient_list */
b5b84cad
VY
94rb_dlink_list oper_list; /* network opers */
95
1aad9782 96char **myargv;
33d43d4f
MU
97volatile sig_atomic_t dorehash = false;
98volatile sig_atomic_t dorehashbans = false;
99volatile sig_atomic_t doremotd = false;
f66f0baa 100bool kline_queued = false;
503727d1
EM
101bool server_state_foreground = false;
102bool opers_see_all_users = false;
bfc44622
AC
103bool ircd_ssl_ok = false;
104bool ircd_zlib_ok = true;
8bd5767b
JT
105
106int testing_conf = 0;
cd27d99c 107time_t startup_time;
8bd5767b 108
346fba92 109int default_server_capabs;
8bd5767b 110
cd27d99c
VY
111int splitmode;
112int splitchecking;
113int split_users;
114int split_servers;
115int eob_count;
c6d72037 116
4d8cfacd
AC
117const 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
2f545aad
AC
136const char *logFileName = NULL;
137const char *pidFileName = NULL;
4d8cfacd 138
fd5af3d0
VY
139void
140ircd_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);
ea82a3ca 162 close_logfiles();
fd5af3d0
VY
163
164 unlink(pidFileName);
165 exit(0);
166}
167
212380e3
AC
168/*
169 * print_startup - print startup information
170 */
171static void
172print_startup(int pid)
173{
b45b2dae
JT
174 int fd;
175
c1bfea73 176#ifndef _WIN32
b45b2dae
JT
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();
c1bfea73 187#endif
4d383612 188 inotice("runtime path: %s", rb_path_to_self());
212380e3
AC
189 inotice("now running in %s mode from %s as pid %d ...",
190 !server_state_foreground ? "background" : "foreground",
191 ConfigFileEntry.dpath, pid);
192
c1bfea73 193#ifndef _WIN32
212380e3
AC
194 /* let the parent process know the initialization was successful
195 * -- jilles */
196 if (!server_state_foreground)
c084fcaf 197 {
2ac4ba96
EM
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();
c084fcaf 205 }
b45b2dae
JT
206 if (dup2(1, 0) == -1)
207 abort();
208 if (dup2(1, 2) == -1)
209 abort();
c1bfea73 210#endif
212380e3
AC
211}
212
212380e3
AC
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 */
220static void
221init_sys(void)
222{
c1bfea73 223#if !defined(_WIN32) && defined(RLIMIT_NOFILE) && defined(HAVE_SYS_RESOURCE_H)
8bd5767b
JT
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");
ec86417c 232 fprintf(stderr, "ERROR: charybdis reserves %d FDs, shell limits must be above this\n", MAX_BUFFER);
8bd5767b
JT
233 exit(EXIT_FAILURE);
234 }
235 return;
236 }
237#endif /* RLIMIT_FD_MAX */
101db4c4 238 maxconnections = MAXCONNECTIONS;
212380e3
AC
239}
240
241static int
242make_daemon(void)
243{
538d2089 244#ifndef _WIN32
212380e3
AC
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); */
538d2089 279#endif
212380e3
AC
280 return 0;
281}
282
283static int printVersion = 0;
284
285struct lgetopt myopts[] = {
212380e3
AC
286 {"configfile", &ConfigFileEntry.configfile,
287 STRING, "File to use for ircd.conf"},
212380e3
AC
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
212380e3
AC
302static void
303check_rehash(void *unused)
304{
305 /*
306 * Check to see whether we have to rehash the configuration ..
307 */
308 if(dorehash)
309 {
ab31d2b0 310 rehash(true);
1b916de5 311 dorehash = false;
212380e3
AC
312 }
313
314 if(dorehashbans)
315 {
ab31d2b0 316 rehash_bans();
1b916de5 317 dorehashbans = false;
212380e3
AC
318 }
319
320 if(doremotd)
321 {
322 sendto_realops_snomask(SNO_GENERAL, L_ALL,
323 "Got signal SIGUSR1, reloading ircd motd file");
041d54ff 324 cache_user_motd();
1b916de5 325 doremotd = false;
212380e3
AC
326 }
327}
328
212380e3
AC
329/*
330 * initalialize_global_set_options
331 *
332 * inputs - none
333 * output - none
55abcbb2 334 * side effects - This sets all global set options needed
212380e3
AC
335 */
336static void
337initialize_global_set_options(void)
338{
339 memset(&GlobalSetOptions, 0, sizeof(GlobalSetOptions));
340 /* memset( &ConfigFileEntry, 0, sizeof(ConfigFileEntry)); */
341
8bd5767b
JT
342 GlobalSetOptions.maxclients = ServerInfo.default_max_clients;
343
344 if(GlobalSetOptions.maxclients > (maxconnections - MAX_BUFFER) || (GlobalSetOptions.maxclients <= 0))
101db4c4
VY
345 GlobalSetOptions.maxclients = maxconnections - MAX_BUFFER;
346
212380e3
AC
347 GlobalSetOptions.autoconn = 1;
348
349 GlobalSetOptions.spam_time = MIN_JOIN_LEAVE_TIME;
350 GlobalSetOptions.spam_num = MAX_JOIN_LEAVE_COUNT;
351
7f3382fe 352 GlobalSetOptions.floodcount = ConfigFileEntry.default_floodcount;
212380e3
AC
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
7f3382fe 364 GlobalSetOptions.ident_timeout = ConfigFileEntry.default_ident_timeout;
212380e3 365
f427c8b0 366 rb_strlcpy(GlobalSetOptions.operstring,
212380e3
AC
367 ConfigFileEntry.default_operstring,
368 sizeof(GlobalSetOptions.operstring));
f427c8b0 369 rb_strlcpy(GlobalSetOptions.adminstring,
212380e3
AC
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 */
385static void
386initialize_server_capabs(void)
387{
388 default_server_capabs &= ~CAP_ZIP;
389}
390
d6c17e5d
AC
391/*
392 * relocate_paths
393 *
394 * inputs - none
395 * output - none
396 * side effects - items in ircd_paths[] array are relocated
397 */
0aaa37f7 398#ifdef _WIN32
d6c17e5d
AC
399static void
400relocate_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}
0aaa37f7 469#endif
212380e3
AC
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 */
478static void
479write_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
5203cba5 487 snprintf(buff, sizeof(buff), "%u\n", pid);
212380e3
AC
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 */
511static void
512check_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);
538d2089 524 if(!rb_kill(pidfromfile, 0))
212380e3
AC
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 */
542static void
543setup_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
6fce54ff
VY
557static void
558ircd_log_cb(const char *str)
559{
fe037171 560 ilog(L_MAIN, "librb reports: %s", str);
6fce54ff
VY
561}
562
563static void
564ircd_restart_cb(const char *str)
565{
fe037171 566 inotice("librb has called the restart callback: %s", str);
6fce54ff
VY
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 */
577static void
578ircd_die_cb(const char *str)
579{
580 if(str != NULL)
581 {
582 /* Try to get the message out to currently logged in operators. */
fe037171
EM
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);
6fce54ff 585 }
6643434b 586 else
fe037171 587 inotice("librb has called the die callback..aborting");
6fce54ff
VY
588
589 unlink(pidFileName);
590 exit(EXIT_FAILURE);
591}
592
fa832850
AC
593struct ev_entry *check_splitmode_ev = NULL;
594
d80645d0
VY
595static int
596seed_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 }
5457b102 610 close(fd);
d80645d0
VY
611 }
612 return 0;
613}
614
615static void
616seed_with_clock(void)
617{
55abcbb2 618 const struct timeval *tv;
d80645d0
VY
619 rb_set_time();
620 tv = rb_current_time_tv();
621 srand(tv->tv_sec ^ (tv->tv_usec | (getpid() << 20)));
622}
623
624static void
625seed_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
212380e3
AC
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 */
646int
bc38c72c 647charybdis_main(int argc, char *argv[])
212380e3
AC
648{
649 int fd;
650
1ba9eba5 651#ifndef _WIN32
212380e3
AC
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 }
1ba9eba5 658#endif
212380e3 659
0aaa37f7 660#ifdef _WIN32
d6c17e5d
AC
661 relocate_paths();
662#endif
adc7be98 663
2f545aad
AC
664 logFileName = ircd_paths[IRCD_PATH_IRCD_LOG];
665 pidFileName = ircd_paths[IRCD_PATH_IRCD_PID];
666
4d8cfacd
AC
667 ConfigFileEntry.dpath = ircd_paths[IRCD_PATH_PREFIX];
668 ConfigFileEntry.configfile = ircd_paths[IRCD_PATH_IRCD_CONF]; /* Server configuration file */
befa24c8 669 ConfigFileEntry.connect_timeout = 30; /* Default to 30 */
346fba92 670
d6c17e5d
AC
671 init_sys();
672
befa24c8 673 umask(077); /* better safe than sorry --SRB */
adc7be98
VY
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
3d3d1a95
VY
684 rb_set_time();
685
212380e3
AC
686 /*
687 * Setup corefile size immediately after boot -kre
688 */
689 setup_corefile();
690
b02a913b
AC
691 /* initialise operhash fairly early. */
692 init_operhash();
693
212380e3
AC
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
330fc5c1 706 rb_dlinkAddTail(&me, &me.node, &global_client_list);
212380e3 707
2af8c7ff
VY
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));
212380e3 712
212380e3
AC
713 if(printVersion)
714 {
b3803848 715 printf("ircd: version %s(%s)\n", ircd_version, serno);
8bd1c8a1
AC
716#ifdef CUSTOM_BRANDING
717 printf("ircd: based on %s-%s\n", PACKAGE_NAME, PACKAGE_VERSION);
718#endif
d2b6b9f3 719 printf("ircd: %s\n", rb_lib_version());
212380e3
AC
720 exit(EXIT_SUCCESS);
721 }
722
212380e3
AC
723 setup_signals();
724
212380e3 725 if (testing_conf)
503727d1 726 server_state_foreground = true;
212380e3 727
09f528c2 728#ifndef _WIN32
212380e3
AC
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);
09f528c2 738#endif
212380e3
AC
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);
31c86ea8 748 inotice("%s", rb_lib_version());
212380e3
AC
749 }
750
751 /* Init the event subsystem */
0edb29fa 752 rb_lib_init(ircd_log_cb, ircd_restart_cb, ircd_die_cb, !server_state_foreground, maxconnections, DNODE_HEAP_SIZE, FD_HEAP_SIZE);
150f35f7 753 rb_linebuf_init(LINEBUF_HEAP_SIZE);
212380e3 754
e861902f 755 rb_init_prng(NULL, RB_PRNG_DEFAULT);
37cd159e 756
e1db84d8
VY
757 seed_random(NULL);
758
346fba92
AC
759 init_builtin_capabs();
760 default_server_capabs = CAP_MASK;
761
212380e3 762 init_main_logfile();
212380e3
AC
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();
212380e3
AC
771 init_hook();
772 init_channels();
773 initclass();
b47f8a4f 774 whowas_init();
212380e3
AC
775 init_reject();
776 init_cache();
777 init_monitor();
030cdce7 778
19716b9f 779 construct_cflags_strings();
030cdce7 780
212380e3 781 load_all_modules(1);
212380e3 782 load_core_modules(1);
2a19fc3f 783
6d063f05 784 init_authd(); /* Start up authd. */
068c6c4a 785 init_dns(); /* Start up DNS query system */
8a26cd19 786
39a68b53 787 privilegeset_set_new("default", "", 0);
212380e3
AC
788
789 if (testing_conf)
790 fprintf(stderr, "\nBeginning config test\n");
ea111ea5 791 read_conf_files(true); /* cold start init conf files */
212380e3 792
55abcbb2
KB
793 mod_add_path(MODULE_DIR);
794 mod_add_path(MODULE_DIR "/autoload");
212380e3 795
b583faf9
AC
796 init_isupport();
797
6eebc373 798 init_bandb();
c6d72037
VY
799 init_ssld();
800
ab31d2b0 801 rehash_bans();
80c9ac51 802
212380e3
AC
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 }
f427c8b0 811 rb_strlcpy(me.name, ServerInfo.name, sizeof(me.name));
212380e3
AC
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 }
f427c8b0 827 rb_strlcpy(me.info, ServerInfo.description, sizeof(me.info));
212380e3 828
8bd5767b
JT
829 if(ServerInfo.ssl_cert != NULL && ServerInfo.ssl_private_key != NULL)
830 {
831 /* just do the rb_setup_ssl_server to validate the config */
c1725bda 832 if(!rb_setup_ssl_server(ServerInfo.ssl_cert, ServerInfo.ssl_private_key, ServerInfo.ssl_dh_params, ServerInfo.ssl_cipher_list))
8bd5767b
JT
833 {
834 ilog(L_MAIN, "WARNING: Unable to setup SSL.");
bfc44622 835 ircd_ssl_ok = false;
8bd5767b
JT
836 }
837 else
bfc44622 838 ircd_ssl_ok = true;
c6d72037
VY
839 }
840
212380e3
AC
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 me.from = &me;
849 me.servptr = &me;
850 SetMe(&me);
851 make_server(&me);
e3354945 852 startup_time = rb_current_time();
212380e3
AC
853 add_to_client_hash(me.name, &me);
854 add_to_id_hash(me.id, &me);
994544c2 855 me.serv->nameinfo = scache_connect(me.name, me.info, 0);
212380e3 856
330fc5c1 857 rb_dlinkAddAlloc(&me, &global_serv_list);
212380e3
AC
858
859 construct_umodebuf();
860
861 check_class();
862 write_pidfile(pidFileName);
863 load_help();
864 open_logfiles();
865
50808796
EM
866 configure_authd();
867
212380e3
AC
868 ilog(L_MAIN, "Server Ready");
869
212380e3
AC
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 */
12aea5fe 875 rb_event_addish("try_connections", try_connections, NULL, STARTUP_CONNECTIONS_TIME);
36645728
VY
876 rb_event_addonce("try_connections_startup", try_connections, NULL, 2);
877 rb_event_add("check_rehash", check_rehash, NULL, 3);
d80645d0 878 rb_event_addish("reseed_srand", seed_random, NULL, 300); /* reseed every 10 minutes */
212380e3 879
212380e3 880 if(splitmode)
36645728 881 check_splitmode_ev = rb_event_add("check_splitmode", check_splitmode, NULL, 5);
212380e3 882
212380e3
AC
883 print_startup(getpid());
884
39944e1f 885 rb_lib_loop(0);
212380e3
AC
886
887 return 0;
888}