[BACK]Return to parse.y CVS log [TXT][DIR] Up to [local] / src / usr.bin / doas

Annotation of src/usr.bin/doas/parse.y, Revision 1.1

1.1     ! tedu        1: /* $OpenBSD$ */
        !             2: /*
        !             3:  * Copyright (c) 2015 Ted Unangst <tedu@openbsd.org>
        !             4:  *
        !             5:  * Permission to use, copy, modify, and distribute this software for any
        !             6:  * purpose with or without fee is hereby granted, provided that the above
        !             7:  * copyright notice and this permission notice appear in all copies.
        !             8:  *
        !             9:  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
        !            10:  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
        !            11:  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
        !            12:  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
        !            13:  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
        !            14:  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
        !            15:  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
        !            16:  */
        !            17:
        !            18: %{
        !            19: #include <sys/types.h>
        !            20: #include <ctype.h>
        !            21: #include <unistd.h>
        !            22: #include <stdint.h>
        !            23: #include <stdarg.h>
        !            24: #include <stdio.h>
        !            25: #include <string.h>
        !            26: #include <err.h>
        !            27:
        !            28: #include "doas.h"
        !            29:
        !            30: typedef struct {
        !            31:        union {
        !            32:                struct {
        !            33:                        int action;
        !            34:                        int options;
        !            35:                        const char **envlist;
        !            36:                };
        !            37:                const char *str;
        !            38:        };
        !            39: } yystype;
        !            40: #define YYSTYPE yystype
        !            41:
        !            42: FILE *yyfp;
        !            43:
        !            44: struct rule **rules;
        !            45: int nrules, maxrules;
        !            46:
        !            47: %}
        !            48:
        !            49: %token TPERMIT TDENY TAS TCMD
        !            50: %token TNOPASS TKEEPENV
        !            51: %token TSTRING
        !            52:
        !            53: %%
        !            54:
        !            55: grammar:       /* empty */
        !            56:                | grammar '\n'
        !            57:                | grammar rule '\n'
        !            58:                ;
        !            59:
        !            60: rule:          action ident target cmd {
        !            61:                        struct rule *r;
        !            62:                        r = calloc(1, sizeof(*r));
        !            63:                        r->action = $1.action;
        !            64:                        r->options = $1.options;
        !            65:                        r->envlist = $1.envlist;
        !            66:                        r->ident = $2.str;
        !            67:                        r->target = $3.str;
        !            68:                        r->cmd = $4.str;
        !            69:                        if (nrules == maxrules) {
        !            70:                                if (maxrules == 0)
        !            71:                                        maxrules = 63;
        !            72:                                else
        !            73:                                        maxrules *= 2;
        !            74:                                if (!(rules = reallocarray(rules, maxrules, sizeof(*rules))))
        !            75:                                        errx(1, "can't allocate rules");
        !            76:                        }
        !            77:                        rules[nrules++] = r;
        !            78:                } ;
        !            79:
        !            80: action:                TPERMIT options {
        !            81:                        $$.action = PERMIT;
        !            82:                        $$.options = $2.options;
        !            83:                        $$.envlist = $2.envlist;
        !            84:                } | TDENY {
        !            85:                        $$.action = DENY;
        !            86:                } ;
        !            87:
        !            88: options:       /* none */
        !            89:                | options option {
        !            90:                        $$.options = $1.options | $2.options;
        !            91:                        $$.envlist = $1.envlist;
        !            92:                        if ($2.envlist) {
        !            93:                                if ($$.envlist)
        !            94:                                        errx(1, "can't have two keepenv sections");
        !            95:                                else
        !            96:                                        $$.envlist = $2.envlist;
        !            97:                        }
        !            98:                } ;
        !            99: option:                TNOPASS {
        !           100:                        $$.options = NOPASS;
        !           101:                } | TKEEPENV {
        !           102:                        $$.options = KEEPENV;
        !           103:                } | TKEEPENV '{' envlist '}' {
        !           104:                        $$.options = KEEPENV;
        !           105:                        $$.envlist = $3.envlist;
        !           106:                } ;
        !           107:
        !           108: envlist:       /* empty */ {
        !           109:                        if (!($$.envlist = calloc(1, sizeof(char *))))
        !           110:                                errx(1, "can't allocate envlist");
        !           111:                } | envlist TSTRING {
        !           112:                        int nenv = arraylen($1.envlist);
        !           113:                        if (!($$.envlist = reallocarray($1.envlist, nenv + 2, sizeof(char *))))
        !           114:                                errx(1, "can't allocate envlist");
        !           115:                        $$.envlist[nenv] = $2.str;
        !           116:                        $$.envlist[nenv + 1] = NULL;
        !           117:                }
        !           118:
        !           119:
        !           120: ident:         TSTRING {
        !           121:                        $$.str = $1.str;
        !           122:                } ;
        !           123:
        !           124: target:                /* optional */ {
        !           125:                        $$.str = NULL;
        !           126:                } | TAS TSTRING {
        !           127:                        $$.str = $2.str;
        !           128:                } ;
        !           129:
        !           130: cmd:           /* optional */ {
        !           131:                        $$.str = NULL;
        !           132:                } | TCMD TSTRING {
        !           133:                        $$.str = $2.str;
        !           134:                } ;
        !           135:
        !           136: %%
        !           137:
        !           138: void
        !           139: yyerror(const char *fmt, ...)
        !           140: {
        !           141:        va_list va;
        !           142:
        !           143:        va_start(va, fmt);
        !           144:        fprintf(stderr, "doas: ");
        !           145:        vfprintf(stderr, fmt, va);
        !           146:        fprintf(stderr, "\n");
        !           147:        va_end(va);
        !           148:        exit(1);
        !           149: }
        !           150:
        !           151: struct keyword {
        !           152:        const char *word;
        !           153:        int token;
        !           154: } keywords[] = {
        !           155:        { "deny", TDENY },
        !           156:        { "permit", TPERMIT },
        !           157:        { "as", TAS },
        !           158:        { "cmd", TCMD },
        !           159:        { "nopass", TNOPASS },
        !           160:        { "keepenv", TKEEPENV },
        !           161: };
        !           162:
        !           163: int
        !           164: yylex(void)
        !           165: {
        !           166:        char buf[1024], *ebuf, *p, *str;
        !           167:        int i, c;
        !           168:
        !           169:        p = buf;
        !           170:        ebuf = buf + sizeof(buf);
        !           171:        while ((c = getc(yyfp)) == ' ' || c == '\t')
        !           172:                ; /* skip spaces */
        !           173:        switch (c) {
        !           174:                case '\n':
        !           175:                case '{':
        !           176:                case '}':
        !           177:                        return c;
        !           178:                case '#':
        !           179:                        while ((c = getc(yyfp)) != '\n' && c != EOF)
        !           180:                                ; /* skip comments */
        !           181:                        if (c == EOF)
        !           182:                                return 0;
        !           183:                        return c;
        !           184:                case EOF:
        !           185:                        return 0;
        !           186:                case ':':
        !           187:                        *p++ = c;
        !           188:                        c = getc(yyfp);
        !           189:                        break;
        !           190:                default:
        !           191:                        break;
        !           192:        }
        !           193:        while (isalnum(c)) {
        !           194:                *p++ = c;
        !           195:                if (p == ebuf)
        !           196:                        yyerror("too much stuff");
        !           197:                c = getc(yyfp);
        !           198:        }
        !           199:        *p = 0;
        !           200:        if (c != EOF)
        !           201:                ungetc(c, yyfp);
        !           202:        for (i = 0; i < sizeof(keywords) / sizeof(keywords[0]); i++) {
        !           203:                if (strcmp(buf, keywords[i].word) == 0)
        !           204:                        return keywords[i].token;
        !           205:        }
        !           206:        if ((str = strdup(buf)) == NULL)
        !           207:                err(1, "strdup");
        !           208:        yylval.str = str;
        !           209:        return TSTRING;
        !           210: }