]> jfr.im git - solanum.git/blob - ircd/ircd_parser.y
ircd: ircd_parser: we do not need to include netinet/in.h
[solanum.git] / ircd / ircd_parser.y
1 /* This code is in the public domain.
2 * $Nightmare: nightmare/src/main/parser.y,v 1.2.2.1.2.1 2002/07/02 03:42:10 ejb Exp $
3 */
4
5 %{
6 #include <sys/types.h>
7 #include <sys/stat.h>
8
9 #include <string.h>
10 #include <stdlib.h>
11 #include <stdarg.h>
12 #include <stdio.h>
13 #define WE_ARE_MEMORY_C
14 #include "stdinc.h"
15 #include "setup.h"
16 #include "common.h"
17 #include "ircd_defs.h"
18 #include "defaults.h"
19 #include "client.h"
20 #include "modules.h"
21 #include "newconf.h"
22
23 #define YY_NO_UNPUT
24
25 int yyparse(void);
26 void yyerror(const char *);
27 int yylex(void);
28
29 static time_t conf_find_time(char*);
30
31 static struct {
32 const char * name;
33 const char * plural;
34 time_t val;
35 } ircd_times[] = {
36 {"second", "seconds", 1},
37 {"minute", "minutes", 60},
38 {"hour", "hours", 60 * 60},
39 {"day", "days", 60 * 60 * 24},
40 {"week", "weeks", 60 * 60 * 24 * 7},
41 {"fortnight", "fortnights", 60 * 60 * 24 * 14},
42 {"month", "months", 60 * 60 * 24 * 7 * 4},
43 {"year", "years", 60 * 60 * 24 * 365},
44 /* ok-- we now do sizes here too. they aren't times, but
45 it's close enough */
46 {"byte", "bytes", 1},
47 {"kb", NULL, 1024},
48 {"kbyte", "kbytes", 1024},
49 {"kilobyte", "kilebytes", 1024},
50 {"mb", NULL, 1024 * 1024},
51 {"mbyte", "mbytes", 1024 * 1024},
52 {"megabyte", "megabytes", 1024 * 1024},
53 {NULL, NULL, 0},
54 };
55
56 time_t conf_find_time(char *name)
57 {
58 int i;
59
60 for (i = 0; ircd_times[i].name; i++)
61 {
62 if (strcasecmp(ircd_times[i].name, name) == 0 ||
63 (ircd_times[i].plural && strcasecmp(ircd_times[i].plural, name) == 0))
64 return ircd_times[i].val;
65 }
66
67 return 0;
68 }
69
70 static struct
71 {
72 const char *word;
73 int yesno;
74 } yesno[] = {
75 {"yes", 1},
76 {"no", 0},
77 {"true", 1},
78 {"false", 0},
79 {"on", 1},
80 {"off", 0},
81 {NULL, 0}
82 };
83
84 static int conf_get_yesno_value(char *str)
85 {
86 int i;
87
88 for (i = 0; yesno[i].word; i++)
89 {
90 if (strcasecmp(str, yesno[i].word) == 0)
91 {
92 return yesno[i].yesno;
93 }
94 }
95
96 return -1;
97 }
98
99 static void free_cur_list(conf_parm_t* list)
100 {
101 if (list->type == CF_STRING || list->type == CF_QSTRING) {
102 rb_free(list->v.string);
103 } else if (list->type == CF_FLIST) {
104 /* Even though CF_FLIST is a flag, comparing with == is valid
105 * because conf_parm_t.type must be either a type or one flag.
106 */
107 free_cur_list(list->v.list);
108 }
109
110 if (list->next) {
111 free_cur_list(list->next);
112 }
113
114 rb_free(list);
115 }
116
117
118 conf_parm_t * cur_list = NULL;
119
120 static void add_cur_list_cpt(conf_parm_t *new)
121 {
122 if (cur_list == NULL)
123 {
124 cur_list = rb_malloc(sizeof(conf_parm_t));
125 cur_list->type = CF_FLIST;
126 cur_list->v.list = new;
127 }
128 else
129 {
130 new->next = cur_list->v.list;
131 cur_list->v.list = new;
132 }
133 }
134
135 static void add_cur_list(int type, char *str, int number)
136 {
137 conf_parm_t *new;
138
139 new = rb_malloc(sizeof(conf_parm_t));
140 new->next = NULL;
141 new->type = type;
142
143 switch(type)
144 {
145 case CF_INT:
146 case CF_TIME:
147 case CF_YESNO:
148 new->v.number = number;
149 break;
150 case CF_STRING:
151 case CF_QSTRING:
152 new->v.string = rb_strdup(str);
153 break;
154 }
155
156 add_cur_list_cpt(new);
157 }
158
159
160 %}
161
162 %union {
163 int number;
164 char string[IRCD_BUFSIZE + 1];
165 conf_parm_t * conf_parm;
166 }
167
168 %token LOADMODULE TWODOTS
169
170 %token <string> QSTRING STRING
171 %token <number> NUMBER
172
173 %type <string> qstring string
174 %type <number> number timespec
175 %type <conf_parm> oneitem single itemlist
176
177 %start conf
178
179 %%
180
181 conf:
182 | conf conf_item
183 | error
184 ;
185
186 conf_item: block
187 | loadmodule
188 ;
189
190 block: string
191 {
192 conf_start_block($1, NULL);
193 }
194 '{' block_items '}' ';'
195 {
196 if (conf_cur_block)
197 conf_end_block(conf_cur_block);
198 }
199 | string qstring
200 {
201 conf_start_block($1, $2);
202 }
203 '{' block_items '}' ';'
204 {
205 if (conf_cur_block)
206 conf_end_block(conf_cur_block);
207 }
208 ;
209
210 block_items: block_items block_item
211 | block_item
212 ;
213
214 block_item: string '=' itemlist ';'
215 {
216 conf_call_set(conf_cur_block, $1, cur_list);
217 free_cur_list(cur_list);
218 cur_list = NULL;
219 }
220 ;
221
222 itemlist: itemlist ',' single
223 | single
224 ;
225
226 single: oneitem
227 {
228 add_cur_list_cpt($1);
229 }
230 | oneitem TWODOTS oneitem
231 {
232 /* "1 .. 5" meaning 1,2,3,4,5 - only valid for integers */
233 if ($1->type != CF_INT || $3->type != CF_INT)
234 {
235 conf_report_error("Both arguments in '..' notation must be integers.");
236 break;
237 }
238 else
239 {
240 int i;
241
242 for (i = $1->v.number; i <= $3->v.number; i++)
243 {
244 add_cur_list(CF_INT, 0, i);
245 }
246 }
247 }
248 ;
249
250 oneitem: qstring
251 {
252 $$ = rb_malloc(sizeof(conf_parm_t));
253 $$->type = CF_QSTRING;
254 $$->v.string = rb_strdup($1);
255 }
256 | timespec
257 {
258 $$ = rb_malloc(sizeof(conf_parm_t));
259 $$->type = CF_TIME;
260 $$->v.number = $1;
261 }
262 | number
263 {
264 $$ = rb_malloc(sizeof(conf_parm_t));
265 $$->type = CF_INT;
266 $$->v.number = $1;
267 }
268 | string
269 {
270 /* a 'string' could also be a yes/no value ..
271 so pass it as that, if so */
272 int val = conf_get_yesno_value($1);
273
274 $$ = rb_malloc(sizeof(conf_parm_t));
275
276 if (val != -1)
277 {
278 $$->type = CF_YESNO;
279 $$->v.number = val;
280 }
281 else
282 {
283 $$->type = CF_STRING;
284 $$->v.string = rb_strdup($1);
285 }
286 }
287 ;
288
289 loadmodule:
290 LOADMODULE QSTRING
291 {
292 char *m_bn;
293 m_bn = rb_basename((char *) $2);
294
295 if (findmodule_byname(m_bn) == -1)
296 {
297 load_one_module($2, MAPI_ORIGIN_EXTENSION, 0);
298 }
299
300 rb_free(m_bn);
301 }
302 ';'
303 ;
304
305 qstring: QSTRING { strcpy($$, $1); } ;
306 string: STRING { strcpy($$, $1); } ;
307 number: NUMBER { $$ = $1; } ;
308
309 timespec: number string
310 {
311 time_t t;
312
313 if ((t = conf_find_time($2)) == 0)
314 {
315 conf_report_error("Unrecognised time type/size '%s'", $2);
316 t = 1;
317 }
318
319 $$ = $1 * t;
320 }
321 | timespec timespec
322 {
323 $$ = $1 + $2;
324 }
325 | timespec number
326 {
327 $$ = $1 + $2;
328 }
329 ;