1 %{ 2 /* 3 * configlexer.lex - lexical analyzer for NSD config file 4 * 5 * Copyright (c) 2001-2006, NLnet Labs. All rights reserved 6 * 7 * See LICENSE for the license. 8 * 9 */ 10 /* because flex keeps having sign-unsigned compare problems that are unfixed*/ 11 #if defined(__clang__)||(defined(__GNUC__)&&((__GNUC__ >4)||(defined(__GNUC_MINOR__)&&(__GNUC__ ==4)&&(__GNUC_MINOR__ >=2)))) 12 #pragma GCC diagnostic ignored "-Wsign-compare" 13 #endif 14 #include <ctype.h> 15 #include <errno.h> 16 #include <string.h> 17 #include <strings.h> 18 #ifdef HAVE_GLOB_H 19 # include <glob.h> 20 #endif 21 22 #include "options.h" 23 #include "configparser.h" 24 25 #if 0 26 #define LEXOUT(s) printf s /* used ONLY when debugging */ 27 #else 28 #define LEXOUT(s) 29 #endif 30 31 struct inc_state { 32 char* filename; 33 int line; 34 YY_BUFFER_STATE buffer; 35 struct inc_state* next; 36 }; 37 static struct inc_state* config_include_stack = NULL; 38 static int inc_depth = 0; 39 40 static void config_start_include(const char* filename) 41 { 42 FILE *input; 43 struct inc_state* s; 44 char* nm; 45 if(inc_depth++ > 10000000) { 46 c_error("too many include files"); 47 return; 48 } 49 if(strlen(filename) == 0) { 50 c_error("empty include file name"); 51 return; 52 } 53 s = (struct inc_state*)malloc(sizeof(*s)); 54 if(!s) { 55 c_error("include %s: malloc failure", filename); 56 return; 57 } 58 nm = strdup(filename); 59 if(!nm) { 60 c_error("include %s: strdup failure", filename); 61 free(s); 62 return; 63 } 64 input = fopen(filename, "r"); 65 if(!input) { 66 c_error("cannot open include file '%s': %s", 67 filename, strerror(errno)); 68 free(s); 69 free(nm); 70 return; 71 } 72 LEXOUT(("switch_to_include_file(%s) ", filename)); 73 s->filename = cfg_parser->filename; 74 s->line = cfg_parser->line; 75 s->buffer = YY_CURRENT_BUFFER; 76 s->next = config_include_stack; 77 config_include_stack = s; 78 79 cfg_parser->filename = nm; 80 cfg_parser->line = 1; 81 yy_switch_to_buffer(yy_create_buffer(input, YY_BUF_SIZE)); 82 } 83 84 static void config_start_include_glob(const char* filename) 85 { 86 /* check for wildcards */ 87 #ifdef HAVE_GLOB 88 glob_t g; 89 int i, r, flags; 90 #endif /* HAVE_GLOB */ 91 if (cfg_parser->chroot) { 92 int l = strlen(cfg_parser->chroot); /* chroot has trailing slash */ 93 if (strncmp(cfg_parser->chroot, filename, l) != 0) { 94 c_error("include file '%s' is not relative to chroot '%s'", 95 filename, cfg_parser->chroot); 96 return; 97 } 98 filename += l - 1; /* strip chroot without trailing slash */ 99 } 100 #ifdef HAVE_GLOB 101 if(!(!strchr(filename, '*') && !strchr(filename, '?') && 102 !strchr(filename, '[') && !strchr(filename, '{') && 103 !strchr(filename, '~'))) { 104 flags = 0 105 #ifdef GLOB_ERR 106 | GLOB_ERR 107 #endif 108 /* do not set GLOB_NOSORT so the results are sorted 109 and in a predictable order. */ 110 #ifdef GLOB_BRACE 111 | GLOB_BRACE 112 #endif 113 #ifdef GLOB_TILDE 114 | GLOB_TILDE 115 #endif 116 ; 117 memset(&g, 0, sizeof(g)); 118 r = glob(filename, flags, NULL, &g); 119 if(r) { 120 /* some error */ 121 globfree(&g); 122 if(r == GLOB_NOMATCH) 123 return; /* no matches for pattern */ 124 config_start_include(filename); /* let original deal with it */ 125 return; 126 } 127 /* process files found, if any */ 128 for(i=(int)g.gl_pathc-1; i>=0; i--) { 129 config_start_include(g.gl_pathv[i]); 130 } 131 globfree(&g); 132 return; 133 } 134 #endif /* HAVE_GLOB */ 135 config_start_include(filename); 136 } 137 138 static void config_end_include(void) 139 { 140 struct inc_state* s = config_include_stack; 141 --inc_depth; 142 if(!s) return; 143 free(cfg_parser->filename); 144 cfg_parser->filename = s->filename; 145 cfg_parser->line = s->line; 146 yy_delete_buffer(YY_CURRENT_BUFFER); 147 yy_switch_to_buffer(s->buffer); 148 config_include_stack = s->next; 149 free(s); 150 } 151 152 #ifndef yy_set_bol /* compat definition, for flex 2.4.6 */ 153 #define yy_set_bol(at_bol) \ 154 { \ 155 if ( ! yy_current_buffer ) \ 156 yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE ); \ 157 yy_current_buffer->yy_ch_buf[0] = ((at_bol)?'\n':' '); \ 158 } 159 #endif 160 161 %} 162 %option noinput 163 %option nounput 164 %{ 165 #ifndef YY_NO_UNPUT 166 #define YY_NO_UNPUT 1 167 #endif 168 #ifndef YY_NO_INPUT 169 #define YY_NO_INPUT 1 170 #endif 171 %} 172 173 SPACE [ \t] 174 LETTER [a-zA-Z] 175 UNQUOTEDLETTER [^\"\n\r \t\\]|\\. 176 NEWLINE [\r\n] 177 COMMENT \# 178 COLON \: 179 ANY [^\"\n\r\\]|\\. 180 181 %x quotedstring include include_quoted 182 183 %% 184 {SPACE}* { LEXOUT(("SP ")); /* ignore */ } 185 {SPACE}*{COMMENT}.* { LEXOUT(("comment(%s) ", yytext)); /* ignore */ } 186 server{COLON} { LEXOUT(("v(%s) ", yytext)); return VAR_SERVER;} 187 name{COLON} { LEXOUT(("v(%s) ", yytext)); return VAR_NAME;} 188 ip-address{COLON} { LEXOUT(("v(%s) ", yytext)); return VAR_IP_ADDRESS;} 189 interface{COLON} { LEXOUT(("v(%s) ", yytext)); return VAR_IP_ADDRESS;} 190 ip-transparent{COLON} { LEXOUT(("v(%s) ", yytext)); return VAR_IP_TRANSPARENT;} 191 ip-freebind{COLON} { LEXOUT(("v(%s) ", yytext)); return VAR_IP_FREEBIND;} 192 send-buffer-size{COLON} { LEXOUT(("v(%s) ", yytext)); return VAR_SEND_BUFFER_SIZE;} 193 receive-buffer-size{COLON} { LEXOUT(("v(%s) ", yytext)); return VAR_RECEIVE_BUFFER_SIZE;} 194 debug-mode{COLON} { LEXOUT(("v(%s) ", yytext)); return VAR_DEBUG_MODE;} 195 use-systemd{COLON} { LEXOUT(("v(%s) ", yytext)); return VAR_USE_SYSTEMD;} 196 hide-version{COLON} { LEXOUT(("v(%s) ", yytext)); return VAR_HIDE_VERSION;} 197 hide-identity{COLON} { LEXOUT(("v(%s) ", yytext)); return VAR_HIDE_IDENTITY;} 198 drop-updates{COLON} { LEXOUT(("v(%s) ", yytext)); return VAR_DROP_UPDATES; } 199 ip4-only{COLON} { LEXOUT(("v(%s) ", yytext)); return VAR_IP4_ONLY;} 200 ip6-only{COLON} { LEXOUT(("v(%s) ", yytext)); return VAR_IP6_ONLY;} 201 do-ip4{COLON} { LEXOUT(("v(%s) ", yytext)); return VAR_DO_IP4;} 202 do-ip6{COLON} { LEXOUT(("v(%s) ", yytext)); return VAR_DO_IP6;} 203 database{COLON} { LEXOUT(("v(%s) ", yytext)); return VAR_DATABASE;} 204 identity{COLON} { LEXOUT(("v(%s) ", yytext)); return VAR_IDENTITY;} 205 version{COLON} { LEXOUT(("v(%s) ", yytext)); return VAR_VERSION;} 206 nsid{COLON} { LEXOUT(("v(%s) ", yytext)); return VAR_NSID;} 207 logfile{COLON} { LEXOUT(("v(%s) ", yytext)); return VAR_LOGFILE;} 208 log-only-syslog{COLON} { LEXOUT(("v(%s) ", yytext)); return VAR_LOG_ONLY_SYSLOG;} 209 server-count{COLON} { LEXOUT(("v(%s) ", yytext)); return VAR_SERVER_COUNT;} 210 tcp-count{COLON} { LEXOUT(("v(%s) ", yytext)); return VAR_TCP_COUNT;} 211 tcp-reject-overflow{COLON} { LEXOUT(("v(%s) ", yytext)); return VAR_TCP_REJECT_OVERFLOW;} 212 tcp-query-count{COLON} { LEXOUT(("v(%s) ", yytext)); return VAR_TCP_QUERY_COUNT;} 213 tcp-timeout{COLON} { LEXOUT(("v(%s) ", yytext)); return VAR_TCP_TIMEOUT;} 214 tcp-mss{COLON} { LEXOUT(("v(%s) ", yytext)); return VAR_TCP_MSS;} 215 outgoing-tcp-mss{COLON} { LEXOUT(("v(%s) ", yytext)); return VAR_OUTGOING_TCP_MSS;} 216 ipv4-edns-size{COLON} { LEXOUT(("v(%s) ", yytext)); return VAR_IPV4_EDNS_SIZE;} 217 ipv6-edns-size{COLON} { LEXOUT(("v(%s) ", yytext)); return VAR_IPV6_EDNS_SIZE;} 218 pidfile{COLON} { LEXOUT(("v(%s) ", yytext)); return VAR_PIDFILE;} 219 port{COLON} { LEXOUT(("v(%s) ", yytext)); return VAR_PORT;} 220 reuseport{COLON} { LEXOUT(("v(%s) ", yytext)); return VAR_REUSEPORT;} 221 statistics{COLON} { LEXOUT(("v(%s) ", yytext)); return VAR_STATISTICS;} 222 chroot{COLON} { LEXOUT(("v(%s) ", yytext)); return VAR_CHROOT;} 223 username{COLON} { LEXOUT(("v(%s) ", yytext)); return VAR_USERNAME;} 224 zonesdir{COLON} { LEXOUT(("v(%s) ", yytext)); return VAR_ZONESDIR;} 225 zonelistfile{COLON} { LEXOUT(("v(%s) ", yytext)); return VAR_ZONELISTFILE;} 226 difffile{COLON} { LEXOUT(("v(%s) ", yytext)); return VAR_DIFFFILE;} 227 xfrdfile{COLON} { LEXOUT(("v(%s) ", yytext)); return VAR_XFRDFILE;} 228 xfrdir{COLON} { LEXOUT(("v(%s) ", yytext)); return VAR_XFRDIR;} 229 xfrd-reload-timeout{COLON} { LEXOUT(("v(%s) ", yytext)); return VAR_XFRD_RELOAD_TIMEOUT;} 230 verbosity{COLON} { LEXOUT(("v(%s) ", yytext)); return VAR_VERBOSITY;} 231 zone{COLON} { LEXOUT(("v(%s) ", yytext)); return VAR_ZONE;} 232 zonefile{COLON} { LEXOUT(("v(%s) ", yytext)); return VAR_ZONEFILE;} 233 zonestats{COLON} { LEXOUT(("v(%s) ", yytext)); return VAR_ZONESTATS;} 234 allow-notify{COLON} { LEXOUT(("v(%s) ", yytext)); return VAR_ALLOW_NOTIFY;} 235 size-limit-xfr{COLON} { LEXOUT(("v(%s) ", yytext)); return VAR_SIZE_LIMIT_XFR;} 236 request-xfr{COLON} { LEXOUT(("v(%s) ", yytext)); return VAR_REQUEST_XFR;} 237 notify{COLON} { LEXOUT(("v(%s) ", yytext)); return VAR_NOTIFY;} 238 notify-retry{COLON} { LEXOUT(("v(%s) ", yytext)); return VAR_NOTIFY_RETRY;} 239 provide-xfr{COLON} { LEXOUT(("v(%s) ", yytext)); return VAR_PROVIDE_XFR;} 240 allow-query{COLON} { LEXOUT(("v(%s) ", yytext)); return VAR_ALLOW_QUERY;} 241 outgoing-interface{COLON} { LEXOUT(("v(%s) ", yytext)); return VAR_OUTGOING_INTERFACE;} 242 allow-axfr-fallback{COLON} { LEXOUT(("v(%s) ", yytext)); return VAR_ALLOW_AXFR_FALLBACK;} 243 tls-auth{COLON} { LEXOUT(("v(%s) ", yytext)); return VAR_TLS_AUTH;} 244 auth-domain-name{COLON} { LEXOUT(("v(%s) ", yytext)); return VAR_TLS_AUTH_DOMAIN_NAME;} 245 client-cert{COLON} { LEXOUT(("v(%s) ", yytext)); return VAR_TLS_AUTH_CLIENT_CERT;} 246 client-key{COLON} { LEXOUT(("v(%s) ", yytext)); return VAR_TLS_AUTH_CLIENT_KEY;} 247 client-key-pw{COLON} { LEXOUT(("v(%s) ", yytext)); return VAR_TLS_AUTH_CLIENT_KEY_PW;} 248 key{COLON} { LEXOUT(("v(%s) ", yytext)); return VAR_KEY;} 249 algorithm{COLON} { LEXOUT(("v(%s) ", yytext)); return VAR_ALGORITHM;} 250 secret{COLON} { LEXOUT(("v(%s) ", yytext)); return VAR_SECRET;} 251 pattern{COLON} { LEXOUT(("v(%s) ", yytext)); return VAR_PATTERN;} 252 include-pattern{COLON} { LEXOUT(("v(%s) ", yytext)); return VAR_INCLUDE_PATTERN;} 253 remote-control{COLON} { LEXOUT(("v(%s) ", yytext)); return VAR_REMOTE_CONTROL;} 254 control-enable{COLON} { LEXOUT(("v(%s) ", yytext)); return VAR_CONTROL_ENABLE;} 255 control-interface{COLON} { LEXOUT(("v(%s) ", yytext)); return VAR_CONTROL_INTERFACE;} 256 control-port{COLON} { LEXOUT(("v(%s) ", yytext)); return VAR_CONTROL_PORT;} 257 server-key-file{COLON} { LEXOUT(("v(%s) ", yytext)); return VAR_SERVER_KEY_FILE;} 258 server-cert-file{COLON} { LEXOUT(("v(%s) ", yytext)); return VAR_SERVER_CERT_FILE;} 259 control-key-file{COLON} { LEXOUT(("v(%s) ", yytext)); return VAR_CONTROL_KEY_FILE;} 260 control-cert-file{COLON} { LEXOUT(("v(%s) ", yytext)); return VAR_CONTROL_CERT_FILE;} 261 AXFR { LEXOUT(("v(%s) ", yytext)); return VAR_AXFR;} 262 UDP { LEXOUT(("v(%s) ", yytext)); return VAR_UDP;} 263 rrl-size{COLON} { LEXOUT(("v(%s) ", yytext)); return VAR_RRL_SIZE;} 264 rrl-ratelimit{COLON} { LEXOUT(("v(%s) ", yytext)); return VAR_RRL_RATELIMIT;} 265 rrl-slip{COLON} { LEXOUT(("v(%s) ", yytext)); return VAR_RRL_SLIP;} 266 rrl-ipv4-prefix-length{COLON} { LEXOUT(("v(%s) ", yytext)); return VAR_RRL_IPV4_PREFIX_LENGTH;} 267 rrl-ipv6-prefix-length{COLON} { LEXOUT(("v(%s) ", yytext)); return VAR_RRL_IPV6_PREFIX_LENGTH;} 268 rrl-whitelist-ratelimit{COLON} { LEXOUT(("v(%s) ", yytext)); return VAR_RRL_WHITELIST_RATELIMIT;} 269 rrl-whitelist{COLON} { LEXOUT(("v(%s) ", yytext)); return VAR_RRL_WHITELIST;} 270 zonefiles-check{COLON} { LEXOUT(("v(%s) ", yytext)); return VAR_ZONEFILES_CHECK;} 271 zonefiles-write{COLON} { LEXOUT(("v(%s) ", yytext)); return VAR_ZONEFILES_WRITE;} 272 dnstap{COLON} { LEXOUT(("v(%s) ", yytext)); return VAR_DNSTAP;} 273 dnstap-enable{COLON} { LEXOUT(("v(%s) ", yytext)); return VAR_DNSTAP_ENABLE;} 274 dnstap-socket-path{COLON} { LEXOUT(("v(%s) ", yytext)); return VAR_DNSTAP_SOCKET_PATH; } 275 dnstap-ip{COLON} { LEXOUT(("v(%s) ", yytext)); return VAR_DNSTAP_IP; } 276 dnstap-tls{COLON} { LEXOUT(("v(%s) ", yytext)); return VAR_DNSTAP_TLS; } 277 dnstap-tls-server-name{COLON} { LEXOUT(("v(%s) ", yytext)); return VAR_DNSTAP_TLS_SERVER_NAME; } 278 dnstap-tls-cert-bundle{COLON} { LEXOUT(("v(%s) ", yytext)); return VAR_DNSTAP_TLS_CERT_BUNDLE; } 279 dnstap-tls-client-key-file{COLON} { LEXOUT(("v(%s) ", yytext)); return VAR_DNSTAP_TLS_CLIENT_KEY_FILE; } 280 dnstap-tls-client-cert-file{COLON} { LEXOUT(("v(%s) ", yytext)); return VAR_DNSTAP_TLS_CLIENT_CERT_FILE; } 281 dnstap-send-identity{COLON} { LEXOUT(("v(%s) ", yytext)); return VAR_DNSTAP_SEND_IDENTITY; } 282 dnstap-send-version{COLON} { LEXOUT(("v(%s) ", yytext)); return VAR_DNSTAP_SEND_VERSION; } 283 dnstap-identity{COLON} { LEXOUT(("v(%s) ", yytext)); return VAR_DNSTAP_IDENTITY; } 284 dnstap-version{COLON} { LEXOUT(("v(%s) ", yytext)); return VAR_DNSTAP_VERSION; } 285 dnstap-log-auth-query-messages{COLON} { LEXOUT(("v(%s) ", yytext)); return VAR_DNSTAP_LOG_AUTH_QUERY_MESSAGES; } 286 dnstap-log-auth-response-messages{COLON} { LEXOUT(("v(%s) ", yytext)); return VAR_DNSTAP_LOG_AUTH_RESPONSE_MESSAGES; } 287 log-time-ascii{COLON} { LEXOUT(("v(%s) ", yytext)); return VAR_LOG_TIME_ASCII;} 288 round-robin{COLON} { LEXOUT(("v(%s) ", yytext)); return VAR_ROUND_ROBIN;} 289 minimal-responses{COLON} { LEXOUT(("v(%s) ", yytext)); return VAR_MINIMAL_RESPONSES;} 290 confine-to-zone{COLON} { LEXOUT(("v(%s) ", yytext)); return VAR_CONFINE_TO_ZONE;} 291 refuse-any{COLON} { LEXOUT(("v(%s) ", yytext)); return VAR_REFUSE_ANY;} 292 max-refresh-time{COLON} { LEXOUT(("v(%s) ", yytext)); return VAR_MAX_REFRESH_TIME;} 293 min-refresh-time{COLON} { LEXOUT(("v(%s) ", yytext)); return VAR_MIN_REFRESH_TIME;} 294 max-retry-time{COLON} { LEXOUT(("v(%s) ", yytext)); return VAR_MAX_RETRY_TIME;} 295 min-retry-time{COLON} { LEXOUT(("v(%s) ", yytext)); return VAR_MIN_RETRY_TIME;} 296 min-expire-time{COLON} { LEXOUT(("v(%s) ", yytext)); return VAR_MIN_EXPIRE_TIME;} 297 store-ixfr{COLON} { LEXOUT(("v(%s) ", yytext)); return VAR_STORE_IXFR;} 298 ixfr-size{COLON} { LEXOUT(("v(%s) ", yytext)); return VAR_IXFR_SIZE;} 299 ixfr-number{COLON} { LEXOUT(("v(%s) ", yytext)); return VAR_IXFR_NUMBER;} 300 create-ixfr{COLON} { LEXOUT(("v(%s) ", yytext)); return VAR_CREATE_IXFR;} 301 multi-master-check{COLON} { LEXOUT(("v(%s) ", yytext)); return VAR_MULTI_MASTER_CHECK;} 302 tls-service-key{COLON} { LEXOUT(("v(%s) ", yytext)); return VAR_TLS_SERVICE_KEY;} 303 tls-service-ocsp{COLON} { LEXOUT(("v(%s) ", yytext)); return VAR_TLS_SERVICE_OCSP;} 304 tls-service-pem{COLON} { LEXOUT(("v(%s) ", yytext)); return VAR_TLS_SERVICE_PEM;} 305 tls-port{COLON} { LEXOUT(("v(%s) ", yytext)); return VAR_TLS_PORT;} 306 tls-cert-bundle{COLON} { LEXOUT(("v(%s) ", yytext)); return VAR_TLS_CERT_BUNDLE; } 307 proxy-protocol-port{COLON} { LEXOUT(("v(%s) ", yytext)); return VAR_PROXY_PROTOCOL_PORT; } 308 answer-cookie{COLON} { LEXOUT(("v(%s) ", yytext)); return VAR_ANSWER_COOKIE;} 309 cookie-secret{COLON} { LEXOUT(("v(%s) ", yytext)); return VAR_COOKIE_SECRET;} 310 cookie-secret-file{COLON} { LEXOUT(("v(%s) ", yytext)); return VAR_COOKIE_SECRET_FILE;} 311 xfrd-tcp-max{COLON} { LEXOUT(("v(%s) ", yytext)); return VAR_XFRD_TCP_MAX;} 312 xfrd-tcp-pipeline{COLON} { LEXOUT(("v(%s) ", yytext)); return VAR_XFRD_TCP_PIPELINE;} 313 verify{COLON} { LEXOUT(("v(%s) ", yytext)); return VAR_VERIFY; } 314 enable{COLON} { LEXOUT(("v(%s) ", yytext)); return VAR_ENABLE; } 315 verify-zone{COLON} { LEXOUT(("v(%s) ", yytext)); return VAR_VERIFY_ZONE; } 316 verify-zones{COLON} { LEXOUT(("v(%s) ", yytext)); return VAR_VERIFY_ZONES; } 317 verifier{COLON} { LEXOUT(("v(%s) ", yytext)); return VAR_VERIFIER; } 318 verifier-count{COLON} { LEXOUT(("v(%s) ", yytext)); return VAR_VERIFIER_COUNT; } 319 verifier-feed-zone{COLON} { LEXOUT(("v(%s) ", yytext)); return VAR_VERIFIER_FEED_ZONE; } 320 verifier-timeout{COLON} { LEXOUT(("v(%s) ", yytext)); return VAR_VERIFIER_TIMEOUT; } 321 {NEWLINE} { LEXOUT(("NL\n")); cfg_parser->line++;} 322 323 servers={UNQUOTEDLETTER}* { 324 yyless(yyleng - (yyleng - 8)); 325 LEXOUT(("v(%s) ", yytext)); 326 return VAR_SERVERS; 327 } 328 bindtodevice={UNQUOTEDLETTER}* { 329 yyless(yyleng - (yyleng - 13)); 330 LEXOUT(("v(%s) ", yytext)); 331 return VAR_BINDTODEVICE; 332 } 333 setfib={UNQUOTEDLETTER}* { 334 yyless(yyleng - (yyleng - 7)); 335 LEXOUT(("v(%s) ", yytext)); 336 return VAR_SETFIB; 337 } 338 339 cpu-affinity{COLON} { LEXOUT(("v(%s) ", yytext)); return VAR_CPU_AFFINITY; } 340 xfrd-cpu-affinity{COLON} { LEXOUT(("v(%s) ", yytext)); return VAR_XFRD_CPU_AFFINITY; } 341 server-[1-9][0-9]*-cpu-affinity{COLON} { 342 char *str = yytext; 343 LEXOUT(("v(%s) ", yytext)); 344 /* Skip server- */ 345 while (*str != '\0' && (*str < '0' || *str > '9')) { 346 str++; 347 } 348 c_lval.llng = strtoll(str, NULL, 10); 349 return VAR_SERVER_CPU_AFFINITY; 350 } 351 352 /* Quoted strings. Strip leading and ending quotes */ 353 \" { BEGIN(quotedstring); LEXOUT(("QS ")); } 354 <quotedstring><<EOF>> { 355 c_error("EOF inside quoted string"); 356 BEGIN(INITIAL); 357 } 358 <quotedstring>{ANY}* { LEXOUT(("STR(%s) ", yytext)); yymore(); } 359 <quotedstring>\n { cfg_parser->line++; yymore(); } 360 <quotedstring>\" { 361 LEXOUT(("QE ")); 362 BEGIN(INITIAL); 363 yytext[yyleng - 1] = '\0'; 364 c_lval.str = region_strdup(cfg_parser->opt->region, yytext); 365 return STRING; 366 } 367 368 /* include: directive */ 369 include{COLON} { LEXOUT(("v(%s) ", yytext)); BEGIN(include); } 370 <include><<EOF>> { 371 c_error("EOF inside include directive"); 372 BEGIN(INITIAL); 373 } 374 <include>{SPACE}* { LEXOUT(("ISP ")); /* ignore */ } 375 <include>{NEWLINE} { LEXOUT(("NL\n")); cfg_parser->line++;} 376 <include>\" { LEXOUT(("IQS ")); BEGIN(include_quoted); } 377 <include>{UNQUOTEDLETTER}* { 378 LEXOUT(("Iunquotedstr(%s) ", yytext)); 379 config_start_include_glob(yytext); 380 BEGIN(INITIAL); 381 } 382 <include_quoted><<EOF>> { 383 c_error("EOF inside quoted string"); 384 BEGIN(INITIAL); 385 } 386 <include_quoted>{ANY}* { LEXOUT(("ISTR(%s) ", yytext)); yymore(); } 387 <include_quoted>{NEWLINE} { cfg_parser->line++; yymore(); } 388 <include_quoted>\" { 389 LEXOUT(("IQE ")); 390 yytext[yyleng - 1] = '\0'; 391 config_start_include_glob(yytext); 392 BEGIN(INITIAL); 393 } 394 <INITIAL><<EOF>> { 395 yy_set_bol(1); /* Set beginning of line, so "^" rules match. */ 396 if (!config_include_stack) { 397 yyterminate(); 398 } else { 399 fclose(yyin); 400 config_end_include(); 401 } 402 } 403 404 {UNQUOTEDLETTER}* { LEXOUT(("unquotedstr(%s) ", yytext)); 405 c_lval.str = region_strdup(cfg_parser->opt->region, yytext); return STRING; } 406 407 %% 408