ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/ircd-hybrid/src/conf/conf.c
Revision: 724
Committed: Sun Jul 16 21:48:50 2006 UTC (17 years, 8 months ago) by adx
Content type: text/x-csrc
File size: 8438 byte(s)
Log Message:
+ began implementing hashtable confs (ACB)

File Contents

# Content
1 /*
2 * ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd).
3 * conf.c: Configuration manager.
4 *
5 * Copyright (C) 2003 by Piotr Nizynski, Advanced IRC Services Project
6 * Copyright (C) 2005 by the Hybrid Development Team.
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
21 * USA
22 *
23 * $Id: conf.c 69 2005-10-04 16:09:51Z adx $
24 */
25
26 #define IN_CONF_C
27 #include "stdinc.h"
28 #include "conf/conf.h"
29 #include "client.h"
30 #include "restart.h"
31 #include "send.h"
32
33 int conf_pass, conf_cold = YES;
34 struct ConfParserContext conf_curctx;
35 char conf_linebuf[CONF_BUFSIZE];
36
37 struct Callback *reset_conf = NULL;
38 struct Callback *verify_conf = NULL;
39 struct Callback *switch_conf_pass = NULL;
40
41 static dlink_list conf_section_list = {NULL, NULL, 0};
42
43 extern int yyparse(void);
44
45 /*
46 * init_conf()
47 *
48 * Initializes the configuration manager.
49 *
50 * inputs: none
51 * output: none
52 */
53 void
54 init_conf(void)
55 {
56 reset_conf = register_callback("reset_conf", NULL);
57 verify_conf = register_callback("verify_conf", NULL);
58 switch_conf_pass = register_callback("switch_conf_pass", NULL);
59
60 init_serverinfo();
61 init_access();
62 init_admin();
63 init_listen();
64 init_logging();
65 init_class();
66 init_channel();
67 init_serverhide();
68 init_general();
69 #ifndef STATIC_MODULES
70 init_modules();
71 #endif
72 init_ilines();
73 init_operator();
74 }
75
76 /*
77 * parse_error()
78 *
79 * Log a parse error message.
80 *
81 * inputs:
82 * fmt - error message format
83 * output: none
84 */
85 static void
86 do_parse_error(int fatal, const char *fmt, va_list args)
87 {
88 char *newbuf = stripws(conf_linebuf);
89 char msg[CONF_BUFSIZE];
90
91 vsnprintf(msg, sizeof(msg), fmt, args);
92
93 if (conf_pass != 0)
94 {
95 sendto_realops_flags(UMODE_ALL, L_ALL, "\"%s\", line %u: %s: %s",
96 conf_curctx.filename, conf_curctx.lineno+1, msg, newbuf);
97 ilog(fatal ? L_CRIT : L_WARN, "\"%s\", line %u: %s: %s",
98 conf_curctx.filename, conf_curctx.lineno+1, msg, newbuf);
99 }
100 else
101 {
102 sendto_realops_flags(UMODE_ALL, L_ALL, "Conf %s: %s",
103 fatal ? "FATAL" : "ERROR", msg);
104 ilog(fatal ? L_CRIT : L_WARN, "Conf %s: %s",
105 fatal ? "FATAL" : "ERROR", msg);
106 }
107 }
108
109 void
110 parse_error(const char *fmt, ...)
111 {
112 va_list args;
113
114 va_start(args, fmt);
115 do_parse_error(NO, fmt, args);
116 va_end(args);
117 }
118
119 void
120 parse_fatal(const char *fmt, ...)
121 {
122 va_list args;
123
124 va_start(args, fmt);
125 do_parse_error(YES, fmt, args);
126 va_end(args);
127
128 server_die("misconfigured server", NO);
129 }
130
131 /*
132 * yyerror()
133 *
134 * Log a parse error message if the current pass is 2.
135 *
136 * inputs:
137 * msg - error message
138 * output: none
139 */
140 void
141 _yyerror(const char *msg)
142 {
143 if (conf_pass == 2)
144 parse_error("%s", msg);
145 }
146
147 /*
148 * conf_yy_input()
149 *
150 * Loads a block of data from the conf file.
151 *
152 * inputs:
153 * buf - address of destination buffer
154 * siz - size of the buffer
155 * output: number of bytes actually read
156 */
157 int
158 conf_yy_input(char *buf, int siz)
159 {
160 return fbgets(buf, siz, conf_curctx.f) == NULL ? 0 : strlen(buf);
161 }
162
163 /*
164 * find_conf_section()
165 *
166 * Finds a conf block (section) structure.
167 *
168 * inputs:
169 * name - name of the block
170 * output: pointer to struct ConfSection or NULL if not found
171 */
172 struct ConfSection *
173 find_conf_section(const char *name)
174 {
175 dlink_node *ptr;
176 struct ConfSection *section;
177
178 DLINK_FOREACH(ptr, conf_section_list.head)
179 {
180 section = ptr->data;
181 if (!strcasecmp(section->name, name))
182 return section;
183 }
184
185 return NULL;
186 }
187
188 /*
189 * add_conf_section()
190 *
191 * Adds a conf block (section) structure.
192 *
193 * inputs:
194 * name - name of the block
195 * pass - pass when the section should be parsed (1 or 2)
196 * output: pointer to struct ConfSection or NULL if already exists
197 */
198 struct ConfSection *
199 add_conf_section(const char *name, int pass)
200 {
201 struct ConfSection *section;
202
203 if (find_conf_section(name) != NULL)
204 return NULL;
205
206 section = MyMalloc(sizeof(struct ConfSection));
207 section->name = name;
208 section->pass = pass;
209 dlinkAdd(section, &section->node, &conf_section_list);
210 return section;
211 }
212
213 /*
214 * delete_conf_section()
215 *
216 * Deletes a conf block (section) structure.
217 *
218 * inputs:
219 * section - pointer to ConfSection structure
220 * output: none
221 */
222 void
223 delete_conf_section(struct ConfSection *section)
224 {
225 dlink_node *ptr, *ptr_next;
226
227 DLINK_FOREACH_SAFE(ptr, ptr_next, section->fields.head)
228 {
229 dlinkDelete(ptr, &section->fields);
230 MyFree(ptr->data);
231 }
232
233 dlinkDelete(&section->node, &conf_section_list);
234 }
235
236 struct ConfField *
237 find_conf_field(struct ConfSection *section, char *name)
238 {
239 dlink_node *ptr;
240 struct ConfField *field;
241
242 if (section == NULL)
243 return NULL;
244 if (section->pass != conf_pass)
245 return NULL;
246
247 DLINK_FOREACH(ptr, section->fields.head)
248 {
249 field = ptr->data;
250 if (!strcasecmp(field->name, name))
251 return field;
252 }
253
254 parse_error("unknown field");
255 return NULL;
256 }
257
258 /*
259 * conf_assign()
260 *
261 * Called when a conf item (xxx = 'yyy'; form) is parsed.
262 *
263 * inputs:
264 * type - type of supplied value
265 * field - pointer to struct ConfField
266 * value - address of value data
267 * output: none
268 */
269 void
270 conf_assign(int type, struct ConfField *field, void *value)
271 {
272 static char *field_types[] =
273 {"NUMBER", "BOOLEAN", "TIME", "SIZE", "STRING", "LIST", "NLIST"};
274
275 if (field == NULL)
276 return;
277
278 if (type == field->type || (type == CT_NUMBER &&
279 (field->type == CT_TIME || field->type == CT_SIZE)))
280 {
281 if (field->handler != NULL)
282 field->handler(value, field->param);
283 }
284 else if (type == CT_NUMBER && field->type == CT_NLIST)
285 {
286 dlink_list list = {NULL, NULL, 0};
287 dlink_node node;
288
289 dlinkAdd((void *) (long) (*(int *) value), &node, &list);
290
291 if (field->handler != NULL)
292 field->handler(&list, field->param);
293 }
294 else
295 parse_error("type mismatch, expected %s", field_types[type]);
296 }
297
298 /*
299 * conf_assign_*()
300 *
301 * Simple field handlers which just write a variable.
302 *
303 * inputs:
304 * value - address of data
305 * var - where to write it
306 * output: none
307 */
308 void
309 conf_assign_bool(void *value, void *var)
310 {
311 *(char *) var = *(int *) value;
312 }
313
314 void
315 conf_assign_number(void *value, void *var)
316 {
317 *(int *) var = *(int *) value;
318 }
319
320 void
321 conf_assign_string(void *value, void *var)
322 {
323 MyFree(*(char **) var);
324 DupString(*(char **) var, (char *) value);
325 }
326
327 /*
328 * add_conf_field()
329 *
330 * Adds a field of type number to the given section.
331 *
332 * inputs:
333 * section - pointer to ConfSection structure
334 * name - name of the field
335 * type - type of the field as defined in conf.h
336 * handler - function to be called when an assignment
337 * is encountered (one argument: info)
338 * output: none
339 */
340 struct ConfField *
341 add_conf_field(struct ConfSection *section, const char *name, int type,
342 CONFF_HANDLER *handler, void *param)
343 {
344 struct ConfField *field = MyMalloc(sizeof(struct ConfField));
345
346 if (handler == NULL)
347 switch (type)
348 {
349 case CT_NUMBER:
350 case CT_TIME:
351 case CT_SIZE:
352 handler = conf_assign_number;
353 break;
354 case CT_BOOL:
355 handler = conf_assign_bool;
356 break;
357 case CT_STRING:
358 handler = conf_assign_string;
359 break;
360 default:
361 assert(0);
362 }
363
364 field->name = name;
365 field->type = type;
366 field->handler = handler;
367 field->param = param;
368 dlinkAdd(field, &field->node, &section->fields);
369 return field;
370 }
371
372 /*
373 * delete_conf_field()
374 *
375 * Deletes a field from a section. Will crash if called incorrectly.
376 *
377 * inputs:
378 * section - pointer to ConfSection structure
379 * field - pointer to ConfField to delete
380 * output: none
381 */
382 void
383 delete_conf_field(struct ConfSection *section, struct ConfField *field)
384 {
385 dlinkDelete(&field->node, &section->fields);
386 MyFree(field);
387 }