]> jfr.im git - irc/ircd-hybrid/bopm.git/blame - src/config.c
Merged in TimeMr14C's IPv6 stuff to main branch.
[irc/ircd-hybrid/bopm.git] / src / config.c
CommitLineData
dcf198ea 1/*
2Copyright (C) 2002 Erik Fears
3
4This program is free software; you can redistribute it and/or
5modify it under the terms of the GNU General Public License
6as published by the Free Software Foundation; either version 2
7of the License, or (at your option) any later version.
8
9This program is distributed in the hope that it will be useful,
10but WITHOUT ANY WARRANTY; without even the implied warranty of
11MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12GNU General Public License for more details.
13
14You should have received a copy of the GNU General Public License
15along with this program; if not, write to the Free Software
16
17 Foundation, Inc.
18 59 Temple Place - Suite 330
19 Boston, MA 02111-1307, USA.
20
21*/
22
5b8249aa 23#include "setup.h"
dcf198ea 24
5b8249aa 25#ifdef STDC_HEADERS
dcf198ea 26#include <string.h>
dcf198ea 27#include <stdlib.h>
21ccdcf9 28#endif
5b8249aa 29
30#include <stdio.h>
2bbfbe9b 31#include <time.h>
dcf198ea 32
33#include "config.h"
12326396 34#include "log.h"
27f391e7 35#include "misc.h"
0a3810c2 36#include "extern.h"
714c9cea 37#include "match.h"
dcf198ea 38
6970fdab 39static void config_checkreq(void);
40static void config_memfail(void);
41static void add_to_list(string_list *oldlist, const char *item);
42static void free_list(string_list *list);
43static void add_to_config(const char *key, const char *val);
44
c185a5dd 45extern int remote_is_ipv6;
46extern int bindto_ipv6;
47
dcf198ea 48/* Global Configuration Variables */
49
12326396 50char *CONF_SERVER = 0;
160e54e5 51char *CONF_PASSWORD = 0;
12326396 52char *CONF_USER = 0;
53char *CONF_NICK = 0;
95b76d38 54char *CONF_REALNAME = 0;
39bbe079 55char *CONF_OPER = 0;
f6cd298a 56char *CONF_OPER_MODES = 0;
f3f135f3 57char *CONF_SCANIP = 0;
1f7133ae 58char *CONF_BINDIRC = 0;
59char *CONF_BINDSCAN = 0;
db4efd6a 60char *CONF_CHANNELS = 0;
356950ca 61char *CONF_KEYS = 0;
ad429564 62char *CONF_NICKSERV_IDENT = 0;
f585b8ee 63char *CONF_CHANSERV_INVITE = 0;
ad429564 64char *CONF_KLINE_COMMAND = 0;
6ff0d219 65char *CONF_DNSBL_ZONE = 0;
66char *CONF_DNSBL_FROM = 0;
67char *CONF_DNSBL_TO = 0;
23dbe610 68char *CONF_SENDMAIL = 0;
5416e96d 69char *CONF_HELP_EMAIL = 0;
70char *CONF_AWAY = 0;
cb36c747 71char *CONF_TARGET_STRING = 0;
c6b668dd 72char *CONF_PIDFILE = 0;
714c9cea 73string_list *CONF_EXCLUDE = 0;
f3f135f3 74
4b8adcde 75unsigned int CONF_SCANPORT = 0;
76unsigned int CONF_PORT = 0;
77unsigned int CONF_FDLIMIT = 0;
87f352be 78unsigned int CONF_TIMEOUT = 0;
dcf198ea 79
80/* Configuration Hash , Hashes Config Params to their Function Handlers*/
4d35687a 81/* NAME , TYPE , REQ, REQMET, PTR TO VAR */
dcf198ea 82config_hash hash[] = {
c185a5dd 83 {"SERVER", TYPE_STRING, 0,0, &CONF_SERVER },
84 {"SERVER6", TYPE_AF, 0,0, &CONF_SERVER },
4d35687a 85 {"PORT", TYPE_INT , 1,0, &CONF_PORT },
160e54e5 86 {"PASSWORD", TYPE_STRING, 0,0, &CONF_PASSWORD },
4d35687a 87 {"USER", TYPE_STRING, 1,0, &CONF_USER },
88 {"NICK", TYPE_STRING, 1,0, &CONF_NICK },
95b76d38 89 {"REALNAME", TYPE_STRING, 1,0, &CONF_REALNAME },
4d35687a 90 {"OPER", TYPE_STRING, 1,0, &CONF_OPER },
91 {"OPER_MODES", TYPE_STRING, 1,0, &CONF_OPER_MODES },
92 {"SCANIP", TYPE_STRING, 1,0, &CONF_SCANIP },
93 {"SCANPORT", TYPE_INT , 1,0, &CONF_SCANPORT },
94 {"BINDIRC", TYPE_STRING, 0,0, &CONF_BINDIRC },
95 {"BINDSCAN", TYPE_STRING, 0,0, &CONF_BINDSCAN },
c185a5dd 96 {"BINDIRC6", TYPE_AF, 0,0, &CONF_BINDIRC },
97 {"BINDSCAN6", TYPE_AF, 0,0, &CONF_BINDSCAN },
0a3810c2 98 {"FDLIMIT", TYPE_INT , 1,0, &CONF_FDLIMIT },
4d35687a 99 {"CHANNELS", TYPE_STRING, 1,0, &CONF_CHANNELS },
874fe20f 100 {"KEYS", TYPE_STRING, 0,0, &CONF_KEYS },
4d35687a 101 {"NICKSERV_IDENT", TYPE_STRING, 0,0, &CONF_NICKSERV_IDENT },
102 {"CHANSERV_INVITE", TYPE_STRING, 0,0, &CONF_CHANSERV_INVITE },
103 {"KLINE_COMMAND", TYPE_STRING, 1,0, &CONF_KLINE_COMMAND },
104 {"DNSBL_ZONE", TYPE_STRING, 0,0, &CONF_DNSBL_ZONE },
105 {"DNSBL_FROM", TYPE_STRING, 0,0, &CONF_DNSBL_FROM },
106 {"DNSBL_TO", TYPE_STRING, 0,0, &CONF_DNSBL_TO },
107 {"SENDMAIL", TYPE_STRING, 0,0, &CONF_SENDMAIL },
108 {"HELP_EMAIL", TYPE_STRING, 1,0, &CONF_HELP_EMAIL },
dbad9c7f 109 {"AWAY", TYPE_STRING, 1,0, &CONF_AWAY },
cb36c747 110 {"TARGET_STRING", TYPE_STRING, 1,0, &CONF_TARGET_STRING },
714c9cea 111 {"EXCLUDE", TYPE_LIST, 0,0, &CONF_EXCLUDE },
87f352be 112 {"TIMEOUT", TYPE_INT, 1,0, &CONF_TIMEOUT },
c6b668dd 113 {"PIDFILE", TYPE_STRING, 1,0, &CONF_PIDFILE },
dbad9c7f 114 {0, 0, 0,0, 0 },
dcf198ea 115};
116
117
118
119/* Parse File */
120
121void config_load(char *filename)
122{
6970fdab 123 /* 1k buffer for reading the file. */
124 char line[1024];
125 size_t i;
126 char *key, *args;
127 FILE *in;
128
129 if (!(in = fopen(filename, "r"))) {
130 log("CONFIG -> No config file found, aborting.");
131 exit(1);
132 }
dcf198ea 133
6970fdab 134 /* Clear anything we have already. */
135 for (i = 0; i < (sizeof(hash) / sizeof(config_hash) - 1); i++) {
136 switch(hash[i].type) {
137 case TYPE_STRING:
c185a5dd 138 case TYPE_AF:
6970fdab 139 if (( *(char**) hash[i].var))
140 free(*(char**)hash[i].var);
141 *(char**)hash[i].var = 0;
142 break;
143 case TYPE_INT:
144 *(int *) hash[i].var = 0;
145 break;
146 case TYPE_LIST:
147 free_list(* (string_list **) hash[i].var);
148 break;
149 }
150 hash[i].reqmet = 0;
151 }
152
153 while (fgets(line, 1023, in)) {
154 if(line[0] == '#')
155 continue;
dcf198ea 156
6970fdab 157 key = strtok(line, " ");
158 args = strtok(NULL, "\n");
159
160 if (!args)
161 continue;
ad429564 162
6970fdab 163 /* Strip leading and trailing spaces. */
164 args = clean(args);
165 add_to_config(key, args);
166 }
167
168 fclose(in);
169 /* Check required parameters. */
170 config_checkreq();
4d35687a 171}
172
6970fdab 173static void config_checkreq()
4d35687a 174{
6970fdab 175 size_t i;
176 int errfnd;
177 string_list *list;
178
179 errfnd = 0;
180
181 for (i = 0; i < (sizeof(hash) / sizeof(config_hash) - 1); i++) {
182 if (hash[i].req && !hash[i].reqmet) {
183 log("CONFIG -> Parameter [%s] required but not "
184 "defined in config.", hash[i].key);
185 errfnd++;
186 } else if (OPT_DEBUG >= 3 && hash[i].reqmet) {
187 switch (hash[i].type) {
c185a5dd 188 case TYPE_AF:
6970fdab 189 case TYPE_STRING:
190 log("CONFIG -> Set [%s]: %s", hash[i].key,
191 *(char**) hash[i].var);
192 break;
193 case TYPE_INT:
194 log("CONFIG -> Set [%s]: %d", hash[i].key,
195 *(int *) hash[i].var);
196 break;
197 case TYPE_LIST:
198 for (list = *(string_list**) (hash[i].var);
199 list; list = list->next) {
200 log("CONFIG -> Set [%s]: %s",
201 hash[i].key, list->text);
202 }
203 break;
204 }
205 }
206 }
207
208 if (errfnd) {
209 log("CONFIG -> %d parameters missing from config file, "
210 "aborting.", errfnd);
211 exit(1);
212 }
dcf198ea 213}
214
6970fdab 215/*
216 * Called when memory allocation somewhere returns an error.
12326396 217 */
218
6970fdab 219static void config_memfail(void)
220{
221 log("CONFIG -> Error allocating memory.");
222 exit(1);
223}
224
225static void add_to_list(string_list *oldlist, const char *item)
12326396 226{
6970fdab 227 string_list *list;
228
229 list = malloc(sizeof(*list));
230
231 if (!list)
232 config_memfail();
233
234 list->next = NULL;
235 list->text = strdup(item);
236
237 if (!list->text)
238 config_memfail();
239
240 collapse(list->text);
241
242 if (!oldlist) {
243 oldlist = list;
244 return;
245 }
246
247 while (oldlist) {
248 if (strcasecmp(list->text, oldlist->text)) {
249 if (oldlist->next) {
250 oldlist = oldlist->next;
251 } else {
252 oldlist->next = list;
253 oldlist = NULL;
254 }
255 } else {
256 free(list);
257 oldlist = NULL;
258 }
259 }
12326396 260}
261
6970fdab 262static void free_list(string_list *list)
263{
264 string_list *t, *nextlist;
265
266 for (t = list; t; ) {
267 nextlist = t->next;
268 free(t->text);
269 free(t);
270 t = nextlist;
271 }
272 t = 0;
273 list = 0;
274}
275
276static void add_to_config(const char *key, const char *val)
277{
278 size_t i;
279
280 for (i = 0; i < (sizeof(hash) / sizeof(config_hash)) - 1; i++) {
281 if (strcasecmp(key, hash[i].key) == 0) {
282 switch (hash[i].type) {
283 case TYPE_STRING:
284 *(char**) hash[i].var = strdup(val);
285 break;
c185a5dd 286 case TYPE_AF:
287 *(char**) hash[i].var = strdup(val);
288
289 /* Ugly hack here. The letter E means, it is the word SERVER */
290 /* BINDIRC and BINDSCAN do not have an E in them. */
291 /* -TimeMr14C - 28.06.2002 */
292 if (strchr(key, 'E'))
293 remote_is_ipv6 = 1;
294 else
295 bindto_ipv6 = 1;
296 /* This was required when setting ipv6 savvy values */
297
298 break;
6970fdab 299 case TYPE_INT:
300 *(int *) hash[i].var = atoi(val);
301 break;
302 case TYPE_LIST:
303 add_to_list(* (string_list **) (hash[i].var),
304 val);
305 break;
306 }
307 hash[i].reqmet = 1;
308 }
309 }
310}