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