File: | src/usr.sbin/ifstated/obj/parse.c |
Warning: | line 754, column 3 Value stored to 'errors' is never read |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | #include <stdlib.h> |
2 | #include <string.h> |
3 | #define YYBYACC1 1 |
4 | #define YYMAJOR1 1 |
5 | #define YYMINOR9 9 |
6 | #define YYLEXyylex() yylex() |
7 | #define YYEMPTY-1 -1 |
8 | #define yyclearin(yychar=(-1)) (yychar=(YYEMPTY-1)) |
9 | #define yyerrok(yyerrflag=0) (yyerrflag=0) |
10 | #define YYRECOVERING()(yyerrflag!=0) (yyerrflag!=0) |
11 | #define YYPREFIX"yy" "yy" |
12 | #line 24 "/usr/src/usr.sbin/ifstated/parse.y" |
13 | #include <sys/types.h> |
14 | #include <sys/time.h> |
15 | #include <sys/socket.h> |
16 | #include <sys/stat.h> |
17 | #include <netinet/in.h> |
18 | #include <arpa/inet.h> |
19 | #include <net/if.h> |
20 | |
21 | #include <ctype.h> |
22 | #include <unistd.h> |
23 | #include <err.h> |
24 | #include <errno(*__errno()).h> |
25 | #include <limits.h> |
26 | #include <stdarg.h> |
27 | #include <stdio.h> |
28 | #include <string.h> |
29 | #include <syslog.h> |
30 | #include <event.h> |
31 | |
32 | #include "ifstated.h" |
33 | #include "log.h" |
34 | |
35 | TAILQ_HEAD(files, file)struct files { struct file *tqh_first; struct file **tqh_last ; } files = TAILQ_HEAD_INITIALIZER(files){ ((void *)0), &(files).tqh_first }; |
36 | static struct file { |
37 | TAILQ_ENTRY(file)struct { struct file *tqe_next; struct file **tqe_prev; } entry; |
38 | FILE *stream; |
39 | char *name; |
40 | int lineno; |
41 | int errors; |
42 | } *file, *topfile; |
43 | struct file *pushfile(const char *, int); |
44 | int popfile(void); |
45 | int check_file_secrecy(int, const char *); |
46 | int yyparse(void); |
47 | int yylex(void); |
48 | int yyerror(const char *, ...) |
49 | __attribute__((__format__ (printf, 1, 2))) |
50 | __attribute__((__nonnull__ (1))); |
51 | int kw_cmp(const void *, const void *); |
52 | int lookup(char *); |
53 | int lgetc(int); |
54 | int lungetc(int); |
55 | int findeol(void); |
56 | |
57 | TAILQ_HEAD(symhead, sym)struct symhead { struct sym *tqh_first; struct sym **tqh_last ; } symhead = TAILQ_HEAD_INITIALIZER(symhead){ ((void *)0), &(symhead).tqh_first }; |
58 | struct sym { |
59 | TAILQ_ENTRY(sym)struct { struct sym *tqe_next; struct sym **tqe_prev; } entry; |
60 | int used; |
61 | int persist; |
62 | char *nam; |
63 | char *val; |
64 | }; |
65 | int symset(const char *, const char *, int); |
66 | char *symget(const char *); |
67 | |
68 | static struct ifsd_config *conf; |
69 | char *start_state; |
70 | |
71 | struct ifsd_action *curaction; |
72 | struct ifsd_state *curstate; |
73 | |
74 | void link_states(struct ifsd_action *); |
75 | void set_expression_depth(struct ifsd_expression *, int); |
76 | void init_state(struct ifsd_state *); |
77 | struct ifsd_ifstate *new_ifstate(char *, int); |
78 | struct ifsd_external *new_external(char *, u_int32_t); |
79 | |
80 | typedef struct { |
81 | union { |
82 | int64_t number; |
83 | char *string; |
84 | struct in_addr addr; |
85 | |
86 | struct ifsd_expression *expression; |
87 | struct ifsd_ifstate *ifstate; |
88 | struct ifsd_external *external; |
89 | |
90 | } v; |
91 | int lineno; |
92 | } YYSTYPE; |
93 | |
94 | #line 95 "parse.c" |
95 | #define STATE257 257 |
96 | #define INITSTATE258 258 |
97 | #define LINK259 259 |
98 | #define UP260 260 |
99 | #define DOWN261 261 |
100 | #define UNKNOWN262 262 |
101 | #define IF263 263 |
102 | #define RUN264 264 |
103 | #define SETSTATE265 265 |
104 | #define EVERY266 266 |
105 | #define INIT267 267 |
106 | #define AND268 268 |
107 | #define OR269 269 |
108 | #define UNARY270 270 |
109 | #define ERROR271 271 |
110 | #define STRING272 272 |
111 | #define NUMBER273 273 |
112 | #define YYERRCODE256 256 |
113 | const short yylhs[] = |
114 | { -1, |
115 | 0, 0, 0, 0, 0, 0, 0, 1, 1, 8, |
116 | 7, 2, 11, 11, 12, 9, 9, 13, 9, 14, |
117 | 14, 15, 15, 17, 16, 3, 3, 3, 4, 6, |
118 | 6, 6, 5, 5, 5, 5, 18, 10, 19, 19, |
119 | 20, 20, |
120 | }; |
121 | const short yylen[] = |
122 | { 2, |
123 | 0, 2, 3, 3, 3, 3, 3, 2, 1, 3, |
124 | 2, 1, 2, 0, 2, 2, 2, 0, 4, 5, |
125 | 2, 3, 2, 0, 3, 5, 5, 5, 3, 1, |
126 | 1, 3, 2, 3, 3, 1, 0, 8, 2, 1, |
127 | 2, 2, |
128 | }; |
129 | const short yydefred[] = |
130 | { 1, |
131 | 0, 0, 0, 0, 18, 0, 0, 0, 2, 0, |
132 | 0, 0, 0, 7, 9, 0, 11, 0, 16, 17, |
133 | 0, 3, 4, 5, 6, 8, 0, 0, 0, 0, |
134 | 0, 30, 31, 0, 36, 0, 0, 0, 0, 0, |
135 | 33, 0, 0, 0, 0, 19, 13, 0, 29, 32, |
136 | 0, 34, 35, 0, 21, 0, 0, 0, 24, 0, |
137 | 0, 0, 40, 26, 27, 28, 0, 0, 0, 0, |
138 | 42, 41, 38, 39, 23, 20, 0, 25, 15, 22, |
139 | }; |
140 | const short yydgoto[] = |
141 | { 1, |
142 | 16, 31, 32, 33, 34, 35, 10, 11, 60, 13, |
143 | 45, 71, 18, 46, 68, 61, 69, 27, 62, 63, |
144 | }; |
145 | const short yysindex[] = |
146 | { 0, |
147 | -10, 2, -259, -257, 0, -255, -254, -40, 0, 13, |
148 | 23, 34, 42, 0, 0, -217, 0, -31, 0, 0, |
149 | -259, 0, 0, 0, 0, 0, 44, -210, -31, -31, |
150 | 11, 0, 0, -9, 0, -217, 44, -65, -214, -38, |
151 | 0, -199, -31, -31, -104, 0, 0, 44, 0, 0, |
152 | 15, 0, 0, 44, 0, -235, -219, -218, 0, 52, |
153 | 52, -114, 0, 0, 0, 0, 52, -98, 44, 44, |
154 | 0, 0, 0, 0, 0, 0, 52, 0, 0, 0,}; |
155 | const short yyrindex[] = |
156 | { 0, |
157 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
158 | 0, 0, 0, 0, 0, -5, 0, 0, 0, 0, |
159 | 0, 0, 0, 0, 0, 0, -60, 19, 0, 0, |
160 | 0, 0, 0, -101, 0, 56, -119, 0, 0, 0, |
161 | 0, 0, 0, 0, 0, 0, 0, -229, 0, 0, |
162 | 0, 0, 0, -215, 0, 0, 0, 0, 0, 0, |
163 | 0, 0, 0, 0, 0, 0, 0, 0, -101, -109, |
164 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,}; |
165 | const short yygindex[] = |
166 | { 0, |
167 | 46, 0, 0, 0, -4, 0, 0, 0, 6, 0, |
168 | -17, -53, 0, -1, 0, 0, 0, 0, 0, 7, |
169 | }; |
170 | #define YYTABLESIZE262 262 |
171 | const short yytable[] = |
172 | { 9, |
173 | 37, 30, 50, 14, 37, 14, 12, 72, 29, 38, |
174 | 73, 14, 15, 75, 17, 14, 19, 20, 54, 47, |
175 | 21, 14, 22, 80, 40, 41, 76, 5, 6, 7, |
176 | 56, 59, 23, 14, 14, 14, 58, 14, 52, 53, |
177 | 64, 65, 66, 24, 5, 6, 7, 14, 14, 14, |
178 | 55, 25, 79, 37, 26, 39, 42, 48, 49, 51, |
179 | 57, 70, 14, 67, 12, 10, 36, 78, 74, 0, |
180 | 0, 0, 0, 77, 0, 0, 0, 0, 0, 0, |
181 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
182 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
183 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
184 | 0, 0, 0, 0, 0, 0, 0, 37, 0, 0, |
185 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
186 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
187 | 0, 0, 0, 14, 14, 14, 0, 14, 5, 6, |
188 | 7, 0, 59, 14, 14, 14, 0, 14, 5, 6, |
189 | 7, 14, 14, 14, 5, 6, 7, 0, 0, 0, |
190 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
191 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
192 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
193 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
194 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
195 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 43, |
196 | 44, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
197 | 28, 0, 0, 0, 0, 2, 3, 4, 0, 0, |
198 | 0, 0, 5, 6, 7, 0, 0, 0, 43, 44, |
199 | 0, 8, |
200 | }; |
201 | const short yycheck[] = |
202 | { 10, |
203 | 10, 33, 41, 123, 10, 125, 1, 61, 40, 27, |
204 | 125, 10, 272, 67, 272, 125, 272, 272, 123, 37, |
205 | 61, 123, 10, 77, 29, 30, 125, 263, 264, 265, |
206 | 48, 267, 10, 263, 264, 265, 54, 267, 43, 44, |
207 | 260, 261, 262, 10, 263, 264, 265, 263, 264, 265, |
208 | 45, 10, 70, 10, 272, 266, 46, 123, 273, 259, |
209 | 46, 10, 123, 58, 46, 10, 21, 69, 62, -1, |
210 | -1, -1, -1, 68, -1, -1, -1, -1, -1, -1, |
211 | -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, |
212 | -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, |
213 | -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, |
214 | -1, -1, -1, -1, -1, -1, -1, 123, -1, -1, |
215 | -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, |
216 | -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, |
217 | -1, -1, -1, 263, 264, 265, -1, 267, 263, 264, |
218 | 265, -1, 267, 263, 264, 265, -1, 267, 263, 264, |
219 | 265, 263, 264, 265, 263, 264, 265, -1, -1, -1, |
220 | -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, |
221 | -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, |
222 | -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, |
223 | -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, |
224 | -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, |
225 | -1, -1, -1, -1, -1, -1, -1, -1, -1, 268, |
226 | 269, -1, -1, -1, -1, -1, -1, -1, -1, -1, |
227 | 272, -1, -1, -1, -1, 256, 257, 258, -1, -1, |
228 | -1, -1, 263, 264, 265, -1, -1, -1, 268, 269, |
229 | -1, 272, |
230 | }; |
231 | #define YYFINAL1 1 |
232 | #ifndef YYDEBUG0 |
233 | #define YYDEBUG0 0 |
234 | #endif |
235 | #define YYMAXTOKEN273 273 |
236 | #if YYDEBUG0 |
237 | const char * const yyname[] = |
238 | { |
239 | "end-of-file",0,0,0,0,0,0,0,0,0,"'\\n'",0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, |
240 | 0,0,"'!'",0,0,0,0,0,0,"'('","')'",0,0,0,0,"'.'",0,0,0,0,0,0,0,0,0,0,0,0,0,0, |
241 | "'='",0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, |
242 | 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,"'{'",0,"'}'",0,0,0,0,0,0,0,0,0, |
243 | 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, |
244 | 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, |
245 | 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, |
246 | 0,0,"STATE","INITSTATE","LINK","UP","DOWN","UNKNOWN","IF","RUN","SETSTATE", |
247 | "EVERY","INIT","AND","OR","UNARY","ERROR","STRING","NUMBER", |
248 | }; |
249 | const char * const yyrule[] = |
250 | {"$accept : grammar", |
251 | "grammar :", |
252 | "grammar : grammar '\\n'", |
253 | "grammar : grammar conf_main '\\n'", |
254 | "grammar : grammar varset '\\n'", |
255 | "grammar : grammar action '\\n'", |
256 | "grammar : grammar state '\\n'", |
257 | "grammar : grammar error '\\n'", |
258 | "string : string STRING", |
259 | "string : STRING", |
260 | "varset : STRING '=' string", |
261 | "conf_main : INITSTATE STRING", |
262 | "interface : STRING", |
263 | "optnl : '\\n' optnl", |
264 | "optnl :", |
265 | "nl : '\\n' optnl", |
266 | "action : RUN STRING", |
267 | "action : SETSTATE STRING", |
268 | "$$1 :", |
269 | "action : IF $$1 expr action_block", |
270 | "action_block : optnl '{' optnl action_l '}'", |
271 | "action_block : optnl action", |
272 | "action_l : action_l action nl", |
273 | "action_l : action nl", |
274 | "$$2 :", |
275 | "init : INIT $$2 action_block", |
276 | "if_test : interface '.' LINK '.' UP", |
277 | "if_test : interface '.' LINK '.' DOWN", |
278 | "if_test : interface '.' LINK '.' UNKNOWN", |
279 | "ext_test : STRING EVERY NUMBER", |
280 | "term : if_test", |
281 | "term : ext_test", |
282 | "term : '(' expr ')'", |
283 | "expr : '!' expr", |
284 | "expr : expr AND expr", |
285 | "expr : expr OR expr", |
286 | "expr : term", |
287 | "$$3 :", |
288 | "state : STATE string $$3 optnl '{' optnl stateopts_l '}'", |
289 | "stateopts_l : stateopts_l stateoptsl", |
290 | "stateopts_l : stateoptsl", |
291 | "stateoptsl : init nl", |
292 | "stateoptsl : action nl", |
293 | }; |
294 | #endif |
295 | #ifdef YYSTACKSIZE10000 |
296 | #undef YYMAXDEPTH10000 |
297 | #define YYMAXDEPTH10000 YYSTACKSIZE10000 |
298 | #else |
299 | #ifdef YYMAXDEPTH10000 |
300 | #define YYSTACKSIZE10000 YYMAXDEPTH10000 |
301 | #else |
302 | #define YYSTACKSIZE10000 10000 |
303 | #define YYMAXDEPTH10000 10000 |
304 | #endif |
305 | #endif |
306 | #define YYINITSTACKSIZE200 200 |
307 | /* LINTUSED */ |
308 | int yydebug; |
309 | int yynerrs; |
310 | int yyerrflag; |
311 | int yychar; |
312 | short *yyssp; |
313 | YYSTYPE *yyvsp; |
314 | YYSTYPE yyval; |
315 | YYSTYPE yylval; |
316 | short *yyss; |
317 | short *yysslim; |
318 | YYSTYPE *yyvs; |
319 | unsigned int yystacksize; |
320 | int yyparse(void); |
321 | #line 358 "/usr/src/usr.sbin/ifstated/parse.y" |
322 | |
323 | struct keywords { |
324 | const char *k_name; |
325 | int k_val; |
326 | }; |
327 | |
328 | int |
329 | yyerror(const char *fmt, ...) |
330 | { |
331 | va_list ap; |
332 | char *msg; |
333 | |
334 | file->errors++; |
335 | va_start(ap, fmt)__builtin_va_start(ap, fmt); |
336 | if (vasprintf(&msg, fmt, ap) == -1) |
337 | fatalx("yyerror vasprintf"); |
338 | va_end(ap)__builtin_va_end(ap); |
339 | logit(LOG_CRIT2, "%s:%d: %s", file->name, yylval.lineno, msg); |
340 | free(msg); |
341 | return (0); |
342 | } |
343 | |
344 | int |
345 | kw_cmp(const void *k, const void *e) |
346 | { |
347 | return (strcmp(k, ((const struct keywords *)e)->k_name)); |
348 | } |
349 | |
350 | int |
351 | lookup(char *s) |
352 | { |
353 | /* this has to be sorted always */ |
354 | static const struct keywords keywords[] = { |
355 | { "&&", AND268}, |
356 | { "down", DOWN261}, |
357 | { "every", EVERY266}, |
358 | { "if", IF263}, |
359 | { "init", INIT267}, |
360 | { "init-state", INITSTATE258}, |
361 | { "link", LINK259}, |
362 | { "run", RUN264}, |
363 | { "set-state", SETSTATE265}, |
364 | { "state", STATE257}, |
365 | { "unknown", UNKNOWN262}, |
366 | { "up", UP260}, |
367 | { "||", OR269} |
368 | }; |
369 | const struct keywords *p; |
370 | |
371 | p = bsearch(s, keywords, sizeof(keywords)/sizeof(keywords[0]), |
372 | sizeof(keywords[0]), kw_cmp); |
373 | |
374 | if (p) |
375 | return (p->k_val); |
376 | else |
377 | return (STRING272); |
378 | } |
379 | |
380 | #define MAXPUSHBACK128 128 |
381 | |
382 | char *parsebuf; |
383 | int parseindex; |
384 | char pushback_buffer[MAXPUSHBACK128]; |
385 | int pushback_index = 0; |
386 | |
387 | int |
388 | lgetc(int quotec) |
389 | { |
390 | int c, next; |
391 | |
392 | if (parsebuf) { |
393 | /* Read character from the parsebuffer instead of input. */ |
394 | if (parseindex >= 0) { |
395 | c = (unsigned char)parsebuf[parseindex++]; |
396 | if (c != '\0') |
397 | return (c); |
398 | parsebuf = NULL((void *)0); |
399 | } else |
400 | parseindex++; |
401 | } |
402 | |
403 | if (pushback_index) |
404 | return ((unsigned char)pushback_buffer[--pushback_index]); |
405 | |
406 | if (quotec) { |
407 | if ((c = getc(file->stream)(!__isthreaded ? (--(file->stream)->_r < 0 ? __srget (file->stream) : (int)(*(file->stream)->_p++)) : (getc )(file->stream))) == EOF(-1)) { |
408 | yyerror("reached end of file while parsing " |
409 | "quoted string"); |
410 | if (file == topfile || popfile() == EOF(-1)) |
411 | return (EOF(-1)); |
412 | return (quotec); |
413 | } |
414 | return (c); |
415 | } |
416 | |
417 | while ((c = getc(file->stream)(!__isthreaded ? (--(file->stream)->_r < 0 ? __srget (file->stream) : (int)(*(file->stream)->_p++)) : (getc )(file->stream))) == '\\') { |
418 | next = getc(file->stream)(!__isthreaded ? (--(file->stream)->_r < 0 ? __srget (file->stream) : (int)(*(file->stream)->_p++)) : (getc )(file->stream)); |
419 | if (next != '\n') { |
420 | c = next; |
421 | break; |
422 | } |
423 | yylval.lineno = file->lineno; |
424 | file->lineno++; |
425 | } |
426 | |
427 | while (c == EOF(-1)) { |
428 | if (file == topfile || popfile() == EOF(-1)) |
429 | return (EOF(-1)); |
430 | c = getc(file->stream)(!__isthreaded ? (--(file->stream)->_r < 0 ? __srget (file->stream) : (int)(*(file->stream)->_p++)) : (getc )(file->stream)); |
431 | } |
432 | return (c); |
433 | } |
434 | |
435 | int |
436 | lungetc(int c) |
437 | { |
438 | if (c == EOF(-1)) |
439 | return (EOF(-1)); |
440 | if (parsebuf) { |
441 | parseindex--; |
442 | if (parseindex >= 0) |
443 | return (c); |
444 | } |
445 | if (pushback_index + 1 >= MAXPUSHBACK128) |
446 | return (EOF(-1)); |
447 | pushback_buffer[pushback_index++] = c; |
448 | return (c); |
449 | } |
450 | |
451 | int |
452 | findeol(void) |
453 | { |
454 | int c; |
455 | |
456 | parsebuf = NULL((void *)0); |
457 | |
458 | /* skip to either EOF or the first real EOL */ |
459 | while (1) { |
460 | if (pushback_index) |
461 | c = (unsigned char)pushback_buffer[--pushback_index]; |
462 | else |
463 | c = lgetc(0); |
464 | if (c == '\n') { |
465 | file->lineno++; |
466 | break; |
467 | } |
468 | if (c == EOF(-1)) |
469 | break; |
470 | } |
471 | return (ERROR271); |
472 | } |
473 | |
474 | int |
475 | yylex(void) |
476 | { |
477 | char buf[8096]; |
478 | char *p, *val; |
479 | int quotec, next, c; |
480 | int token; |
481 | |
482 | top: |
483 | p = buf; |
484 | while ((c = lgetc(0)) == ' ' || c == '\t') |
485 | ; /* nothing */ |
486 | |
487 | yylval.lineno = file->lineno; |
488 | if (c == '#') |
489 | while ((c = lgetc(0)) != '\n' && c != EOF(-1)) |
490 | ; /* nothing */ |
491 | if (c == '$' && parsebuf == NULL((void *)0)) { |
492 | while (1) { |
493 | if ((c = lgetc(0)) == EOF(-1)) |
494 | return (0); |
495 | |
496 | if (p + 1 >= buf + sizeof(buf) - 1) { |
497 | yyerror("string too long"); |
498 | return (findeol()); |
499 | } |
500 | if (isalnum(c) || c == '_') { |
501 | *p++ = c; |
502 | continue; |
503 | } |
504 | *p = '\0'; |
505 | lungetc(c); |
506 | break; |
507 | } |
508 | val = symget(buf); |
509 | if (val == NULL((void *)0)) { |
510 | yyerror("macro '%s' not defined", buf); |
511 | return (findeol()); |
512 | } |
513 | parsebuf = val; |
514 | parseindex = 0; |
515 | goto top; |
516 | } |
517 | |
518 | switch (c) { |
519 | case '\'': |
520 | case '"': |
521 | quotec = c; |
522 | while (1) { |
523 | if ((c = lgetc(quotec)) == EOF(-1)) |
524 | return (0); |
525 | if (c == '\n') { |
526 | file->lineno++; |
527 | continue; |
528 | } else if (c == '\\') { |
529 | if ((next = lgetc(quotec)) == EOF(-1)) |
530 | return (0); |
531 | if (next == quotec || next == ' ' || |
532 | next == '\t') |
533 | c = next; |
534 | else if (next == '\n') { |
535 | file->lineno++; |
536 | continue; |
537 | } else |
538 | lungetc(next); |
539 | } else if (c == quotec) { |
540 | *p = '\0'; |
541 | break; |
542 | } else if (c == '\0') { |
543 | yyerror("syntax error"); |
544 | return (findeol()); |
545 | } |
546 | if (p + 1 >= buf + sizeof(buf) - 1) { |
547 | yyerror("string too long"); |
548 | return (findeol()); |
549 | } |
550 | *p++ = c; |
551 | } |
552 | yylval.v.string = strdup(buf); |
553 | if (yylval.v.string == NULL((void *)0)) |
554 | err(1, "%s", __func__); |
555 | return (STRING272); |
556 | } |
557 | |
558 | #define allowed_to_end_number(x)(isspace(x) || x == ')' || x ==',' || x == '/' || x == '}' || x == '=') \ |
559 | (isspace(x) || x == ')' || x ==',' || x == '/' || x == '}' || x == '=') |
560 | |
561 | if (c == '-' || isdigit(c)) { |
562 | do { |
563 | *p++ = c; |
564 | if ((size_t)(p-buf) >= sizeof(buf)) { |
565 | yyerror("string too long"); |
566 | return (findeol()); |
567 | } |
568 | } while ((c = lgetc(0)) != EOF(-1) && isdigit(c)); |
569 | lungetc(c); |
570 | if (p == buf + 1 && buf[0] == '-') |
571 | goto nodigits; |
572 | if (c == EOF(-1) || allowed_to_end_number(c)(isspace(c) || c == ')' || c ==',' || c == '/' || c == '}' || c == '=')) { |
573 | const char *errstr = NULL((void *)0); |
574 | |
575 | *p = '\0'; |
576 | yylval.v.number = strtonum(buf, LLONG_MIN(-9223372036854775807LL -1LL), |
577 | LLONG_MAX9223372036854775807LL, &errstr); |
578 | if (errstr) { |
579 | yyerror("\"%s\" invalid number: %s", |
580 | buf, errstr); |
581 | return (findeol()); |
582 | } |
583 | return (NUMBER273); |
584 | } else { |
585 | nodigits: |
586 | while (p > buf + 1) |
587 | lungetc((unsigned char)*--p); |
588 | c = (unsigned char)*--p; |
589 | if (c == '-') |
590 | return (c); |
591 | } |
592 | } |
593 | |
594 | #define allowed_in_string(x)(isalnum(x) || (ispunct(x) && x != '(' && x != ')' && x != '{' && x != '}' && x != '!' && x != '=' && x != '#' && x != ',' && x != '.')) \ |
595 | (isalnum(x) || (ispunct(x) && x != '(' && x != ')' && \ |
596 | x != '{' && x != '}' && \ |
597 | x != '!' && x != '=' && x != '#' && \ |
598 | x != ',' && x != '.')) |
599 | |
600 | if (isalnum(c) || c == ':' || c == '_' || c == '&' || c == '|') { |
601 | do { |
602 | *p++ = c; |
603 | if ((size_t)(p-buf) >= sizeof(buf)) { |
604 | yyerror("string too long"); |
605 | return (findeol()); |
606 | } |
607 | } while ((c = lgetc(0)) != EOF(-1) && (allowed_in_string(c)(isalnum(c) || (ispunct(c) && c != '(' && c != ')' && c != '{' && c != '}' && c != '!' && c != '=' && c != '#' && c != ',' && c != '.')))); |
608 | lungetc(c); |
609 | *p = '\0'; |
610 | if ((token = lookup(buf)) == STRING272) |
611 | if ((yylval.v.string = strdup(buf)) == NULL((void *)0)) |
612 | err(1, "%s", __func__); |
613 | return (token); |
614 | } |
615 | if (c == '\n') { |
616 | yylval.lineno = file->lineno; |
617 | file->lineno++; |
618 | } |
619 | if (c == EOF(-1)) |
620 | return (0); |
621 | return (c); |
622 | } |
623 | |
624 | int |
625 | check_file_secrecy(int fd, const char *fname) |
626 | { |
627 | struct stat st; |
628 | |
629 | if (fstat(fd, &st)) { |
630 | warn("cannot stat %s", fname); |
631 | return (-1); |
632 | } |
633 | if (st.st_uid != 0 && st.st_uid != getuid()) { |
634 | warnx("%s: owner not root or current user", fname); |
635 | return (-1); |
636 | } |
637 | if (st.st_mode & (S_IWGRP0000020 | S_IXGRP0000010 | S_IRWXO0000007)) { |
638 | warnx("%s: group writable or world read/writable", fname); |
639 | return (-1); |
640 | } |
641 | return (0); |
642 | } |
643 | |
644 | struct file * |
645 | pushfile(const char *name, int secret) |
646 | { |
647 | struct file *nfile; |
648 | |
649 | if ((nfile = calloc(1, sizeof(struct file))) == NULL((void *)0)) { |
650 | warn("%s", __func__); |
651 | return (NULL((void *)0)); |
652 | } |
653 | if ((nfile->name = strdup(name)) == NULL((void *)0)) { |
654 | warn("%s", __func__); |
655 | free(nfile); |
656 | return (NULL((void *)0)); |
657 | } |
658 | if ((nfile->stream = fopen(nfile->name, "r")) == NULL((void *)0)) { |
659 | warn("%s: %s", __func__, nfile->name); |
660 | free(nfile->name); |
661 | free(nfile); |
662 | return (NULL((void *)0)); |
663 | } else if (secret && |
664 | check_file_secrecy(fileno(nfile->stream)(!__isthreaded ? ((nfile->stream)->_file) : (fileno)(nfile ->stream)), nfile->name)) { |
665 | fclose(nfile->stream); |
666 | free(nfile->name); |
667 | free(nfile); |
668 | return (NULL((void *)0)); |
669 | } |
670 | nfile->lineno = 1; |
671 | TAILQ_INSERT_TAIL(&files, nfile, entry)do { (nfile)->entry.tqe_next = ((void *)0); (nfile)->entry .tqe_prev = (&files)->tqh_last; *(&files)->tqh_last = (nfile); (&files)->tqh_last = &(nfile)->entry .tqe_next; } while (0); |
672 | return (nfile); |
673 | } |
674 | |
675 | int |
676 | popfile(void) |
677 | { |
678 | struct file *prev; |
679 | |
680 | if ((prev = TAILQ_PREV(file, files, entry)(*(((struct files *)((file)->entry.tqe_prev))->tqh_last ))) != NULL((void *)0)) |
681 | prev->errors += file->errors; |
682 | |
683 | TAILQ_REMOVE(&files, file, entry)do { if (((file)->entry.tqe_next) != ((void *)0)) (file)-> entry.tqe_next->entry.tqe_prev = (file)->entry.tqe_prev ; else (&files)->tqh_last = (file)->entry.tqe_prev; *(file)->entry.tqe_prev = (file)->entry.tqe_next; ; ; } while (0); |
684 | fclose(file->stream); |
685 | free(file->name); |
686 | free(file); |
687 | file = prev; |
688 | return (file ? 0 : EOF(-1)); |
689 | } |
690 | |
691 | struct ifsd_config * |
692 | parse_config(char *filename, int opts) |
693 | { |
694 | int errors = 0; |
695 | struct sym *sym, *next; |
696 | struct ifsd_state *state; |
697 | |
698 | if ((conf = calloc(1, sizeof(struct ifsd_config))) == NULL((void *)0)) { |
699 | err(1, "%s", __func__); |
700 | return (NULL((void *)0)); |
701 | } |
702 | |
703 | if ((file = pushfile(filename, 0)) == NULL((void *)0)) { |
704 | free(conf); |
705 | return (NULL((void *)0)); |
706 | } |
707 | topfile = file; |
708 | |
709 | TAILQ_INIT(&conf->states)do { (&conf->states)->tqh_first = ((void *)0); (& conf->states)->tqh_last = &(&conf->states)-> tqh_first; } while (0); |
710 | |
711 | init_state(&conf->initstate); |
712 | curaction = conf->initstate.body; |
713 | conf->opts = opts; |
714 | |
715 | yyparse(); |
716 | |
717 | /* Link states */ |
718 | TAILQ_FOREACH(state, &conf->states, entries)for((state) = ((&conf->states)->tqh_first); (state) != ((void *)0); (state) = ((state)->entries.tqe_next)) { |
719 | link_states(state->init); |
720 | link_states(state->body); |
721 | } |
722 | |
723 | errors = file->errors; |
724 | popfile(); |
725 | |
726 | if (start_state != NULL((void *)0)) { |
727 | TAILQ_FOREACH(state, &conf->states, entries)for((state) = ((&conf->states)->tqh_first); (state) != ((void *)0); (state) = ((state)->entries.tqe_next)) { |
728 | if (strcmp(start_state, state->name) == 0) { |
729 | conf->curstate = state; |
730 | break; |
731 | } |
732 | } |
733 | if (conf->curstate == NULL((void *)0)) |
734 | errx(1, "invalid start state %s", start_state); |
735 | } else { |
736 | conf->curstate = TAILQ_FIRST(&conf->states)((&conf->states)->tqh_first); |
737 | } |
738 | |
739 | /* Free macros and check which have not been used. */ |
740 | TAILQ_FOREACH_SAFE(sym, &symhead, entry, next)for ((sym) = ((&symhead)->tqh_first); (sym) != ((void * )0) && ((next) = ((sym)->entry.tqe_next), 1); (sym ) = (next)) { |
741 | if ((conf->opts & IFSD_OPT_VERBOSE20x00000002) && !sym->used) |
742 | fprintf(stderr(&__sF[2]), "warning: macro '%s' not " |
743 | "used\n", sym->nam); |
744 | if (!sym->persist) { |
745 | free(sym->nam); |
746 | free(sym->val); |
747 | TAILQ_REMOVE(&symhead, sym, entry)do { if (((sym)->entry.tqe_next) != ((void *)0)) (sym)-> entry.tqe_next->entry.tqe_prev = (sym)->entry.tqe_prev; else (&symhead)->tqh_last = (sym)->entry.tqe_prev; *(sym)->entry.tqe_prev = (sym)->entry.tqe_next; ; ; } while (0); |
748 | free(sym); |
749 | } |
750 | } |
751 | |
752 | if (errors) { |
753 | clear_config(conf); |
754 | errors = 0; |
Value stored to 'errors' is never read | |
755 | return (NULL((void *)0)); |
756 | } |
757 | |
758 | return (conf); |
759 | } |
760 | |
761 | void |
762 | link_states(struct ifsd_action *action) |
763 | { |
764 | struct ifsd_action *subaction; |
765 | |
766 | switch (action->type) { |
767 | default: |
768 | case IFSD_ACTION_COMMAND1: |
769 | break; |
770 | case IFSD_ACTION_CHANGESTATE2: { |
771 | struct ifsd_state *state; |
772 | |
773 | TAILQ_FOREACH(state, &conf->states, entries)for((state) = ((&conf->states)->tqh_first); (state) != ((void *)0); (state) = ((state)->entries.tqe_next)) { |
774 | if (strcmp(action->act.statename, |
775 | state->name) == 0) { |
776 | action->act.nextstate = state; |
777 | break; |
778 | } |
779 | } |
780 | if (state == NULL((void *)0)) { |
781 | fprintf(stderr(&__sF[2]), "error: state '%s' not declared\n", |
782 | action->act.statename); |
783 | file->errors++; |
784 | } |
785 | break; |
786 | } |
787 | case IFSD_ACTION_CONDITION3: |
788 | TAILQ_FOREACH(subaction, &action->act.c.actions, entries)for((subaction) = ((&action->act.c.actions)->tqh_first ); (subaction) != ((void *)0); (subaction) = ((subaction)-> entries.tqe_next)) |
789 | link_states(subaction); |
790 | break; |
791 | } |
792 | } |
793 | |
794 | int |
795 | symset(const char *nam, const char *val, int persist) |
796 | { |
797 | struct sym *sym; |
798 | |
799 | TAILQ_FOREACH(sym, &symhead, entry)for((sym) = ((&symhead)->tqh_first); (sym) != ((void * )0); (sym) = ((sym)->entry.tqe_next)) { |
800 | if (strcmp(nam, sym->nam) == 0) |
801 | break; |
802 | } |
803 | |
804 | if (sym != NULL((void *)0)) { |
805 | if (sym->persist == 1) |
806 | return (0); |
807 | else { |
808 | free(sym->nam); |
809 | free(sym->val); |
810 | TAILQ_REMOVE(&symhead, sym, entry)do { if (((sym)->entry.tqe_next) != ((void *)0)) (sym)-> entry.tqe_next->entry.tqe_prev = (sym)->entry.tqe_prev; else (&symhead)->tqh_last = (sym)->entry.tqe_prev; *(sym)->entry.tqe_prev = (sym)->entry.tqe_next; ; ; } while (0); |
811 | free(sym); |
812 | } |
813 | } |
814 | if ((sym = calloc(1, sizeof(*sym))) == NULL((void *)0)) |
815 | return (-1); |
816 | |
817 | sym->nam = strdup(nam); |
818 | if (sym->nam == NULL((void *)0)) { |
819 | free(sym); |
820 | return (-1); |
821 | } |
822 | sym->val = strdup(val); |
823 | if (sym->val == NULL((void *)0)) { |
824 | free(sym->nam); |
825 | free(sym); |
826 | return (-1); |
827 | } |
828 | sym->used = 0; |
829 | sym->persist = persist; |
830 | TAILQ_INSERT_TAIL(&symhead, sym, entry)do { (sym)->entry.tqe_next = ((void *)0); (sym)->entry. tqe_prev = (&symhead)->tqh_last; *(&symhead)->tqh_last = (sym); (&symhead)->tqh_last = &(sym)->entry. tqe_next; } while (0); |
831 | return (0); |
832 | } |
833 | |
834 | int |
835 | cmdline_symset(char *s) |
836 | { |
837 | char *sym, *val; |
838 | int ret; |
839 | |
840 | if ((val = strrchr(s, '=')) == NULL((void *)0)) |
841 | return (-1); |
842 | sym = strndup(s, val - s); |
843 | if (sym == NULL((void *)0)) |
844 | err(1, "%s", __func__); |
845 | ret = symset(sym, val + 1, 1); |
846 | free(sym); |
847 | |
848 | return (ret); |
849 | } |
850 | |
851 | char * |
852 | symget(const char *nam) |
853 | { |
854 | struct sym *sym; |
855 | |
856 | TAILQ_FOREACH(sym, &symhead, entry)for((sym) = ((&symhead)->tqh_first); (sym) != ((void * )0); (sym) = ((sym)->entry.tqe_next)) { |
857 | if (strcmp(nam, sym->nam) == 0) { |
858 | sym->used = 1; |
859 | return (sym->val); |
860 | } |
861 | } |
862 | return (NULL((void *)0)); |
863 | } |
864 | |
865 | void |
866 | set_expression_depth(struct ifsd_expression *expression, int depth) |
867 | { |
868 | expression->depth = depth; |
869 | if (conf->maxdepth < depth) |
870 | conf->maxdepth = depth; |
871 | if (expression->left != NULL((void *)0)) |
872 | set_expression_depth(expression->left, depth + 1); |
873 | if (expression->right != NULL((void *)0)) |
874 | set_expression_depth(expression->right, depth + 1); |
875 | } |
876 | |
877 | void |
878 | init_state(struct ifsd_state *state) |
879 | { |
880 | TAILQ_INIT(&state->interface_states)do { (&state->interface_states)->tqh_first = ((void *)0); (&state->interface_states)->tqh_last = & (&state->interface_states)->tqh_first; } while (0); |
881 | TAILQ_INIT(&state->external_tests)do { (&state->external_tests)->tqh_first = ((void * )0); (&state->external_tests)->tqh_last = &(& state->external_tests)->tqh_first; } while (0); |
882 | |
883 | if ((state->init = calloc(1, sizeof(*state->init))) == NULL((void *)0)) |
884 | err(1, "%s", __func__); |
885 | state->init->type = IFSD_ACTION_CONDITION3; |
886 | TAILQ_INIT(&state->init->act.c.actions)do { (&state->init->act.c.actions)->tqh_first = ( (void *)0); (&state->init->act.c.actions)->tqh_last = &(&state->init->act.c.actions)->tqh_first ; } while (0); |
887 | |
888 | if ((state->body = calloc(1, sizeof(*state->body))) == NULL((void *)0)) |
889 | err(1, "%s", __func__); |
890 | state->body->type = IFSD_ACTION_CONDITION3; |
891 | TAILQ_INIT(&state->body->act.c.actions)do { (&state->body->act.c.actions)->tqh_first = ( (void *)0); (&state->body->act.c.actions)->tqh_last = &(&state->body->act.c.actions)->tqh_first ; } while (0); |
892 | } |
893 | |
894 | struct ifsd_ifstate * |
895 | new_ifstate(char *ifname, int s) |
896 | { |
897 | struct ifsd_ifstate *ifstate = NULL((void *)0); |
898 | struct ifsd_state *state; |
899 | |
900 | if (curstate != NULL((void *)0)) |
901 | state = curstate; |
902 | else |
903 | state = &conf->initstate; |
904 | |
905 | TAILQ_FOREACH(ifstate, &state->interface_states, entries)for((ifstate) = ((&state->interface_states)->tqh_first ); (ifstate) != ((void *)0); (ifstate) = ((ifstate)->entries .tqe_next)) |
906 | if (strcmp(ifstate->ifname, ifname) == 0 && |
907 | ifstate->ifstate == s) |
908 | break; |
909 | if (ifstate == NULL((void *)0)) { |
910 | if ((ifstate = calloc(1, sizeof(*ifstate))) == NULL((void *)0)) |
911 | err(1, "%s", __func__); |
912 | if (strlcpy(ifstate->ifname, ifname, |
913 | sizeof(ifstate->ifname)) >= sizeof(ifstate->ifname)) |
914 | errx(1, "ifname strlcpy truncation"); |
915 | free(ifname); |
916 | ifstate->ifstate = s; |
917 | TAILQ_INIT(&ifstate->expressions)do { (&ifstate->expressions)->tqh_first = ((void *) 0); (&ifstate->expressions)->tqh_last = &(& ifstate->expressions)->tqh_first; } while (0); |
918 | TAILQ_INSERT_TAIL(&state->interface_states, ifstate, entries)do { (ifstate)->entries.tqe_next = ((void *)0); (ifstate)-> entries.tqe_prev = (&state->interface_states)->tqh_last ; *(&state->interface_states)->tqh_last = (ifstate) ; (&state->interface_states)->tqh_last = &(ifstate )->entries.tqe_next; } while (0); |
919 | } |
920 | ifstate->prevstate = -1; |
921 | ifstate->refcount++; |
922 | return (ifstate); |
923 | } |
924 | |
925 | struct ifsd_external * |
926 | new_external(char *command, u_int32_t frequency) |
927 | { |
928 | struct ifsd_external *external = NULL((void *)0); |
929 | struct ifsd_state *state; |
930 | |
931 | if (curstate != NULL((void *)0)) |
932 | state = curstate; |
933 | else |
934 | state = &conf->initstate; |
935 | |
936 | TAILQ_FOREACH(external, &state->external_tests, entries)for((external) = ((&state->external_tests)->tqh_first ); (external) != ((void *)0); (external) = ((external)->entries .tqe_next)) |
937 | if (strcmp(external->command, command) == 0 && |
938 | external->frequency == frequency) |
939 | break; |
940 | if (external == NULL((void *)0)) { |
941 | if ((external = calloc(1, sizeof(*external))) == NULL((void *)0)) |
942 | err(1, "%s", __func__); |
943 | if ((external->command = strdup(command)) == NULL((void *)0)) |
944 | err(1, "%s", __func__); |
945 | external->frequency = frequency; |
946 | TAILQ_INIT(&external->expressions)do { (&external->expressions)->tqh_first = ((void * )0); (&external->expressions)->tqh_last = &(& external->expressions)->tqh_first; } while (0); |
947 | TAILQ_INSERT_TAIL(&state->external_tests, external, entries)do { (external)->entries.tqe_next = ((void *)0); (external )->entries.tqe_prev = (&state->external_tests)-> tqh_last; *(&state->external_tests)->tqh_last = (external ); (&state->external_tests)->tqh_last = &(external )->entries.tqe_next; } while (0); |
948 | } |
949 | external->prevstatus = -1; |
950 | external->refcount++; |
951 | return (external); |
952 | } |
953 | #line 946 "parse.c" |
954 | /* allocate initial stack or double stack size, up to YYMAXDEPTH */ |
955 | static int yygrowstack(void) |
956 | { |
957 | unsigned int newsize; |
958 | long sslen; |
959 | short *newss; |
960 | YYSTYPE *newvs; |
961 | |
962 | if ((newsize = yystacksize) == 0) |
963 | newsize = YYINITSTACKSIZE200; |
964 | else if (newsize >= YYMAXDEPTH10000) |
965 | return -1; |
966 | else if ((newsize *= 2) > YYMAXDEPTH10000) |
967 | newsize = YYMAXDEPTH10000; |
968 | sslen = yyssp - yyss; |
969 | #ifdef SIZE_MAX0xffffffffffffffffUL |
970 | #define YY_SIZE_MAX0xffffffffffffffffUL SIZE_MAX0xffffffffffffffffUL |
971 | #else |
972 | #define YY_SIZE_MAX0xffffffffffffffffUL 0xffffffffU |
973 | #endif |
974 | if (newsize && YY_SIZE_MAX0xffffffffffffffffUL / newsize < sizeof *newss) |
975 | goto bail; |
976 | newss = (short *)realloc(yyss, newsize * sizeof *newss); |
977 | if (newss == NULL((void *)0)) |
978 | goto bail; |
979 | yyss = newss; |
980 | yyssp = newss + sslen; |
981 | if (newsize && YY_SIZE_MAX0xffffffffffffffffUL / newsize < sizeof *newvs) |
982 | goto bail; |
983 | newvs = (YYSTYPE *)realloc(yyvs, newsize * sizeof *newvs); |
984 | if (newvs == NULL((void *)0)) |
985 | goto bail; |
986 | yyvs = newvs; |
987 | yyvsp = newvs + sslen; |
988 | yystacksize = newsize; |
989 | yysslim = yyss + newsize - 1; |
990 | return 0; |
991 | bail: |
992 | if (yyss) |
993 | free(yyss); |
994 | if (yyvs) |
995 | free(yyvs); |
996 | yyss = yyssp = NULL((void *)0); |
997 | yyvs = yyvsp = NULL((void *)0); |
998 | yystacksize = 0; |
999 | return -1; |
1000 | } |
1001 | |
1002 | #define YYABORTgoto yyabort goto yyabort |
1003 | #define YYREJECTgoto yyabort goto yyabort |
1004 | #define YYACCEPTgoto yyaccept goto yyaccept |
1005 | #define YYERRORgoto yyerrlab goto yyerrlab |
1006 | int |
1007 | yyparse(void) |
1008 | { |
1009 | int yym, yyn, yystate; |
1010 | #if YYDEBUG0 |
1011 | const char *yys; |
1012 | |
1013 | if ((yys = getenv("YYDEBUG"))) |
1014 | { |
1015 | yyn = *yys; |
1016 | if (yyn >= '0' && yyn <= '9') |
1017 | yydebug = yyn - '0'; |
1018 | } |
1019 | #endif /* YYDEBUG */ |
1020 | |
1021 | yynerrs = 0; |
1022 | yyerrflag = 0; |
1023 | yychar = (-1); |
1024 | |
1025 | if (yyss == NULL((void *)0) && yygrowstack()) goto yyoverflow; |
1026 | yyssp = yyss; |
1027 | yyvsp = yyvs; |
1028 | *yyssp = yystate = 0; |
1029 | |
1030 | yyloop: |
1031 | if ((yyn = yydefred[yystate]) != 0) goto yyreduce; |
1032 | if (yychar < 0) |
1033 | { |
1034 | if ((yychar = yylex()) < 0) yychar = 0; |
1035 | #if YYDEBUG0 |
1036 | if (yydebug) |
1037 | { |
1038 | yys = 0; |
1039 | if (yychar <= YYMAXTOKEN273) yys = yyname[yychar]; |
1040 | if (!yys) yys = "illegal-symbol"; |
1041 | printf("%sdebug: state %d, reading %d (%s)\n", |
1042 | YYPREFIX"yy", yystate, yychar, yys); |
1043 | } |
1044 | #endif |
1045 | } |
1046 | if ((yyn = yysindex[yystate]) && (yyn += yychar) >= 0 && |
1047 | yyn <= YYTABLESIZE262 && yycheck[yyn] == yychar) |
1048 | { |
1049 | #if YYDEBUG0 |
1050 | if (yydebug) |
1051 | printf("%sdebug: state %d, shifting to state %d\n", |
1052 | YYPREFIX"yy", yystate, yytable[yyn]); |
1053 | #endif |
1054 | if (yyssp >= yysslim && yygrowstack()) |
1055 | { |
1056 | goto yyoverflow; |
1057 | } |
1058 | *++yyssp = yystate = yytable[yyn]; |
1059 | *++yyvsp = yylval; |
1060 | yychar = (-1); |
1061 | if (yyerrflag > 0) --yyerrflag; |
1062 | goto yyloop; |
1063 | } |
1064 | if ((yyn = yyrindex[yystate]) && (yyn += yychar) >= 0 && |
1065 | yyn <= YYTABLESIZE262 && yycheck[yyn] == yychar) |
1066 | { |
1067 | yyn = yytable[yyn]; |
1068 | goto yyreduce; |
1069 | } |
1070 | if (yyerrflag) goto yyinrecovery; |
1071 | #if defined(__GNUC__4) |
1072 | goto yynewerror; |
1073 | #endif |
1074 | yynewerror: |
1075 | yyerror("syntax error"); |
1076 | #if defined(__GNUC__4) |
1077 | goto yyerrlab; |
1078 | #endif |
1079 | yyerrlab: |
1080 | ++yynerrs; |
1081 | yyinrecovery: |
1082 | if (yyerrflag < 3) |
1083 | { |
1084 | yyerrflag = 3; |
1085 | for (;;) |
1086 | { |
1087 | if ((yyn = yysindex[*yyssp]) && (yyn += YYERRCODE256) >= 0 && |
1088 | yyn <= YYTABLESIZE262 && yycheck[yyn] == YYERRCODE256) |
1089 | { |
1090 | #if YYDEBUG0 |
1091 | if (yydebug) |
1092 | printf("%sdebug: state %d, error recovery shifting\ |
1093 | to state %d\n", YYPREFIX"yy", *yyssp, yytable[yyn]); |
1094 | #endif |
1095 | if (yyssp >= yysslim && yygrowstack()) |
1096 | { |
1097 | goto yyoverflow; |
1098 | } |
1099 | *++yyssp = yystate = yytable[yyn]; |
1100 | *++yyvsp = yylval; |
1101 | goto yyloop; |
1102 | } |
1103 | else |
1104 | { |
1105 | #if YYDEBUG0 |
1106 | if (yydebug) |
1107 | printf("%sdebug: error recovery discarding state %d\n", |
1108 | YYPREFIX"yy", *yyssp); |
1109 | #endif |
1110 | if (yyssp <= yyss) goto yyabort; |
1111 | --yyssp; |
1112 | --yyvsp; |
1113 | } |
1114 | } |
1115 | } |
1116 | else |
1117 | { |
1118 | if (yychar == 0) goto yyabort; |
1119 | #if YYDEBUG0 |
1120 | if (yydebug) |
1121 | { |
1122 | yys = 0; |
1123 | if (yychar <= YYMAXTOKEN273) yys = yyname[yychar]; |
1124 | if (!yys) yys = "illegal-symbol"; |
1125 | printf("%sdebug: state %d, error recovery discards token %d (%s)\n", |
1126 | YYPREFIX"yy", yystate, yychar, yys); |
1127 | } |
1128 | #endif |
1129 | yychar = (-1); |
1130 | goto yyloop; |
1131 | } |
1132 | yyreduce: |
1133 | #if YYDEBUG0 |
1134 | if (yydebug) |
1135 | printf("%sdebug: state %d, reducing by rule %d (%s)\n", |
1136 | YYPREFIX"yy", yystate, yyn, yyrule[yyn]); |
1137 | #endif |
1138 | yym = yylen[yyn]; |
1139 | if (yym) |
1140 | yyval = yyvsp[1-yym]; |
1141 | else |
1142 | memset(&yyval, 0, sizeof yyval); |
1143 | switch (yyn) |
1144 | { |
1145 | case 7: |
1146 | #line 128 "/usr/src/usr.sbin/ifstated/parse.y" |
1147 | { file->errors++; } |
1148 | break; |
1149 | case 8: |
1150 | #line 131 "/usr/src/usr.sbin/ifstated/parse.y" |
1151 | { |
1152 | if (asprintf(&yyval.v.string, "%s %s", yyvsp[-1].v.string, yyvsp[0].v.string) == -1) { |
1153 | free(yyvsp[-1].v.string); |
1154 | free(yyvsp[0].v.string); |
1155 | yyerror("string: asprintf"); |
1156 | YYERRORgoto yyerrlab; |
1157 | } |
1158 | free(yyvsp[-1].v.string); |
1159 | free(yyvsp[0].v.string); |
1160 | } |
1161 | break; |
1162 | case 10: |
1163 | #line 144 "/usr/src/usr.sbin/ifstated/parse.y" |
1164 | { |
1165 | char *s = yyvsp[-2].v.string; |
1166 | if (conf->opts & IFSD_OPT_VERBOSE0x00000001) |
1167 | printf("%s = \"%s\"\n", yyvsp[-2].v.string, yyvsp[0].v.string); |
1168 | while (*s++) { |
1169 | if (isspace((unsigned char)*s)) { |
1170 | yyerror("macro name cannot contain " |
1171 | "whitespace"); |
1172 | free(yyvsp[-2].v.string); |
1173 | free(yyvsp[0].v.string); |
1174 | YYERRORgoto yyerrlab; |
1175 | } |
1176 | } |
1177 | if (symset(yyvsp[-2].v.string, yyvsp[0].v.string, 0) == -1) { |
1178 | free(yyvsp[-2].v.string); |
1179 | free(yyvsp[0].v.string); |
1180 | yyerror("cannot store variable"); |
1181 | YYERRORgoto yyerrlab; |
1182 | } |
1183 | free(yyvsp[-2].v.string); |
1184 | free(yyvsp[0].v.string); |
1185 | } |
1186 | break; |
1187 | case 11: |
1188 | #line 168 "/usr/src/usr.sbin/ifstated/parse.y" |
1189 | { |
1190 | start_state = yyvsp[0].v.string; |
1191 | } |
1192 | break; |
1193 | case 12: |
1194 | #line 173 "/usr/src/usr.sbin/ifstated/parse.y" |
1195 | { |
1196 | if (if_nametoindex(yyvsp[0].v.string) == 0) { |
1197 | yyerror("unknown interface %s", yyvsp[0].v.string); |
1198 | free(yyvsp[0].v.string); |
1199 | YYERRORgoto yyerrlab; |
1200 | } |
1201 | yyval.v.string = yyvsp[0].v.string; |
1202 | } |
1203 | break; |
1204 | case 16: |
1205 | #line 190 "/usr/src/usr.sbin/ifstated/parse.y" |
1206 | { |
1207 | struct ifsd_action *action; |
1208 | |
1209 | if ((action = calloc(1, sizeof(*action))) == NULL((void *)0)) |
1210 | err(1, "action: calloc"); |
1211 | action->type = IFSD_ACTION_COMMAND1; |
1212 | action->act.command = yyvsp[0].v.string; |
1213 | TAILQ_INSERT_TAIL(&curaction->act.c.actions,do { (action)->entries.tqe_next = ((void *)0); (action)-> entries.tqe_prev = (&curaction->act.c.actions)->tqh_last ; *(&curaction->act.c.actions)->tqh_last = (action) ; (&curaction->act.c.actions)->tqh_last = &(action )->entries.tqe_next; } while (0) |
1214 | action, entries)do { (action)->entries.tqe_next = ((void *)0); (action)-> entries.tqe_prev = (&curaction->act.c.actions)->tqh_last ; *(&curaction->act.c.actions)->tqh_last = (action) ; (&curaction->act.c.actions)->tqh_last = &(action )->entries.tqe_next; } while (0); |
1215 | } |
1216 | break; |
1217 | case 17: |
1218 | #line 200 "/usr/src/usr.sbin/ifstated/parse.y" |
1219 | { |
1220 | struct ifsd_action *action; |
1221 | |
1222 | if (curstate == NULL((void *)0)) { |
1223 | free(yyvsp[0].v.string); |
1224 | yyerror("set-state must be used inside 'if'"); |
1225 | YYERRORgoto yyerrlab; |
1226 | } |
1227 | if ((action = calloc(1, sizeof(*action))) == NULL((void *)0)) |
1228 | err(1, "action: calloc"); |
1229 | action->type = IFSD_ACTION_CHANGESTATE2; |
1230 | action->act.statename = yyvsp[0].v.string; |
1231 | TAILQ_INSERT_TAIL(&curaction->act.c.actions,do { (action)->entries.tqe_next = ((void *)0); (action)-> entries.tqe_prev = (&curaction->act.c.actions)->tqh_last ; *(&curaction->act.c.actions)->tqh_last = (action) ; (&curaction->act.c.actions)->tqh_last = &(action )->entries.tqe_next; } while (0) |
1232 | action, entries)do { (action)->entries.tqe_next = ((void *)0); (action)-> entries.tqe_prev = (&curaction->act.c.actions)->tqh_last ; *(&curaction->act.c.actions)->tqh_last = (action) ; (&curaction->act.c.actions)->tqh_last = &(action )->entries.tqe_next; } while (0); |
1233 | } |
1234 | break; |
1235 | case 18: |
1236 | #line 215 "/usr/src/usr.sbin/ifstated/parse.y" |
1237 | { |
1238 | struct ifsd_action *action; |
1239 | |
1240 | if ((action = calloc(1, sizeof(*action))) == NULL((void *)0)) |
1241 | err(1, "action: calloc"); |
1242 | action->type = IFSD_ACTION_CONDITION3; |
1243 | TAILQ_INIT(&action->act.c.actions)do { (&action->act.c.actions)->tqh_first = ((void * )0); (&action->act.c.actions)->tqh_last = &(& action->act.c.actions)->tqh_first; } while (0); |
1244 | TAILQ_INSERT_TAIL(&curaction->act.c.actions,do { (action)->entries.tqe_next = ((void *)0); (action)-> entries.tqe_prev = (&curaction->act.c.actions)->tqh_last ; *(&curaction->act.c.actions)->tqh_last = (action) ; (&curaction->act.c.actions)->tqh_last = &(action )->entries.tqe_next; } while (0) |
1245 | action, entries)do { (action)->entries.tqe_next = ((void *)0); (action)-> entries.tqe_prev = (&curaction->act.c.actions)->tqh_last ; *(&curaction->act.c.actions)->tqh_last = (action) ; (&curaction->act.c.actions)->tqh_last = &(action )->entries.tqe_next; } while (0); |
1246 | action->parent = curaction; |
1247 | curaction = action; |
1248 | } |
1249 | break; |
1250 | case 19: |
1251 | #line 226 "/usr/src/usr.sbin/ifstated/parse.y" |
1252 | { |
1253 | set_expression_depth(curaction->act.c.expression, 0); |
1254 | curaction = curaction->parent; |
1255 | } |
1256 | break; |
1257 | case 24: |
1258 | #line 240 "/usr/src/usr.sbin/ifstated/parse.y" |
1259 | { |
1260 | if (curstate != NULL((void *)0)) |
1261 | curaction = curstate->init; |
1262 | else |
1263 | curaction = conf->initstate.init; |
1264 | } |
1265 | break; |
1266 | case 25: |
1267 | #line 245 "/usr/src/usr.sbin/ifstated/parse.y" |
1268 | { |
1269 | if (curstate != NULL((void *)0)) |
1270 | curaction = curstate->body; |
1271 | else |
1272 | curaction = conf->initstate.body; |
1273 | } |
1274 | break; |
1275 | case 26: |
1276 | #line 253 "/usr/src/usr.sbin/ifstated/parse.y" |
1277 | { |
1278 | yyval.v.ifstate = new_ifstate(yyvsp[-4].v.string, IFSD_LINKUP2); |
1279 | } |
1280 | break; |
1281 | case 27: |
1282 | #line 256 "/usr/src/usr.sbin/ifstated/parse.y" |
1283 | { |
1284 | yyval.v.ifstate = new_ifstate(yyvsp[-4].v.string, IFSD_LINKDOWN1); |
1285 | } |
1286 | break; |
1287 | case 28: |
1288 | #line 259 "/usr/src/usr.sbin/ifstated/parse.y" |
1289 | { |
1290 | yyval.v.ifstate = new_ifstate(yyvsp[-4].v.string, IFSD_LINKUNKNOWN0); |
1291 | } |
1292 | break; |
1293 | case 29: |
1294 | #line 264 "/usr/src/usr.sbin/ifstated/parse.y" |
1295 | { |
1296 | if (yyvsp[0].v.number <= 0 || yyvsp[0].v.number > UINT_MAX(2147483647 *2U +1U)) { |
1297 | yyerror("invalid interval: %lld", yyvsp[0].v.number); |
1298 | free(yyvsp[-2].v.string); |
1299 | YYERRORgoto yyerrlab; |
1300 | } |
1301 | yyval.v.external = new_external(yyvsp[-2].v.string, yyvsp[0].v.number); |
1302 | free(yyvsp[-2].v.string); |
1303 | } |
1304 | break; |
1305 | case 30: |
1306 | #line 275 "/usr/src/usr.sbin/ifstated/parse.y" |
1307 | { |
1308 | if ((yyval.v.expression = calloc(1, sizeof(*yyval.v.expression))) == NULL((void *)0)) |
1309 | err(1, NULL((void *)0)); |
1310 | curaction->act.c.expression = yyval.v.expression; |
1311 | yyval.v.expression->type = IFSD_OPER_IFSTATE5; |
1312 | yyval.v.expression->u.ifstate = yyvsp[0].v.ifstate; |
1313 | TAILQ_INSERT_TAIL(&yyvsp[0].v.ifstate->expressions, yyval.v.expression, entries)do { (yyval.v.expression)->entries.tqe_next = ((void *)0); (yyval.v.expression)->entries.tqe_prev = (&yyvsp[0].v .ifstate->expressions)->tqh_last; *(&yyvsp[0].v.ifstate ->expressions)->tqh_last = (yyval.v.expression); (& yyvsp[0].v.ifstate->expressions)->tqh_last = &(yyval .v.expression)->entries.tqe_next; } while (0); |
1314 | } |
1315 | break; |
1316 | case 31: |
1317 | #line 283 "/usr/src/usr.sbin/ifstated/parse.y" |
1318 | { |
1319 | if ((yyval.v.expression = calloc(1, sizeof(*yyval.v.expression))) == NULL((void *)0)) |
1320 | err(1, NULL((void *)0)); |
1321 | curaction->act.c.expression = yyval.v.expression; |
1322 | yyval.v.expression->type = IFSD_OPER_EXTERNAL4; |
1323 | yyval.v.expression->u.external = yyvsp[0].v.external; |
1324 | TAILQ_INSERT_TAIL(&yyvsp[0].v.external->expressions, yyval.v.expression, entries)do { (yyval.v.expression)->entries.tqe_next = ((void *)0); (yyval.v.expression)->entries.tqe_prev = (&yyvsp[0].v .external->expressions)->tqh_last; *(&yyvsp[0].v.external ->expressions)->tqh_last = (yyval.v.expression); (& yyvsp[0].v.external->expressions)->tqh_last = &(yyval .v.expression)->entries.tqe_next; } while (0); |
1325 | } |
1326 | break; |
1327 | case 32: |
1328 | #line 291 "/usr/src/usr.sbin/ifstated/parse.y" |
1329 | { |
1330 | yyval.v.expression = yyvsp[-1].v.expression; |
1331 | } |
1332 | break; |
1333 | case 33: |
1334 | #line 296 "/usr/src/usr.sbin/ifstated/parse.y" |
1335 | { |
1336 | if ((yyval.v.expression = calloc(1, sizeof(*yyval.v.expression))) == NULL((void *)0)) |
1337 | err(1, NULL((void *)0)); |
1338 | curaction->act.c.expression = yyval.v.expression; |
1339 | yyval.v.expression->type = IFSD_OPER_NOT3; |
1340 | yyvsp[0].v.expression->parent = yyval.v.expression; |
1341 | yyval.v.expression->right = yyvsp[0].v.expression; |
1342 | } |
1343 | break; |
1344 | case 34: |
1345 | #line 304 "/usr/src/usr.sbin/ifstated/parse.y" |
1346 | { |
1347 | if ((yyval.v.expression = calloc(1, sizeof(*yyval.v.expression))) == NULL((void *)0)) |
1348 | err(1, NULL((void *)0)); |
1349 | curaction->act.c.expression = yyval.v.expression; |
1350 | yyval.v.expression->type = IFSD_OPER_AND1; |
1351 | yyvsp[-2].v.expression->parent = yyval.v.expression; |
1352 | yyvsp[0].v.expression->parent = yyval.v.expression; |
1353 | yyval.v.expression->left = yyvsp[-2].v.expression; |
1354 | yyval.v.expression->right = yyvsp[0].v.expression; |
1355 | } |
1356 | break; |
1357 | case 35: |
1358 | #line 314 "/usr/src/usr.sbin/ifstated/parse.y" |
1359 | { |
1360 | if ((yyval.v.expression = calloc(1, sizeof(*yyval.v.expression))) == NULL((void *)0)) |
1361 | err(1, NULL((void *)0)); |
1362 | curaction->act.c.expression = yyval.v.expression; |
1363 | yyval.v.expression->type = IFSD_OPER_OR2; |
1364 | yyvsp[-2].v.expression->parent = yyval.v.expression; |
1365 | yyvsp[0].v.expression->parent = yyval.v.expression; |
1366 | yyval.v.expression->left = yyvsp[-2].v.expression; |
1367 | yyval.v.expression->right = yyvsp[0].v.expression; |
1368 | } |
1369 | break; |
1370 | case 37: |
1371 | #line 327 "/usr/src/usr.sbin/ifstated/parse.y" |
1372 | { |
1373 | struct ifsd_state *state = NULL((void *)0); |
1374 | |
1375 | TAILQ_FOREACH(state, &conf->states, entries)for((state) = ((&conf->states)->tqh_first); (state) != ((void *)0); (state) = ((state)->entries.tqe_next)) |
1376 | if (!strcmp(state->name, yyvsp[0].v.string)) { |
1377 | yyerror("state %s already exists", yyvsp[0].v.string); |
1378 | free(yyvsp[0].v.string); |
1379 | YYERRORgoto yyerrlab; |
1380 | } |
1381 | if ((state = calloc(1, sizeof(*curstate))) == NULL((void *)0)) |
1382 | err(1, NULL((void *)0)); |
1383 | init_state(state); |
1384 | state->name = yyvsp[0].v.string; |
1385 | curstate = state; |
1386 | curaction = state->body; |
1387 | } |
1388 | break; |
1389 | case 38: |
1390 | #line 342 "/usr/src/usr.sbin/ifstated/parse.y" |
1391 | { |
1392 | TAILQ_INSERT_TAIL(&conf->states, curstate, entries)do { (curstate)->entries.tqe_next = ((void *)0); (curstate )->entries.tqe_prev = (&conf->states)->tqh_last; *(&conf->states)->tqh_last = (curstate); (&conf ->states)->tqh_last = &(curstate)->entries.tqe_next ; } while (0); |
1393 | curstate = NULL((void *)0); |
1394 | curaction = conf->initstate.body; |
1395 | } |
1396 | break; |
1397 | #line 1390 "parse.c" |
1398 | } |
1399 | yyssp -= yym; |
1400 | yystate = *yyssp; |
1401 | yyvsp -= yym; |
1402 | yym = yylhs[yyn]; |
1403 | if (yystate == 0 && yym == 0) |
1404 | { |
1405 | #if YYDEBUG0 |
1406 | if (yydebug) |
1407 | printf("%sdebug: after reduction, shifting from state 0 to\ |
1408 | state %d\n", YYPREFIX"yy", YYFINAL1); |
1409 | #endif |
1410 | yystate = YYFINAL1; |
1411 | *++yyssp = YYFINAL1; |
1412 | *++yyvsp = yyval; |
1413 | if (yychar < 0) |
1414 | { |
1415 | if ((yychar = yylex()) < 0) yychar = 0; |
1416 | #if YYDEBUG0 |
1417 | if (yydebug) |
1418 | { |
1419 | yys = 0; |
1420 | if (yychar <= YYMAXTOKEN273) yys = yyname[yychar]; |
1421 | if (!yys) yys = "illegal-symbol"; |
1422 | printf("%sdebug: state %d, reading %d (%s)\n", |
1423 | YYPREFIX"yy", YYFINAL1, yychar, yys); |
1424 | } |
1425 | #endif |
1426 | } |
1427 | if (yychar == 0) goto yyaccept; |
1428 | goto yyloop; |
1429 | } |
1430 | if ((yyn = yygindex[yym]) && (yyn += yystate) >= 0 && |
1431 | yyn <= YYTABLESIZE262 && yycheck[yyn] == yystate) |
1432 | yystate = yytable[yyn]; |
1433 | else |
1434 | yystate = yydgoto[yym]; |
1435 | #if YYDEBUG0 |
1436 | if (yydebug) |
1437 | printf("%sdebug: after reduction, shifting from state %d \ |
1438 | to state %d\n", YYPREFIX"yy", *yyssp, yystate); |
1439 | #endif |
1440 | if (yyssp >= yysslim && yygrowstack()) |
1441 | { |
1442 | goto yyoverflow; |
1443 | } |
1444 | *++yyssp = yystate; |
1445 | *++yyvsp = yyval; |
1446 | goto yyloop; |
1447 | yyoverflow: |
1448 | yyerror("yacc stack overflow"); |
1449 | yyabort: |
1450 | if (yyss) |
1451 | free(yyss); |
1452 | if (yyvs) |
1453 | free(yyvs); |
1454 | yyss = yyssp = NULL((void *)0); |
1455 | yyvs = yyvsp = NULL((void *)0); |
1456 | yystacksize = 0; |
1457 | return (1); |
1458 | yyaccept: |
1459 | if (yyss) |
1460 | free(yyss); |
1461 | if (yyvs) |
1462 | free(yyvs); |
1463 | yyss = yyssp = NULL((void *)0); |
1464 | yyvs = yyvsp = NULL((void *)0); |
1465 | yystacksize = 0; |
1466 | return (0); |
1467 | } |