ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/ircd-hybrid/trunk/src/ircd.c
Revision: 9228
Committed: Sun Jan 26 14:17:46 2020 UTC (5 years, 7 months ago) by michael
Content type: text/x-csrc
File size: 12476 byte(s)
Log Message:
- ircd.c: remove unused header inclusion

File Contents

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

Properties

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