ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/ircd-hybrid/src/conf/conf.c
Revision: 719
Committed: Sun Jul 16 16:56:58 2006 UTC (20 years ago) by adx
Content type: text/x-csrc
File size: 8421 byte(s)
Log Message:
+ reworked operator{} blocks to make them independent from oldconf
+ moved some utilities from s_conf.* to libio
+ added stub for auth{} blocks

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_admin();
62 init_listen();
63 init_logging();
64 init_class();
65 init_channel();
66 init_serverhide();
67 init_general();
68 #ifndef STATIC_MODULES
69 init_modules();
70 #endif
71 init_ilines();
72 init_operator();
73 }
74
75 /*
76 * parse_error()
77 *
78 * Log a parse error message.
79 *
80 * inputs:
81 * fmt - error message format
82 * output: none
83 */
84 static void
85 do_parse_error(int fatal, const char *fmt, va_list args)
86 {
87 char *newbuf = stripws(conf_linebuf);
88 char msg[CONF_BUFSIZE];
89
90 vsnprintf(msg, sizeof(msg), fmt, args);
91
92 if (conf_pass != 0)
93 {
94 sendto_realops_flags(UMODE_ALL, L_ALL, "\"%s\", line %u: %s: %s",
95 conf_curctx.filename, conf_curctx.lineno+1, msg, newbuf);
96 ilog(fatal ? L_CRIT : L_WARN, "\"%s\", line %u: %s: %s",
97 conf_curctx.filename, conf_curctx.lineno+1, msg, newbuf);
98 }
99 else
100 {
101 sendto_realops_flags(UMODE_ALL, L_ALL, "Conf %s: %s",
102 fatal ? "FATAL" : "ERROR", msg);
103 ilog(fatal ? L_CRIT : L_WARN, "Conf %s: %s",
104 fatal ? "FATAL" : "ERROR", msg);
105 }
106 }
107
108 void
109 parse_error(const char *fmt, ...)
110 {
111 va_list args;
112
113 va_start(args, fmt);
114 do_parse_error(NO, fmt, args);
115 va_end(args);
116 }
117
118 void
119 parse_fatal(const char *fmt, ...)
120 {
121 va_list args;
122
123 va_start(args, fmt);
124 do_parse_error(YES, fmt, args);
125 va_end(args);
126
127 server_die("misconfigured server", NO);
128 }
129
130 /*
131 * yyerror()
132 *
133 * Log a parse error message if the current pass is 2.
134 *
135 * inputs:
136 * msg - error message
137 * output: none
138 */
139 void
140 _yyerror(const char *msg)
141 {
142 if (conf_pass == 2)
143 parse_error("%s", msg);
144 }
145
146 /*
147 * conf_yy_input()
148 *
149 * Loads a block of data from the conf file.
150 *
151 * inputs:
152 * buf - address of destination buffer
153 * siz - size of the buffer
154 * output: number of bytes actually read
155 */
156 int
157 conf_yy_input(char *buf, int siz)
158 {
159 return fbgets(buf, siz, conf_curctx.f) == NULL ? 0 : strlen(buf);
160 }
161
162 /*
163 * find_conf_section()
164 *
165 * Finds a conf block (section) structure.
166 *
167 * inputs:
168 * name - name of the block
169 * output: pointer to struct ConfSection or NULL if not found
170 */
171 struct ConfSection *
172 find_conf_section(const char *name)
173 {
174 dlink_node *ptr;
175 struct ConfSection *section;
176
177 DLINK_FOREACH(ptr, conf_section_list.head)
178 {
179 section = ptr->data;
180 if (!strcasecmp(section->name, name))
181 return section;
182 }
183
184 return NULL;
185 }
186
187 /*
188 * add_conf_section()
189 *
190 * Adds a conf block (section) structure.
191 *
192 * inputs:
193 * name - name of the block
194 * pass - pass when the section should be parsed (1 or 2)
195 * output: pointer to struct ConfSection or NULL if already exists
196 */
197 struct ConfSection *
198 add_conf_section(const char *name, int pass)
199 {
200 struct ConfSection *section;
201
202 if (find_conf_section(name) != NULL)
203 return NULL;
204
205 section = MyMalloc(sizeof(struct ConfSection));
206 section->name = name;
207 section->pass = pass;
208 dlinkAdd(section, &section->node, &conf_section_list);
209 return section;
210 }
211
212 /*
213 * delete_conf_section()
214 *
215 * Deletes a conf block (section) structure.
216 *
217 * inputs:
218 * section - pointer to ConfSection structure
219 * output: none
220 */
221 void
222 delete_conf_section(struct ConfSection *section)
223 {
224 dlink_node *ptr, *ptr_next;
225
226 DLINK_FOREACH_SAFE(ptr, ptr_next, section->fields.head)
227 {
228 dlinkDelete(ptr, &section->fields);
229 MyFree(ptr->data);
230 }
231
232 dlinkDelete(&section->node, &conf_section_list);
233 }
234
235 struct ConfField *
236 find_conf_field(struct ConfSection *section, char *name)
237 {
238 dlink_node *ptr;
239 struct ConfField *field;
240
241 if (section == NULL)
242 return NULL;
243 if (section->pass != conf_pass)
244 return NULL;
245
246 DLINK_FOREACH(ptr, section->fields.head)
247 {
248 field = ptr->data;
249 if (!strcasecmp(field->name, name))
250 return field;
251 }
252
253 parse_error("unknown field");
254 return NULL;
255 }
256
257 /*
258 * conf_assign()
259 *
260 * Called when a conf item (xxx = 'yyy'; form) is parsed.
261 *
262 * inputs:
263 * type - type of supplied value
264 * field - pointer to struct ConfField
265 * value - address of value data
266 * output: none
267 */
268 void
269 conf_assign(int type, struct ConfField *field, void *value)
270 {
271 static char *field_types[] =
272 {"NUMBER", "BOOLEAN", "TIME", "SIZE", "STRING", "LIST", "NLIST"};
273
274 if (field == NULL)
275 return;
276
277 if (type == field->type || (type == CT_NUMBER &&
278 (field->type == CT_TIME || field->type == CT_SIZE)))
279 {
280 if (field->handler != NULL)
281 field->handler(value, field->param);
282 }
283 else if (type == CT_NUMBER && field->type == CT_NLIST)
284 {
285 dlink_list list = {NULL, NULL, 0};
286 dlink_node node;
287
288 dlinkAdd((void *) (long) (*(int *) value), &node, &list);
289
290 if (field->handler != NULL)
291 field->handler(&list, field->param);
292 }
293 else
294 parse_error("type mismatch, expected %s", field_types[type]);
295 }
296
297 /*
298 * conf_assign_*()
299 *
300 * Simple field handlers which just write a variable.
301 *
302 * inputs:
303 * value - address of data
304 * var - where to write it
305 * output: none
306 */
307 void
308 conf_assign_bool(void *value, void *var)
309 {
310 *(char *) var = *(int *) value;
311 }
312
313 void
314 conf_assign_number(void *value, void *var)
315 {
316 *(int *) var = *(int *) value;
317 }
318
319 void
320 conf_assign_string(void *value, void *var)
321 {
322 MyFree(*(char **) var);
323 DupString(*(char **) var, (char *) value);
324 }
325
326 /*
327 * add_conf_field()
328 *
329 * Adds a field of type number to the given section.
330 *
331 * inputs:
332 * section - pointer to ConfSection structure
333 * name - name of the field
334 * type - type of the field as defined in conf.h
335 * handler - function to be called when an assignment
336 * is encountered (one argument: info)
337 * output: none
338 */
339 struct ConfField *
340 add_conf_field(struct ConfSection *section, const char *name, int type,
341 CONFF_HANDLER *handler, void *param)
342 {
343 struct ConfField *field = MyMalloc(sizeof(struct ConfField));
344
345 if (handler == NULL)
346 switch (type)
347 {
348 case CT_NUMBER:
349 case CT_TIME:
350 case CT_SIZE:
351 handler = conf_assign_number;
352 break;
353 case CT_BOOL:
354 handler = conf_assign_bool;
355 break;
356 case CT_STRING:
357 handler = conf_assign_string;
358 break;
359 default:
360 assert(0);
361 }
362
363 field->name = name;
364 field->type = type;
365 field->handler = handler;
366 field->param = param;
367 dlinkAdd(field, &field->node, &section->fields);
368 return field;
369 }
370
371 /*
372 * delete_conf_field()
373 *
374 * Deletes a field from a section. Will crash if called incorrectly.
375 *
376 * inputs:
377 * section - pointer to ConfSection structure
378 * field - pointer to ConfField to delete
379 * output: none
380 */
381 void
382 delete_conf_field(struct ConfSection *section, struct ConfField *field)
383 {
384 dlinkDelete(&field->node, &section->fields);
385 MyFree(field);
386 }