GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: usr.bin/doas/parse.c Lines: 154 177 87.0 %
Date: 2017-11-07 Branches: 82 129 63.6 %

Line Branch Exec Source
1
#include <stdlib.h>
2
#include <string.h>
3
#define YYBYACC 1
4
#define YYMAJOR 1
5
#define YYMINOR 9
6
#define YYLEX yylex()
7
#define YYEMPTY -1
8
#define yyclearin (yychar=(YYEMPTY))
9
#define yyerrok (yyerrflag=0)
10
#define YYRECOVERING() (yyerrflag!=0)
11
#define YYPREFIX "yy"
12
#line 19 "parse.y"
13
#include <sys/types.h>
14
#include <ctype.h>
15
#include <unistd.h>
16
#include <stdint.h>
17
#include <stdarg.h>
18
#include <stdio.h>
19
#include <string.h>
20
#include <err.h>
21
22
#include "doas.h"
23
24
typedef struct {
25
	union {
26
		struct {
27
			int action;
28
			int options;
29
			const char *cmd;
30
			const char **cmdargs;
31
			const char **envlist;
32
		};
33
		const char **strlist;
34
		const char *str;
35
	};
36
	int lineno;
37
	int colno;
38
} yystype;
39
#define YYSTYPE yystype
40
41
FILE *yyfp;
42
43
struct rule **rules;
44
int nrules;
45
static int maxrules;
46
47
int parse_errors = 0;
48
49
static void yyerror(const char *, ...);
50
static int yylex(void);
51
52
static size_t
53
arraylen(const char **arr)
54
{
55
	size_t cnt = 0;
56
57
	while (*arr) {
58
		cnt++;
59
		arr++;
60
	}
61
	return cnt;
62
}
63
64
#line 65 "parse.c"
65
#define TPERMIT 257
66
#define TDENY 258
67
#define TAS 259
68
#define TCMD 260
69
#define TARGS 261
70
#define TNOPASS 262
71
#define TPERSIST 263
72
#define TKEEPENV 264
73
#define TSETENV 265
74
#define TSTRING 266
75
#define YYERRCODE 256
76
const short yylhs[] =
77
	{                                        -1,
78
    0,    0,    0,    0,    1,    2,    2,    6,    6,    7,
79
    7,    7,    7,    8,    8,    3,    4,    4,    5,    5,
80
    9,    9,
81
};
82
const short yylen[] =
83
	{                                         2,
84
    0,    2,    3,    2,    4,    2,    1,    0,    2,    1,
85
    1,    1,    4,    0,    2,    1,    0,    2,    0,    3,
86
135
    0,    2,
87
135
};
88
const short yydefred[] =
89
135
	{                                      0,
90
135
    0,    0,    4,    8,    7,    2,    0,    0,    0,    3,
91
135
   16,    0,   10,   11,   12,    0,    9,    0,    0,   14,
92
135
   18,    0,    5,    0,    0,   15,   13,   14,   20,    0,
93
135
};
94
135
const short yydgoto[] =
95
135
	{                                       2,
96
135
    7,    8,   12,   19,   23,    9,   17,   24,   29,
97
36
};
98
const short yysindex[] =
99
	{                                   -253,
100
18
   -1,   -6,    0,    0,    0,    0,    2, -256, -257,    0,
101
18
    0, -246,    0,    0,    0, -109,    0, -251, -244,    0,
102
    0, -249,    0, -123, -243,    0,    0,    0,    0, -247,};
103
const short yyrindex[] =
104
	{                                      1,
105
135
    0,    0,    0,    0,    0,    0,    0,    0, -245,    0,
106
    0,  -10,    0,    0,    0,    0,    0,    0,   10,    0,
107
135
    0,    0,    0,    0,   12,    0,    0,    0,    0,   13,};
