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