/[svn]/ircd-hybrid/trunk/src/ircd.c
ViewVC logotype

Contents of /ircd-hybrid/trunk/src/ircd.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 8893 - (show annotations)
Sun Apr 21 14:12:35 2019 UTC (3 years, 3 months ago) by michael
File MIME type: text/x-chdr
File size: 13291 byte(s)
- auth.c: remove auth_timeout_queries() and related code. Just let the dns and identd timeouts finish the request
- Removed IDENTTIMEOUT from '/set' options. We now no longer allow users to change this on runtime. identd timeout is 5 seconds now

1 /*
2 * ircd-hybrid: an advanced, lightweight Internet Relay Chat Daemon (ircd)
3 *
4 * Copyright (c) 1997-2019 ircd-hybrid development team
5 *
6 * This program 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 2 of the License, or
9 * (at your option) any later version.
10 *
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.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
19 * USA
20 */
21
22 /*! \file ircd.c
23 * \brief Starts up and runs the ircd.
24 * \version $Id$
25 */
26
27 #include "stdinc.h"
28 #include "user.h"
29 #include "list.h"
30 #include "ircd.h"
31 #include "channel.h"
32 #include "channel_mode.h"
33 #include "client.h"
34 #include "event.h"
35 #include "fdlist.h"
36 #include "hash.h"
37 #include "id.h"
38 #include "irc_string.h"
39 #include "ircd_signal.h"
40 #include "motd.h"
41 #include "conf.h"
42 #include "hostmask.h"
43 #include "parse.h"
44 #include "res.h"
45 #include "restart.h"
46 #include "rng_mt.h"
47 #include "s_bsd.h"
48 #include "log.h"
49 #include "server.h"
50 #include "server_capab.h"
51 #include "send.h"
52 #include "modules.h"
53 #include "memory.h"
54 #include "ircd_getopt.h"
55 #include "conf_db.h"
56 #include "conf_class.h"
57 #include "ipcache.h"
58 #include "isupport.h"
59 #include "patchlevel.h"
60 #include "serno.h"
61
62
63 struct SetOptions GlobalSetOptions; /* /quote set variables */
64 struct Counter Count;
65 struct ServerState_t server_state;
66 struct ServerStatistics ServerStats;
67 struct ServerTime SystemTime;
68 struct Connection meConnection; /* That's also part of me */
69 struct Client me = { .connection = &meConnection }; /* That's me */
70
71 char **myargv;
72 const char *logFileName = LPATH;
73 const char *pidFileName = PPATH;
74
75 bool dorehash;
76 bool doremotd;
77
78 static bool printVersion;
79
80 static struct lgetopt myopts[] =
81 {
82 { "configfile", &ConfigGeneral.configfile,
83 STRING, "File to use for ircd.conf" },
84 { "klinefile", &ConfigGeneral.klinefile,
85 STRING, "File to use for kline database" },
86 { "dlinefile", &ConfigGeneral.dlinefile,
87 STRING, "File to use for dline database" },
88 { "xlinefile", &ConfigGeneral.xlinefile,
89 STRING, "File to use for xline database" },
90 { "resvfile", &ConfigGeneral.resvfile,
91 STRING, "File to use for resv database" },
92 { "logfile", &logFileName,
93 STRING, "File to use for ircd.log" },
94 { "pidfile", &pidFileName,
95 STRING, "File to use for process ID" },
96 { "foreground", &server_state.foreground,
97 BOOLEAN, "Run in foreground (don't detach)" },
98 { "version", &printVersion,
99 BOOLEAN, "Print version and exit" },
100 { "help", NULL, USAGE, "Print this text" },
101 { NULL, NULL, STRING, NULL },
102 };
103
104 static struct event event_cleanup_tklines =
105 {
106 .name = "cleanup_tklines",
107 .handler = cleanup_tklines,
108 .when = CLEANUP_TKLINES_TIME
109 };
110
111 static struct event event_try_connections =
112 {
113 .name = "try_connections",
114 .handler = try_connections,
115 .when = STARTUP_CONNECTIONS_TIME
116 };
117
118 static struct event event_comm_checktimeouts =
119 {
120 .name = "comm_checktimeouts",
121 .handler = comm_checktimeouts,
122 .when = 1
123 };
124
125 static struct event event_save_all_databases =
126 {
127 .name = "save_all_databases",
128 .handler = save_all_databases,
129 .when = DATABASE_UPDATE_TIMEOUT
130 };
131
132 struct event event_write_links_file =
133 {
134 .name = "write_links_file",
135 .handler = write_links_file,
136 };
137
138
139 void
140 set_time(void)
141 {
142 struct timeval newtime = { .tv_sec = 0, .tv_usec = 0 };
143
144 if (gettimeofday(&newtime, NULL) == -1)
145 {
146 char buf[IRCD_BUFSIZE];
147
148 snprintf(buf, sizeof(buf), "Clock failure, TS can be corrupted: %s",
149 strerror(errno));
150 server_die(buf, false);
151 }
152
153 if ((uintmax_t)newtime.tv_sec < CurrentTime)
154 {
155 ilog(LOG_TYPE_IRCD, "System clock is running backwards - (%ju < %ju)",
156 (uintmax_t)newtime.tv_sec, CurrentTime);
157 sendto_realops_flags(UMODE_DEBUG, L_ALL, SEND_NOTICE,
158 "System clock is running backwards - (%ju < %ju)",
159 (uintmax_t)newtime.tv_sec, CurrentTime);
160 event_set_back_events(CurrentTime - (uintmax_t)newtime.tv_sec);
161 }
162
163 SystemTime.tv_sec = newtime.tv_sec;
164 SystemTime.tv_usec = newtime.tv_usec;
165 }
166
167 static void
168 io_loop(void)
169 {
170 while (true)
171 {
172 if (listing_client_list.head)
173 {
174 dlink_node *node = NULL, *node_next = NULL;
175 DLINK_FOREACH_SAFE(node, node_next, listing_client_list.head)
176 safe_list_channels(node->data, false);
177 }
178
179 /* Run pending events */
180 event_run();
181
182 comm_select();
183 exit_aborted_clients();
184 free_exited_clients();
185
186 /* Check to see whether we have to rehash the configuration. */
187 if (dorehash == true)
188 {
189 conf_rehash(true);
190 dorehash = false;
191 }
192
193 if (doremotd == true)
194 {
195 motd_recache();
196 sendto_realops_flags(UMODE_SERVNOTICE, L_ALL, SEND_NOTICE,
197 "Got signal SIGUSR1, reloading motd file(s)");
198 doremotd = false;
199 }
200 }
201 }
202
203 /* initalialize_global_set_options()
204 *
205 * inputs - none
206 * output - none
207 * side effects - This sets all global set options needed
208 */
209 static void
210 initialize_global_set_options(void)
211 {
212 GlobalSetOptions.maxclients = ConfigServerInfo.default_max_clients;
213 GlobalSetOptions.autoconn = true;
214 GlobalSetOptions.spam_time = MIN_JOIN_LEAVE_TIME;
215 GlobalSetOptions.spam_num = MAX_JOIN_LEAVE_COUNT;
216 GlobalSetOptions.floodcount = ConfigGeneral.default_floodcount;
217 GlobalSetOptions.floodtime = ConfigGeneral.default_floodtime;
218 GlobalSetOptions.joinfloodcount = ConfigChannel.default_join_flood_count;
219 GlobalSetOptions.joinfloodtime = ConfigChannel.default_join_flood_time;
220 }
221
222 /* write_pidfile()
223 *
224 * inputs - filename+path of pid file
225 * output - NONE
226 * side effects - write the pid of the ircd to filename
227 */
228 static void
229 write_pidfile(const char *filename)
230 {
231 FILE *fb;
232
233 if ((fb = fopen(filename, "w")))
234 {
235 char buf[IRCD_BUFSIZE];
236 unsigned int pid = (unsigned int)getpid();
237
238 snprintf(buf, sizeof(buf), "%u\n", pid);
239
240 if (fputs(buf, fb) == -1)
241 ilog(LOG_TYPE_IRCD, "Error writing to pid file %s: %s",
242 filename, strerror(errno));
243
244 fclose(fb);
245 }
246 else
247 ilog(LOG_TYPE_IRCD, "Error opening pid file %s: %s",
248 filename, strerror(errno));
249 }
250
251 /* check_pidfile()
252 *
253 * inputs - filename+path of pid file
254 * output - none
255 * side effects - reads pid from pidfile and checks if ircd is in process
256 * list. if it is, gracefully exits
257 * -kre
258 */
259 static void
260 check_pidfile(const char *filename)
261 {
262 FILE *fb;
263 char buf[IRCD_BUFSIZE];
264
265 if ((fb = fopen(filename, "r")))
266 {
267 if (fgets(buf, 20, fb) == NULL)
268 ilog(LOG_TYPE_IRCD, "Error reading from pid file %s: %s",
269 filename, strerror(errno));
270 else
271 {
272 pid_t pid = atoi(buf);
273
274 if (kill(pid, 0) == 0)
275 {
276 /* log(L_ERROR, "Server is already running"); */
277 printf("ircd: daemon is already running\n");
278 exit(EXIT_FAILURE);
279 }
280 }
281
282 fclose(fb);
283 }
284 else if (errno != ENOENT)
285 ilog(LOG_TYPE_IRCD, "Error opening pid file %s: %s",
286 filename, strerror(errno));
287 }
288
289 /* setup_corefile()
290 *
291 * inputs - nothing
292 * output - nothing
293 * side effects - setups corefile to system limits.
294 * -kre
295 */
296 static void
297 setup_corefile(void)
298 {
299 struct rlimit rlim; /* resource limits */
300
301 /* Set corefilesize to maximum */
302 if (getrlimit(RLIMIT_CORE, &rlim) == 0)
303 {
304 rlim.rlim_cur = rlim.rlim_max;
305 setrlimit(RLIMIT_CORE, &rlim);
306 }
307 }
308
309 static void
310 setup_fdlimit(void)
311 {
312 struct rlimit rlim; /* resource limits */
313
314 if (getrlimit(RLIMIT_NOFILE, &rlim))
315 {
316 fprintf(stderr, "getrlimit: couldn't get maximum number of file descriptors: %s\n",
317 strerror(errno));
318 exit(EXIT_FAILURE);
319 }
320
321 if (rlim.rlim_max > 0xFFFF)
322 rlim.rlim_max = 0xFFFF;
323 rlim.rlim_cur = rlim.rlim_max;
324
325 if (setrlimit(RLIMIT_NOFILE, &rlim) == 0)
326 hard_fdlimit = rlim.rlim_cur;
327 else
328 {
329 fprintf(stderr, "setrlimit: couldn't set maximum number of file descriptors: %s\n",
330 strerror(errno));
331 exit(EXIT_FAILURE);
332 }
333 }
334
335 /*
336 * print_startup - print startup information
337 */
338 static void
339 print_startup(int pid)
340 {
341 printf("ircd: version %s(%s)\n", PATCHLEVEL, SERIALNUM);
342 printf("ircd: pid %d\n", pid);
343 printf("ircd: running in %s mode from %s\n", !server_state.foreground ? "background"
344 : "foreground", ConfigGeneral.dpath);
345 }
346
347 static void
348 make_daemon(void)
349 {
350 int pid;
351
352 if ((pid = fork()) < 0)
353 {
354 perror("fork");
355 exit(EXIT_FAILURE);
356 }
357 else if (pid > 0)
358 {
359 print_startup(pid);
360 exit(EXIT_SUCCESS);
361 }
362
363 setsid();
364 }
365
366 int
367 main(int argc, char *argv[])
368 {
369 /* Check to see if the user is running us as root, which is a nono */
370 if (geteuid() == 0)
371 {
372 fprintf(stderr, "ERROR: This server won't run as root/superuser\n");
373 return -1;
374 }
375
376 /* Setup corefile size immediately after boot -kre */
377 setup_corefile();
378
379 setup_fdlimit();
380
381 /* Save server boot time right away, so getrusage works correctly */
382 set_time();
383
384 /* It's not random, but it ought to be a little harder to guess */
385 init_genrand(SystemTime.tv_sec ^ (SystemTime.tv_usec | (getpid() << 20)));
386
387 ConfigGeneral.dpath = DPATH;
388 ConfigGeneral.spath = SPATH;
389 ConfigGeneral.mpath = MPATH;
390 ConfigGeneral.configfile = CPATH; /* Server configuration file */
391 ConfigGeneral.klinefile = KPATH; /* Server kline file */
392 ConfigGeneral.xlinefile = XPATH; /* Server xline file */
393 ConfigGeneral.dlinefile = DLPATH; /* dline file */
394 ConfigGeneral.resvfile = RESVPATH; /* resv file */
395
396 myargv = argv;
397 umask(077); /* umask 077: u=rwx,g=,o= */
398
399 parseargs(&argc, &argv, myopts);
400
401 if (printVersion == true)
402 {
403 printf("ircd: version %s(%s)\n", PATCHLEVEL, SERIALNUM);
404 exit(EXIT_SUCCESS);
405 }
406
407 if (chdir(ConfigGeneral.dpath))
408 {
409 perror("chdir");
410 exit(EXIT_FAILURE);
411 }
412
413 if (server_state.foreground == false)
414 {
415 make_daemon();
416 close_standard_fds(); /* this needs to be before comm_select_init()! */
417 }
418 else
419 print_startup(getpid());
420
421 setup_signals();
422
423 /* We need this to initialise the fd array before anything else */
424 fdlist_init();
425 log_set_file(LOG_TYPE_IRCD, 0, logFileName);
426
427 comm_select_init(); /* This needs to be setup early ! -- adrian */
428 tls_init();
429
430 /* Check if there is pidfile and daemon already running */
431 check_pidfile(pidFileName);
432
433 isupport_init();
434 hash_init();
435 ipcache_init();
436 client_init();
437 class_init();
438 resolver_init(); /* Needs to be setup before the io loop */
439 modules_init();
440 read_conf_files(true); /* cold start init conf files */
441 capab_init(); /* Set up default_server_capabs */
442 initialize_global_set_options(); /* Has to be called after read_conf_files() */
443 channel_mode_init();
444 read_links_file();
445 motd_init();
446 user_modes_init();
447
448 if (EmptyString(ConfigServerInfo.name))
449 {
450 ilog(LOG_TYPE_IRCD, "ERROR: No server name specified in serverinfo block.");
451 exit(EXIT_FAILURE);
452 }
453
454 strlcpy(me.name, ConfigServerInfo.name, sizeof(me.name));
455
456 /* serverinfo {} description must exist. If not, error out.*/
457 if (EmptyString(ConfigServerInfo.description))
458 {
459 ilog(LOG_TYPE_IRCD, "ERROR: No server description specified in serverinfo block.");
460 exit(EXIT_FAILURE);
461 }
462
463 strlcpy(me.info, ConfigServerInfo.description, sizeof(me.info));
464
465 if (EmptyString(ConfigServerInfo.sid))
466 {
467 ilog(LOG_TYPE_IRCD, "Generating server ID");
468 generate_sid();
469 }
470 else
471 strlcpy(me.id, ConfigServerInfo.sid, sizeof(me.id));
472
473 init_uid();
474
475 me.from = &me;
476 me.servptr = &me;
477 me.connection->lasttime = CurrentTime;
478 me.connection->since = CurrentTime;
479 me.connection->firsttime = CurrentTime;
480
481 SetMe(&me);
482 server_make(&me);
483
484 hash_add_id(&me);
485 hash_add_client(&me);
486
487 dlinkAdd(&me, &me.node, &global_server_list);
488
489 load_kline_database(ConfigGeneral.klinefile);
490 load_dline_database(ConfigGeneral.dlinefile);
491 load_xline_database(ConfigGeneral.xlinefile);
492 load_resv_database(ConfigGeneral.resvfile);
493
494 load_all_modules(true);
495 load_conf_modules();
496 load_core_modules(true);
497
498 write_pidfile(pidFileName);
499
500 event_addish(&event_cleanup_tklines, NULL);
501
502 /* We want try_connections to be called as soon as possible now! -- adrian */
503 /* No, 'cause after a restart it would cause all sorts of nick collides */
504 event_addish(&event_try_connections, NULL);
505
506 /* Setup the timeout check. I'll shift it later :) -- adrian */
507 event_add(&event_comm_checktimeouts, NULL);
508
509 event_addish(&event_save_all_databases, NULL);
510
511 if (ConfigServerHide.flatten_links_delay && event_write_links_file.active == false)
512 {
513 event_write_links_file.when = ConfigServerHide.flatten_links_delay;
514 event_add(&event_write_links_file, NULL);
515 }
516
517 ilog(LOG_TYPE_IRCD, "Server ready. Running version: %s(%s)", PATCHLEVEL, SERIALNUM);
518 io_loop();
519
520 return 0;
521 }

Properties

Name Value
svn:eol-style native
svn:keywords Id

svnadmin@ircd-hybrid.org
ViewVC Help
Powered by ViewVC 1.1.28