ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/cvsroot/ermyth/src/conf.C
Revision: 1.3
Committed: Sat Jul 21 13:23:21 2007 UTC (16 years, 11 months ago) by pippijn
Content type: text/plain
Branch: MAIN
Changes since 1.2: +1 -1 lines
Log Message:
- added rcsid to some files
- more documentation tweaks
- made most protocol commands local to phandler.C
- added ircd metadata (inspircd only for now)
- added inspircd swhois support

File Contents

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