ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/ermyth/src/conf.C
Revision: 1.2
Committed: Sat Jul 21 01:29:10 2007 UTC (16 years, 10 months ago) by pippijn
Content type: text/plain
Branch: MAIN
Changes since 1.1: +1 -1 lines
Log Message:
- moved to new documentation system
- fixed small build error

File Contents

# User Rev Content
1 pippijn 1.1 /*
2     * conf.C: Configuration processing.
3 pippijn 1.2 * Rights to this code are documented in doc/pod/license.pod.
4 pippijn 1.1 *
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     }