]> jfr.im git - solanum.git/blame - ircd/ircd_parser.y
commio: further win32 fixes
[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 $
212380e3
AC
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"
9b8e9eb3 20#include "defaults.h"
212380e3
AC
21#include "client.h"
22#include "modules.h"
23#include "newconf.h"
24
25#define YY_NO_UNPUT
26
6ab8c0d3 27int yyparse(void);
67b7840a 28void yyerror(const char *);
6ab8c0d3 29int yylex(void);
212380e3
AC
30
31static time_t conf_find_time(char*);
32
33static struct {
34 const char * name;
35 const char * plural;
e8cfec47 36 time_t val;
212380e3
AC
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},
e8cfec47 46 /* ok-- we now do sizes here too. they aren't times, but
212380e3
AC
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
58time_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
72static 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
86static 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
101static void free_cur_list(conf_parm_t* list)
102{
dceac3e4
KB
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);
212380e3
AC
110 }
111
dceac3e4 112 if (list->next) {
212380e3 113 free_cur_list(list->next);
dceac3e4
KB
114 }
115
116 rb_free(list);
212380e3
AC
117}
118
e8cfec47 119
212380e3
AC
120conf_parm_t * cur_list = NULL;
121
122static void add_cur_list_cpt(conf_parm_t *new)
123{
124 if (cur_list == NULL)
125 {
eddc2ab6 126 cur_list = rb_malloc(sizeof(conf_parm_t));
dceac3e4 127 cur_list->type = CF_FLIST;
212380e3
AC
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
137static void add_cur_list(int type, char *str, int number)
138{
139 conf_parm_t *new;
140
eddc2ab6 141 new = rb_malloc(sizeof(conf_parm_t));
212380e3
AC
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:
47a03750 154 new->v.string = rb_strdup(str);
212380e3
AC
155 break;
156 }
157
158 add_cur_list_cpt(new);
159}
160
161
162%}
163
164%union {
e8cfec47
JT
165 int number;
166 char string[IRCD_BUFSIZE + 1];
212380e3
AC
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
e8cfec47 176%type <number> number timespec
212380e3
AC
177%type <conf_parm> oneitem single itemlist
178
179%start conf
180
181%%
182
e8cfec47
JT
183conf:
184 | conf conf_item
212380e3
AC
185 | error
186 ;
187
188conf_item: block
189 | loadmodule
190 ;
191
e8cfec47
JT
192block: string
193 {
212380e3
AC
194 conf_start_block($1, NULL);
195 }
e8cfec47 196 '{' block_items '}' ';'
212380e3
AC
197 {
198 if (conf_cur_block)
e8cfec47 199 conf_end_block(conf_cur_block);
212380e3 200 }
e8cfec47
JT
201 | string qstring
202 {
212380e3
AC
203 conf_start_block($1, $2);
204 }
205 '{' block_items '}' ';'
206 {
207 if (conf_cur_block)
e8cfec47 208 conf_end_block(conf_cur_block);
212380e3
AC
209 }
210 ;
211
e8cfec47
JT
212block_items: block_items block_item
213 | block_item
212380e3
AC
214 ;
215
216block_item: string '=' itemlist ';'
217 {
dceac3e4 218 conf_call_set(conf_cur_block, $1, cur_list);
212380e3
AC
219 free_cur_list(cur_list);
220 cur_list = NULL;
221 }
222 ;
223
224itemlist: itemlist ',' single
225 | single
226 ;
227
228single: 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 */
dceac3e4 235 if ($1->type != CF_INT || $3->type != CF_INT)
212380e3
AC
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
252oneitem: qstring
253 {
eddc2ab6 254 $$ = rb_malloc(sizeof(conf_parm_t));
212380e3 255 $$->type = CF_QSTRING;
47a03750 256 $$->v.string = rb_strdup($1);
212380e3
AC
257 }
258 | timespec
259 {
eddc2ab6 260 $$ = rb_malloc(sizeof(conf_parm_t));
212380e3
AC
261 $$->type = CF_TIME;
262 $$->v.number = $1;
263 }
264 | number
265 {
eddc2ab6 266 $$ = rb_malloc(sizeof(conf_parm_t));
212380e3
AC
267 $$->type = CF_INT;
268 $$->v.number = $1;
269 }
270 | string
271 {
e8cfec47 272 /* a 'string' could also be a yes/no value ..
212380e3
AC
273 so pass it as that, if so */
274 int val = conf_get_yesno_value($1);
275
eddc2ab6 276 $$ = rb_malloc(sizeof(conf_parm_t));
212380e3
AC
277
278 if (val != -1)
279 {
280 $$->type = CF_YESNO;
281 $$->v.number = val;
282 }
283 else
284 {
285 $$->type = CF_STRING;
47a03750 286 $$->v.string = rb_strdup($1);
212380e3
AC
287 }
288 }
289 ;
290
291loadmodule:
292 LOADMODULE QSTRING
293 {
216d70e9
EM
294 char *m_bn;
295 m_bn = rb_basename((char *) $2);
212380e3 296
216d70e9
EM
297 if (findmodule_byname(m_bn) == -1)
298 {
299 load_one_module($2, MAPI_ORIGIN_EXTENSION, 0);
300 }
1d393245 301
216d70e9 302 rb_free(m_bn);
212380e3
AC
303 }
304 ';'
305 ;
306
307qstring: QSTRING { strcpy($$, $1); } ;
308string: STRING { strcpy($$, $1); } ;
309number: NUMBER { $$ = $1; } ;
310
311timespec: number string
e8cfec47 312 {
212380e3
AC
313 time_t t;
314
315 if ((t = conf_find_time($2)) == 0)
316 {
317 conf_report_error("Unrecognised time type/size '%s'", $2);
318 t = 1;
319 }
e8cfec47 320
212380e3
AC
321 $$ = $1 * t;
322 }
323 | timespec timespec
324 {
325 $$ = $1 + $2;
326 }
327 | timespec number
328 {
329 $$ = $1 + $2;
330 }
331 ;