ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/branches/ircd-hybrid-newconf/src/ircd.c
Revision: 1027
Committed: Sun Nov 8 13:01:13 2009 UTC (16 years, 9 months ago) by michael
Content type: text/x-csrc
File size: 14254 byte(s)
Log Message:
- Move old 7.3 sources to branches/ircd-hybrid-newconf

File Contents

# User Rev Content
1 adx 30 /*
2     * ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd).
3     * ircd.c: Starts up and runs the ircd.
4     *
5     * Copyright (C) 2002 by the past and present ircd coders, and others.
6     *
7     * This program is free software; you can redistribute it and/or modify
8     * it under the terms of the GNU General Public License as published by
9     * the Free Software Foundation; either version 2 of the License, or
10     * (at your option) any later version.
11     *
12     * This program is distributed in the hope that it will be useful,
13     * but WITHOUT ANY WARRANTY; without even the implied warranty of
14     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15     * GNU General Public License for more details.
16     *
17     * You should have received a copy of the GNU General Public License
18     * along with this program; if not, write to the Free Software
19     * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
20     * USA
21     *
22 knight 31 * $Id$
23 adx 30 */
24    
25 adx 185 #ifdef IN_IRCD
26 adx 30 #include "stdinc.h"
27 adx 743 #include "conf/conf.h"
28 adx 801 #include "user.h"
29 adx 30 #include "ircd.h"
30     #include "channel.h"
31     #include "channel_mode.h"
32     #include "client.h"
33     #include "common.h"
34     #include "hash.h"
35     #include "ircd_signal.h"
36     #include "motd.h"
37     #include "ircd_handler.h"
38     #include "msg.h" /* msgtab */
39     #include "numeric.h"
40     #include "packet.h"
41     #include "parse.h"
42     #include "restart.h"
43     #include "s_auth.h"
44 db 91 #include "parse_aline.h"
45 adx 801 #include "server.h"
46 adx 30 #include "send.h"
47     #include "whowas.h"
48     #include "motd.h"
49 michael 217 #include "watch.h"
50 michael 684 #include "patchlevel.h"
51     #include "serno.h"
52 adx 30
53    
54     /* /quote set variables */
55     struct SetOptions GlobalSetOptions;
56 michael 515 struct ServerStatistics ServerStats;
57 adx 30 /* admin info set from ircd.conf */
58     struct Counter Count = { 0, 0, 0, 0, 0, 0, 0, 0 };
59 adx 743 struct ServerState_t ServerState = { 0 };
60 adx 30 struct Client me; /* That's me */
61     struct LocalUser meLocalUser; /* That's also part of me */
62    
63     char **myargv;
64 michael 684 const char *ircd_version = PATCHLEVEL;
65     const char *serno = SERIALNUM;
66     char ircd_platform[IRCD_BUFSIZE];
67 adx 30
68     int dorehash = 0;
69     int doremotd = 0;
70    
71     /* Set to zero because it should be initialized later using
72     * initialize_server_capabs
73     */
74     int default_server_capabs = 0;
75    
76     #ifdef HAVE_LIBCRYPTO
77     int bio_spare_fd = -1;
78     #endif
79    
80     int splitmode;
81     int splitchecking;
82    
83 adx 68 static dlink_node *fdlimit_hook;
84    
85 adx 30 /* Do klines the same way hybrid-6 did them, i.e. at the
86     * top of the next io_loop instead of in the same loop as
87     * the klines are being applied.
88     *
89     * This should fix strange CPU starvation as very indirectly reported.
90     * (Why do you people not email bug reports? WHY? WHY?)
91     *
92     * - Dianora
93     */
94    
95     int rehashed_klines = 0;
96    
97     #ifndef _WIN32
98     /*
99     * print_startup - print startup information
100     */
101     static void
102     print_startup(int pid)
103     {
104     printf("ircd: version %s\n", ircd_version);
105     printf("ircd: pid %d\n", pid);
106 adx 743 printf("ircd: running in %s mode from %s\n",
107     ServerState.foreground ? "foreground" : "background", DPATH);
108 adx 30 }
109    
110     static void
111     make_daemon(void)
112     {
113     int pid;
114    
115     if ((pid = fork()) < 0)
116     {
117     perror("fork");
118     exit(EXIT_FAILURE);
119     }
120     else if (pid > 0)
121     {
122     print_startup(pid);
123     exit(EXIT_SUCCESS);
124     }
125    
126     setsid();
127     }
128     #endif
129    
130 michael 695 static struct lgetopt myopts[] = {
131 adx 743 {"configfile", &ServerState.configfile,
132 adx 30 STRING, "File to use for ircd.conf"},
133 adx 743 {"klinefile", &ServerState.klinefile,
134 adx 30 STRING, "File to use for kline.conf"},
135 adx 743 {"rklinefile", &ServerState.rklinefile,
136     STRING, "File to use for rkline.conf"},
137     {"dlinefile", &ServerState.dlinefile,
138     STRING, "File to use for dline.conf"},
139     {"glinefile", &ServerState.glinefile,
140     STRING, "File to use for gline.conf"},
141     {"xlinefile", &ServerState.xlinefile,
142 adx 30 STRING, "File to use for xline.conf"},
143 adx 743 {"rxlinefile", &ServerState.rxlinefile,
144     STRING, "File to use for rxline.conf"},
145     {"cresvfile", &ServerState.cresvfile,
146     STRING, "File to use for cresv.conf"},
147     {"nresvfile", &ServerState.nresvfile,
148     STRING, "File to use for nresv.conf"},
149     {"logfile", &ServerState.logfile,
150 adx 30 STRING, "File to use for ircd.log"},
151 adx 743 {"pidfile", &ServerState.pidfile,
152 adx 30 STRING, "File to use for process ID"},
153 adx 743 {"foreground", &ServerState.foreground,
154 adx 30 YESNO, "Run in foreground (don't detach)"},
155 adx 743 {"version", &ServerState.printversion,
156 adx 30 YESNO, "Print version and exit"},
157     {"help", NULL, USAGE, "Print this text"},
158     {NULL, NULL, STRING, NULL},
159     };
160    
161     static void
162     io_loop(void)
163     {
164     while (1 == 1)
165     {
166     /*
167     * Maybe we want a flags word?
168     * ie. if (REHASHED_KLINES(global_flags))
169     * SET_REHASHED_KLINES(global_flags)
170     * CLEAR_REHASHED_KLINES(global_flags)
171     *
172     * - Dianora
173     */
174     if (rehashed_klines)
175     {
176     check_conf_klines();
177     rehashed_klines = 0;
178     }
179    
180     if (listing_client_list.head)
181     {
182     dlink_node *ptr = NULL, *ptr_next = NULL;
183     DLINK_FOREACH_SAFE(ptr, ptr_next, listing_client_list.head)
184     {
185     struct Client *client_p = ptr->data;
186     assert(client_p->localClient->list_task);
187 michael 398 safe_list_channels(client_p, client_p->localClient->list_task, 0);
188 adx 30 }
189     }
190    
191     /* Run pending events, then get the number of seconds to the next
192     * event
193     */
194     while (eventNextTime() <= CurrentTime)
195     eventRun();
196    
197     comm_select();
198     exit_aborted_clients();
199     free_exited_clients();
200     send_queued_all();
201    
202 adx 743 // Check to see whether we have to rehash the configuration ..
203 adx 30 if (dorehash)
204     {
205 adx 743 sendto_realops_flags(UMODE_ALL, L_ALL,
206     "Got signal SIGHUP, reloading ircd configuration");
207     read_conf_files(NO);
208 adx 30 dorehash = 0;
209     }
210 michael 450
211 adx 30 if (doremotd)
212     {
213 adx 743 read_message_file(&motd);
214 adx 30 sendto_realops_flags(UMODE_ALL, L_ALL,
215 adx 743 "Got signal SIGUSR1, reloading ircd MOTD file");
216 adx 30 doremotd = 0;
217     }
218     }
219     }
220    
221     /* initalialize_global_set_options()
222     *
223     * inputs - none
224     * output - none
225     * side effects - This sets all global set options needed
226 adx 205 * XXX to be removed with old s_conf.c
227 adx 30 */
228     static void
229     initialize_global_set_options(void)
230     {
231     memset(&GlobalSetOptions, 0, sizeof(GlobalSetOptions));
232    
233     GlobalSetOptions.autoconn = 1;
234     GlobalSetOptions.spam_time = MIN_JOIN_LEAVE_TIME;
235     GlobalSetOptions.spam_num = MAX_JOIN_LEAVE_COUNT;
236    
237 adx 743 if (General.default_floodcount)
238     GlobalSetOptions.floodcount = General.default_floodcount;
239 adx 30 else
240     GlobalSetOptions.floodcount = 10;
241    
242 adx 743 // XXX I have no idea what to try here - Dianora
243 adx 30 GlobalSetOptions.joinfloodcount = 16;
244     GlobalSetOptions.joinfloodtime = 8;
245    
246 adx 743 GlobalSetOptions.split_servers = Channel.default_split_server_count;
247     GlobalSetOptions.split_users = Channel.default_split_user_count;
248 adx 30
249 adx 743 if (GlobalSetOptions.split_users && GlobalSetOptions.split_servers &&
250     (Channel.no_create_on_split || Channel.no_join_on_split))
251 adx 30 {
252     splitmode = 1;
253     splitchecking = 1;
254     }
255    
256     GlobalSetOptions.ident_timeout = IDENT_TIMEOUT;
257 adx 743 GlobalSetOptions.idletime = General.idletime;
258 db 278 GlobalSetOptions.maxlisters = 10; /* XXX ya ya ya - db */
259 adx 30 }
260    
261     /* write_pidfile()
262     *
263     * inputs - filename+path of pid file
264     * output - NONE
265     * side effects - write the pid of the ircd to filename
266     */
267     static void
268     write_pidfile(const char *filename)
269     {
270     FBFILE *fb;
271    
272     if ((fb = fbopen(filename, "w")))
273     {
274     char buff[32];
275     unsigned int pid = (unsigned int)getpid();
276     size_t nbytes = ircsprintf(buff, "%u\n", pid);
277    
278     if ((fbputs(buff, fb, nbytes) == -1))
279     ilog(L_ERROR, "Error writing %u to pid file %s (%s)",
280     pid, filename, strerror(errno));
281    
282     fbclose(fb);
283     }
284     else
285     {
286     ilog(L_ERROR, "Error opening pid file %s", filename);
287     }
288     }
289    
290     /* check_pidfile()
291     *
292     * inputs - filename+path of pid file
293     * output - none
294     * side effects - reads pid from pidfile and checks if ircd is in process
295     * list. if it is, gracefully exits
296     * -kre
297     */
298     static void
299     check_pidfile(const char *filename)
300     {
301     #ifndef _WIN32
302     FBFILE *fb;
303     char buff[32];
304     pid_t pidfromfile;
305    
306 adx 743 // Don't do logging here, since we don't have log() initialised
307 adx 30 if ((fb = fbopen(filename, "r")))
308     {
309     if (fbgets(buff, 20, fb) == NULL)
310     {
311     /* log(L_ERROR, "Error reading from pid file %s (%s)", filename,
312     * strerror(errno));
313     */
314     }
315     else
316     {
317     pidfromfile = atoi(buff);
318    
319     if (!kill(pidfromfile, 0))
320     {
321 adx 743 // log(L_ERROR, "Server is already running");
322 adx 30 printf("ircd: daemon is already running\n");
323     exit(-1);
324     }
325     }
326    
327     fbclose(fb);
328     }
329     else if (errno != ENOENT)
330     {
331 adx 743 // log(L_ERROR, "Error opening pid file %s", filename);
332 adx 30 }
333     #endif
334     }
335    
336     /* init_ssl()
337     *
338     * inputs - nothing
339     * output - nothing
340     * side effects - setups SSL context.
341     */
342     static void
343 michael 702 ssl_init(void)
344 adx 30 {
345     #ifdef HAVE_LIBCRYPTO
346 michael 452 SSL_library_init();
347 adx 30 SSL_load_error_strings();
348    
349     ServerInfo.ctx = SSL_CTX_new(SSLv23_server_method());
350 michael 450
351 adx 30 if (!ServerInfo.ctx)
352     {
353     const char *s;
354    
355     fprintf(stderr, "ERROR: Could not initialize the SSL context -- %s\n",
356     s = ERR_lib_error_string(ERR_get_error()));
357     ilog(L_CRIT, "ERROR: Could not initialize the SSL context -- %s\n", s);
358     }
359    
360     SSL_CTX_set_options(ServerInfo.ctx, SSL_OP_NO_SSLv2);
361     SSL_CTX_set_options(ServerInfo.ctx, SSL_OP_TLS_ROLLBACK_BUG|SSL_OP_ALL);
362     SSL_CTX_set_verify(ServerInfo.ctx, SSL_VERIFY_NONE, NULL);
363    
364     bio_spare_fd = save_spare_fd("SSL private key validation");
365     #endif /* HAVE_LIBCRYPTO */
366     }
367    
368     /* init_callbacks()
369     *
370     * inputs - nothing
371     * output - nothing
372     * side effects - setups standard hook points
373     */
374     static void
375     init_callbacks(void)
376     {
377 adx 211 entering_umode_cb = register_callback("entering_umode", NULL);
378 adx 178 iorecv_cb = register_callback("iorecv", iorecv_default);
379     iosend_cb = register_callback("iosend", iosend_default);
380 adx 30 iorecvctrl_cb = register_callback("iorecvctrl", NULL);
381     iosendctrl_cb = register_callback("iosendctrl", NULL);
382 adx 743 authorize_client = register_callback("authorize_client", do_authorize_client);
383     uid_get = register_callback("uid_get", do_uid_get);
384 adx 211 umode_cb = register_callback("changing_umode", change_simple_umode);
385 adx 30 }
386    
387 adx 68 static void *
388     changing_fdlimit(va_list args)
389     {
390     int old_fdlimit = hard_fdlimit;
391     int fdmax = va_arg(args, int);
392    
393 michael 649 /*
394     * allow MAXCLIENTS_MIN clients even at the cost of MAX_BUFFER and
395     * some not really LEAKED_FDS
396     */
397     fdmax = LIBIO_MAX(fdmax, LEAKED_FDS + MAX_BUFFER + MAXCLIENTS_MIN);
398 adx 68
399     pass_callback(fdlimit_hook, fdmax);
400    
401     if (ServerInfo.max_clients > MAXCLIENTS_MAX)
402     {
403     if (old_fdlimit != 0)
404     sendto_realops_flags(UMODE_ALL, L_ALL,
405     "HARD_FDLIMIT changed to %d, adjusting MAXCLIENTS to %d",
406     hard_fdlimit, MAXCLIENTS_MAX);
407    
408     ServerInfo.max_clients = MAXCLIENTS_MAX;
409     }
410    
411     return NULL;
412     }
413    
414 adx 185 EXTERN int
415 adx 30 main(int argc, char *argv[])
416     {
417 michael 515 /*
418     * Check to see if the user is running us as root, which is a nono
419 adx 30 */
420     #ifndef _WIN32
421     if (geteuid() == 0)
422     {
423     fprintf(stderr, "Don't run ircd as root!!!\n");
424 adx 62 return 1;
425 adx 30 }
426    
427 adx 743 // Setup corefile size immediately after boot -kre
428 adx 30 setup_corefile();
429     #endif
430    
431     memset(&ServerInfo, 0, sizeof(ServerInfo));
432 michael 515 memset(&ServerStats, 0, sizeof(ServerStats));
433 adx 30
434 adx 743 ServerState.configfile = CPATH; // Server configuration file
435     ServerState.klinefile = KPATH; // Server kline file
436     ServerState.rklinefile = RKPATH; // Server regex kline file
437     ServerState.dlinefile = DLPATH; // dline file
438     ServerState.glinefile = GPATH; // gline log file
439 adx 771 ServerState.xlinefile = XPATH; // Server xline file
440     ServerState.rxlinefile = RXPATH; // Server regex xline file
441 adx 743 ServerState.cresvfile = CRESVPATH; // channel resv file
442     ServerState.nresvfile = NRESVPATH; // nick resv file
443 adx 771 ServerState.logfile = LPATH;
444     ServerState.pidfile = PPATH;
445 adx 30 myargv = argv;
446 adx 743 umask(077); // better safe than sorry --SRB
447 adx 30
448     parseargs(&argc, &argv, myopts);
449    
450 adx 743 if (ServerState.printversion)
451 adx 30 {
452     printf("ircd: version %s\n", ircd_version);
453     exit(EXIT_SUCCESS);
454     }
455    
456 adx 743 if (chdir(DPATH))
457 adx 30 {
458     perror("chdir");
459     exit(EXIT_FAILURE);
460     }
461    
462 michael 702 ssl_init();
463 adx 30
464     #ifndef _WIN32
465 adx 743 if (!ServerState.foreground)
466 adx 30 make_daemon();
467     else
468     print_startup(getpid());
469 adx 77 #endif
470 adx 30
471 adx 743 libio_init(!ServerState.foreground);
472 adx 772 init_restart();
473 adx 229 fdlimit_hook = install_hook(fdlimit_cb, changing_fdlimit);
474    
475 adx 743 check_pidfile(ServerState.pidfile);
476 adx 229 setup_signals();
477 michael 684 libio_get_platform(ircd_platform, sizeof(ircd_platform));
478 adx 743 init_log(ServerState.logfile);
479     ServerState.can_use_v6 = check_can_use_v6();
480 adx 229
481 db 228 memset(&me, 0, sizeof(me));
482     memset(&meLocalUser, 0, sizeof(meLocalUser));
483     me.localClient = &meLocalUser;
484     me.from = me.servptr = &me;
485     me.lasttime = me.since = me.firsttime = CurrentTime;
486     SetMe(&me);
487     make_server(&me);
488     dlinkAdd(&me, &me.node, &global_client_list);
489     dlinkAdd(&me, make_dlink_node(), &global_serv_list);
490    
491 adx 30 init_callbacks();
492 adx 743 init_motd();
493     init_isupport();
494 michael 702 hash_init();
495 adx 30 clear_tree_parse();
496     init_client();
497 michael 655 whowas_init();
498     watch_init();
499 michael 702 init_auth();
500 michael 695 channel_init();
501 adx 48 init_channel_modes();
502 michael 702 server_init();
503 adx 743 init_conf();
504 stu 828 modules_init();
505 adx 743 read_conf_files(YES); // cold start init conf files
506     init_uid();
507     initialize_global_set_options();
508 michael 257
509 adx 30 /*
510     * assemble_umode_buffer() has to be called after
511     * reading conf/loading modules.
512     */
513     assemble_umode_buffer();
514    
515 adx 743 write_pidfile(ServerState.pidfile);
516 adx 30
517     ilog(L_NOTICE, "Server Ready");
518    
519 adx 743 // We want try_connections to be called as soon as possible now! -- adrian
520     // No, 'cause after a restart it would cause all sorts of nick collides
521 adx 30 eventAddIsh("try_connections", try_connections, NULL, STARTUP_CONNECTIONS_TIME);
522    
523     eventAddIsh("collect_zipstats", collect_zipstats, NULL, ZIPSTATS_TIME);
524    
525 adx 743 // Setup the timeout check. I'll shift it later :) -- adrian
526 adx 30 eventAddIsh("comm_checktimeouts", comm_checktimeouts, NULL, 1);
527    
528     io_loop();
529 michael 450 return 0;
530 adx 30 }
531 adx 185
532     #else
533    
534     #include <windows.h>
535    
536     extern __declspec(dllimport) main(int, char **);
537    
538     /*
539     * Initial entry point for Win32 GUI applications, called by the C runtime.
540     *
541     * It should be only a wrapper for main(), since when compiled as a console
542     * application, main() is called instead.
543     */
544     int WINAPI
545     WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
546     LPSTR lpCmdLine, int nCmdShow)
547     {
548     /* Do we really need these pidfile, logfile etc arguments?
549     * And we are not on a console, so -help or -foreground is meaningless. */
550    
551     char *argv[2] = {"ircd", NULL};
552    
553     return main(1, argv);
554     }
555    
556     #endif

Properties

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