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