1 %{ 2 /*- 3 * Copyright (c) 2011 James Gritton 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25 * SUCH DAMAGE. 26 */ 27 28 #include <sys/cdefs.h> 29 __FBSDID("$FreeBSD$"); 30 31 #include <stdlib.h> 32 #include <string.h> 33 34 #include "jailp.h" 35 36 #ifdef DEBUG 37 #define YYDEBUG 1 38 #endif 39 %} 40 41 %union { 42 struct cfjail *j; 43 struct cfparams *pp; 44 struct cfparam *p; 45 struct cfstrings *ss; 46 struct cfstring *s; 47 char *cs; 48 } 49 50 %token PLEQ 51 %token <cs> STR STR1 VAR VAR1 52 53 %type <j> jail 54 %type <pp> param_l 55 %type <p> param name 56 %type <ss> value 57 %type <s> string 58 59 %% 60 61 /* 62 * A config file is a series of jails (containing parameters) and jail-less 63 * parameters which realy belong to a global pseudo-jail. 64 */ 65 conf : 66 ; 67 | conf jail 68 ; 69 | conf param ';' 70 { 71 struct cfjail *j; 72 73 j = TAILQ_LAST(&cfjails, cfjails); 74 if (!j || strcmp(j->name, "*")) { 75 j = add_jail(); 76 j->name = estrdup("*"); 77 } 78 TAILQ_INSERT_TAIL(&j->params, $2, tq); 79 } 80 | conf ';' 81 82 jail : STR '{' param_l '}' 83 { 84 $$ = add_jail(); 85 $$->name = $1; 86 TAILQ_CONCAT(&$$->params, $3, tq); 87 free($3); 88 } 89 ; 90 91 param_l : 92 { 93 $$ = emalloc(sizeof(struct cfparams)); 94 TAILQ_INIT($$); 95 } 96 | param_l param ';' 97 { 98 $$ = $1; 99 TAILQ_INSERT_TAIL($$, $2, tq); 100 } 101 | param_l ';' 102 ; 103 104 /* 105 * Parameters have a name and an optional list of value strings, 106 * which may have "+=" or "=" preceding them. 107 */ 108 param : name 109 { 110 $$ = $1; 111 } 112 | name '=' value 113 { 114 $$ = $1; 115 TAILQ_CONCAT(&$$->val, $3, tq); 116 free($3); 117 } 118 | name PLEQ value 119 { 120 $$ = $1; 121 TAILQ_CONCAT(&$$->val, $3, tq); 122 $$->flags |= PF_APPEND; 123 free($3); 124 } 125 | name value 126 { 127 $$ = $1; 128 TAILQ_CONCAT(&$$->val, $2, tq); 129 free($2); 130 } 131 | error 132 { 133 } 134 ; 135 136 /* 137 * A parameter has a fixed name. A variable definition looks just like a 138 * parameter except that the name is a variable. 139 */ 140 name : STR 141 { 142 $$ = emalloc(sizeof(struct cfparam)); 143 $$->name = $1; 144 TAILQ_INIT(&$$->val); 145 $$->flags = 0; 146 } 147 | VAR 148 { 149 $$ = emalloc(sizeof(struct cfparam)); 150 $$->name = $1; 151 TAILQ_INIT(&$$->val); 152 $$->flags = PF_VAR; 153 } 154 ; 155 156 value : string 157 { 158 $$ = emalloc(sizeof(struct cfstrings)); 159 TAILQ_INIT($$); 160 TAILQ_INSERT_TAIL($$, $1, tq); 161 } 162 | value ',' string 163 { 164 $$ = $1; 165 TAILQ_INSERT_TAIL($$, $3, tq); 166 } 167 ; 168 169 /* 170 * Strings may be passed in pieces, because of quoting and/or variable 171 * interpolation. Reassemble them into a single string. 172 */ 173 string : STR 174 { 175 $$ = emalloc(sizeof(struct cfstring)); 176 $$->s = $1; 177 $$->len = strlen($1); 178 STAILQ_INIT(&$$->vars); 179 } 180 | VAR 181 { 182 struct cfvar *v; 183 184 $$ = emalloc(sizeof(struct cfstring)); 185 $$->s = estrdup(""); 186 $$->len = 0; 187 STAILQ_INIT(&$$->vars); 188 v = emalloc(sizeof(struct cfvar)); 189 v->name = $1; 190 v->pos = 0; 191 STAILQ_INSERT_TAIL(&$$->vars, v, tq); 192 } 193 | string STR1 194 { 195 size_t len1; 196 197 $$ = $1; 198 len1 = strlen($2); 199 $$->s = erealloc($$->s, $$->len + len1 + 1); 200 strcpy($$->s + $$->len, $2); 201 free($2); 202 $$->len += len1; 203 } 204 | string VAR1 205 { 206 struct cfvar *v; 207 208 $$ = $1; 209 v = emalloc(sizeof(struct cfvar)); 210 v->name = $2; 211 v->pos = $$->len; 212 STAILQ_INSERT_TAIL(&$$->vars, v, tq); 213 } 214 ; 215 216 %% 217