ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/ermyth/src/conf.C
Revision: 1.10
Committed: Sat Sep 22 14:27:30 2007 UTC (16 years, 7 months ago) by pippijn
Content type: text/plain
Branch: MAIN
CVS Tags: HEAD
Changes since 1.9: +25 -19 lines
Log Message:
split up ermyth into ermyth-modules, libermyth (currently just ermyth-util) and ermyth-core

File Contents

# Content
1 /*
2 * conf.C: Configuration processing.
3 *
4 * Copyright © 2007 Pippijn van Steenhoven / The Ermyth Team
5 * Rights to this code are as documented in COPYING.
6 *
7 *
8 * Portions of this file were derived from sources bearing the following license:
9 * Rights to this code are documented in doc/pod/license.pod.
10 * Copyright © 2005-2007 Atheme Project (http://www.atheme.org)
11 */
12
13 static char const rcsid[] = "$Id: conf.C,v 1.9 2007-09-16 18:54:44 pippijn Exp $";
14
15 #include "atheme.h"
16 #include "confparse.h"
17 #include <ermyth/crypto.h>
18 #include <ermyth/database.h>
19 #include <ermyth/module.h>
20 #include <account/myuser.h>
21 #include <account/mychan.h>
22 #include <account/chanacs.h>
23 #include "uplink.h"
24 #include "pmodule.h"
25 #include "privs.h"
26
27 ConfTable::callbacks ConfTable::callback;
28
29 static void deinit_conf (void);
30
31 enum config_error
32 {
33 no_param,
34 wrong_param
35 };
36
37 template<config_error e>
38 int param_error (config_entry_t *ce, char const * const msg = NULL);
39
40 template<>
41 int param_error<no_param> (config_entry_t *ce, char const * const msg)
42 {
43 slog (LG_INFO, "%s:%i: %s: %s",
44 ce->ce_fileptr->cf_filename,
45 ce->ce_varlinenum, msg ? msg : "no parameter for option",
46 ce->ce_varname);
47 return 1;
48 }
49
50 template<>
51 int param_error<wrong_param> (config_entry_t *ce, char const * const msg)
52 {
53 slog (LG_INFO, "%s:%i: %s: %s",
54 ce->ce_fileptr->cf_filename,
55 ce->ce_varlinenum, msg ? msg : "wrong parameter for option",
56 ce->ce_varname);
57 return 1;
58 }
59
60 static int c_serverinfo (config_entry_t *);
61 static int c_general (config_entry_t *);
62 static int c_database (config_entry_t *);
63 static int c_uplink (config_entry_t *);
64 static int c_chanserv (config_entry_t *);
65 static int c_globserv (config_entry_t *);
66 static int c_operserv (config_entry_t *);
67 static int c_memoserv (config_entry_t *);
68 static int c_gameserv (config_entry_t *);
69 static int c_nickserv (config_entry_t *);
70 static int c_saslserv (config_entry_t *);
71 static int c_loadmodule (config_entry_t *);
72 static int c_backend (config_entry_t *);
73 static int c_crypto (config_entry_t *);
74 static int c_protocol (config_entry_t *);
75 static int c_operclass (config_entry_t *);
76 static int c_operator (config_entry_t *);
77 static int c_logfile (config_entry_t *);
78
79 static int c_si_name (config_entry_t *);
80 static int c_si_desc (config_entry_t *);
81 static int c_si_numeric (config_entry_t *);
82 static int c_si_vhost (config_entry_t *);
83 static int c_si_recontime (config_entry_t *);
84 static int c_si_restarttime (config_entry_t *);
85 static int c_si_netname (config_entry_t *);
86 static int c_si_hidehostsuffix (config_entry_t *);
87 static int c_si_adminname (config_entry_t *);
88 static int c_si_adminemail (config_entry_t *);
89 static int c_si_mta (config_entry_t *);
90 static int c_si_loglevel (config_entry_t *);
91 static int c_si_maxlogins (config_entry_t *);
92 static int c_si_maxusers (config_entry_t *);
93 static int c_si_maxnicks (config_entry_t *);
94 static int c_si_maxchans (config_entry_t *);
95 static int c_si_emaillimit (config_entry_t *);
96 static int c_si_emailtime (config_entry_t *);
97 static int c_si_auth (config_entry_t *);
98 static int c_si_mdlimit (config_entry_t *);
99 static int c_si_casemapping (config_entry_t *);
100
101 /* ChanServ client information. */
102 static int c_ci_nick (config_entry_t *);
103 static int c_ci_user (config_entry_t *);
104 static int c_ci_host (config_entry_t *);
105 static int c_ci_real (config_entry_t *);
106 static int c_ci_fantasy (config_entry_t *);
107 static int c_ci_vop (config_entry_t *);
108 static int c_ci_hop (config_entry_t *);
109 static int c_ci_aop (config_entry_t *);
110 static int c_ci_sop (config_entry_t *);
111 static int c_ci_changets (config_entry_t *);
112 static int c_ci_trigger (config_entry_t *);
113 static int c_ci_expire (config_entry_t *);
114 static int c_ci_maxchanacs (config_entry_t *);
115 static int c_ci_maxfounders (config_entry_t *);
116
117 /* GlobServ client information. */
118 static int c_gl_nick (config_entry_t *);
119 static int c_gl_user (config_entry_t *);
120 static int c_gl_host (config_entry_t *);
121 static int c_gl_real (config_entry_t *);
122
123 /* OperServ client information. */
124 static int c_oi_nick (config_entry_t *);
125 static int c_oi_user (config_entry_t *);
126 static int c_oi_host (config_entry_t *);
127 static int c_oi_real (config_entry_t *);
128
129 /* NickServ client information. */
130 static int c_ni_nick (config_entry_t *);
131 static int c_ni_user (config_entry_t *);
132 static int c_ni_host (config_entry_t *);
133 static int c_ni_real (config_entry_t *);
134 static int c_ni_spam (config_entry_t *);
135 static int c_ni_no_nick_ownership (config_entry_t *);
136 static int c_ni_expire (config_entry_t *);
137
138 /* SaslServ client information. */
139 static int c_ss_nick (config_entry_t *);
140 static int c_ss_user (config_entry_t *);
141 static int c_ss_host (config_entry_t *);
142 static int c_ss_real (config_entry_t *);
143
144 /* MemoServ client information. */
145 static int c_ms_nick (config_entry_t *);
146 static int c_ms_user (config_entry_t *);
147 static int c_ms_host (config_entry_t *);
148 static int c_ms_real (config_entry_t *);
149
150 /* GameServ client information. */
151 static int c_gs_nick (config_entry_t *);
152 static int c_gs_user (config_entry_t *);
153 static int c_gs_host (config_entry_t *);
154 static int c_gs_real (config_entry_t *);
155
156 /* Database information. */
157 static int c_db_user (config_entry_t *);
158 static int c_db_host (config_entry_t *);
159 static int c_db_password (config_entry_t *);
160 static int c_db_database (config_entry_t *);
161 static int c_db_port (config_entry_t *);
162
163 static int c_gi_chan (config_entry_t *);
164 static int c_gi_silent (config_entry_t *);
165 static int c_gi_verbose_wallops (config_entry_t *);
166 static int c_gi_use_privmsg (config_entry_t *);
167 static int c_gi_join_chans (config_entry_t *);
168 static int c_gi_leave_chans (config_entry_t *);
169 static int c_gi_uflags (config_entry_t *);
170 static int c_gi_cflags (config_entry_t *);
171 static int c_gi_raw (config_entry_t *);
172 static int c_gi_flood_msgs (config_entry_t *);
173 static int c_gi_flood_time (config_entry_t *);
174 static int c_gi_kline_time (config_entry_t *);
175 static int c_gi_commit_interval (config_entry_t *);
176 static int c_gi_expire (config_entry_t *);
177 static int c_gi_secure (config_entry_t *);
178 static int c_gi_default_clone_limit (config_entry_t *);
179
180 /* *INDENT-OFF* */
181
182 static Token uflags[] = {
183 { "HOLD", MU_HOLD },
184 { "NEVEROP", MU_NEVEROP },
185 { "NOOP", MU_NOOP },
186 { "HIDEMAIL", MU_HIDEMAIL },
187 { "NONE", 0 },
188 { NULL, 0 }
189 };
190
191 static Token cflags[] = {
192 { "HOLD", MC_HOLD },
193 { "SECURE", MC_SECURE },
194 { "VERBOSE", MC_VERBOSE },
195 { "KEEPTOPIC", MC_KEEPTOPIC },
196 { "VERBOSE_OPS", MC_VERBOSE_OPS },
197 { "TOPICLOCK", MC_TOPICLOCK },
198 { "GUARD", MC_GUARD },
199 { "NONE", 0 },
200 { NULL, 0 }
201 };
202
203 static Token logflags[] = {
204 { "DEBUG", LG_ALL },
205 { "TRACE", LG_INFO | LG_ERROR | LG_CMD_ALL | LG_NETWORK | LG_WALLOPS | LG_REGISTER },
206 { "MISC", LG_INFO | LG_ERROR | LG_CMD_ADMIN | LG_CMD_REGISTER | LG_CMD_SET | LG_NETWORK | LG_WALLOPS | LG_REGISTER },
207 { "NOTICE", LG_INFO | LG_ERROR | LG_CMD_ADMIN | LG_CMD_REGISTER | LG_NETWORK | LG_REGISTER },
208 { "ALL", LG_ALL },
209 { "INFO", LG_INFO },
210 { "ERROR", LG_ERROR },
211 { "COMMANDS", LG_CMD_ALL },
212 { "ADMIN", LG_CMD_ADMIN },
213 { "REGISTER", LG_CMD_REGISTER | LG_REGISTER },
214 { "SET", LG_CMD_SET },
215 { "NETWORK", LG_NETWORK },
216 { "WALLOPS", LG_WALLOPS },
217 { "RAWDATA", LG_RAWDATA },
218 { NULL, 0 }
219 };
220
221 static ConfTable::list_type confblocks;
222 static ConfTable::list_type conf_si_table;
223 static ConfTable::list_type conf_ci_table;
224 static ConfTable::list_type conf_gl_table;
225 static ConfTable::list_type conf_oi_table;
226 static ConfTable::list_type conf_ni_table;
227 static ConfTable::list_type conf_db_table;
228 static ConfTable::list_type conf_gi_table;
229 static ConfTable::list_type conf_ms_table;
230 static ConfTable::list_type conf_la_table;
231 static ConfTable::list_type conf_ss_table;
232 static ConfTable::list_type conf_gs_table;
233
234 /* *INDENT-ON* */
235
236 static void
237 conf_report_error (config_entry_t *ce, char const * const fmt, ...)
238 {
239 va_list va;
240 char buf[BUFSIZE];
241
242 return_if_fail (ce != NULL);
243 return_if_fail (fmt != NULL);
244
245 va_start (va, fmt);
246 vsnprintf (buf, BUFSIZE, fmt, va);
247 va_end (va);
248
249 slog (LG_INFO, "%s:%d: configuration error - %s", ce->ce_fileptr->cf_filename, ce->ce_varlinenum, buf);
250 }
251
252 static void
253 conf_process (config_file_t *cfp)
254 {
255 config_file_t *cfptr;
256 config_entry_t *ce;
257 ConfTable *ct = NULL;
258
259 for (cfptr = cfp; cfptr; cfptr = cfptr->cf_next)
260 {
261 for (ce = cfptr->cf_entries; ce; ce = ce->ce_next)
262 {
263 foreach (ConfTable *ct2, confblocks)
264 {
265 ct = ct2;
266 if (!strcasecmp (ct->name, ce->ce_varname))
267 {
268 ct->handler (ce);
269 break;
270 }
271 }
272
273 if (ct == NULL)
274 conf_report_error (ce, "invalid configuration option: %s", ce->ce_varname);
275 }
276 }
277 }
278
279 bool
280 conf_parse (char *file)
281 {
282 config_file_t *cfp;
283
284 cfp = config_load (file);
285 if (cfp == NULL)
286 {
287 slog (LG_ERROR, "conf_parse(): unable to load configuration file: %s", strerror (errno));
288
289 return false;
290 }
291
292 conf_process (cfp);
293 config_free (cfp);
294
295 if (!protocol::handler::loaded)
296 {
297 slog (LG_ERROR, "No protocol module loaded, aborting");
298 exit (EXIT_FAILURE);
299 }
300
301 ConfTable::callback.ready ();
302 return true;
303 }
304
305 void
306 conf_cleanup ()
307 {
308 me.cleanup ();
309
310 if (config_options.chan)
311 sfree (config_options.chan);
312 if (config_options.global)
313 sfree (config_options.global);
314
315 if (chansvs.trigger != NULL)
316 sfree (chansvs.trigger);
317
318 deinit_conf ();
319 }
320
321 void
322 conf_init (void)
323 {
324 me.init ();
325 if (chansvs.nick)
326 sfree (chansvs.nick);
327 if (config_options.chan)
328 sfree (config_options.chan);
329 if (config_options.global)
330 sfree (config_options.global);
331
332 chansvs.nick = config_options.chan = config_options.global = config_options.languagefile = NULL;
333
334 config_options.flood_msgs = config_options.flood_time = config_options.kline_time = config_options.commit_interval = 0;
335
336 nicksvs.expiry = chansvs.expiry = 0;
337
338 config_options.defuflags = config_options.defcflags = 0x00000000;
339
340 config_options.silent = config_options.join_chans = config_options.leave_chans = config_options.raw = false;
341
342 me.auth = AUTH_NONE;
343
344 me.mdlimit = 30;
345
346 chansvs.fantasy = false;
347 chansvs.ca_vop = CA_VOP_DEF & ca_all;
348 chansvs.ca_hop = CA_HOP_DEF & ca_all;
349 chansvs.ca_aop = CA_AOP_DEF & ca_all;
350 chansvs.ca_sop = CA_SOP_DEF & ca_all;
351 chansvs.changets = false;
352 if (chansvs.trigger != NULL)
353 sfree (chansvs.trigger);
354 chansvs.trigger = sstrdup ("!");
355 chansvs.maxchanacs = 0;
356 chansvs.maxfounders = 4;
357
358 if (!(runflags & RF_REHASHING))
359 {
360 if (me.name)
361 sfree (me.name);
362 if (me.desc)
363 sfree (me.desc);
364 if (me.vhost)
365 sfree (me.vhost);
366 if (chansvs.user)
367 sfree (chansvs.user);
368 if (chansvs.host)
369 sfree (chansvs.host);
370 if (chansvs.real)
371 sfree (chansvs.real);
372
373 me.name = me.desc = me.vhost = chansvs.user = chansvs.host = chansvs.real = NULL;
374
375 set_match_mapping (MATCH_RFC1459); /* default to RFC compliancy */
376 }
377 }
378
379 int
380 subblock_handler (config_entry_t *ce, ConfTable::list_type &entries)
381 {
382 ConfTable *ct = NULL;
383
384 for (ce = ce->ce_entries; ce; ce = ce->ce_next)
385 {
386 foreach (ConfTable *ct2, entries)
387 {
388 ct = ct2;
389
390 if (!strcasecmp (ct->name, ce->ce_varname))
391 {
392 ct->handler (ce);
393 break;
394 }
395 }
396
397 if (ct == NULL)
398 conf_report_error (ce, "invalid configuration option: %s", ce->ce_varname);
399 }
400 return 0;
401 }
402
403 ConfTable *
404 find_top_conf (char const * const name)
405 {
406 foreach (ConfTable *ct, confblocks)
407 if (!strcasecmp (ct->name, name))
408 return ct;
409
410 return NULL;
411 }
412
413 ConfTable *
414 find_conf_item (char const * const name, ConfTable::list_type &conflist)
415 {
416 foreach (ConfTable *ct, conflist)
417 if (!strcasecmp (ct->name, name))
418 return ct;
419
420 return NULL;
421 }
422
423 void
424 add_top_conf (char const * const name, int (*handler) (config_entry_t *ce))
425 {
426 ConfTable *ct;
427
428 if ((ct = find_top_conf (name)))
429 {
430 slog (LG_DEBUG, "add_top_conf(): duplicate config block '%s'.", name);
431 return;
432 }
433
434 ct = new ConfTable (name, 1, handler);
435
436 confblocks.insert (ct);
437 }
438
439 void
440 add_conf_item (char const * const name, ConfTable::list_type &conflist, int (*handler) (config_entry_t *ce))
441 {
442 ConfTable *ct;
443
444 if ((ct = find_conf_item (name, conflist)))
445 {
446 slog (LG_DEBUG, "add_conf_item(): duplicate item %s", name);
447 return;
448 }
449
450 ct = new ConfTable (name, 1, handler);
451
452 conflist.insert (ct);
453 }
454
455 void
456 del_top_conf (char const * const name)
457 {
458 ConfTable *ct;
459
460 if (!(ct = find_top_conf (name)))
461 {
462 slog (LG_DEBUG, "del_top_conf(): cannot delete nonexistant block %s", name);
463 return;
464 }
465
466 confblocks.erase (ct);
467
468 delete ct;
469 }
470
471 void
472 del_conf_item (char const * const name, ConfTable::list_type &conflist)
473 {
474 ConfTable *ct;
475
476 if (!(ct = find_conf_item (name, conflist)))
477 {
478 slog (LG_DEBUG, "del_conf_item(): cannot delete nonexistant item %s", name);
479 return;
480 }
481
482 conflist.erase (ct);
483
484 delete ct;
485 }
486
487 /* stolen from Sentinel */
488 #define TOKEN_UNMATCHED -1
489 #define TOKEN_ERROR -2
490
491 static int
492 token_to_value (Token token_table[], char *token)
493 {
494 int i;
495
496 if ((token_table != NULL) && (token != NULL))
497 {
498 for (i = 0; token_table[i].text != NULL; i++)
499 if (strcasecmp (token_table[i].text, token) == 0)
500 return token_table[i].value;
501 /* If no match... */
502 return TOKEN_UNMATCHED;
503 }
504
505 /* Otherwise... */
506 return TOKEN_ERROR;
507 }
508
509 void
510 init_newconf (void)
511 {
512 #if 0
513 conftable_heap = BlockHeapCreate (sizeof (ConfTable), 32);
514 #endif
515
516 /* First we set up the blocks. */
517 add_top_conf ("SERVERINFO", c_serverinfo);
518 add_top_conf ("CHANSERV", c_chanserv);
519 add_top_conf ("GLOBAL", c_globserv);
520 add_top_conf ("OPERSERV", c_operserv);
521 add_top_conf ("NICKSERV", c_nickserv);
522 add_top_conf ("SASLSERV", c_saslserv);
523 add_top_conf ("MEMOSERV", c_memoserv);
524 add_top_conf ("GAMESERV", c_gameserv);
525 add_top_conf ("UPLINK", c_uplink);
526 add_top_conf ("GENERAL", c_general);
527 add_top_conf ("DATABASE", c_database);
528 add_top_conf ("LOADMODULE", c_loadmodule);
529 add_top_conf ("BACKEND", c_backend);
530 add_top_conf ("CRYPTO", c_crypto);
531 add_top_conf ("PROTOCOL", c_protocol);
532 add_top_conf ("OPERCLASS", c_operclass);
533 add_top_conf ("OPERATOR", c_operator);
534 add_top_conf ("LOGFILE", c_logfile);
535
536 /* Now we fill in the information */
537 add_conf_item ("NAME", conf_si_table, c_si_name);
538 add_conf_item ("DESC", conf_si_table, c_si_desc);
539 add_conf_item ("NUMERIC", conf_si_table, c_si_numeric);
540 add_conf_item ("VHOST", conf_si_table, c_si_vhost);
541 add_conf_item ("RECONTIME", conf_si_table, c_si_recontime);
542 add_conf_item ("RESTARTTIME", conf_si_table, c_si_restarttime);
543 add_conf_item ("EXPIRE", conf_si_table, c_gi_expire);
544 add_conf_item ("NETNAME", conf_si_table, c_si_netname);
545 add_conf_item ("HIDEHOSTSUFFIX", conf_si_table, c_si_hidehostsuffix);
546 add_conf_item ("ADMINNAME", conf_si_table, c_si_adminname);
547 add_conf_item ("ADMINEMAIL", conf_si_table, c_si_adminemail);
548 add_conf_item ("MTA", conf_si_table, c_si_mta);
549 add_conf_item ("LOGLEVEL", conf_si_table, c_si_loglevel);
550 add_conf_item ("MAXLOGINS", conf_si_table, c_si_maxlogins);
551 add_conf_item ("MAXUSERS", conf_si_table, c_si_maxusers);
552 add_conf_item ("MAXNICKS", conf_si_table, c_si_maxnicks);
553 add_conf_item ("MAXCHANS", conf_si_table, c_si_maxchans);
554 add_conf_item ("EMAILLIMIT", conf_si_table, c_si_emaillimit);
555 add_conf_item ("EMAILTIME", conf_si_table, c_si_emailtime);
556 add_conf_item ("AUTH", conf_si_table, c_si_auth);
557 add_conf_item ("MDLIMIT", conf_si_table, c_si_mdlimit);
558 add_conf_item ("CASEMAPPING", conf_si_table, c_si_casemapping);
559
560 /* general{} block. */
561 add_conf_item ("CHAN", conf_gi_table, c_gi_chan);
562 add_conf_item ("VERBOSE_WALLOPS", conf_gi_table, c_gi_verbose_wallops);
563 add_conf_item ("USE_PRIVMSG", conf_gi_table, c_gi_use_privmsg);
564 add_conf_item ("SILENT", conf_gi_table, c_gi_silent);
565 add_conf_item ("JOIN_CHANS", conf_gi_table, c_gi_join_chans);
566 add_conf_item ("LEAVE_CHANS", conf_gi_table, c_gi_leave_chans);
567 add_conf_item ("UFLAGS", conf_gi_table, c_gi_uflags);
568 add_conf_item ("CFLAGS", conf_gi_table, c_gi_cflags);
569 add_conf_item ("RAW", conf_gi_table, c_gi_raw);
570 add_conf_item ("SECURE", conf_gi_table, c_gi_secure);
571 add_conf_item ("FLOOD_MSGS", conf_gi_table, c_gi_flood_msgs);
572 add_conf_item ("FLOOD_TIME", conf_gi_table, c_gi_flood_time);
573 add_conf_item ("KLINE_TIME", conf_gi_table, c_gi_kline_time);
574 add_conf_item ("COMMIT_INTERVAL", conf_gi_table, c_gi_commit_interval);
575 add_conf_item ("EXPIRE", conf_gi_table, c_gi_expire);
576 add_conf_item ("DEFAULT_CLONE_LIMIT", conf_gi_table, c_gi_default_clone_limit);
577
578 /* chanserv{} block */
579 add_conf_item ("NICK", conf_ci_table, c_ci_nick);
580 add_conf_item ("USER", conf_ci_table, c_ci_user);
581 add_conf_item ("HOST", conf_ci_table, c_ci_host);
582 add_conf_item ("REAL", conf_ci_table, c_ci_real);
583 add_conf_item ("FANTASY", conf_ci_table, c_ci_fantasy);
584 add_conf_item ("VOP", conf_ci_table, c_ci_vop);
585 add_conf_item ("HOP", conf_ci_table, c_ci_hop);
586 add_conf_item ("AOP", conf_ci_table, c_ci_aop);
587 add_conf_item ("SOP", conf_ci_table, c_ci_sop);
588 add_conf_item ("CHANGETS", conf_ci_table, c_ci_changets);
589 add_conf_item ("TRIGGER", conf_ci_table, c_ci_trigger);
590 add_conf_item ("EXPIRE", conf_ci_table, c_ci_expire);
591 add_conf_item ("MAXCHANACS", conf_ci_table, c_ci_maxchanacs);
592 add_conf_item ("MAXFOUNDERS", conf_ci_table, c_ci_maxfounders);
593
594 /* global{} block */
595 add_conf_item ("NICK", conf_gl_table, c_gl_nick);
596 add_conf_item ("USER", conf_gl_table, c_gl_user);
597 add_conf_item ("HOST", conf_gl_table, c_gl_host);
598 add_conf_item ("REAL", conf_gl_table, c_gl_real);
599
600 /* operserv{} block */
601 add_conf_item ("NICK", conf_oi_table, c_oi_nick);
602 add_conf_item ("USER", conf_oi_table, c_oi_user);
603 add_conf_item ("HOST", conf_oi_table, c_oi_host);
604 add_conf_item ("REAL", conf_oi_table, c_oi_real);
605
606 /* nickserv{} block */
607 add_conf_item ("NICK", conf_ni_table, c_ni_nick);
608 add_conf_item ("USER", conf_ni_table, c_ni_user);
609 add_conf_item ("HOST", conf_ni_table, c_ni_host);
610 add_conf_item ("REAL", conf_ni_table, c_ni_real);
611 add_conf_item ("SPAM", conf_ni_table, c_ni_spam);
612 add_conf_item ("NO_NICK_OWNERSHIP", conf_ni_table, c_ni_no_nick_ownership);
613 add_conf_item ("EXPIRE", conf_ni_table, c_ni_expire);
614
615 /* saslserv{} block */
616 add_conf_item ("NICK", conf_ss_table, c_ss_nick);
617 add_conf_item ("USER", conf_ss_table, c_ss_user);
618 add_conf_item ("HOST", conf_ss_table, c_ss_host);
619 add_conf_item ("REAL", conf_ss_table, c_ss_real);
620
621 /* memoserv{} block */
622 add_conf_item ("NICK", conf_ms_table, c_ms_nick);
623 add_conf_item ("USER", conf_ms_table, c_ms_user);
624 add_conf_item ("HOST", conf_ms_table, c_ms_host);
625 add_conf_item ("REAL", conf_ms_table, c_ms_real);
626
627 /* memoserv{} block */
628 add_conf_item ("NICK", conf_gs_table, c_gs_nick);
629 add_conf_item ("USER", conf_gs_table, c_gs_user);
630 add_conf_item ("HOST", conf_gs_table, c_gs_host);
631 add_conf_item ("REAL", conf_gs_table, c_gs_real);
632
633 /* database{} block */
634 add_conf_item ("USER", conf_db_table, c_db_user);
635 add_conf_item ("HOST", conf_db_table, c_db_host);
636 add_conf_item ("PASSWORD", conf_db_table, c_db_password);
637 add_conf_item ("DATABASE", conf_db_table, c_db_database);
638 add_conf_item ("PORT", conf_db_table, c_db_port);
639 }
640
641 static void
642 deinit_conf (void)
643 {
644 #if 0
645 conftable_heap = BlockHeapCreate (sizeof (ConfTable), 32);
646 #endif
647
648 /* Now we fill in the information */
649 del_conf_item ("NAME", conf_si_table);
650 del_conf_item ("DESC", conf_si_table);
651 del_conf_item ("NUMERIC", conf_si_table);
652 del_conf_item ("VHOST", conf_si_table);
653 del_conf_item ("RECONTIME", conf_si_table);
654 del_conf_item ("RESTARTTIME", conf_si_table);
655 del_conf_item ("EXPIRE", conf_si_table);
656 del_conf_item ("NETNAME", conf_si_table);
657 del_conf_item ("HIDEHOSTSUFFIX", conf_si_table);
658 del_conf_item ("ADMINNAME", conf_si_table);
659 del_conf_item ("ADMINEMAIL", conf_si_table);
660 del_conf_item ("MTA", conf_si_table);
661 del_conf_item ("LOGLEVEL", conf_si_table);
662 del_conf_item ("MAXLOGINS", conf_si_table);
663 del_conf_item ("MAXUSERS", conf_si_table);
664 del_conf_item ("MAXNICKS", conf_si_table);
665 del_conf_item ("MAXCHANS", conf_si_table);
666 del_conf_item ("EMAILLIMIT", conf_si_table);
667 del_conf_item ("EMAILTIME", conf_si_table);
668 del_conf_item ("AUTH", conf_si_table);
669 del_conf_item ("MDLIMIT", conf_si_table);
670 del_conf_item ("CASEMAPPING", conf_si_table);
671
672 /* general{} block. */
673 del_conf_item ("CHAN", conf_gi_table);
674 del_conf_item ("VERBOSE_WALLOPS", conf_gi_table);
675 del_conf_item ("USE_PRIVMSG", conf_gi_table);
676 del_conf_item ("SILENT", conf_gi_table);
677 del_conf_item ("JOIN_CHANS", conf_gi_table);
678 del_conf_item ("LEAVE_CHANS", conf_gi_table);
679 del_conf_item ("UFLAGS", conf_gi_table);
680 del_conf_item ("CFLAGS", conf_gi_table);
681 del_conf_item ("RAW", conf_gi_table);
682 del_conf_item ("SECURE", conf_gi_table);
683 del_conf_item ("FLOOD_MSGS", conf_gi_table);
684 del_conf_item ("FLOOD_TIME", conf_gi_table);
685 del_conf_item ("KLINE_TIME", conf_gi_table);
686 del_conf_item ("COMMIT_INTERVAL", conf_gi_table);
687 del_conf_item ("EXPIRE", conf_gi_table);
688 del_conf_item ("DEFAULT_CLONE_LIMIT", conf_gi_table);
689
690 /* chanserv{} block */
691 del_conf_item ("NICK", conf_ci_table);
692 del_conf_item ("USER", conf_ci_table);
693 del_conf_item ("HOST", conf_ci_table);
694 del_conf_item ("REAL", conf_ci_table);
695 del_conf_item ("FANTASY", conf_ci_table);
696 del_conf_item ("VOP", conf_ci_table);
697 del_conf_item ("HOP", conf_ci_table);
698 del_conf_item ("AOP", conf_ci_table);
699 del_conf_item ("SOP", conf_ci_table);
700 del_conf_item ("CHANGETS", conf_ci_table);
701 del_conf_item ("TRIGGER", conf_ci_table);
702 del_conf_item ("EXPIRE", conf_ci_table);
703 del_conf_item ("MAXCHANACS", conf_ci_table);
704 del_conf_item ("MAXFOUNDERS", conf_ci_table);
705
706 /* global{} block */
707 del_conf_item ("NICK", conf_gl_table);
708 del_conf_item ("USER", conf_gl_table);
709 del_conf_item ("HOST", conf_gl_table);
710 del_conf_item ("REAL", conf_gl_table);
711
712 /* operserv{} block */
713 del_conf_item ("NICK", conf_oi_table);
714 del_conf_item ("USER", conf_oi_table);
715 del_conf_item ("HOST", conf_oi_table);
716 del_conf_item ("REAL", conf_oi_table);
717
718 /* nickserv{} block */
719 del_conf_item ("NICK", conf_ni_table);
720 del_conf_item ("USER", conf_ni_table);
721 del_conf_item ("HOST", conf_ni_table);
722 del_conf_item ("REAL", conf_ni_table);
723 del_conf_item ("SPAM", conf_ni_table);
724 del_conf_item ("NO_NICK_OWNERSHIP", conf_ni_table);
725 del_conf_item ("EXPIRE", conf_ni_table);
726
727 /* saslserv{} block */
728 del_conf_item ("NICK", conf_ss_table);
729 del_conf_item ("USER", conf_ss_table);
730 del_conf_item ("HOST", conf_ss_table);
731 del_conf_item ("REAL", conf_ss_table);
732
733 /* memoserv{} block */
734 del_conf_item ("NICK", conf_ms_table);
735 del_conf_item ("USER", conf_ms_table);
736 del_conf_item ("HOST", conf_ms_table);
737 del_conf_item ("REAL", conf_ms_table);
738
739 /* memoserv{} block */
740 del_conf_item ("NICK", conf_gs_table);
741 del_conf_item ("USER", conf_gs_table);
742 del_conf_item ("HOST", conf_gs_table);
743 del_conf_item ("REAL", conf_gs_table);
744
745 /* database{} block */
746 del_conf_item ("USER", conf_db_table);
747 del_conf_item ("HOST", conf_db_table);
748 del_conf_item ("PASSWORD", conf_db_table);
749 del_conf_item ("DATABASE", conf_db_table);
750 del_conf_item ("PORT", conf_db_table);
751
752 /* First we set up the blocks. */
753 del_top_conf ("SERVERINFO");
754 del_top_conf ("CHANSERV");
755 del_top_conf ("GLOBAL");
756 del_top_conf ("OPERSERV");
757 del_top_conf ("NICKSERV");
758 del_top_conf ("SASLSERV");
759 del_top_conf ("MEMOSERV");
760 del_top_conf ("GAMESERV");
761 del_top_conf ("UPLINK");
762 del_top_conf ("GENERAL");
763 del_top_conf ("DATABASE");
764 del_top_conf ("LOADMODULE");
765 del_top_conf ("BACKEND");
766 del_top_conf ("CRYPTO");
767 del_top_conf ("PROTOCOL");
768 del_top_conf ("OPERCLASS");
769 del_top_conf ("OPERATOR");
770 del_top_conf ("LOGFILE");
771 }
772
773 static int
774 c_serverinfo (config_entry_t *ce)
775 {
776 return subblock_handler (ce, conf_si_table);
777 }
778
779 static int
780 c_chanserv (config_entry_t *ce)
781 {
782 return subblock_handler (ce, conf_ci_table);
783 }
784
785 static int
786 c_globserv (config_entry_t *ce)
787 {
788 return subblock_handler (ce, conf_gl_table);
789 }
790
791 static int
792 c_operserv (config_entry_t *ce)
793 {
794 return subblock_handler (ce, conf_oi_table);
795 }
796
797 static int
798 c_nickserv (config_entry_t *ce)
799 {
800 return subblock_handler (ce, conf_ni_table);
801 }
802
803 static int
804 c_saslserv (config_entry_t *ce)
805 {
806 return subblock_handler (ce, conf_ss_table);
807 }
808
809 static int
810 c_memoserv (config_entry_t *ce)
811 {
812 return subblock_handler (ce, conf_ms_table);
813 }
814
815 static int
816 c_gameserv (config_entry_t *ce)
817 {
818 return subblock_handler (ce, conf_gs_table);
819 }
820
821 static int
822 c_database (config_entry_t *ce)
823 {
824 return subblock_handler (ce, conf_db_table);
825 }
826
827 static int
828 c_protocol (config_entry_t *ce)
829 {
830 char *name;
831
832 if (cold_start == false)
833 return 0;
834
835 if (ce->vardata<char *> () == NULL)
836 return param_error<no_param> (ce);
837
838 name = ce->vardata<char *> ();
839
840 typedef factory::factory_mgr<protocol::handler> protocol_factory;
841 protocol_factory &f = protocol_factory::instance ();
842
843 if (!f.provides (name))
844 return param_error<wrong_param> (ce, "no such protocol handler");
845
846 phandler = f.create (name);
847
848 return 0;
849 }
850
851 static int
852 c_loadmodule (config_entry_t *ce)
853 {
854 char *name;
855
856 if (cold_start == false)
857 return 0;
858
859 if (ce->vardata<char *> () == NULL)
860 return param_error<no_param> (ce);
861
862 name = ce->vardata<char *> ();
863
864 if (!modules::provides (name))
865 return param_error<wrong_param> (ce, "no such module");
866
867 modules::enable (name);
868
869 return 0;
870 }
871
872 static int
873 c_crypto (config_entry_t *ce)
874 {
875 char *name;
876
877 if (cold_start == false)
878 return 0;
879
880 if (ce->vardata<char *> () == NULL)
881 return param_error<no_param> (ce);
882
883 name = ce->vardata<char *> ();
884
885 typedef factory::factory_mgr<crypto::handler> crypto_factory;
886 crypto_factory &f = crypto_factory::instance ();
887
888 if (!f.provides (name))
889 return param_error<wrong_param> (ce, "no such crypto handler");
890
891 crypter = f.create (name);
892
893 return 0;
894 }
895
896 static int
897 c_backend (config_entry_t *ce)
898 {
899 char *name;
900
901 if (cold_start == false)
902 return 0;
903
904 if (ce->vardata<char *> () == NULL)
905 return param_error<no_param> (ce);
906
907 name = ce->vardata<char *> ();
908
909 typedef factory::factory_mgr<database::handler> backend_factory;
910 backend_factory &f = backend_factory::instance ();
911
912 if (!f.provides (name))
913 return param_error<wrong_param> (ce, "no such database backend");
914
915 backend = f.create (name);
916
917 return 0;
918 }
919
920 static int
921 c_uplink (config_entry_t *ce)
922 {
923 char *name;
924 char *host = NULL, *vhost = NULL, *password = NULL;
925 unsigned int port = 0;
926
927 if (ce->vardata<char *> () == NULL)
928 return param_error<no_param> (ce);
929
930 if (me.name != NULL && !irccasecmp (ce->vardata<char *> (), me.name))
931 slog (LG_ERROR, "%s:%d: uplink's server name %s should not be the same as our server name, continuing anyway", ce->ce_fileptr->cf_filename, ce->ce_varlinenum, ce->vardata<char *> ());
932 else if (!strchr (ce->vardata<char *> (), '.'))
933 slog (LG_ERROR, "%s:%d: uplink's server name %s is invalid, continuing anyway", ce->ce_fileptr->cf_filename, ce->ce_varlinenum, ce->vardata<char *> ());
934 else if (isdigit (ce->vardata<char *> ()[0]))
935 slog (LG_ERROR, "%s:%d: uplink's server name %s starts with a digit, probably invalid (continuing anyway)", ce->ce_fileptr->cf_filename, ce->ce_varlinenum, ce->vardata<char *> ());
936
937 name = ce->vardata<char *> ();
938
939 for (ce = ce->ce_entries; ce; ce = ce->ce_next)
940 {
941 if (!strcasecmp ("HOST", ce->ce_varname))
942 {
943 if (ce->vardata<char *> () == NULL)
944 return param_error<no_param> (ce);
945
946 host = ce->vardata<char *> ();
947 }
948 else if (!strcasecmp ("VHOST", ce->ce_varname))
949 {
950 if (ce->vardata<char *> () == NULL)
951 return param_error<no_param> (ce);
952
953 vhost = ce->vardata<char *> ();
954 }
955 else if (!strcasecmp ("PASSWORD", ce->ce_varname))
956 {
957 if (ce->vardata<char *> () == NULL)
958 return param_error<no_param> (ce);
959
960 password = ce->vardata<char *> ();
961 }
962 else if (!strcasecmp ("PORT", ce->ce_varname))
963 {
964 if (ce->vardata<char *> () == NULL)
965 return param_error<no_param> (ce);
966
967 port = ce->vardata<int> ();
968 }
969 else
970 {
971 slog (LG_ERROR, "%s:%d: Invalid configuration option uplink::%s", ce->ce_fileptr->cf_filename, ce->ce_varlinenum, ce->ce_varname);
972 continue;
973 }
974 }
975
976 uplink_add (name, host, password, vhost, port);
977
978 return 0;
979 }
980
981 static int
982 c_operclass (config_entry_t *ce)
983 {
984 operclass_t *operclass;
985 char *name;
986 char *privs = NULL, *newprivs;
987 int flags = 0;
988
989 if (ce->vardata<char *> () == NULL)
990 return param_error<no_param> (ce);
991
992 name = ce->vardata<char *> ();
993
994 for (ce = ce->ce_entries; ce; ce = ce->ce_next)
995 {
996 if (!strcasecmp ("PRIVS", ce->ce_varname))
997 {
998 if (ce->vardata<char *> () == NULL && ce->ce_entries == NULL)
999 return param_error<no_param> (ce);
1000
1001 if (ce->ce_entries == NULL)
1002 {
1003 if (privs == NULL)
1004 privs = sstrdup (ce->vardata<char *> ());
1005 else
1006 {
1007 newprivs = salloc<char> (strlen (privs) + 1 + strlen (ce->vardata<char *> ()) + 1);
1008 strcpy (newprivs, privs);
1009 strcat (newprivs, " ");
1010 strcat (newprivs, ce->vardata<char *> ());
1011 sfree (privs);
1012 privs = newprivs;
1013 }
1014 }
1015 else
1016 {
1017 config_entry_t *conf_p;
1018 /*
1019 * New definition format for operclasses.
1020 *
1021 * operclass "sra" {
1022 * privs = {
1023 * special:ircop;
1024 * };
1025 * };
1026 *
1027 * - nenolod
1028 */
1029 for (conf_p = ce->ce_entries; conf_p; conf_p = conf_p->ce_next)
1030 {
1031 if (privs == NULL)
1032 privs = sstrdup (conf_p->ce_varname);
1033 else
1034 {
1035 newprivs = salloc<char> (strlen (privs) + 1 + strlen (conf_p->ce_varname) + 1);
1036 strcpy (newprivs, privs);
1037 strcat (newprivs, " ");
1038 strcat (newprivs, conf_p->ce_varname);
1039 sfree (privs);
1040 privs = newprivs;
1041 }
1042 }
1043 }
1044 }
1045 else if (!strcasecmp ("NEEDOPER", ce->ce_varname))
1046 flags |= OPERCLASS_NEEDOPER;
1047 else
1048 {
1049 slog (LG_ERROR, "%s:%d: Invalid configuration option operclass::%s", ce->ce_fileptr->cf_filename, ce->ce_varlinenum, ce->ce_varname);
1050 continue;
1051 }
1052 }
1053
1054 operclass = operclass_add (name, privs ? privs : "");
1055 if (operclass != NULL)
1056 operclass->flags |= flags;
1057 sfree (privs);
1058 return 0;
1059 }
1060
1061 static int
1062 c_operator (config_entry_t *ce)
1063 {
1064 char *name;
1065 operclass_t *operclass = NULL;
1066 config_entry_t *topce;
1067
1068 if (ce->vardata<char *> () == NULL)
1069 return param_error<no_param> (ce);
1070
1071 topce = ce;
1072 name = ce->vardata<char *> ();
1073
1074 for (ce = ce->ce_entries; ce; ce = ce->ce_next)
1075 {
1076 if (!strcasecmp ("OPERCLASS", ce->ce_varname))
1077 {
1078 if (ce->vardata<char *> () == NULL)
1079 return param_error<no_param> (ce);
1080
1081 operclass = operclass_find (ce->vardata<char *> ());
1082 if (operclass == NULL)
1083 slog (LG_ERROR, "%s:%d: invalid operclass %s for operator %s", ce->ce_fileptr->cf_filename, ce->ce_varlinenum, ce->vardata<char *> (), name);
1084 }
1085 else
1086 {
1087 slog (LG_ERROR, "%s:%d: Invalid configuration option operator::%s", ce->ce_fileptr->cf_filename, ce->ce_varlinenum, ce->ce_varname);
1088 continue;
1089 }
1090 }
1091
1092 if (operclass != NULL)
1093 soper_add (name, operclass->name, SOPER_CONF);
1094 else
1095 slog (LG_ERROR, "%s:%d: skipping operator %s because of bad/missing parameters", topce->ce_fileptr->cf_filename, topce->ce_varlinenum, name);
1096 return 0;
1097 }
1098
1099 static int
1100 c_general (config_entry_t *ce)
1101 {
1102 return subblock_handler (ce, conf_gi_table);
1103 }
1104
1105 static int
1106 c_si_name (config_entry_t *ce)
1107 {
1108 if (ce->vardata<char *> () == NULL)
1109 return param_error<no_param> (ce);
1110
1111 if (!(runflags & RF_REHASHING))
1112 me.name = sstrdup (ce->vardata<char *> ());
1113
1114 return 0;
1115 }
1116
1117 static int
1118 c_si_desc (config_entry_t *ce)
1119 {
1120 if (ce->vardata<char *> () == NULL)
1121 return param_error<no_param> (ce);
1122
1123 if (me.desc != NULL)
1124 sfree (me.desc);
1125 me.desc = sstrdup (ce->vardata<char *> ());
1126
1127 return 0;
1128 }
1129
1130 static int
1131 c_si_numeric (config_entry_t *ce)
1132 {
1133 if (ce->vardata<char *> () == NULL)
1134 return param_error<no_param> (ce);
1135
1136 if (!(runflags & RF_REHASHING))
1137 me.numeric = sstrdup (ce->vardata<char *> ());
1138
1139 return 0;
1140 }
1141
1142 static int
1143 c_si_mdlimit (config_entry_t *ce)
1144 {
1145 if (ce->vardata<char *> () == NULL)
1146 return param_error<no_param> (ce);
1147
1148 me.mdlimit = ce->vardata<int> ();
1149
1150 return 0;
1151 }
1152
1153 static int
1154 c_si_vhost (config_entry_t *ce)
1155 {
1156 if (ce->vardata<char *> () == NULL)
1157 return param_error<no_param> (ce);
1158
1159 me.vhost = sstrdup (ce->vardata<char *> ());
1160
1161 return 0;
1162 }
1163
1164 static int
1165 c_si_recontime (config_entry_t *ce)
1166 {
1167 if (ce->vardata<char *> () == NULL)
1168 return param_error<no_param> (ce);
1169
1170 me.recontime = ce->vardata<int> ();
1171
1172 return 0;
1173 }
1174
1175 static int
1176 c_si_restarttime (config_entry_t *ce)
1177 {
1178 if (ce->vardata<char *> () == NULL)
1179 return param_error<no_param> (ce);
1180
1181 me.restarttime = ce->vardata<int> ();
1182
1183 return 0;
1184 }
1185
1186 static int
1187 c_si_netname (config_entry_t *ce)
1188 {
1189 if (ce->vardata<char *> () == NULL)
1190 return param_error<no_param> (ce);
1191
1192 me.netname = sstrdup (ce->vardata<char *> ());
1193
1194 return 0;
1195 }
1196
1197 static int
1198 c_si_hidehostsuffix (config_entry_t *ce)
1199 {
1200 if (ce->vardata<char *> () == NULL)
1201 return param_error<no_param> (ce);
1202
1203 me.hidehostsuffix = sstrdup (ce->vardata<char *> ());
1204
1205 return 0;
1206 }
1207
1208 static int
1209 c_si_adminname (config_entry_t *ce)
1210 {
1211 if (ce->vardata<char *> () == NULL)
1212 return param_error<no_param> (ce);
1213
1214 me.adminname = sstrdup (ce->vardata<char *> ());
1215
1216 return 0;
1217 }
1218
1219 static int
1220 c_si_adminemail (config_entry_t *ce)
1221 {
1222 if (ce->vardata<char *> () == NULL)
1223 return param_error<no_param> (ce);
1224
1225 me.adminemail = sstrdup (ce->vardata<char *> ());
1226
1227 return 0;
1228 }
1229
1230 static int
1231 c_si_mta (config_entry_t *ce)
1232 {
1233 if (ce->vardata<char *> () == NULL)
1234 return param_error<no_param> (ce);
1235
1236 me.mta = sstrdup (ce->vardata<char *> ());
1237
1238 return 0;
1239 }
1240
1241 static int
1242 c_si_loglevel (config_entry_t *ce)
1243 {
1244 config_entry_t *flce;
1245 int val;
1246 int mask = 0;
1247
1248 if (ce->vardata<char *> () != NULL)
1249 {
1250 val = token_to_value (logflags, ce->vardata<char *> ());
1251
1252 if ((val != TOKEN_UNMATCHED) && (val != TOKEN_ERROR))
1253 mask |= val;
1254 else
1255 slog (LG_INFO, "%s:%d: unknown flag: %s", ce->ce_fileptr->cf_filename, ce->ce_varlinenum, ce->vardata<char *> ());
1256 }
1257 for (flce = ce->ce_entries; flce; flce = flce->ce_next)
1258 {
1259 val = token_to_value (logflags, flce->ce_varname);
1260
1261 if ((val != TOKEN_UNMATCHED) && (val != TOKEN_ERROR))
1262 mask |= val;
1263 else
1264 slog (LG_INFO, "%s:%d: unknown flag: %s", flce->ce_fileptr->cf_filename, flce->ce_varlinenum, flce->ce_varname);
1265 }
1266 log_master_set_mask (mask);
1267
1268 return 0;
1269 }
1270
1271 static int
1272 c_si_maxlogins (config_entry_t *ce)
1273 {
1274 if (ce->vardata<char *> () == NULL)
1275 return param_error<no_param> (ce);
1276
1277 me.maxlogins = ce->vardata<int> ();
1278
1279 return 0;
1280
1281 }
1282
1283 static int
1284 c_si_maxusers (config_entry_t *ce)
1285 {
1286 if (ce->vardata<char *> () == NULL)
1287 return param_error<no_param> (ce);
1288
1289 me.maxusers = ce->vardata<int> ();
1290
1291 return 0;
1292
1293 }
1294
1295 static int
1296 c_si_maxnicks (config_entry_t *ce)
1297 {
1298 if (ce->vardata<char *> () == NULL)
1299 return param_error<no_param> (ce);
1300
1301 me.maxnicks = ce->vardata<int> ();
1302
1303 return 0;
1304 }
1305
1306 static int
1307 c_si_maxchans (config_entry_t *ce)
1308 {
1309 if (ce->vardata<char *> () == NULL)
1310 return param_error<no_param> (ce);
1311
1312 me.maxchans = ce->vardata<int> ();
1313
1314 return 0;
1315 }
1316
1317 static int
1318 c_si_emaillimit (config_entry_t *ce)
1319 {
1320 if (ce->vardata<char *> () == NULL)
1321 return param_error<no_param> (ce);
1322
1323 me.emaillimit = ce->vardata<int> ();
1324
1325 return 0;
1326 }
1327
1328 static int
1329 c_si_emailtime (config_entry_t *ce)
1330 {
1331 if (ce->vardata<char *> () == NULL)
1332 return param_error<no_param> (ce);
1333
1334 me.emailtime = ce->vardata<int> ();
1335
1336 return 0;
1337 }
1338
1339 static int
1340 c_si_auth (config_entry_t *ce)
1341 {
1342 if (ce->vardata<char *> () == NULL)
1343 return param_error<no_param> (ce);
1344
1345 if (!strcasecmp ("EMAIL", ce->vardata<char *> ()))
1346 me.auth = AUTH_EMAIL;
1347
1348 else
1349 me.auth = AUTH_NONE;
1350
1351 return 0;
1352 }
1353
1354 static int
1355 c_si_casemapping (config_entry_t *ce)
1356 {
1357 if (ce->vardata<char *> () == NULL)
1358 return param_error<no_param> (ce);
1359
1360 if (!strcasecmp ("ASCII", ce->vardata<char *> ()))
1361 set_match_mapping (MATCH_ASCII);
1362
1363 else
1364 set_match_mapping (MATCH_RFC1459);
1365
1366 return 0;
1367 }
1368
1369 static int
1370 c_ci_nick (config_entry_t *ce)
1371 {
1372 if (ce->vardata<char *> () == NULL)
1373 return param_error<no_param> (ce);
1374
1375 if (chansvs.nick != NULL)
1376 sfree (chansvs.nick);
1377 chansvs.nick = sstrdup (ce->vardata<char *> ());
1378
1379 return 0;
1380 }
1381
1382 static int
1383 c_ci_user (config_entry_t *ce)
1384 {
1385 if (ce->vardata<char *> () == NULL)
1386 return param_error<no_param> (ce);
1387
1388 if (chansvs.user != NULL)
1389 sfree (chansvs.user);
1390 chansvs.user = sstrdup (ce->vardata<char *> ());
1391
1392 return 0;
1393 }
1394
1395 static int
1396 c_ci_host (config_entry_t *ce)
1397 {
1398 if (ce->vardata<char *> () == NULL)
1399 return param_error<no_param> (ce);
1400
1401 if (chansvs.host != NULL)
1402 sfree (chansvs.host);
1403 chansvs.host = sstrdup (ce->vardata<char *> ());
1404
1405 return 0;
1406 }
1407
1408 static int
1409 c_ci_real (config_entry_t *ce)
1410 {
1411 if (ce->vardata<char *> () == NULL)
1412 return param_error<no_param> (ce);
1413
1414 if (chansvs.real != NULL)
1415 sfree (chansvs.real);
1416 chansvs.real = sstrdup (ce->vardata<char *> ());
1417
1418 return 0;
1419 }
1420
1421 static int
1422 c_ci_fantasy (config_entry_t *ce)
1423 {
1424 chansvs.fantasy = true;
1425
1426 return 0;
1427 }
1428
1429 static int
1430 c_ci_vop (config_entry_t *ce)
1431 {
1432 if (ce->vardata<char *> () == NULL)
1433 return param_error<no_param> (ce);
1434
1435 chansvs.ca_vop = flags_to_bitmask (ce->vardata<char *> (), chanacs_flags, 0);
1436
1437 return 0;
1438 }
1439
1440 static int
1441 c_ci_hop (config_entry_t *ce)
1442 {
1443 if (ce->vardata<char *> () == NULL)
1444 return param_error<no_param> (ce);
1445
1446 chansvs.ca_hop = flags_to_bitmask (ce->vardata<char *> (), chanacs_flags, 0);
1447
1448 return 0;
1449 }
1450
1451 static int
1452 c_ci_aop (config_entry_t *ce)
1453 {
1454 if (ce->vardata<char *> () == NULL)
1455 return param_error<no_param> (ce);
1456
1457 chansvs.ca_aop = flags_to_bitmask (ce->vardata<char *> (), chanacs_flags, 0);
1458
1459 return 0;
1460 }
1461
1462 static int
1463 c_ci_sop (config_entry_t *ce)
1464 {
1465 if (ce->vardata<char *> () == NULL)
1466 return param_error<no_param> (ce);
1467
1468 chansvs.ca_sop = flags_to_bitmask (ce->vardata<char *> (), chanacs_flags, 0);
1469
1470 return 0;
1471 }
1472
1473 static int
1474 c_ci_changets (config_entry_t *ce)
1475 {
1476 chansvs.changets = true;
1477 return 0;
1478 }
1479
1480 static int
1481 c_ci_trigger (config_entry_t *ce)
1482 {
1483 if (ce->vardata<char *> () == NULL)
1484 return param_error<no_param> (ce);
1485
1486 if (chansvs.trigger != NULL)
1487 sfree (chansvs.trigger);
1488 chansvs.trigger = sstrdup (ce->vardata<char *> ());
1489
1490 return 0;
1491 }
1492
1493 static int
1494 c_ci_expire (config_entry_t *ce)
1495 {
1496 if (ce->vardata<char *> () == NULL)
1497 return param_error<no_param> (ce);
1498
1499 chansvs.expiry = (ce->vardata<int> () * 60 * 60 * 24);
1500
1501 return 0;
1502 }
1503
1504 static int
1505 c_ci_maxchanacs (config_entry_t *ce)
1506 {
1507 if (ce->vardata<char *> () == NULL)
1508 return param_error<no_param> (ce);
1509
1510 chansvs.maxchanacs = ce->vardata<int> ();
1511
1512 return 0;
1513 }
1514
1515 static int
1516 c_ci_maxfounders (config_entry_t *ce)
1517 {
1518 if (ce->vardata<char *> () == NULL)
1519 return param_error<no_param> (ce);
1520
1521 chansvs.maxfounders = ce->vardata<int> ();
1522
1523 return 0;
1524 }
1525
1526 static int
1527 c_gi_chan (config_entry_t *ce)
1528 {
1529 if (ce->vardata<char *> () == NULL)
1530 return param_error<no_param> (ce);
1531
1532 config_options.chan = sstrdup (ce->vardata<char *> ());
1533
1534 return 0;
1535 }
1536
1537 static int
1538 c_gi_silent (config_entry_t *ce)
1539 {
1540 config_options.silent = true;
1541 return 0;
1542 }
1543
1544 static int
1545 c_gi_verbose_wallops (config_entry_t *ce)
1546 {
1547 config_options.verbose_wallops = true;
1548 return 0;
1549 }
1550
1551 static int
1552 c_gi_use_privmsg (config_entry_t *ce)
1553 {
1554 config_options.use_privmsg = true;
1555 return 0;
1556 }
1557
1558 static int
1559 c_gi_secure (config_entry_t *ce)
1560 {
1561 config_options.secure = true;
1562 return 0;
1563 }
1564
1565 static int
1566 c_gi_join_chans (config_entry_t *ce)
1567 {
1568 config_options.join_chans = true;
1569 return 0;
1570 }
1571
1572 static int
1573 c_gi_leave_chans (config_entry_t *ce)
1574 {
1575 config_options.leave_chans = true;
1576 return 0;
1577 }
1578
1579 static int
1580 c_gi_uflags (config_entry_t *ce)
1581 {
1582 config_entry_t *flce;
1583
1584 for (flce = ce->ce_entries; flce; flce = flce->ce_next)
1585 {
1586 int val;
1587
1588 val = token_to_value (uflags, flce->ce_varname);
1589
1590 if ((val != TOKEN_UNMATCHED) && (val != TOKEN_ERROR))
1591 config_options.defuflags |= val;
1592
1593 else
1594 {
1595 slog (LG_INFO, "%s:%d: unknown flag: %s", flce->ce_fileptr->cf_filename, flce->ce_varlinenum, flce->ce_varname);
1596 }
1597 }
1598
1599 return 0;
1600 }
1601
1602 static int
1603 c_gi_cflags (config_entry_t *ce)
1604 {
1605 config_entry_t *flce;
1606
1607 for (flce = ce->ce_entries; flce; flce = flce->ce_next)
1608 {
1609 int val;
1610
1611 val = token_to_value (cflags, flce->ce_varname);
1612
1613 if ((val != TOKEN_UNMATCHED) && (val != TOKEN_ERROR))
1614 config_options.defcflags |= val;
1615
1616 else
1617 {
1618 slog (LG_INFO, "%s:%d: unknown flag: %s", flce->ce_fileptr->cf_filename, flce->ce_varlinenum, flce->ce_varname);
1619 }
1620 }
1621
1622 if (config_options.defcflags & MC_TOPICLOCK)
1623 config_options.defcflags |= MC_KEEPTOPIC;
1624
1625 return 0;
1626 }
1627
1628 static int
1629 c_gi_raw (config_entry_t *ce)
1630 {
1631 config_options.raw = true;
1632 return 0;
1633 }
1634
1635 static int
1636 c_gi_flood_msgs (config_entry_t *ce)
1637 {
1638 if (ce->vardata<char *> () == NULL)
1639 return param_error<no_param> (ce);
1640
1641 config_options.flood_msgs = ce->vardata<int> ();
1642
1643 return 0;
1644 }
1645
1646 static int
1647 c_gi_flood_time (config_entry_t *ce)
1648 {
1649 if (ce->vardata<char *> () == NULL)
1650 return param_error<no_param> (ce);
1651
1652 config_options.flood_time = ce->vardata<int> ();
1653
1654 return 0;
1655 }
1656
1657 static int
1658 c_gi_kline_time (config_entry_t *ce)
1659 {
1660 if (ce->vardata<char *> () == NULL)
1661 return param_error<no_param> (ce);
1662
1663 config_options.kline_time = (ce->vardata<int> () * 60 * 60 * 24);
1664
1665 return 0;
1666 }
1667
1668 static int
1669 c_gi_commit_interval (config_entry_t *ce)
1670 {
1671 if (ce->vardata<char *> () == NULL)
1672 return param_error<no_param> (ce);
1673
1674 config_options.commit_interval = (ce->vardata<int> () * 60);
1675
1676 return 0;
1677 }
1678
1679 static int
1680 c_gi_expire (config_entry_t *ce)
1681 {
1682 if (ce->vardata<char *> () == NULL)
1683 return param_error<no_param> (ce);
1684
1685 slog (LG_INFO, "warning: general::expire has been deprecated. please use nickserv::expire and chanserv::expire respectively.");
1686
1687 nicksvs.expiry = (ce->vardata<int> () * 60 * 60 * 24);
1688 chansvs.expiry = (ce->vardata<int> () * 60 * 60 * 24);
1689
1690 return 0;
1691 }
1692
1693 static int
1694 c_gi_default_clone_limit (config_entry_t *ce)
1695 {
1696 if (ce->vardata<char *> () == NULL)
1697 return param_error<no_param> (ce);
1698
1699 config_options.default_clone_limit = ce->vardata<int> ();
1700
1701 return 0;
1702 }
1703
1704 static int
1705 c_oi_nick (config_entry_t *ce)
1706 {
1707 if (ce->vardata<char *> () == NULL)
1708 return param_error<no_param> (ce);
1709
1710 if (opersvs.nick != NULL)
1711 sfree (opersvs.nick);
1712 opersvs.nick = sstrdup (ce->vardata<char *> ());
1713
1714 return 0;
1715 }
1716
1717 static int
1718 c_oi_user (config_entry_t *ce)
1719 {
1720 if (ce->vardata<char *> () == NULL)
1721 return param_error<no_param> (ce);
1722
1723 if (opersvs.user != NULL)
1724 sfree (opersvs.user);
1725 opersvs.user = sstrdup (ce->vardata<char *> ());
1726
1727 return 0;
1728 }
1729
1730 static int
1731 c_oi_host (config_entry_t *ce)
1732 {
1733 if (ce->vardata<char *> () == NULL)
1734 return param_error<no_param> (ce);
1735
1736 if (opersvs.host != NULL)
1737 sfree (opersvs.host);
1738 opersvs.host = sstrdup (ce->vardata<char *> ());
1739
1740 return 0;
1741 }
1742
1743 static int
1744 c_oi_real (config_entry_t *ce)
1745 {
1746 if (ce->vardata<char *> () == NULL)
1747 return param_error<no_param> (ce);
1748
1749 if (opersvs.real != NULL)
1750 sfree (opersvs.real);
1751 opersvs.real = sstrdup (ce->vardata<char *> ());
1752
1753 return 0;
1754 }
1755
1756 static int
1757 c_ni_nick (config_entry_t *ce)
1758 {
1759 if (ce->vardata<char *> () == NULL)
1760 return param_error<no_param> (ce);
1761
1762 if (nicksvs.nick != NULL)
1763 sfree (nicksvs.nick);
1764 nicksvs.nick = sstrdup (ce->vardata<char *> ());
1765
1766 return 0;
1767 }
1768
1769 static int
1770 c_ni_user (config_entry_t *ce)
1771 {
1772 if (ce->vardata<char *> () == NULL)
1773 return param_error<no_param> (ce);
1774
1775 if (nicksvs.user != NULL)
1776 sfree (nicksvs.user);
1777 nicksvs.user = sstrdup (ce->vardata<char *> ());
1778
1779 return 0;
1780 }
1781
1782 static int
1783 c_ni_host (config_entry_t *ce)
1784 {
1785 if (ce->vardata<char *> () == NULL)
1786 return param_error<no_param> (ce);
1787
1788 if (nicksvs.host != NULL)
1789 sfree (nicksvs.host);
1790 nicksvs.host = sstrdup (ce->vardata<char *> ());
1791
1792 return 0;
1793 }
1794
1795 static int
1796 c_ni_real (config_entry_t *ce)
1797 {
1798 if (ce->vardata<char *> () == NULL)
1799 return param_error<no_param> (ce);
1800
1801 if (nicksvs.real != NULL)
1802 sfree (nicksvs.real);
1803 nicksvs.real = sstrdup (ce->vardata<char *> ());
1804
1805 return 0;
1806 }
1807
1808 static int
1809 c_ni_spam (config_entry_t *ce)
1810 {
1811 nicksvs.spam = true;
1812 return 0;
1813 }
1814
1815 static int
1816 c_ni_no_nick_ownership (config_entry_t *ce)
1817 {
1818 nicksvs.no_nick_ownership = true;
1819 return 0;
1820 }
1821
1822 static int
1823 c_ni_expire (config_entry_t *ce)
1824 {
1825 if (ce->vardata<char *> () == NULL)
1826 return param_error<no_param> (ce);
1827
1828 nicksvs.expiry = (ce->vardata<int> () * 60 * 60 * 24);
1829
1830 return 0;
1831 }
1832
1833 static int
1834 c_ss_nick (config_entry_t *ce)
1835 {
1836 if (ce->vardata<char *> () == NULL)
1837 return param_error<no_param> (ce);
1838
1839 if (saslsvs.nick != NULL)
1840 sfree (saslsvs.nick);
1841 saslsvs.nick = sstrdup (ce->vardata<char *> ());
1842
1843 return 0;
1844 }
1845
1846 static int
1847 c_ss_user (config_entry_t *ce)
1848 {
1849 if (ce->vardata<char *> () == NULL)
1850 return param_error<no_param> (ce);
1851
1852 if (saslsvs.user != NULL)
1853 sfree (saslsvs.user);
1854 saslsvs.user = sstrdup (ce->vardata<char *> ());
1855
1856 return 0;
1857 }
1858
1859 static int
1860 c_ss_host (config_entry_t *ce)
1861 {
1862 if (ce->vardata<char *> () == NULL)
1863 return param_error<no_param> (ce);
1864
1865 if (saslsvs.host != NULL)
1866 sfree (saslsvs.host);
1867 saslsvs.host = sstrdup (ce->vardata<char *> ());
1868
1869 return 0;
1870 }
1871
1872 static int
1873 c_ss_real (config_entry_t *ce)
1874 {
1875 if (ce->vardata<char *> () == NULL)
1876 return param_error<no_param> (ce);
1877
1878 if (saslsvs.real != NULL)
1879 sfree (saslsvs.real);
1880 saslsvs.real = sstrdup (ce->vardata<char *> ());
1881
1882 return 0;
1883 }
1884
1885 static int
1886 c_ms_nick (config_entry_t *ce)
1887 {
1888 if (ce->vardata<char *> () == NULL)
1889 return param_error<no_param> (ce);
1890
1891 if (memosvs.nick != NULL)
1892 sfree (memosvs.nick);
1893 memosvs.nick = sstrdup (ce->vardata<char *> ());
1894
1895 return 0;
1896 }
1897
1898 static int
1899 c_ms_user (config_entry_t *ce)
1900 {
1901 if (ce->vardata<char *> () == NULL)
1902 return param_error<no_param> (ce);
1903
1904 if (memosvs.user != NULL)
1905 sfree (memosvs.user);
1906 memosvs.user = sstrdup (ce->vardata<char *> ());
1907
1908 return 0;
1909 }
1910
1911 static int
1912 c_ms_host (config_entry_t *ce)
1913 {
1914 if (ce->vardata<char *> () == NULL)
1915 return param_error<no_param> (ce);
1916
1917 if (memosvs.host != NULL)
1918 sfree (memosvs.host);
1919 memosvs.host = sstrdup (ce->vardata<char *> ());
1920
1921 return 0;
1922 }
1923
1924 static int
1925 c_ms_real (config_entry_t *ce)
1926 {
1927 if (ce->vardata<char *> () == NULL)
1928 return param_error<no_param> (ce);
1929
1930 if (memosvs.real != NULL)
1931 sfree (memosvs.real);
1932 memosvs.real = sstrdup (ce->vardata<char *> ());
1933
1934 return 0;
1935 }
1936
1937 static int
1938 c_gs_nick (config_entry_t *ce)
1939 {
1940 if (ce->vardata<char *> () == NULL)
1941 return param_error<no_param> (ce);
1942
1943 if (gamesvs.nick != NULL)
1944 sfree (gamesvs.nick);
1945 gamesvs.nick = sstrdup (ce->vardata<char *> ());
1946
1947 return 0;
1948 }
1949
1950 static int
1951 c_gs_user (config_entry_t *ce)
1952 {
1953 if (ce->vardata<char *> () == NULL)
1954 return param_error<no_param> (ce);
1955
1956 if (gamesvs.user != NULL)
1957 sfree (gamesvs.user);
1958 gamesvs.user = sstrdup (ce->vardata<char *> ());
1959
1960 return 0;
1961 }
1962
1963 static int
1964 c_gs_host (config_entry_t *ce)
1965 {
1966 if (ce->vardata<char *> () == NULL)
1967 return param_error<no_param> (ce);
1968
1969 if (gamesvs.host != NULL)
1970 sfree (gamesvs.host);
1971 gamesvs.host = sstrdup (ce->vardata<char *> ());
1972
1973 return 0;
1974 }
1975
1976 static int
1977 c_gs_real (config_entry_t *ce)
1978 {
1979 if (ce->vardata<char *> () == NULL)
1980 return param_error<no_param> (ce);
1981
1982 if (gamesvs.real != NULL)
1983 sfree (gamesvs.real);
1984 gamesvs.real = sstrdup (ce->vardata<char *> ());
1985
1986 return 0;
1987 }
1988
1989 static int
1990 c_gl_nick (config_entry_t *ce)
1991 {
1992 if (ce->vardata<char *> () == NULL)
1993 return param_error<no_param> (ce);
1994
1995 if (globsvs.nick != NULL)
1996 sfree (globsvs.nick);
1997 globsvs.nick = sstrdup (ce->vardata<char *> ());
1998
1999 return 0;
2000 }
2001
2002 static int
2003 c_gl_user (config_entry_t *ce)
2004 {
2005 if (ce->vardata<char *> () == NULL)
2006 return param_error<no_param> (ce);
2007
2008 if (globsvs.user != NULL)
2009 sfree (globsvs.user);
2010 globsvs.user = sstrdup (ce->vardata<char *> ());
2011
2012 return 0;
2013 }
2014
2015 static int
2016 c_gl_host (config_entry_t *ce)
2017 {
2018 if (ce->vardata<char *> () == NULL)
2019 return param_error<no_param> (ce);
2020
2021 if (globsvs.host != NULL)
2022 sfree (globsvs.host);
2023 globsvs.host = sstrdup (ce->vardata<char *> ());
2024
2025 return 0;
2026 }
2027
2028 static int
2029 c_gl_real (config_entry_t *ce)
2030 {
2031 if (ce->vardata<char *> () == NULL)
2032 return param_error<no_param> (ce);
2033
2034 if (globsvs.real != NULL)
2035 sfree (globsvs.real);
2036 globsvs.real = sstrdup (ce->vardata<char *> ());
2037
2038 return 0;
2039 }
2040
2041 static int
2042 c_db_user (config_entry_t *ce)
2043 {
2044 if (ce->vardata<char *> () == NULL)
2045 return param_error<no_param> (ce);
2046
2047 if (database_options.user != NULL)
2048 sfree (database_options.user);
2049 database_options.user = sstrdup (ce->vardata<char *> ());
2050
2051 return 0;
2052 }
2053
2054 static int
2055 c_db_host (config_entry_t *ce)
2056 {
2057 if (ce->vardata<char *> () == NULL)
2058 return param_error<no_param> (ce);
2059
2060 if (database_options.host != NULL)
2061 sfree (database_options.host);
2062 database_options.host = sstrdup (ce->vardata<char *> ());
2063
2064 return 0;
2065 }
2066
2067 static int
2068 c_db_password (config_entry_t *ce)
2069 {
2070 if (ce->vardata<char *> () == NULL)
2071 return param_error<no_param> (ce);
2072
2073 if (database_options.pass != NULL)
2074 sfree (database_options.pass);
2075 database_options.pass = sstrdup (ce->vardata<char *> ());
2076
2077 return 0;
2078 }
2079
2080 static int
2081 c_db_database (config_entry_t *ce)
2082 {
2083 if (ce->vardata<char *> () == NULL)
2084 return param_error<no_param> (ce);
2085
2086 if (database_options.database != NULL)
2087 sfree (database_options.database);
2088 database_options.database = sstrdup (ce->vardata<char *> ());
2089
2090 return 0;
2091 }
2092
2093 static int
2094 c_db_port (config_entry_t *ce)
2095 {
2096 if (ce->vardata<int> () == 0)
2097 return param_error<no_param> (ce);
2098
2099 database_options.port = ce->vardata<int> ();
2100
2101 return 0;
2102 }
2103
2104 static int
2105 c_logfile (config_entry_t *ce)
2106 {
2107 config_entry_t *flce;
2108 unsigned int logval = 0;
2109
2110 if (ce->vardata<char *> () == NULL)
2111 return param_error<no_param> (ce);
2112
2113 for (flce = ce->ce_entries; flce; flce = flce->ce_next)
2114 {
2115 int val;
2116
2117 val = token_to_value (logflags, flce->ce_varname);
2118
2119 if ((val != TOKEN_UNMATCHED) && (val != TOKEN_ERROR))
2120 logval |= val;
2121 else
2122 {
2123 slog (LG_INFO, "%s:%d: unknown flag: %s", flce->ce_fileptr->cf_filename, flce->ce_varlinenum, flce->ce_varname);
2124 }
2125 }
2126
2127 logfile_t::create (ce->vardata<char *> (), logval);
2128
2129 return 0;
2130 }
2131
2132 bool
2133 conf_rehash (void)
2134 {
2135 me_t hold_me;
2136 char *oldsnoop;
2137 config_file_t *cfp;
2138
2139 /* we're rehashing */
2140 slog (LG_INFO, "conf_rehash(): rehashing");
2141 runflags |= RF_REHASHING;
2142
2143 errno = 0;
2144 cfp = config_load (config_file);
2145 if (cfp == NULL)
2146 {
2147 slog (LG_ERROR, "conf_rehash(): unable to load configuration file: %s, aborting rehash", strerror (errno));
2148 runflags &= ~RF_REHASHING;
2149 return false;
2150 }
2151
2152 hold_me = me;
2153
2154 oldsnoop = config_options.chan != NULL ? sstrdup (config_options.chan) : NULL;
2155
2156 /* reset everything */
2157 conf_init ();
2158 mark_all_illegal ();
2159 log_shutdown ();
2160
2161 /* now reload */
2162 log_open ();
2163 conf_process (cfp);
2164 config_free (cfp);
2165 ConfTable::callback.ready ();
2166
2167 /* now recheck */
2168 if (!conf_check ())
2169 {
2170 slog (LG_ERROR, "conf_rehash(): conf file was malformed, aborting rehash");
2171
2172 /* freeing the new conf strings */
2173 sfree (chansvs.nick);
2174 me.cleanup ();
2175
2176 /* return everything to the way it was before */
2177 me = hold_me;
2178
2179 /* not fully ok, oh well */
2180 unmark_all_illegal ();
2181
2182 sfree (oldsnoop);
2183
2184 runflags &= ~RF_REHASHING;
2185 return false;
2186 }
2187
2188 if (oldsnoop != NULL || config_options.chan != NULL)
2189 {
2190 if (config_options.chan == NULL)
2191 partall (oldsnoop);
2192 else if (oldsnoop == NULL)
2193 joinall (config_options.chan);
2194 else if (strcmp (oldsnoop, config_options.chan))
2195 {
2196 partall (oldsnoop);
2197 joinall (config_options.chan);
2198 }
2199 }
2200
2201 remove_illegals ();
2202
2203 sfree (oldsnoop);
2204
2205 runflags &= ~RF_REHASHING;
2206 return true;
2207 }
2208
2209 bool
2210 conf_check (void)
2211 {
2212 if (!me.name)
2213 {
2214 slog (LG_ERROR, "conf_check(): no `name' set in %s", config_file);
2215 return false;
2216 }
2217
2218 /* The following checks could perhaps be stricter */
2219 if (!strchr (me.name, '.') || strchr ("!\"#$%&+,-./:@", me.name[0]) || strchr (me.name, ' '))
2220 {
2221 slog (LG_ERROR, "conf_check(): bogus `name' in %s (did you specify a valid server name?)", config_file);
2222 return false;
2223 }
2224
2225 if (isdigit (me.name[0]))
2226 slog (LG_ERROR, "conf_check(): `name' in %s starts with a digit, probably invalid (continuing anyway)", config_file);
2227
2228 if (!me.desc)
2229 me.desc = sstrdup ("Ermyth IRC Services");
2230
2231 if ((!me.recontime) || (me.recontime < 10))
2232 {
2233 slog (LG_INFO, "conf_check(): invalid `recontime' set in %s; " "defaulting to 10", config_file);
2234 me.recontime = 10;
2235 }
2236
2237 if (!me.netname)
2238 {
2239 slog (LG_INFO, "conf_check(): no `netname' set in %s", config_file);
2240 return false;
2241 }
2242
2243 if (!me.adminname)
2244 {
2245 slog (LG_INFO, "conf_check(): no `adminname' set in %s", config_file);
2246 return false;
2247 }
2248
2249 if (!me.adminemail)
2250 {
2251 slog (LG_INFO, "conf_check(): no `adminemail' set in %s", config_file);
2252 return false;
2253 }
2254
2255 if (!me.mta && me.auth == AUTH_EMAIL)
2256 {
2257 slog (LG_INFO, "conf_check(): no `mta' set in %s (but `auth' is email)", config_file);
2258 return false;
2259 }
2260
2261 if (!me.maxlogins)
2262 {
2263 slog (LG_INFO, "conf_check(): no `maxlogins' set in %s; " "defaulting to 5", config_file);
2264 me.maxlogins = 5;
2265 }
2266
2267 if (!me.maxusers)
2268 {
2269 slog (LG_INFO, "conf_check(): no `maxusers' set in %s; " "defaulting to 5", config_file);
2270 me.maxusers = 5;
2271 }
2272
2273 if (!me.maxnicks)
2274 {
2275 if (!nicksvs.no_nick_ownership)
2276 slog (LG_INFO, "conf_check(): no `maxnicks' set in %s; " "defaulting to 5", config_file);
2277 me.maxnicks = 5;
2278 }
2279
2280 if (!me.maxchans)
2281 {
2282 slog (LG_INFO, "conf_check(): no `maxchans' set in %s; " "defaulting to 5", config_file);
2283 me.maxchans = 5;
2284 }
2285
2286 if (!me.emaillimit)
2287 {
2288 slog (LG_INFO, "conf_check(): no `emaillimit' set in %s; " "defaulting to 10", config_file);
2289 me.emaillimit = 10;
2290 }
2291
2292 if (!me.emailtime)
2293 {
2294 slog (LG_INFO, "conf_check(): no `emailtime' set in %s; " "defaulting to 300", config_file);
2295 me.emailtime = 300;
2296 }
2297
2298 if (me.auth != 0 && me.auth != 1)
2299 {
2300 slog (LG_INFO, "conf_check(): no `auth' set in %s; " "defaulting to NONE", config_file);
2301 me.auth = AUTH_NONE;
2302 }
2303
2304 if (!chansvs.nick || !chansvs.user || !chansvs.host || !chansvs.real)
2305 {
2306 slog (LG_ERROR, "conf_check(): invalid chanserv{} block in %s", config_file);
2307 return false;
2308 }
2309
2310 if ((strchr (chansvs.user, ' ')) || (strlen (chansvs.user) > 10))
2311 {
2312 slog (LG_ERROR, "conf_check(): invalid `chanserv::user' in %s", config_file);
2313 return false;
2314 }
2315
2316 /* we know ca_all now */
2317 chansvs.ca_vop &= ca_all;
2318 chansvs.ca_hop &= ca_all;
2319 chansvs.ca_aop &= ca_all;
2320 chansvs.ca_sop &= ca_all;
2321 /* chansvs.ca_hop may be equal to chansvs.ca_vop to disable HOP */
2322 if (!chansvs.ca_vop || !chansvs.ca_hop || !chansvs.ca_aop || !chansvs.ca_sop || chansvs.ca_vop == chansvs.ca_aop || chansvs.ca_vop == chansvs.ca_sop || chansvs.ca_hop == chansvs.ca_aop || chansvs.ca_hop == chansvs.ca_sop || chansvs.ca_aop == chansvs.ca_sop)
2323 {
2324 slog (LG_INFO, "conf_check(): invalid xop levels in %s, using defaults", config_file);
2325 chansvs.ca_vop = CA_VOP_DEF & ca_all;
2326 chansvs.ca_hop = CA_HOP_DEF & ca_all;
2327 chansvs.ca_aop = CA_AOP_DEF & ca_all;
2328 chansvs.ca_sop = CA_SOP_DEF & ca_all;
2329 }
2330
2331 if (config_options.flood_msgs && !config_options.flood_time)
2332 config_options.flood_time = 10;
2333
2334 if (!config_options.default_clone_limit)
2335 config_options.default_clone_limit = 6;
2336
2337 /* recall that commit_interval is in seconds */
2338 if ((!config_options.commit_interval) || (config_options.commit_interval < 60) || (config_options.commit_interval > 3600))
2339 {
2340 slog (LG_INFO, "conf_check(): invalid `commit_interval' set in %s; " "defaulting to 5 minutes", config_file);
2341 config_options.commit_interval = 300;
2342 }
2343
2344 return true;
2345 }