configlexer.lex revision 307729
1255736Sdavidch%{
2296071Sdavidcs/*
3255736Sdavidch * configlexer.lex - lexical analyzer for unbound config file
4255736Sdavidch *
5255736Sdavidch * Copyright (c) 2001-2006, NLnet Labs. All rights reserved
6255736Sdavidch *
7255736Sdavidch * See LICENSE for the license.
8255736Sdavidch *
9255736Sdavidch */
10255736Sdavidch#include "config.h"
11255736Sdavidch
12255736Sdavidch/* because flex keeps having sign-unsigned compare problems that are unfixed*/
13255736Sdavidch#pragma GCC diagnostic ignored "-Wsign-compare"
14296071Sdavidcs
15255736Sdavidch#include <ctype.h>
16255736Sdavidch#include <string.h>
17255736Sdavidch#include <strings.h>
18255736Sdavidch#ifdef HAVE_GLOB_H
19255736Sdavidch# include <glob.h>
20255736Sdavidch#endif
21255736Sdavidch
22255736Sdavidch#include "util/config_file.h"
23255736Sdavidch#include "configparser.h"
24255736Sdavidchvoid ub_c_error(const char *message);
25255736Sdavidch
26255736Sdavidch#if 0
27255736Sdavidch#define LEXOUT(s)  printf s /* used ONLY when debugging */
28255736Sdavidch#else
29255736Sdavidch#define LEXOUT(s)
30255736Sdavidch#endif
31296071Sdavidcs
32255736Sdavidch/** avoid warning in about fwrite return value */
33255736Sdavidch#define ECHO ub_c_error_msg("syntax error at text: %s", ub_c_text)
34255736Sdavidch
35255736Sdavidch/** A parser variable, this is a statement in the config file which is
36255736Sdavidch * of the form variable: value1 value2 ...  nargs is the number of values. */
37255736Sdavidch#define YDVAR(nargs, var) \
38255736Sdavidch	num_args=(nargs); \
39255736Sdavidch	LEXOUT(("v(%s%d) ", ub_c_text, num_args)); \
40255736Sdavidch	if(num_args > 0) { BEGIN(val); } \
41255736Sdavidch	return (var);
42255736Sdavidch
43255736Sdavidchstruct inc_state {
44255736Sdavidch	char* filename;
45255736Sdavidch	int line;
46255736Sdavidch	YY_BUFFER_STATE buffer;
47255736Sdavidch	struct inc_state* next;
48255736Sdavidch};
49255736Sdavidchstatic struct inc_state* config_include_stack = NULL;
50255736Sdavidchstatic int inc_depth = 0;
51255736Sdavidchstatic int inc_prev = 0;
52255736Sdavidchstatic int num_args = 0;
53255736Sdavidch
54255736Sdavidchvoid init_cfg_parse(void)
55255736Sdavidch{
56255736Sdavidch	config_include_stack = NULL;
57255736Sdavidch	inc_depth = 0;
58255736Sdavidch	inc_prev = 0;
59255736Sdavidch	num_args = 0;
60255736Sdavidch}
61255736Sdavidch
62255736Sdavidchstatic void config_start_include(const char* filename)
63255736Sdavidch{
64255736Sdavidch	FILE *input;
65255736Sdavidch	struct inc_state* s;
66255736Sdavidch	char* nm;
67255736Sdavidch	if(inc_depth++ > 100000) {
68255736Sdavidch		ub_c_error_msg("too many include files");
69255736Sdavidch		return;
70255736Sdavidch	}
71255736Sdavidch	if(*filename == '\0') {
72255736Sdavidch		ub_c_error_msg("empty include file name");
73255736Sdavidch		return;
74255736Sdavidch	}
75255736Sdavidch	s = (struct inc_state*)malloc(sizeof(*s));
76255736Sdavidch	if(!s) {
77255736Sdavidch		ub_c_error_msg("include %s: malloc failure", filename);
78255736Sdavidch		return;
79255736Sdavidch	}
80255736Sdavidch	if(cfg_parser->chroot && strncmp(filename, cfg_parser->chroot,
81255736Sdavidch		strlen(cfg_parser->chroot)) == 0) {
82255736Sdavidch		filename += strlen(cfg_parser->chroot);
83255736Sdavidch	}
84255736Sdavidch	nm = strdup(filename);
85255736Sdavidch	if(!nm) {
86255736Sdavidch		ub_c_error_msg("include %s: strdup failure", filename);
87255736Sdavidch		free(s);
88255736Sdavidch		return;
89255736Sdavidch	}
90255736Sdavidch	input = fopen(filename, "r");
91255736Sdavidch	if(!input) {
92255736Sdavidch		ub_c_error_msg("cannot open include file '%s': %s",
93255736Sdavidch			filename, strerror(errno));
94255736Sdavidch		free(s);
95255736Sdavidch		free(nm);
96255736Sdavidch		return;
97255736Sdavidch	}
98255736Sdavidch	LEXOUT(("switch_to_include_file(%s)\n", filename));
99255736Sdavidch	s->filename = cfg_parser->filename;
100255736Sdavidch	s->line = cfg_parser->line;
101255736Sdavidch	s->buffer = YY_CURRENT_BUFFER;
102255736Sdavidch	s->next = config_include_stack;
103255736Sdavidch	config_include_stack = s;
104255736Sdavidch	cfg_parser->filename = nm;
105255736Sdavidch	cfg_parser->line = 1;
106255736Sdavidch	yy_switch_to_buffer(yy_create_buffer(input, YY_BUF_SIZE));
107255736Sdavidch}
108255736Sdavidch
109255736Sdavidchstatic void config_start_include_glob(const char* filename)
110255736Sdavidch{
111255736Sdavidch
112255736Sdavidch	/* check for wildcards */
113255736Sdavidch#ifdef HAVE_GLOB
114255736Sdavidch	glob_t g;
115255736Sdavidch	size_t i;
116255736Sdavidch	int r, flags;
117255736Sdavidch	if(!(!strchr(filename, '*') && !strchr(filename, '?') && !strchr(filename, '[') &&
118255736Sdavidch		!strchr(filename, '{') && !strchr(filename, '~'))) {
119255736Sdavidch		flags = 0
120255736Sdavidch#ifdef GLOB_ERR
121255736Sdavidch			| GLOB_ERR
122255736Sdavidch#endif
123255736Sdavidch#ifdef GLOB_NOSORT
124255736Sdavidch			| GLOB_NOSORT
125255736Sdavidch#endif
126255736Sdavidch#ifdef GLOB_BRACE
127255736Sdavidch			| GLOB_BRACE
128255736Sdavidch#endif
129255736Sdavidch#ifdef GLOB_TILDE
130255736Sdavidch			| GLOB_TILDE
131255736Sdavidch#endif
132255736Sdavidch		;
133255736Sdavidch		memset(&g, 0, sizeof(g));
134255736Sdavidch		if(cfg_parser->chroot && strncmp(filename, cfg_parser->chroot,
135296071Sdavidcs			strlen(cfg_parser->chroot)) == 0) {
136296071Sdavidcs			filename += strlen(cfg_parser->chroot);
137296071Sdavidcs		}
138296071Sdavidcs		r = glob(filename, flags, NULL, &g);
139255736Sdavidch		if(r) {
140255736Sdavidch			/* some error */
141255736Sdavidch			globfree(&g);
142255736Sdavidch			if(r == GLOB_NOMATCH)
143255736Sdavidch				return; /* no matches for pattern */
144255736Sdavidch			config_start_include(filename); /* let original deal with it */
145255736Sdavidch			return;
146255736Sdavidch		}
147255736Sdavidch		/* process files found, if any */
148255736Sdavidch		for(i=0; i<(size_t)g.gl_pathc; i++) {
149255736Sdavidch			config_start_include(g.gl_pathv[i]);
150255736Sdavidch		}
151255736Sdavidch		globfree(&g);
152255736Sdavidch		return;
153255736Sdavidch	}
154255736Sdavidch#endif /* HAVE_GLOB */
155255736Sdavidch
156255736Sdavidch	config_start_include(filename);
157255736Sdavidch}
158255736Sdavidch
159255736Sdavidchstatic void config_end_include(void)
160255736Sdavidch{
161255736Sdavidch	struct inc_state* s = config_include_stack;
162255736Sdavidch	--inc_depth;
163255736Sdavidch	if(!s) return;
164255736Sdavidch	free(cfg_parser->filename);
165255736Sdavidch	cfg_parser->filename = s->filename;
166255736Sdavidch	cfg_parser->line = s->line;
167255736Sdavidch	yy_delete_buffer(YY_CURRENT_BUFFER);
168255736Sdavidch	yy_switch_to_buffer(s->buffer);
169255736Sdavidch	config_include_stack = s->next;
170255736Sdavidch	free(s);
171255736Sdavidch}
172255736Sdavidch
173255736Sdavidch#ifndef yy_set_bol /* compat definition, for flex 2.4.6 */
174255736Sdavidch#define yy_set_bol(at_bol) \
175255736Sdavidch        { \
176255736Sdavidch	        if ( ! yy_current_buffer ) \
177255736Sdavidch	                yy_current_buffer = yy_create_buffer( ub_c_in, YY_BUF_SIZE ); \
178255736Sdavidch	        yy_current_buffer->yy_ch_buf[0] = ((at_bol)?'\n':' '); \
179255736Sdavidch        }
180255736Sdavidch#endif
181255736Sdavidch
182255736Sdavidch%}
183255736Sdavidch%option noinput
184255736Sdavidch%option nounput
185255736Sdavidch%{
186255736Sdavidch#ifndef YY_NO_UNPUT
187255736Sdavidch#define YY_NO_UNPUT 1
188255736Sdavidch#endif
189255736Sdavidch#ifndef YY_NO_INPUT
190255736Sdavidch#define YY_NO_INPUT 1
191255736Sdavidch#endif
192255736Sdavidch%}
193255736Sdavidch
194255736SdavidchSPACE   [ \t]
195255736SdavidchLETTER  [a-zA-Z]
196255736SdavidchUNQUOTEDLETTER [^\'\"\n\r \t\\]|\\.
197255736SdavidchUNQUOTEDLETTER_NOCOLON [^\:\'\"\n\r \t\\]|\\.
198255736SdavidchNEWLINE [\r\n]
199255736SdavidchCOMMENT \#
200255736SdavidchCOLON 	\:
201255736SdavidchDQANY     [^\"\n\r\\]|\\.
202255736SdavidchSQANY     [^\'\n\r\\]|\\.
203255736Sdavidch
204255736Sdavidch%x	quotedstring singlequotedstr include include_quoted val
205255736Sdavidch
206255736Sdavidch%%
207255736Sdavidch<INITIAL,val>{SPACE}*	{
208255736Sdavidch	LEXOUT(("SP ")); /* ignore */ }
209255736Sdavidch<INITIAL,val>{SPACE}*{COMMENT}.*	{
210255736Sdavidch	/* note that flex makes the longest match and '.' is any but not nl */
211255736Sdavidch	LEXOUT(("comment(%s) ", ub_c_text)); /* ignore */ }
212255736Sdavidchserver{COLON}			{ YDVAR(0, VAR_SERVER) }
213255736Sdavidchqname-minimisation{COLON}	{ YDVAR(1, VAR_QNAME_MINIMISATION) }
214255736Sdavidchnum-threads{COLON}		{ YDVAR(1, VAR_NUM_THREADS) }
215255736Sdavidchverbosity{COLON}		{ YDVAR(1, VAR_VERBOSITY) }
216255736Sdavidchport{COLON}			{ YDVAR(1, VAR_PORT) }
217255736Sdavidchoutgoing-range{COLON}		{ YDVAR(1, VAR_OUTGOING_RANGE) }
218255736Sdavidchoutgoing-port-permit{COLON}	{ YDVAR(1, VAR_OUTGOING_PORT_PERMIT) }
219255736Sdavidchoutgoing-port-avoid{COLON}	{ YDVAR(1, VAR_OUTGOING_PORT_AVOID) }
220255736Sdavidchoutgoing-num-tcp{COLON}		{ YDVAR(1, VAR_OUTGOING_NUM_TCP) }
221255736Sdavidchincoming-num-tcp{COLON}		{ YDVAR(1, VAR_INCOMING_NUM_TCP) }
222255736Sdavidchdo-ip4{COLON}			{ YDVAR(1, VAR_DO_IP4) }
223255736Sdavidchdo-ip6{COLON}			{ YDVAR(1, VAR_DO_IP6) }
224255736Sdavidchprefer-ip6{COLON}		{ YDVAR(1, VAR_PREFER_IP6) }
225255736Sdavidchdo-udp{COLON}			{ YDVAR(1, VAR_DO_UDP) }
226255736Sdavidchdo-tcp{COLON}			{ YDVAR(1, VAR_DO_TCP) }
227255736Sdavidchtcp-upstream{COLON}		{ YDVAR(1, VAR_TCP_UPSTREAM) }
228255736Sdavidchtcp-mss{COLON}			{ YDVAR(1, VAR_TCP_MSS) }
229255736Sdavidchoutgoing-tcp-mss{COLON}		{ YDVAR(1, VAR_OUTGOING_TCP_MSS) }
230255736Sdavidchssl-upstream{COLON}		{ YDVAR(1, VAR_SSL_UPSTREAM) }
231255736Sdavidchssl-service-key{COLON}		{ YDVAR(1, VAR_SSL_SERVICE_KEY) }
232255736Sdavidchssl-service-pem{COLON}		{ YDVAR(1, VAR_SSL_SERVICE_PEM) }
233255736Sdavidchssl-port{COLON}			{ YDVAR(1, VAR_SSL_PORT) }
234255736Sdavidchdo-daemonize{COLON}		{ YDVAR(1, VAR_DO_DAEMONIZE) }
235255736Sdavidchinterface{COLON}		{ YDVAR(1, VAR_INTERFACE) }
236255736Sdavidchip-address{COLON}		{ YDVAR(1, VAR_INTERFACE) }
237255736Sdavidchoutgoing-interface{COLON}	{ YDVAR(1, VAR_OUTGOING_INTERFACE) }
238255736Sdavidchinterface-automatic{COLON}	{ YDVAR(1, VAR_INTERFACE_AUTOMATIC) }
239255736Sdavidchso-rcvbuf{COLON}		{ YDVAR(1, VAR_SO_RCVBUF) }
240255736Sdavidchso-sndbuf{COLON}		{ YDVAR(1, VAR_SO_SNDBUF) }
241296071Sdavidcsso-reuseport{COLON}		{ YDVAR(1, VAR_SO_REUSEPORT) }
242296071Sdavidcsip-transparent{COLON}		{ YDVAR(1, VAR_IP_TRANSPARENT) }
243255736Sdavidchip-freebind{COLON}		{ YDVAR(1, VAR_IP_FREEBIND) }
244255736Sdavidchchroot{COLON}			{ YDVAR(1, VAR_CHROOT) }
245255736Sdavidchusername{COLON}			{ YDVAR(1, VAR_USERNAME) }
246255736Sdavidchdirectory{COLON}		{ YDVAR(1, VAR_DIRECTORY) }
247255736Sdavidchlogfile{COLON}			{ YDVAR(1, VAR_LOGFILE) }
248255736Sdavidchpidfile{COLON}			{ YDVAR(1, VAR_PIDFILE) }
249255736Sdavidchroot-hints{COLON}		{ YDVAR(1, VAR_ROOT_HINTS) }
250255736Sdavidchedns-buffer-size{COLON}		{ YDVAR(1, VAR_EDNS_BUFFER_SIZE) }
251255736Sdavidchmsg-buffer-size{COLON}		{ YDVAR(1, VAR_MSG_BUFFER_SIZE) }
252255736Sdavidchmsg-cache-size{COLON}		{ YDVAR(1, VAR_MSG_CACHE_SIZE) }
253255736Sdavidchmsg-cache-slabs{COLON}		{ YDVAR(1, VAR_MSG_CACHE_SLABS) }
254255736Sdavidchrrset-cache-size{COLON}		{ YDVAR(1, VAR_RRSET_CACHE_SIZE) }
255255736Sdavidchrrset-cache-slabs{COLON}	{ YDVAR(1, VAR_RRSET_CACHE_SLABS) }
256255736Sdavidchcache-max-ttl{COLON}     	{ YDVAR(1, VAR_CACHE_MAX_TTL) }
257255736Sdavidchcache-max-negative-ttl{COLON}   { YDVAR(1, VAR_CACHE_MAX_NEGATIVE_TTL) }
258255736Sdavidchcache-min-ttl{COLON}     	{ YDVAR(1, VAR_CACHE_MIN_TTL) }
259255736Sdavidchinfra-host-ttl{COLON}		{ YDVAR(1, VAR_INFRA_HOST_TTL) }
260255736Sdavidchinfra-lame-ttl{COLON}		{ YDVAR(1, VAR_INFRA_LAME_TTL) }
261255736Sdavidchinfra-cache-slabs{COLON}	{ YDVAR(1, VAR_INFRA_CACHE_SLABS) }
262255736Sdavidchinfra-cache-numhosts{COLON}	{ YDVAR(1, VAR_INFRA_CACHE_NUMHOSTS) }
263255736Sdavidchinfra-cache-lame-size{COLON}	{ YDVAR(1, VAR_INFRA_CACHE_LAME_SIZE) }
264255736Sdavidchinfra-cache-min-rtt{COLON}	{ YDVAR(1, VAR_INFRA_CACHE_MIN_RTT) }
265255736Sdavidchnum-queries-per-thread{COLON}	{ YDVAR(1, VAR_NUM_QUERIES_PER_THREAD) }
266255736Sdavidchjostle-timeout{COLON}		{ YDVAR(1, VAR_JOSTLE_TIMEOUT) }
267255736Sdavidchdelay-close{COLON}		{ YDVAR(1, VAR_DELAY_CLOSE) }
268255736Sdavidchtarget-fetch-policy{COLON}	{ YDVAR(1, VAR_TARGET_FETCH_POLICY) }
269255736Sdavidchharden-short-bufsize{COLON}	{ YDVAR(1, VAR_HARDEN_SHORT_BUFSIZE) }
270255736Sdavidchharden-large-queries{COLON}	{ YDVAR(1, VAR_HARDEN_LARGE_QUERIES) }
271255736Sdavidchharden-glue{COLON}		{ YDVAR(1, VAR_HARDEN_GLUE) }
272255736Sdavidchharden-dnssec-stripped{COLON}	{ YDVAR(1, VAR_HARDEN_DNSSEC_STRIPPED) }
273255736Sdavidchharden-below-nxdomain{COLON}	{ YDVAR(1, VAR_HARDEN_BELOW_NXDOMAIN) }
274255736Sdavidchharden-referral-path{COLON}	{ YDVAR(1, VAR_HARDEN_REFERRAL_PATH) }
275255736Sdavidchharden-algo-downgrade{COLON}	{ YDVAR(1, VAR_HARDEN_ALGO_DOWNGRADE) }
276255736Sdavidchuse-caps-for-id{COLON}		{ YDVAR(1, VAR_USE_CAPS_FOR_ID) }
277255736Sdavidchcaps-whitelist{COLON}		{ YDVAR(1, VAR_CAPS_WHITELIST) }
278255736Sdavidchunwanted-reply-threshold{COLON}	{ YDVAR(1, VAR_UNWANTED_REPLY_THRESHOLD) }
279255736Sdavidchprivate-address{COLON}		{ YDVAR(1, VAR_PRIVATE_ADDRESS) }
280255736Sdavidchprivate-domain{COLON}		{ YDVAR(1, VAR_PRIVATE_DOMAIN) }
281255736Sdavidchprefetch-key{COLON}		{ YDVAR(1, VAR_PREFETCH_KEY) }
282255736Sdavidchprefetch{COLON}			{ YDVAR(1, VAR_PREFETCH) }
283255736Sdavidchstub-zone{COLON}		{ YDVAR(0, VAR_STUB_ZONE) }
284255736Sdavidchname{COLON}			{ YDVAR(1, VAR_NAME) }
285255736Sdavidchstub-addr{COLON}		{ YDVAR(1, VAR_STUB_ADDR) }
286255736Sdavidchstub-host{COLON}		{ YDVAR(1, VAR_STUB_HOST) }
287255736Sdavidchstub-prime{COLON}		{ YDVAR(1, VAR_STUB_PRIME) }
288255736Sdavidchstub-first{COLON}		{ YDVAR(1, VAR_STUB_FIRST) }
289255736Sdavidchforward-zone{COLON}		{ YDVAR(0, VAR_FORWARD_ZONE) }
290255736Sdavidchforward-addr{COLON}		{ YDVAR(1, VAR_FORWARD_ADDR) }
291255736Sdavidchforward-host{COLON}		{ YDVAR(1, VAR_FORWARD_HOST) }
292255736Sdavidchforward-first{COLON}		{ YDVAR(1, VAR_FORWARD_FIRST) }
293255736Sdavidchdo-not-query-address{COLON}	{ YDVAR(1, VAR_DO_NOT_QUERY_ADDRESS) }
294255736Sdavidchdo-not-query-localhost{COLON}	{ YDVAR(1, VAR_DO_NOT_QUERY_LOCALHOST) }
295255736Sdavidchaccess-control{COLON}		{ YDVAR(2, VAR_ACCESS_CONTROL) }
296255736Sdavidchhide-identity{COLON}		{ YDVAR(1, VAR_HIDE_IDENTITY) }
297255736Sdavidchhide-version{COLON}		{ YDVAR(1, VAR_HIDE_VERSION) }
298255736Sdavidchidentity{COLON}			{ YDVAR(1, VAR_IDENTITY) }
299255736Sdavidchversion{COLON}			{ YDVAR(1, VAR_VERSION) }
300255736Sdavidchmodule-config{COLON}     	{ YDVAR(1, VAR_MODULE_CONF) }
301255736Sdavidchdlv-anchor{COLON}		{ YDVAR(1, VAR_DLV_ANCHOR) }
302255736Sdavidchdlv-anchor-file{COLON}		{ YDVAR(1, VAR_DLV_ANCHOR_FILE) }
303255736Sdavidchtrust-anchor-file{COLON}	{ YDVAR(1, VAR_TRUST_ANCHOR_FILE) }
304255736Sdavidchauto-trust-anchor-file{COLON}	{ YDVAR(1, VAR_AUTO_TRUST_ANCHOR_FILE) }
305255736Sdavidchtrusted-keys-file{COLON}	{ YDVAR(1, VAR_TRUSTED_KEYS_FILE) }
306255736Sdavidchtrust-anchor{COLON}		{ YDVAR(1, VAR_TRUST_ANCHOR) }
307255736Sdavidchval-override-date{COLON}	{ YDVAR(1, VAR_VAL_OVERRIDE_DATE) }
308255736Sdavidchval-sig-skew-min{COLON}		{ YDVAR(1, VAR_VAL_SIG_SKEW_MIN) }
309255736Sdavidchval-sig-skew-max{COLON}		{ YDVAR(1, VAR_VAL_SIG_SKEW_MAX) }
310255736Sdavidchval-bogus-ttl{COLON}		{ YDVAR(1, VAR_BOGUS_TTL) }
311255736Sdavidchval-clean-additional{COLON}	{ YDVAR(1, VAR_VAL_CLEAN_ADDITIONAL) }
312255736Sdavidchval-permissive-mode{COLON}	{ YDVAR(1, VAR_VAL_PERMISSIVE_MODE) }
313255736Sdavidchignore-cd-flag{COLON}		{ YDVAR(1, VAR_IGNORE_CD_FLAG) }
314255736Sdavidchval-log-level{COLON}		{ YDVAR(1, VAR_VAL_LOG_LEVEL) }
315255736Sdavidchkey-cache-size{COLON}		{ YDVAR(1, VAR_KEY_CACHE_SIZE) }
316255736Sdavidchkey-cache-slabs{COLON}		{ YDVAR(1, VAR_KEY_CACHE_SLABS) }
317255736Sdavidchneg-cache-size{COLON}		{ YDVAR(1, VAR_NEG_CACHE_SIZE) }
318255736Sdavidchval-nsec3-keysize-iterations{COLON}	{
319255736Sdavidch				  YDVAR(1, VAR_VAL_NSEC3_KEYSIZE_ITERATIONS) }
320255736Sdavidchadd-holddown{COLON}		{ YDVAR(1, VAR_ADD_HOLDDOWN) }
321255736Sdavidchdel-holddown{COLON}		{ YDVAR(1, VAR_DEL_HOLDDOWN) }
322255736Sdavidchkeep-missing{COLON}		{ YDVAR(1, VAR_KEEP_MISSING) }
323255736Sdavidchpermit-small-holddown{COLON}	{ YDVAR(1, VAR_PERMIT_SMALL_HOLDDOWN) }
324255736Sdavidchuse-syslog{COLON}		{ YDVAR(1, VAR_USE_SYSLOG) }
325255736Sdavidchlog-time-ascii{COLON}		{ YDVAR(1, VAR_LOG_TIME_ASCII) }
326255736Sdavidchlog-queries{COLON}		{ YDVAR(1, VAR_LOG_QUERIES) }
327255736Sdavidchlocal-zone{COLON}		{ YDVAR(2, VAR_LOCAL_ZONE) }
328255736Sdavidchlocal-data{COLON}		{ YDVAR(1, VAR_LOCAL_DATA) }
329255736Sdavidchlocal-data-ptr{COLON}		{ YDVAR(1, VAR_LOCAL_DATA_PTR) }
330255736Sdavidchunblock-lan-zones{COLON}	{ YDVAR(1, VAR_UNBLOCK_LAN_ZONES) }
331255736Sdavidchinsecure-lan-zones{COLON}	{ YDVAR(1, VAR_INSECURE_LAN_ZONES) }
332255736Sdavidchstatistics-interval{COLON}	{ YDVAR(1, VAR_STATISTICS_INTERVAL) }
333255736Sdavidchstatistics-cumulative{COLON}	{ YDVAR(1, VAR_STATISTICS_CUMULATIVE) }
334255736Sdavidchextended-statistics{COLON}	{ YDVAR(1, VAR_EXTENDED_STATISTICS) }
335255736Sdavidchremote-control{COLON}		{ YDVAR(0, VAR_REMOTE_CONTROL) }
336255736Sdavidchcontrol-enable{COLON}		{ YDVAR(1, VAR_CONTROL_ENABLE) }
337255736Sdavidchcontrol-interface{COLON}	{ YDVAR(1, VAR_CONTROL_INTERFACE) }
338255736Sdavidchcontrol-port{COLON}		{ YDVAR(1, VAR_CONTROL_PORT) }
339255736Sdavidchcontrol-use-cert{COLON}		{ YDVAR(1, VAR_CONTROL_USE_CERT) }
340255736Sdavidchserver-key-file{COLON}		{ YDVAR(1, VAR_SERVER_KEY_FILE) }
341255736Sdavidchserver-cert-file{COLON}		{ YDVAR(1, VAR_SERVER_CERT_FILE) }
342255736Sdavidchcontrol-key-file{COLON}		{ YDVAR(1, VAR_CONTROL_KEY_FILE) }
343255736Sdavidchcontrol-cert-file{COLON}	{ YDVAR(1, VAR_CONTROL_CERT_FILE) }
344255736Sdavidchpython-script{COLON}		{ YDVAR(1, VAR_PYTHON_SCRIPT) }
345255736Sdavidchpython{COLON}			{ YDVAR(0, VAR_PYTHON) }
346255736Sdavidchdomain-insecure{COLON}		{ YDVAR(1, VAR_DOMAIN_INSECURE) }
347255736Sdavidchminimal-responses{COLON}	{ YDVAR(1, VAR_MINIMAL_RESPONSES) }
348255736Sdavidchrrset-roundrobin{COLON}		{ YDVAR(1, VAR_RRSET_ROUNDROBIN) }
349255736Sdavidchmax-udp-size{COLON}		{ YDVAR(1, VAR_MAX_UDP_SIZE) }
350255736Sdavidchdns64-prefix{COLON}		{ YDVAR(1, VAR_DNS64_PREFIX) }
351255736Sdavidchdns64-synthall{COLON}		{ YDVAR(1, VAR_DNS64_SYNTHALL) }
352255736Sdavidchdefine-tag{COLON}		{ YDVAR(1, VAR_DEFINE_TAG) }
353255736Sdavidchlocal-zone-tag{COLON}		{ YDVAR(2, VAR_LOCAL_ZONE_TAG) }
354255736Sdavidchaccess-control-tag{COLON}	{ YDVAR(2, VAR_ACCESS_CONTROL_TAG) }
355255736Sdavidchaccess-control-tag-action{COLON} { YDVAR(3, VAR_ACCESS_CONTROL_TAG_ACTION) }
356255736Sdavidchaccess-control-tag-data{COLON}	{ YDVAR(3, VAR_ACCESS_CONTROL_TAG_DATA) }
357255736Sdavidchlocal-zone-override{COLON}	{ YDVAR(3, VAR_LOCAL_ZONE_OVERRIDE) }
358255736Sdavidchdnstap{COLON}			{ YDVAR(0, VAR_DNSTAP) }
359255736Sdavidchdnstap-enable{COLON}		{ YDVAR(1, VAR_DNSTAP_ENABLE) }
360255736Sdavidchdnstap-socket-path{COLON}	{ YDVAR(1, VAR_DNSTAP_SOCKET_PATH) }
361255736Sdavidchdnstap-send-identity{COLON}	{ YDVAR(1, VAR_DNSTAP_SEND_IDENTITY) }
362255736Sdavidchdnstap-send-version{COLON}	{ YDVAR(1, VAR_DNSTAP_SEND_VERSION) }
363255736Sdavidchdnstap-identity{COLON}		{ YDVAR(1, VAR_DNSTAP_IDENTITY) }
364255736Sdavidchdnstap-version{COLON}		{ YDVAR(1, VAR_DNSTAP_VERSION) }
365255736Sdavidchdnstap-log-resolver-query-messages{COLON}	{
366255736Sdavidch		YDVAR(1, VAR_DNSTAP_LOG_RESOLVER_QUERY_MESSAGES) }
367255736Sdavidchdnstap-log-resolver-response-messages{COLON}	{
368255736Sdavidch		YDVAR(1, VAR_DNSTAP_LOG_RESOLVER_RESPONSE_MESSAGES) }
369255736Sdavidchdnstap-log-client-query-messages{COLON}		{
370255736Sdavidch		YDVAR(1, VAR_DNSTAP_LOG_CLIENT_QUERY_MESSAGES) }
371255736Sdavidchdnstap-log-client-response-messages{COLON}	{
372255736Sdavidch		YDVAR(1, VAR_DNSTAP_LOG_CLIENT_RESPONSE_MESSAGES) }
373255736Sdavidchdnstap-log-forwarder-query-messages{COLON}	{
374255736Sdavidch		YDVAR(1, VAR_DNSTAP_LOG_FORWARDER_QUERY_MESSAGES) }
375255736Sdavidchdnstap-log-forwarder-response-messages{COLON}	{
376255736Sdavidch		YDVAR(1, VAR_DNSTAP_LOG_FORWARDER_RESPONSE_MESSAGES) }
377255736Sdavidchdisable-dnssec-lame-check{COLON} { YDVAR(1, VAR_DISABLE_DNSSEC_LAME_CHECK) }
378255736Sdavidchratelimit{COLON}		{ YDVAR(1, VAR_RATELIMIT) }
379255736Sdavidchratelimit-slabs{COLON}		{ YDVAR(1, VAR_RATELIMIT_SLABS) }
380255736Sdavidchratelimit-size{COLON}		{ YDVAR(1, VAR_RATELIMIT_SIZE) }
381255736Sdavidchratelimit-for-domain{COLON}	{ YDVAR(2, VAR_RATELIMIT_FOR_DOMAIN) }
382255736Sdavidchratelimit-below-domain{COLON}	{ YDVAR(2, VAR_RATELIMIT_BELOW_DOMAIN) }
383255736Sdavidchratelimit-factor{COLON}		{ YDVAR(1, VAR_RATELIMIT_FACTOR) }
384255736Sdavidch<INITIAL,val>{NEWLINE}		{ LEXOUT(("NL\n")); cfg_parser->line++; }
385255736Sdavidch
386255736Sdavidch	/* Quoted strings. Strip leading and ending quotes */
387255736Sdavidch<val>\"			{ BEGIN(quotedstring); LEXOUT(("QS ")); }
388255736Sdavidch<quotedstring><<EOF>>   {
389255736Sdavidch        ub_c_error("EOF inside quoted string");
390255736Sdavidch	if(--num_args == 0) { BEGIN(INITIAL); }
391255736Sdavidch	else		    { BEGIN(val); }
392255736Sdavidch}
393255736Sdavidch<quotedstring>{DQANY}*  { LEXOUT(("STR(%s) ", ub_c_text)); yymore(); }
394255736Sdavidch<quotedstring>{NEWLINE} { ub_c_error("newline inside quoted string, no end \"");
395255736Sdavidch			  cfg_parser->line++; BEGIN(INITIAL); }
396255736Sdavidch<quotedstring>\" {
397255736Sdavidch        LEXOUT(("QE "));
398255736Sdavidch	if(--num_args == 0) { BEGIN(INITIAL); }
399255736Sdavidch	else		    { BEGIN(val); }
400255736Sdavidch        ub_c_text[ub_c_leng - 1] = '\0';
401255736Sdavidch	ub_c_lval.str = strdup(ub_c_text);
402255736Sdavidch	if(!ub_c_lval.str)
403255736Sdavidch		ub_c_error("out of memory");
404255736Sdavidch        return STRING_ARG;
405255736Sdavidch}
406255736Sdavidch
407255736Sdavidch	/* Single Quoted strings. Strip leading and ending quotes */
408255736Sdavidch<val>\'			{ BEGIN(singlequotedstr); LEXOUT(("SQS ")); }
409255736Sdavidch<singlequotedstr><<EOF>>   {
410255736Sdavidch        ub_c_error("EOF inside quoted string");
411255736Sdavidch	if(--num_args == 0) { BEGIN(INITIAL); }
412255736Sdavidch	else		    { BEGIN(val); }
413255736Sdavidch}
414255736Sdavidch<singlequotedstr>{SQANY}*  { LEXOUT(("STR(%s) ", ub_c_text)); yymore(); }
415255736Sdavidch<singlequotedstr>{NEWLINE} { ub_c_error("newline inside quoted string, no end '");
416255736Sdavidch			     cfg_parser->line++; BEGIN(INITIAL); }
417255736Sdavidch<singlequotedstr>\' {
418        LEXOUT(("SQE "));
419	if(--num_args == 0) { BEGIN(INITIAL); }
420	else		    { BEGIN(val); }
421        ub_c_text[ub_c_leng - 1] = '\0';
422	ub_c_lval.str = strdup(ub_c_text);
423	if(!ub_c_lval.str)
424		ub_c_error("out of memory");
425        return STRING_ARG;
426}
427
428	/* include: directive */
429<INITIAL,val>include{COLON}	{
430	LEXOUT(("v(%s) ", ub_c_text)); inc_prev = YYSTATE; BEGIN(include); }
431<include><<EOF>>	{
432        ub_c_error("EOF inside include directive");
433        BEGIN(inc_prev);
434}
435<include>{SPACE}*	{ LEXOUT(("ISP ")); /* ignore */ }
436<include>{NEWLINE}	{ LEXOUT(("NL\n")); cfg_parser->line++;}
437<include>\"		{ LEXOUT(("IQS ")); BEGIN(include_quoted); }
438<include>{UNQUOTEDLETTER}*	{
439	LEXOUT(("Iunquotedstr(%s) ", ub_c_text));
440	config_start_include_glob(ub_c_text);
441	BEGIN(inc_prev);
442}
443<include_quoted><<EOF>>	{
444        ub_c_error("EOF inside quoted string");
445        BEGIN(inc_prev);
446}
447<include_quoted>{DQANY}*	{ LEXOUT(("ISTR(%s) ", ub_c_text)); yymore(); }
448<include_quoted>{NEWLINE}	{ ub_c_error("newline before \" in include name");
449				  cfg_parser->line++; BEGIN(inc_prev); }
450<include_quoted>\"	{
451	LEXOUT(("IQE "));
452	ub_c_text[ub_c_leng - 1] = '\0';
453	config_start_include_glob(ub_c_text);
454	BEGIN(inc_prev);
455}
456<INITIAL,val><<EOF>>	{
457	LEXOUT(("LEXEOF "));
458	yy_set_bol(1); /* Set beginning of line, so "^" rules match.  */
459	if (!config_include_stack) {
460		yyterminate();
461	} else {
462		fclose(ub_c_in);
463		config_end_include();
464	}
465}
466
467<val>{UNQUOTEDLETTER}*	{ LEXOUT(("unquotedstr(%s) ", ub_c_text));
468			if(--num_args == 0) { BEGIN(INITIAL); }
469			ub_c_lval.str = strdup(ub_c_text); return STRING_ARG; }
470
471{UNQUOTEDLETTER_NOCOLON}*	{
472	ub_c_error_msg("unknown keyword '%s'", ub_c_text);
473	}
474
475<*>.	{
476	ub_c_error_msg("stray '%s'", ub_c_text);
477	}
478
479%%
480