108
const short yygindex[] =
109
126
	{                                      0,
110
126
    0,    0,    0,    0,    0,    0,    0,   -4,    0,
111
126
};
112
#define YYTABLESIZE 259
113
144
const short yytable[] =
114
18
	{                                      17,
115
18
    1,   27,    1,    6,   13,   14,   15,   16,    3,   11,
116
    1,   10,   18,   20,   21,   22,   25,   28,   26,   19,
117
18
    6,   21,   22,   30,    0,    0,    0,    0,    0,    0,
118
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
119
126
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
120
126
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
121
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
122
153
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
123
27
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
124
27
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
125
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
126
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
127
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
128
27
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
129
9
    0,    0,   26,    0,    0,    0,    0,    0,    0,    0,
130
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
131
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
132
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
133
9
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
134
9
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
135
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
136
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
137
18
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
138
18
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
139
    0,    0,    0,    0,    0,    0,    0,    0,    0,   17,
140
18
    4,    5,    0,    0,    0,    0,    0,    1,    1,
141
};
142
const short yycheck[] =
143
	{                                      10,
144
    0,  125,  256,   10,  262,  263,  264,  265,   10,  266,
145
   10,   10,  259,  123,  266,  260,  266,  261,  266,   10,
146
9
  266,   10,   10,   28,   -1,   -1,   -1,   -1,   -1,   -1,
147
9
   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
148
   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
149
9
   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
150
   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
151
54
   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
152
   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
153
   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
154
270
   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
155
270
   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
156
   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
157
   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
158
270
   -1,   -1,  266,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
159
270
   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
160
   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
161
270
   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
162
   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
163
   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
164
144
   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
165
   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
166
144
   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
167
   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
168
144
   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,  260,
169
  257,  258,   -1,   -1,   -1,   -1,   -1,  257,  258,
170
144
};
171
#define YYFINAL 2
172
#ifndef YYDEBUG
173
#define YYDEBUG 0
174
45
#endif
175
45
#define YYMAXTOKEN 266
176
#if YYDEBUG
177
135
const char * const yyname[] =
178
90
	{
179
"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,
180
90
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,
181
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,
182
45
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,
183
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,
184
90
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,
185
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,"TPERMIT","TDENY",
186
45
"TAS","TCMD","TARGS","TNOPASS","TPERSIST","TKEEPENV","TSETENV","TSTRING",
187
};
188
const char * const yyrule[] =
189
	{"$accept : grammar",
190
"grammar :",
191
"grammar : grammar '\\n'",
192
"grammar : grammar rule '\\n'",
193
"grammar : error '\\n'",
194
"rule : action ident target cmd",
195
"action : TPERMIT options",
196
"action : TDENY",
197
"options :",
198
"options : options option",
199
"option : TNOPASS",
200
"option : TPERSIST",
201
"option : TKEEPENV",
202
"option : TSETENV '{' strlist '}'",
203
"strlist :",
204
"strlist : strlist TSTRING",
205
"ident : TSTRING",
206
"target :",
207
"target : TAS TSTRING",
208
"cmd :",
209
"cmd : TCMD TSTRING args",
210
"args :",
211
"args : TARGS strlist",
212
};
213
#endif
214
#ifndef YYSTYPE
215
typedef int YYSTYPE;
216
#endif
217
#ifdef YYSTACKSIZE
218
#undef YYMAXDEPTH
219
#define YYMAXDEPTH YYSTACKSIZE
220
#else
221
#ifdef YYMAXDEPTH
222
#define YYSTACKSIZE YYMAXDEPTH
223
#else
224
#define YYSTACKSIZE 10000
225
#define YYMAXDEPTH 10000
226
#endif
227
#endif
228
#define YYINITSTACKSIZE 200
229
/* LINTUSED */
230
int yydebug;
231
int yynerrs;
232
int yyerrflag;
233
int yychar;
234
short *yyssp;
235
YYSTYPE *yyvsp;
236
YYSTYPE yyval;
237
YYSTYPE yylval;
238
short *yyss;
239
short *yysslim;
240
YYSTYPE *yyvs;
241
unsigned int yystacksize;
242
int yyparse(void);
243
#line 188 "parse.y"
244
245
void
246
yyerror(const char *fmt, ...)
247
{
248
	va_list va;
249
250
	fprintf(stderr, "doas: ");
251
	va_start(va, fmt);
252
	vfprintf(stderr, fmt, va);
253
	va_end(va);
254
	fprintf(stderr, " at line %d\n", yylval.lineno + 1);
255
	parse_errors++;
256
}
257
258
static struct keyword {
259
	const char *word;
260
	int token;
261
} keywords[] = {
262
	{ "deny", TDENY },
263
	{ "permit", TPERMIT },
264
	{ "as", TAS },
265
	{ "cmd", TCMD },
266
	{ "args", TARGS },
267
	{ "nopass", TNOPASS },
268
	{ "persist", TPERSIST },
269
	{ "keepenv", TKEEPENV },
270
	{ "setenv", TSETENV },
271
};
272
273
int
274
yylex(void)
275
{
276
	char buf[1024], *ebuf, *p, *str;
277
	int i, c, quotes = 0, escape = 0, qpos = -1, nonkw = 0;
278
279
	p = buf;
280
	ebuf = buf + sizeof(buf);
281
282
repeat:
283
	/* skip whitespace first */
284
	for (c = getc(yyfp); c == ' ' || c == '\t'; c = getc(yyfp))
285
		yylval.colno++;
286
287
	/* check for special one-character constructions */
288
	switch (c) {
289
		case '\n':
290
			yylval.colno = 0;
291
			yylval.lineno++;
292
			/* FALLTHROUGH */
293
		case '{':
294
		case '}':
295
			return c;
296
		case '#':
297
			/* skip comments; NUL is allowed; no continuation */
298
			while ((c = getc(yyfp)) != '\n')
299
				if (c == EOF)
300
					goto eof;
301
			yylval.colno = 0;
302
			yylval.lineno++;
303
			return c;
304
		case EOF:
305
			goto eof;
306
	}
307
308
	/* parsing next word */
309
	for (;; c = getc(yyfp), yylval.colno++) {
310
		switch (c) {
311
		case '\0':
312
			yyerror("unallowed character NUL in column %d",
313
			    yylval.colno + 1);
314
			escape = 0;
315
			continue;
316
		case '\\':
317
			escape = !escape;
318
			if (escape)
319
				continue;
320
			break;
321
		case '\n':
322
			if (quotes)
323
				yyerror("unterminated quotes in column %d",
324
				    qpos + 1);
325
			if (escape) {
326
				nonkw = 1;
327
				escape = 0;
328
				yylval.colno = 0;
329
				yylval.lineno++;
330
				continue;
331
			}
332
			goto eow;
333
		case EOF:
334
			if (escape)
335
				yyerror("unterminated escape in column %d",
336
				    yylval.colno);
337
			if (quotes)
338
				yyerror("unterminated quotes in column %d",
339
				    qpos + 1);
340
			goto eow;
341
			/* FALLTHROUGH */
342
		case '{':
343
		case '}':
344
		case '#':
345
		case ' ':
346
		case '\t':
347
			if (!escape && !quotes)
348
				goto eow;
349
			break;
350
		case '"':
351
			if (!escape) {
352
				quotes = !quotes;
353
				if (quotes) {
354
					nonkw = 1;
355
					qpos = yylval.colno;
356
				}
357
				continue;
358
			}
359
		}
360
		*p++ = c;
361
		if (p == ebuf) {
362
			yyerror("too long line");
363
			p = buf;
364
		}
365
		escape = 0;
366
	}
367
368
eow:
369
	*p = 0;
370
	if (c != EOF)
371
		ungetc(c, yyfp);
372
	if (p == buf) {
373
		/*
374
		 * There could be a number of reasons for empty buffer,
375
		 * and we handle all of them here, to avoid cluttering
376
		 * the main loop.
377
		 */
378
		if (c == EOF)
379
			goto eof;
380
		else if (qpos == -1)    /* accept, e.g., empty args: cmd foo args "" */
381
			goto repeat;
382
	}
383
	if (!nonkw) {
384
		for (i = 0; i < sizeof(keywords) / sizeof(keywords[0]); i++) {
385
			if (strcmp(buf, keywords[i].word) == 0)
386
				return keywords[i].token;
387
		}
388
	}
389
	if ((str = strdup(buf)) == NULL)
390
		err(1, "strdup");
391
	yylval.str = str;
392
	return TSTRING;
393
394
eof:
395
	if (ferror(yyfp))
396
		yyerror("input error reading config");
397
	return 0;
398
}
399
#line 392 "parse.c"
400
36
/* allocate initial stack or double stack size, up to YYMAXDEPTH */
401
18
static int yygrowstack(void)
402
{
403
    unsigned int newsize;
404
    long sslen;
405
    short *newss;
406
18
    YYSTYPE *newvs;
407
408
    if ((newsize = yystacksize) == 0)
409
        newsize = YYINITSTACKSIZE;
410
    else if (newsize >= YYMAXDEPTH)
411
        return -1;
412

36
    else if ((newsize *= 2) > YYMAXDEPTH)
413
        newsize = YYMAXDEPTH;
414
36
    sslen = yyssp - yyss;
415
18
#ifdef SIZE_MAX
416
18
#define YY_SIZE_MAX SIZE_MAX
417
#else
418
18
#define YY_SIZE_MAX 0xffffffffU
419
18
#endif
420

36
    if (newsize && YY_SIZE_MAX / newsize < sizeof *newss)
421
        goto bail;
422
36
    newss = yyss ? (short *)realloc(yyss, newsize * sizeof *newss) :
423
18
      (short *)malloc(newsize * sizeof *newss); /* overflow check above */
424
18
    if (newss == NULL)
425
        goto bail;
426
18
    yyss = newss;
427
18
    yyssp = newss + sslen;
428
18
    if (newsize && YY_SIZE_MAX / newsize < sizeof *newvs)
429
18
        goto bail;
430
18
    newvs = yyvs ? (YYSTYPE *)realloc(yyvs, newsize * sizeof *newvs) :
431
      (YYSTYPE *)malloc(newsize * sizeof *newvs); /* overflow check above */
432
    if (newvs == NULL)
433
        goto bail;
434
    yyvs = newvs;
435
    yyvsp = newvs + sslen;
436
    yystacksize = newsize;
437
    yysslim = yyss + newsize - 1;
438
    return 0;
439
bail:
440
18
    if (yyss)
441
            free(yyss);
442
    if (yyvs)
443
            free(yyvs);
444
    yyss = yyssp = NULL;
445
    yyvs = yyvsp = NULL;
446
    yystacksize = 0;
447
    return -1;
448
}
449
450
#define YYABORT goto yyabort
451
#define YYREJECT goto yyabort
452
#define YYACCEPT goto yyaccept
453
#define YYERROR goto yyerrlab
454
int
455
yyparse(void)
456
{
457
    int yym, yyn, yystate;
458
#if YYDEBUG
459
    const char *yys;
460
461
36
    if ((yys = getenv("YYDEBUG")))
462
18
    {
463
18
        yyn = *yys;
464
        if (yyn >= '0' && yyn <= '9')
465

36
            yydebug = yyn - '0';
466
18
    }
467
18
#endif /* YYDEBUG */
468
18
469
    yynerrs = 0;
470
    yyerrflag = 0;
471
2520
    yychar = (-1);
472
1458
473
    if (yyss == NULL && yygrowstack()) goto yyoverflow;
474
864
    yyssp = yyss;
475
    yyvsp = yyvs;
476
    *yyssp = yystate = 0;
477
478
yyloop:
479
    if ((yyn = yydefred[yystate]) != 0) goto yyreduce;
480
    if (yychar < 0)
481
    {
482
        if ((yychar = yylex()) < 0) yychar = 0;
483
#if YYDEBUG
484
        if (yydebug)
485
864
        {
486

5634
            yys = 0;
487
2718
            if (yychar <= YYMAXTOKEN) yys = yyname[yychar];
488
            if (!yys) yys = "illegal-symbol";
489
            printf("%sdebug: state %d, reading %d (%s)\n",
490
                    YYPREFIX, yystate, yychar, yys);
491
        }
492
#endif
493
    }
494

1017
    if ((yyn = yysindex[yystate]) && (yyn += yychar) >= 0 &&
495
            yyn <= YYTABLESIZE && yycheck[yyn] == yychar)
496
    {
497
#if YYDEBUG
498
1017
        if (yydebug)
499
1017
            printf("%sdebug: state %d, shifting to state %d\n",
500
1017
                    YYPREFIX, yystate, yytable[yyn]);
501
1017
#endif
502
        if (yyssp >= yysslim && yygrowstack())
503
        {
504

1737
            goto yyoverflow;
505
864
        }
506
        *++yyssp = yystate = yytable[yyn];
507
423
        *++yyvsp = yylval;
508
423
        yychar = (-1);
509
        if (yyerrflag > 0)  --yyerrflag;
510
18
        goto yyloop;
511
    }
512
    if ((yyn = yyrindex[yystate]) && (yyn += yychar) >= 0 &&
513
            yyn <= YYTABLESIZE && yycheck[yyn] == yychar)
514
    {
515
9
        yyn = yytable[yyn];
516
        goto yyreduce;
517
9
    }
518
    if (yyerrflag) goto yyinrecovery;
519
#if defined(__GNUC__)
520
9
    goto yynewerror;
521
#endif
522
18
yynewerror:
523
    yyerror("syntax error");
524
9
#if defined(__GNUC__)
525
63
    goto yyerrlab;
526
#endif
527

252
yyerrlab:
528
126
    ++yynerrs;
529
yyinrecovery:
530
    if (yyerrflag < 3)
531
    {
532
        yyerrflag = 3;
533
        for (;;)
534
        {
535

9
            if ((yyn = yysindex[*yyssp]) && (yyn += YYERRCODE) >= 0 &&
536
                    yyn <= YYTABLESIZE && yycheck[yyn] == YYERRCODE)
537
            {
538
#if YYDEBUG
539
9
                if (yydebug)
540
9
                    printf("%sdebug: state %d, error recovery shifting\
541
9
 to state %d\n", YYPREFIX, *yyssp, yytable[yyn]);
542
#endif
543
                if (yyssp >= yysslim && yygrowstack())
544
                {
545
                    goto yyoverflow;
546
                }
547
                *++yyssp = yystate = yytable[yyn];
548
                *++yyvsp = yylval;
549
                goto yyloop;
550
54
            }
551
54
            else
552
54
            {
553
#if YYDEBUG
554
                if (yydebug)
555
                    printf("%sdebug: error recovery discarding state %d\n",
556
                            YYPREFIX, *yyssp);
557
#endif
558
9
                if (yyssp <= yyss) goto yyabort;
559
                --yyssp;
560
                --yyvsp;
561
            }
562
        }
563
    }
564
    else
565
    {
566
        if (yychar == 0) goto yyabort;
567
#if YYDEBUG
568
        if (yydebug)
569
        {
570
            yys = 0;
571
            if (yychar <= YYMAXTOKEN) yys = yyname[yychar];
572
            if (!yys) yys = "illegal-symbol";
573
            printf("%sdebug: state %d, error recovery discards token %d (%s)\n",
574
                    YYPREFIX, yystate, yychar, yys);
575
        }
576
#endif
577
        yychar = (-1);
578
1485
        goto yyloop;
579
1485
    }
580
1053
yyreduce:
581
#if YYDEBUG
582
432
    if (yydebug)
583




2781
        printf("%sdebug: state %d, reducing by rule %d (%s)\n",
584
                YYPREFIX, yystate, yyn, yyrule[yyn]);
585
#endif
586
    yym = yylen[yyn];
587
    if (yym)
588
        yyval = yyvsp[1-yym];
589
    else
590
        memset(&yyval, 0, sizeof yyval);
591
    switch (yyn)
592
    {
593
case 5:
594
#line 84 "parse.y"
595
{
596
			struct rule *r;
597
			r = calloc(1, sizeof(*r));
598
			if (!r)
599
				errx(1, "can't allocate rule");
600
			r->action = yyvsp[-3].action;
601
			r->options = yyvsp[-3].options;
602
			r->envlist = yyvsp[-3].envlist;
603
			r->ident = yyvsp[-2].str;
604
			r->target = yyvsp[-1].str;
605
			r->cmd = yyvsp[0].cmd;
606
			r->cmdargs = yyvsp[0].cmdargs;
607
			if (nrules == maxrules) {
608
				if (maxrules == 0)
609
					maxrules = 63;
610
				else
611
					maxrules *= 2;
612
				if (!(rules = reallocarray(rules, maxrules,
613
				    sizeof(*rules))))
614
					errx(1, "can't allocate rules");
615
			}
616
			rules[nrules++] = r;
617
		}
618
break;
619
case 6:
620
#line 108 "parse.y"
621
{
622
			yyval.action = PERMIT;
623
			yyval.options = yyvsp[0].options;
624
			yyval.envlist = yyvsp[0].envlist;
625
		}
626
break;
627
case 7:
628
#line 112 "parse.y"
629
{
630
			yyval.action = DENY;
631
			yyval.options = 0;
632
			yyval.envlist = NULL;
633
		}
634
break;
635
case 8:
636
#line 118 "parse.y"
637
{
638
			yyval.options = 0;
639
			yyval.envlist = NULL;
640
		}
641
break;
642
case 9:
643
#line 121 "parse.y"
644
{
645
			yyval.options = yyvsp[-1].options | yyvsp[0].options;
646
			yyval.envlist = yyvsp[-1].envlist;
647
			if ((yyval.options & (NOPASS|PERSIST)) == (NOPASS|PERSIST)) {
648
				yyerror("can't combine nopass and persist");
649
				YYERROR;
650
			}
651
			if (yyvsp[0].envlist) {
652
				if (yyval.envlist) {
653
					yyerror("can't have two setenv sections");
654
					YYERROR;
655
				} else
656
					yyval.envlist = yyvsp[0].envlist;
657
			}
658
		}
659
break;
660
case 10:
661
#line 136 "parse.y"
662
{
663
			yyval.options = NOPASS;
664
			yyval.envlist = NULL;
665
		}
666
break;
667
case 11:
668
#line 139 "parse.y"
669
{
670
			yyval.options = PERSIST;
671
			yyval.envlist = NULL;
672
		}
673
break;
674
case 12:
675
#line 142 "parse.y"
676
{
677
			yyval.options = KEEPENV;
678
			yyval.envlist = NULL;
679
		}
680
break;
681
case 13:
682
#line 145 "parse.y"
683
{
684
			yyval.options = 0;
685
			yyval.envlist = yyvsp[-1].strlist;
686
		}
687
break;
688
case 14:
689
#line 150 "parse.y"
690
{
691
			if (!(yyval.strlist = calloc(1, sizeof(char *))))
692
				errx(1, "can't allocate strlist");
693
		}
694
break;
695
case 15:
696
#line 153 "parse.y"
697
{
698
			int nstr = arraylen(yyvsp[-1].strlist);
699
			if (!(yyval.strlist = reallocarray(yyvsp[-1].strlist, nstr + 2,
700
			    sizeof(char *))))
701
				errx(1, "can't allocate strlist");
702
			yyval.strlist[nstr] = yyvsp[0].str;
703
			yyval.strlist[nstr + 1] = NULL;
704
		}
705
break;
706
case 16:
707
#line 163 "parse.y"
708
{
709
			yyval.str = yyvsp[0].str;
710
		}
711
break;
712
case 17:
713
#line 167 "parse.y"
714
{
715
			yyval.str = NULL;
716
		}
717
break;
718
case 18:
719
#line 169 "parse.y"
720
{
721
			yyval.str = yyvsp[0].str;
722
		}
723
break;
724
case 19:
725
#line 173 "parse.y"
726
{
727
			yyval.cmd = NULL;
728
			yyval.cmdargs = NULL;
729
		}
730
break;
731
case 20:
732
#line 176 "parse.y"
733
{
734
			yyval.cmd = yyvsp[-1].str;
735
			yyval.cmdargs = yyvsp[0].cmdargs;
736
		}
737
break;
738
case 21:
739
#line 181 "parse.y"
740
{
741
			yyval.cmdargs = NULL;
742
		}
743
break;
744
1485
case 22:
745
1485
#line 183 "parse.y"
746
1485
{
747
1485
			yyval.cmdargs = yyvsp[0].strlist;
748
1485
		}
749
break;
750
#line 743 "parse.c"
751
    }
752
    yyssp -= yym;
753
    yystate = *yyssp;
754
    yyvsp -= yym;
755
    yym = yylhs[yyn];
756
189
    if (yystate == 0 && yym == 0)
757
189
    {
758
189
#if YYDEBUG
759
        if (yydebug)
760
171
            printf("%sdebug: after reduction, shifting from state 0 to\
761
 state %d\n", YYPREFIX, YYFINAL);
762
#endif
763
        yystate = YYFINAL;
764
        *++yyssp = YYFINAL;
765
        *++yyvsp = yyval;
766
        if (yychar < 0)
767
        {
768
            if ((yychar = yylex()) < 0) yychar = 0;
769
#if YYDEBUG
770
            if (yydebug)
771
171
            {
772
189
                yys = 0;
773
                if (yychar <= YYMAXTOKEN) yys = yyname[yychar];
774
                if (!yys) yys = "illegal-symbol";
775

2268
                printf("%sdebug: state %d, reading %d (%s)\n",
776
648
                        YYPREFIX, YYFINAL, yychar, yys);
777
90
            }
778
#endif
779
1206
        }
780
        if (yychar == 0) goto yyaccept;
781
        goto yyloop;
782
    }
783
    if ((yyn = yygindex[yym]) && (yyn += yystate) >= 0 &&
784
            yyn <= YYTABLESIZE && yycheck[yyn] == yystate)
785

1296
        yystate = yytable[yyn];
786
    else
787
        yystate = yydgoto[yym];
788
#if YYDEBUG
789
1296
    if (yydebug)
790
1296
        printf("%sdebug: after reduction, shifting from state %d \
791
1296
to state %d\n", YYPREFIX, *yyssp, yystate);
792
#endif
793
    if (yyssp >= yysslim && yygrowstack())
794
    {
795
9
        goto yyoverflow;
796
9
    }
797
9
    *++yyssp = yystate;
798
9
    *++yyvsp = yyval;
799
9
    goto yyloop;
800
9
yyoverflow:
801
9
    yyerror("yacc stack overflow");
802
9
yyabort:
803
    if (yyss)
804
9
            free(yyss);
805
9
    if (yyvs)
806
9
            free(yyvs);
807
9
    yyss = yyssp = NULL;
808
9
    yyvs = yyvsp = NULL;
809
9
    yystacksize = 0;
810
9
    return (1);
811
9
yyaccept:
812
18
    if (yyss)
813
            free(yyss);
814
    if (yyvs)
815
            free(yyvs);
816
    yyss = yyssp = NULL;
817
    yyvs = yyvsp = NULL;
818
    yystacksize = 0;
819
    return (0);
820
}