configparser.y revision 269257
1/*
2 * configparser.y -- yacc grammar for unbound configuration files
3 *
4 * Copyright (c) 2001-2006, NLnet Labs. All rights reserved.
5 *
6 * Copyright (c) 2007, NLnet Labs. All rights reserved.
7 *
8 * This software is open source.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 *
14 * Redistributions of source code must retain the above copyright notice,
15 * this list of conditions and the following disclaimer.
16 *
17 * Redistributions in binary form must reproduce the above copyright notice,
18 * this list of conditions and the following disclaimer in the documentation
19 * and/or other materials provided with the distribution.
20 *
21 * Neither the name of the NLNET LABS nor the names of its contributors may
22 * be used to endorse or promote products derived from this software without
23 * specific prior written permission.
24 *
25 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
26 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
27 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
28 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
29 * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
30 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
31 * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
32 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
33 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
34 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
35 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 */
37
38%{
39#include "config.h"
40
41#include <stdarg.h>
42#include <stdio.h>
43#include <string.h>
44#include <stdlib.h>
45#include <assert.h>
46
47#include "util/config_file.h"
48#include "util/net_help.h"
49
50int ub_c_lex(void);
51void ub_c_error(const char *message);
52
53/* these need to be global, otherwise they cannot be used inside yacc */
54extern struct config_parser_state* cfg_parser;
55
56#if 0
57#define OUTYY(s)  printf s /* used ONLY when debugging */
58#else
59#define OUTYY(s)
60#endif
61
62%}
63%union {
64	char*	str;
65};
66
67%token SPACE LETTER NEWLINE COMMENT COLON ANY ZONESTR
68%token <str> STRING_ARG
69%token VAR_SERVER VAR_VERBOSITY VAR_NUM_THREADS VAR_PORT
70%token VAR_OUTGOING_RANGE VAR_INTERFACE
71%token VAR_DO_IP4 VAR_DO_IP6 VAR_DO_UDP VAR_DO_TCP
72%token VAR_CHROOT VAR_USERNAME VAR_DIRECTORY VAR_LOGFILE VAR_PIDFILE
73%token VAR_MSG_CACHE_SIZE VAR_MSG_CACHE_SLABS VAR_NUM_QUERIES_PER_THREAD
74%token VAR_RRSET_CACHE_SIZE VAR_RRSET_CACHE_SLABS VAR_OUTGOING_NUM_TCP
75%token VAR_INFRA_HOST_TTL VAR_INFRA_LAME_TTL VAR_INFRA_CACHE_SLABS
76%token VAR_INFRA_CACHE_NUMHOSTS VAR_INFRA_CACHE_LAME_SIZE VAR_NAME
77%token VAR_STUB_ZONE VAR_STUB_HOST VAR_STUB_ADDR VAR_TARGET_FETCH_POLICY
78%token VAR_HARDEN_SHORT_BUFSIZE VAR_HARDEN_LARGE_QUERIES
79%token VAR_FORWARD_ZONE VAR_FORWARD_HOST VAR_FORWARD_ADDR
80%token VAR_DO_NOT_QUERY_ADDRESS VAR_HIDE_IDENTITY VAR_HIDE_VERSION
81%token VAR_IDENTITY VAR_VERSION VAR_HARDEN_GLUE VAR_MODULE_CONF
82%token VAR_TRUST_ANCHOR_FILE VAR_TRUST_ANCHOR VAR_VAL_OVERRIDE_DATE
83%token VAR_BOGUS_TTL VAR_VAL_CLEAN_ADDITIONAL VAR_VAL_PERMISSIVE_MODE
84%token VAR_INCOMING_NUM_TCP VAR_MSG_BUFFER_SIZE VAR_KEY_CACHE_SIZE
85%token VAR_KEY_CACHE_SLABS VAR_TRUSTED_KEYS_FILE
86%token VAR_VAL_NSEC3_KEYSIZE_ITERATIONS VAR_USE_SYSLOG
87%token VAR_OUTGOING_INTERFACE VAR_ROOT_HINTS VAR_DO_NOT_QUERY_LOCALHOST
88%token VAR_CACHE_MAX_TTL VAR_HARDEN_DNSSEC_STRIPPED VAR_ACCESS_CONTROL
89%token VAR_LOCAL_ZONE VAR_LOCAL_DATA VAR_INTERFACE_AUTOMATIC
90%token VAR_STATISTICS_INTERVAL VAR_DO_DAEMONIZE VAR_USE_CAPS_FOR_ID
91%token VAR_STATISTICS_CUMULATIVE VAR_OUTGOING_PORT_PERMIT
92%token VAR_OUTGOING_PORT_AVOID VAR_DLV_ANCHOR_FILE VAR_DLV_ANCHOR
93%token VAR_NEG_CACHE_SIZE VAR_HARDEN_REFERRAL_PATH VAR_PRIVATE_ADDRESS
94%token VAR_PRIVATE_DOMAIN VAR_REMOTE_CONTROL VAR_CONTROL_ENABLE
95%token VAR_CONTROL_INTERFACE VAR_CONTROL_PORT VAR_SERVER_KEY_FILE
96%token VAR_SERVER_CERT_FILE VAR_CONTROL_KEY_FILE VAR_CONTROL_CERT_FILE
97%token VAR_EXTENDED_STATISTICS VAR_LOCAL_DATA_PTR VAR_JOSTLE_TIMEOUT
98%token VAR_STUB_PRIME VAR_UNWANTED_REPLY_THRESHOLD VAR_LOG_TIME_ASCII
99%token VAR_DOMAIN_INSECURE VAR_PYTHON VAR_PYTHON_SCRIPT VAR_VAL_SIG_SKEW_MIN
100%token VAR_VAL_SIG_SKEW_MAX VAR_CACHE_MIN_TTL VAR_VAL_LOG_LEVEL
101%token VAR_AUTO_TRUST_ANCHOR_FILE VAR_KEEP_MISSING VAR_ADD_HOLDDOWN
102%token VAR_DEL_HOLDDOWN VAR_SO_RCVBUF VAR_EDNS_BUFFER_SIZE VAR_PREFETCH
103%token VAR_PREFETCH_KEY VAR_SO_SNDBUF VAR_SO_REUSEPORT VAR_HARDEN_BELOW_NXDOMAIN
104%token VAR_IGNORE_CD_FLAG VAR_LOG_QUERIES VAR_TCP_UPSTREAM VAR_SSL_UPSTREAM
105%token VAR_SSL_SERVICE_KEY VAR_SSL_SERVICE_PEM VAR_SSL_PORT VAR_FORWARD_FIRST
106%token VAR_STUB_FIRST VAR_MINIMAL_RESPONSES VAR_RRSET_ROUNDROBIN
107%token VAR_MAX_UDP_SIZE VAR_DELAY_CLOSE VAR_UNBLOCK_LAN_ZONES
108
109%%
110toplevelvars: /* empty */ | toplevelvars toplevelvar ;
111toplevelvar: serverstart contents_server | stubstart contents_stub |
112	forwardstart contents_forward | pythonstart contents_py |
113	rcstart contents_rc
114	;
115
116/* server: declaration */
117serverstart: VAR_SERVER
118	{
119		OUTYY(("\nP(server:)\n"));
120	}
121	;
122contents_server: contents_server content_server
123	| ;
124content_server: server_num_threads | server_verbosity | server_port |
125	server_outgoing_range | server_do_ip4 |
126	server_do_ip6 | server_do_udp | server_do_tcp |
127	server_interface | server_chroot | server_username |
128	server_directory | server_logfile | server_pidfile |
129	server_msg_cache_size | server_msg_cache_slabs |
130	server_num_queries_per_thread | server_rrset_cache_size |
131	server_rrset_cache_slabs | server_outgoing_num_tcp |
132	server_infra_host_ttl | server_infra_lame_ttl |
133	server_infra_cache_slabs | server_infra_cache_numhosts |
134	server_infra_cache_lame_size | server_target_fetch_policy |
135	server_harden_short_bufsize | server_harden_large_queries |
136	server_do_not_query_address | server_hide_identity |
137	server_hide_version | server_identity | server_version |
138	server_harden_glue | server_module_conf | server_trust_anchor_file |
139	server_trust_anchor | server_val_override_date | server_bogus_ttl |
140	server_val_clean_additional | server_val_permissive_mode |
141	server_incoming_num_tcp | server_msg_buffer_size |
142	server_key_cache_size | server_key_cache_slabs |
143	server_trusted_keys_file | server_val_nsec3_keysize_iterations |
144	server_use_syslog | server_outgoing_interface | server_root_hints |
145	server_do_not_query_localhost | server_cache_max_ttl |
146	server_harden_dnssec_stripped | server_access_control |
147	server_local_zone | server_local_data | server_interface_automatic |
148	server_statistics_interval | server_do_daemonize |
149	server_use_caps_for_id | server_statistics_cumulative |
150	server_outgoing_port_permit | server_outgoing_port_avoid |
151	server_dlv_anchor_file | server_dlv_anchor | server_neg_cache_size |
152	server_harden_referral_path | server_private_address |
153	server_private_domain | server_extended_statistics |
154	server_local_data_ptr | server_jostle_timeout |
155	server_unwanted_reply_threshold | server_log_time_ascii |
156	server_domain_insecure | server_val_sig_skew_min |
157	server_val_sig_skew_max | server_cache_min_ttl | server_val_log_level |
158	server_auto_trust_anchor_file | server_add_holddown |
159	server_del_holddown | server_keep_missing | server_so_rcvbuf |
160	server_edns_buffer_size | server_prefetch | server_prefetch_key |
161	server_so_sndbuf | server_harden_below_nxdomain | server_ignore_cd_flag |
162	server_log_queries | server_tcp_upstream | server_ssl_upstream |
163	server_ssl_service_key | server_ssl_service_pem | server_ssl_port |
164	server_minimal_responses | server_rrset_roundrobin | server_max_udp_size |
165	server_so_reuseport | server_delay_close | server_unblock_lan_zones
166	;
167stubstart: VAR_STUB_ZONE
168	{
169		struct config_stub* s;
170		OUTYY(("\nP(stub_zone:)\n"));
171		s = (struct config_stub*)calloc(1, sizeof(struct config_stub));
172		if(s) {
173			s->next = cfg_parser->cfg->stubs;
174			cfg_parser->cfg->stubs = s;
175		} else
176			yyerror("out of memory");
177	}
178	;
179contents_stub: contents_stub content_stub
180	| ;
181content_stub: stub_name | stub_host | stub_addr | stub_prime | stub_first
182	;
183forwardstart: VAR_FORWARD_ZONE
184	{
185		struct config_stub* s;
186		OUTYY(("\nP(forward_zone:)\n"));
187		s = (struct config_stub*)calloc(1, sizeof(struct config_stub));
188		if(s) {
189			s->next = cfg_parser->cfg->forwards;
190			cfg_parser->cfg->forwards = s;
191		} else
192			yyerror("out of memory");
193	}
194	;
195contents_forward: contents_forward content_forward
196	| ;
197content_forward: forward_name | forward_host | forward_addr | forward_first
198	;
199server_num_threads: VAR_NUM_THREADS STRING_ARG
200	{
201		OUTYY(("P(server_num_threads:%s)\n", $2));
202		if(atoi($2) == 0 && strcmp($2, "0") != 0)
203			yyerror("number expected");
204		else cfg_parser->cfg->num_threads = atoi($2);
205		free($2);
206	}
207	;
208server_verbosity: VAR_VERBOSITY STRING_ARG
209	{
210		OUTYY(("P(server_verbosity:%s)\n", $2));
211		if(atoi($2) == 0 && strcmp($2, "0") != 0)
212			yyerror("number expected");
213		else cfg_parser->cfg->verbosity = atoi($2);
214		free($2);
215	}
216	;
217server_statistics_interval: VAR_STATISTICS_INTERVAL STRING_ARG
218	{
219		OUTYY(("P(server_statistics_interval:%s)\n", $2));
220		if(strcmp($2, "") == 0 || strcmp($2, "0") == 0)
221			cfg_parser->cfg->stat_interval = 0;
222		else if(atoi($2) == 0)
223			yyerror("number expected");
224		else cfg_parser->cfg->stat_interval = atoi($2);
225		free($2);
226	}
227	;
228server_statistics_cumulative: VAR_STATISTICS_CUMULATIVE STRING_ARG
229	{
230		OUTYY(("P(server_statistics_cumulative:%s)\n", $2));
231		if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
232			yyerror("expected yes or no.");
233		else cfg_parser->cfg->stat_cumulative = (strcmp($2, "yes")==0);
234		free($2);
235	}
236	;
237server_extended_statistics: VAR_EXTENDED_STATISTICS STRING_ARG
238	{
239		OUTYY(("P(server_extended_statistics:%s)\n", $2));
240		if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
241			yyerror("expected yes or no.");
242		else cfg_parser->cfg->stat_extended = (strcmp($2, "yes")==0);
243		free($2);
244	}
245	;
246server_port: VAR_PORT STRING_ARG
247	{
248		OUTYY(("P(server_port:%s)\n", $2));
249		if(atoi($2) == 0)
250			yyerror("port number expected");
251		else cfg_parser->cfg->port = atoi($2);
252		free($2);
253	}
254	;
255server_interface: VAR_INTERFACE STRING_ARG
256	{
257		OUTYY(("P(server_interface:%s)\n", $2));
258		if(cfg_parser->cfg->num_ifs == 0)
259			cfg_parser->cfg->ifs = calloc(1, sizeof(char*));
260		else 	cfg_parser->cfg->ifs = realloc(cfg_parser->cfg->ifs,
261				(cfg_parser->cfg->num_ifs+1)*sizeof(char*));
262		if(!cfg_parser->cfg->ifs)
263			yyerror("out of memory");
264		else
265			cfg_parser->cfg->ifs[cfg_parser->cfg->num_ifs++] = $2;
266	}
267	;
268server_outgoing_interface: VAR_OUTGOING_INTERFACE STRING_ARG
269	{
270		OUTYY(("P(server_outgoing_interface:%s)\n", $2));
271		if(cfg_parser->cfg->num_out_ifs == 0)
272			cfg_parser->cfg->out_ifs = calloc(1, sizeof(char*));
273		else 	cfg_parser->cfg->out_ifs = realloc(
274			cfg_parser->cfg->out_ifs,
275			(cfg_parser->cfg->num_out_ifs+1)*sizeof(char*));
276		if(!cfg_parser->cfg->out_ifs)
277			yyerror("out of memory");
278		else
279			cfg_parser->cfg->out_ifs[
280				cfg_parser->cfg->num_out_ifs++] = $2;
281	}
282	;
283server_outgoing_range: VAR_OUTGOING_RANGE STRING_ARG
284	{
285		OUTYY(("P(server_outgoing_range:%s)\n", $2));
286		if(atoi($2) == 0)
287			yyerror("number expected");
288		else cfg_parser->cfg->outgoing_num_ports = atoi($2);
289		free($2);
290	}
291	;
292server_outgoing_port_permit: VAR_OUTGOING_PORT_PERMIT STRING_ARG
293	{
294		OUTYY(("P(server_outgoing_port_permit:%s)\n", $2));
295		if(!cfg_mark_ports($2, 1,
296			cfg_parser->cfg->outgoing_avail_ports, 65536))
297			yyerror("port number or range (\"low-high\") expected");
298		free($2);
299	}
300	;
301server_outgoing_port_avoid: VAR_OUTGOING_PORT_AVOID STRING_ARG
302	{
303		OUTYY(("P(server_outgoing_port_avoid:%s)\n", $2));
304		if(!cfg_mark_ports($2, 0,
305			cfg_parser->cfg->outgoing_avail_ports, 65536))
306			yyerror("port number or range (\"low-high\") expected");
307		free($2);
308	}
309	;
310server_outgoing_num_tcp: VAR_OUTGOING_NUM_TCP STRING_ARG
311	{
312		OUTYY(("P(server_outgoing_num_tcp:%s)\n", $2));
313		if(atoi($2) == 0 && strcmp($2, "0") != 0)
314			yyerror("number expected");
315		else cfg_parser->cfg->outgoing_num_tcp = atoi($2);
316		free($2);
317	}
318	;
319server_incoming_num_tcp: VAR_INCOMING_NUM_TCP STRING_ARG
320	{
321		OUTYY(("P(server_incoming_num_tcp:%s)\n", $2));
322		if(atoi($2) == 0 && strcmp($2, "0") != 0)
323			yyerror("number expected");
324		else cfg_parser->cfg->incoming_num_tcp = atoi($2);
325		free($2);
326	}
327	;
328server_interface_automatic: VAR_INTERFACE_AUTOMATIC STRING_ARG
329	{
330		OUTYY(("P(server_interface_automatic:%s)\n", $2));
331		if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
332			yyerror("expected yes or no.");
333		else cfg_parser->cfg->if_automatic = (strcmp($2, "yes")==0);
334		free($2);
335	}
336	;
337server_do_ip4: VAR_DO_IP4 STRING_ARG
338	{
339		OUTYY(("P(server_do_ip4:%s)\n", $2));
340		if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
341			yyerror("expected yes or no.");
342		else cfg_parser->cfg->do_ip4 = (strcmp($2, "yes")==0);
343		free($2);
344	}
345	;
346server_do_ip6: VAR_DO_IP6 STRING_ARG
347	{
348		OUTYY(("P(server_do_ip6:%s)\n", $2));
349		if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
350			yyerror("expected yes or no.");
351		else cfg_parser->cfg->do_ip6 = (strcmp($2, "yes")==0);
352		free($2);
353	}
354	;
355server_do_udp: VAR_DO_UDP STRING_ARG
356	{
357		OUTYY(("P(server_do_udp:%s)\n", $2));
358		if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
359			yyerror("expected yes or no.");
360		else cfg_parser->cfg->do_udp = (strcmp($2, "yes")==0);
361		free($2);
362	}
363	;
364server_do_tcp: VAR_DO_TCP STRING_ARG
365	{
366		OUTYY(("P(server_do_tcp:%s)\n", $2));
367		if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
368			yyerror("expected yes or no.");
369		else cfg_parser->cfg->do_tcp = (strcmp($2, "yes")==0);
370		free($2);
371	}
372	;
373server_tcp_upstream: VAR_TCP_UPSTREAM STRING_ARG
374	{
375		OUTYY(("P(server_tcp_upstream:%s)\n", $2));
376		if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
377			yyerror("expected yes or no.");
378		else cfg_parser->cfg->tcp_upstream = (strcmp($2, "yes")==0);
379		free($2);
380	}
381	;
382server_ssl_upstream: VAR_SSL_UPSTREAM STRING_ARG
383	{
384		OUTYY(("P(server_ssl_upstream:%s)\n", $2));
385		if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
386			yyerror("expected yes or no.");
387		else cfg_parser->cfg->ssl_upstream = (strcmp($2, "yes")==0);
388		free($2);
389	}
390	;
391server_ssl_service_key: VAR_SSL_SERVICE_KEY STRING_ARG
392	{
393		OUTYY(("P(server_ssl_service_key:%s)\n", $2));
394		free(cfg_parser->cfg->ssl_service_key);
395		cfg_parser->cfg->ssl_service_key = $2;
396	}
397	;
398server_ssl_service_pem: VAR_SSL_SERVICE_PEM STRING_ARG
399	{
400		OUTYY(("P(server_ssl_service_pem:%s)\n", $2));
401		free(cfg_parser->cfg->ssl_service_pem);
402		cfg_parser->cfg->ssl_service_pem = $2;
403	}
404	;
405server_ssl_port: VAR_SSL_PORT STRING_ARG
406	{
407		OUTYY(("P(server_ssl_port:%s)\n", $2));
408		if(atoi($2) == 0)
409			yyerror("port number expected");
410		else cfg_parser->cfg->ssl_port = atoi($2);
411		free($2);
412	}
413	;
414server_do_daemonize: VAR_DO_DAEMONIZE STRING_ARG
415	{
416		OUTYY(("P(server_do_daemonize:%s)\n", $2));
417		if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
418			yyerror("expected yes or no.");
419		else cfg_parser->cfg->do_daemonize = (strcmp($2, "yes")==0);
420		free($2);
421	}
422	;
423server_use_syslog: VAR_USE_SYSLOG STRING_ARG
424	{
425		OUTYY(("P(server_use_syslog:%s)\n", $2));
426		if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
427			yyerror("expected yes or no.");
428		else cfg_parser->cfg->use_syslog = (strcmp($2, "yes")==0);
429#if !defined(HAVE_SYSLOG_H) && !defined(UB_ON_WINDOWS)
430		if(strcmp($2, "yes") == 0)
431			yyerror("no syslog services are available. "
432				"(reconfigure and compile to add)");
433#endif
434		free($2);
435	}
436	;
437server_log_time_ascii: VAR_LOG_TIME_ASCII STRING_ARG
438	{
439		OUTYY(("P(server_log_time_ascii:%s)\n", $2));
440		if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
441			yyerror("expected yes or no.");
442		else cfg_parser->cfg->log_time_ascii = (strcmp($2, "yes")==0);
443		free($2);
444	}
445	;
446server_log_queries: VAR_LOG_QUERIES STRING_ARG
447	{
448		OUTYY(("P(server_log_queries:%s)\n", $2));
449		if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
450			yyerror("expected yes or no.");
451		else cfg_parser->cfg->log_queries = (strcmp($2, "yes")==0);
452		free($2);
453	}
454	;
455server_chroot: VAR_CHROOT STRING_ARG
456	{
457		OUTYY(("P(server_chroot:%s)\n", $2));
458		free(cfg_parser->cfg->chrootdir);
459		cfg_parser->cfg->chrootdir = $2;
460	}
461	;
462server_username: VAR_USERNAME STRING_ARG
463	{
464		OUTYY(("P(server_username:%s)\n", $2));
465		free(cfg_parser->cfg->username);
466		cfg_parser->cfg->username = $2;
467	}
468	;
469server_directory: VAR_DIRECTORY STRING_ARG
470	{
471		OUTYY(("P(server_directory:%s)\n", $2));
472		free(cfg_parser->cfg->directory);
473		cfg_parser->cfg->directory = $2;
474	}
475	;
476server_logfile: VAR_LOGFILE STRING_ARG
477	{
478		OUTYY(("P(server_logfile:%s)\n", $2));
479		free(cfg_parser->cfg->logfile);
480		cfg_parser->cfg->logfile = $2;
481		cfg_parser->cfg->use_syslog = 0;
482	}
483	;
484server_pidfile: VAR_PIDFILE STRING_ARG
485	{
486		OUTYY(("P(server_pidfile:%s)\n", $2));
487		free(cfg_parser->cfg->pidfile);
488		cfg_parser->cfg->pidfile = $2;
489	}
490	;
491server_root_hints: VAR_ROOT_HINTS STRING_ARG
492	{
493		OUTYY(("P(server_root_hints:%s)\n", $2));
494		if(!cfg_strlist_insert(&cfg_parser->cfg->root_hints, $2))
495			yyerror("out of memory");
496	}
497	;
498server_dlv_anchor_file: VAR_DLV_ANCHOR_FILE STRING_ARG
499	{
500		OUTYY(("P(server_dlv_anchor_file:%s)\n", $2));
501		free(cfg_parser->cfg->dlv_anchor_file);
502		cfg_parser->cfg->dlv_anchor_file = $2;
503	}
504	;
505server_dlv_anchor: VAR_DLV_ANCHOR STRING_ARG
506	{
507		OUTYY(("P(server_dlv_anchor:%s)\n", $2));
508		if(!cfg_strlist_insert(&cfg_parser->cfg->dlv_anchor_list, $2))
509			yyerror("out of memory");
510	}
511	;
512server_auto_trust_anchor_file: VAR_AUTO_TRUST_ANCHOR_FILE STRING_ARG
513	{
514		OUTYY(("P(server_auto_trust_anchor_file:%s)\n", $2));
515		if(!cfg_strlist_insert(&cfg_parser->cfg->
516			auto_trust_anchor_file_list, $2))
517			yyerror("out of memory");
518	}
519	;
520server_trust_anchor_file: VAR_TRUST_ANCHOR_FILE STRING_ARG
521	{
522		OUTYY(("P(server_trust_anchor_file:%s)\n", $2));
523		if(!cfg_strlist_insert(&cfg_parser->cfg->
524			trust_anchor_file_list, $2))
525			yyerror("out of memory");
526	}
527	;
528server_trusted_keys_file: VAR_TRUSTED_KEYS_FILE STRING_ARG
529	{
530		OUTYY(("P(server_trusted_keys_file:%s)\n", $2));
531		if(!cfg_strlist_insert(&cfg_parser->cfg->
532			trusted_keys_file_list, $2))
533			yyerror("out of memory");
534	}
535	;
536server_trust_anchor: VAR_TRUST_ANCHOR STRING_ARG
537	{
538		OUTYY(("P(server_trust_anchor:%s)\n", $2));
539		if(!cfg_strlist_insert(&cfg_parser->cfg->trust_anchor_list, $2))
540			yyerror("out of memory");
541	}
542	;
543server_domain_insecure: VAR_DOMAIN_INSECURE STRING_ARG
544	{
545		OUTYY(("P(server_domain_insecure:%s)\n", $2));
546		if(!cfg_strlist_insert(&cfg_parser->cfg->domain_insecure, $2))
547			yyerror("out of memory");
548	}
549	;
550server_hide_identity: VAR_HIDE_IDENTITY STRING_ARG
551	{
552		OUTYY(("P(server_hide_identity:%s)\n", $2));
553		if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
554			yyerror("expected yes or no.");
555		else cfg_parser->cfg->hide_identity = (strcmp($2, "yes")==0);
556		free($2);
557	}
558	;
559server_hide_version: VAR_HIDE_VERSION STRING_ARG
560	{
561		OUTYY(("P(server_hide_version:%s)\n", $2));
562		if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
563			yyerror("expected yes or no.");
564		else cfg_parser->cfg->hide_version = (strcmp($2, "yes")==0);
565		free($2);
566	}
567	;
568server_identity: VAR_IDENTITY STRING_ARG
569	{
570		OUTYY(("P(server_identity:%s)\n", $2));
571		free(cfg_parser->cfg->identity);
572		cfg_parser->cfg->identity = $2;
573	}
574	;
575server_version: VAR_VERSION STRING_ARG
576	{
577		OUTYY(("P(server_version:%s)\n", $2));
578		free(cfg_parser->cfg->version);
579		cfg_parser->cfg->version = $2;
580	}
581	;
582server_so_rcvbuf: VAR_SO_RCVBUF STRING_ARG
583	{
584		OUTYY(("P(server_so_rcvbuf:%s)\n", $2));
585		if(!cfg_parse_memsize($2, &cfg_parser->cfg->so_rcvbuf))
586			yyerror("buffer size expected");
587		free($2);
588	}
589	;
590server_so_sndbuf: VAR_SO_SNDBUF STRING_ARG
591	{
592		OUTYY(("P(server_so_sndbuf:%s)\n", $2));
593		if(!cfg_parse_memsize($2, &cfg_parser->cfg->so_sndbuf))
594			yyerror("buffer size expected");
595		free($2);
596	}
597	;
598server_so_reuseport: VAR_SO_REUSEPORT STRING_ARG
599    {
600        OUTYY(("P(server_so_reuseport:%s)\n", $2));
601        if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
602            yyerror("expected yes or no.");
603        else cfg_parser->cfg->so_reuseport =
604            (strcmp($2, "yes")==0);
605        free($2);
606    }
607    ;
608server_edns_buffer_size: VAR_EDNS_BUFFER_SIZE STRING_ARG
609	{
610		OUTYY(("P(server_edns_buffer_size:%s)\n", $2));
611		if(atoi($2) == 0)
612			yyerror("number expected");
613		else if (atoi($2) < 12)
614			yyerror("edns buffer size too small");
615		else if (atoi($2) > 65535)
616			cfg_parser->cfg->edns_buffer_size = 65535;
617		else cfg_parser->cfg->edns_buffer_size = atoi($2);
618		free($2);
619	}
620	;
621server_msg_buffer_size: VAR_MSG_BUFFER_SIZE STRING_ARG
622	{
623		OUTYY(("P(server_msg_buffer_size:%s)\n", $2));
624		if(atoi($2) == 0)
625			yyerror("number expected");
626		else if (atoi($2) < 4096)
627			yyerror("message buffer size too small (use 4096)");
628		else cfg_parser->cfg->msg_buffer_size = atoi($2);
629		free($2);
630	}
631	;
632server_msg_cache_size: VAR_MSG_CACHE_SIZE STRING_ARG
633	{
634		OUTYY(("P(server_msg_cache_size:%s)\n", $2));
635		if(!cfg_parse_memsize($2, &cfg_parser->cfg->msg_cache_size))
636			yyerror("memory size expected");
637		free($2);
638	}
639	;
640server_msg_cache_slabs: VAR_MSG_CACHE_SLABS STRING_ARG
641	{
642		OUTYY(("P(server_msg_cache_slabs:%s)\n", $2));
643		if(atoi($2) == 0)
644			yyerror("number expected");
645		else {
646			cfg_parser->cfg->msg_cache_slabs = atoi($2);
647			if(!is_pow2(cfg_parser->cfg->msg_cache_slabs))
648				yyerror("must be a power of 2");
649		}
650		free($2);
651	}
652	;
653server_num_queries_per_thread: VAR_NUM_QUERIES_PER_THREAD STRING_ARG
654	{
655		OUTYY(("P(server_num_queries_per_thread:%s)\n", $2));
656		if(atoi($2) == 0)
657			yyerror("number expected");
658		else cfg_parser->cfg->num_queries_per_thread = atoi($2);
659		free($2);
660	}
661	;
662server_jostle_timeout: VAR_JOSTLE_TIMEOUT STRING_ARG
663	{
664		OUTYY(("P(server_jostle_timeout:%s)\n", $2));
665		if(atoi($2) == 0 && strcmp($2, "0") != 0)
666			yyerror("number expected");
667		else cfg_parser->cfg->jostle_time = atoi($2);
668		free($2);
669	}
670	;
671server_delay_close: VAR_DELAY_CLOSE STRING_ARG
672	{
673		OUTYY(("P(server_delay_close:%s)\n", $2));
674		if(atoi($2) == 0 && strcmp($2, "0") != 0)
675			yyerror("number expected");
676		else cfg_parser->cfg->delay_close = atoi($2);
677		free($2);
678	}
679	;
680server_unblock_lan_zones: VAR_UNBLOCK_LAN_ZONES STRING_ARG
681	{
682		OUTYY(("P(server_unblock_lan_zones:%s)\n", $2));
683		if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
684			yyerror("expected yes or no.");
685		else cfg_parser->cfg->unblock_lan_zones =
686			(strcmp($2, "yes")==0);
687		free($2);
688	}
689	;
690server_rrset_cache_size: VAR_RRSET_CACHE_SIZE STRING_ARG
691	{
692		OUTYY(("P(server_rrset_cache_size:%s)\n", $2));
693		if(!cfg_parse_memsize($2, &cfg_parser->cfg->rrset_cache_size))
694			yyerror("memory size expected");
695		free($2);
696	}
697	;
698server_rrset_cache_slabs: VAR_RRSET_CACHE_SLABS STRING_ARG
699	{
700		OUTYY(("P(server_rrset_cache_slabs:%s)\n", $2));
701		if(atoi($2) == 0)
702			yyerror("number expected");
703		else {
704			cfg_parser->cfg->rrset_cache_slabs = atoi($2);
705			if(!is_pow2(cfg_parser->cfg->rrset_cache_slabs))
706				yyerror("must be a power of 2");
707		}
708		free($2);
709	}
710	;
711server_infra_host_ttl: VAR_INFRA_HOST_TTL STRING_ARG
712	{
713		OUTYY(("P(server_infra_host_ttl:%s)\n", $2));
714		if(atoi($2) == 0 && strcmp($2, "0") != 0)
715			yyerror("number expected");
716		else cfg_parser->cfg->host_ttl = atoi($2);
717		free($2);
718	}
719	;
720server_infra_lame_ttl: VAR_INFRA_LAME_TTL STRING_ARG
721	{
722		OUTYY(("P(server_infra_lame_ttl:%s)\n", $2));
723		verbose(VERB_DETAIL, "ignored infra-lame-ttl: %s (option "
724			"removed, use infra-host-ttl)", $2);
725		free($2);
726	}
727	;
728server_infra_cache_numhosts: VAR_INFRA_CACHE_NUMHOSTS STRING_ARG
729	{
730		OUTYY(("P(server_infra_cache_numhosts:%s)\n", $2));
731		if(atoi($2) == 0)
732			yyerror("number expected");
733		else cfg_parser->cfg->infra_cache_numhosts = atoi($2);
734		free($2);
735	}
736	;
737server_infra_cache_lame_size: VAR_INFRA_CACHE_LAME_SIZE STRING_ARG
738	{
739		OUTYY(("P(server_infra_cache_lame_size:%s)\n", $2));
740		verbose(VERB_DETAIL, "ignored infra-cache-lame-size: %s "
741			"(option removed, use infra-cache-numhosts)", $2);
742		free($2);
743	}
744	;
745server_infra_cache_slabs: VAR_INFRA_CACHE_SLABS STRING_ARG
746	{
747		OUTYY(("P(server_infra_cache_slabs:%s)\n", $2));
748		if(atoi($2) == 0)
749			yyerror("number expected");
750		else {
751			cfg_parser->cfg->infra_cache_slabs = atoi($2);
752			if(!is_pow2(cfg_parser->cfg->infra_cache_slabs))
753				yyerror("must be a power of 2");
754		}
755		free($2);
756	}
757	;
758server_target_fetch_policy: VAR_TARGET_FETCH_POLICY STRING_ARG
759	{
760		OUTYY(("P(server_target_fetch_policy:%s)\n", $2));
761		free(cfg_parser->cfg->target_fetch_policy);
762		cfg_parser->cfg->target_fetch_policy = $2;
763	}
764	;
765server_harden_short_bufsize: VAR_HARDEN_SHORT_BUFSIZE STRING_ARG
766	{
767		OUTYY(("P(server_harden_short_bufsize:%s)\n", $2));
768		if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
769			yyerror("expected yes or no.");
770		else cfg_parser->cfg->harden_short_bufsize =
771			(strcmp($2, "yes")==0);
772		free($2);
773	}
774	;
775server_harden_large_queries: VAR_HARDEN_LARGE_QUERIES STRING_ARG
776	{
777		OUTYY(("P(server_harden_large_queries:%s)\n", $2));
778		if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
779			yyerror("expected yes or no.");
780		else cfg_parser->cfg->harden_large_queries =
781			(strcmp($2, "yes")==0);
782		free($2);
783	}
784	;
785server_harden_glue: VAR_HARDEN_GLUE STRING_ARG
786	{
787		OUTYY(("P(server_harden_glue:%s)\n", $2));
788		if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
789			yyerror("expected yes or no.");
790		else cfg_parser->cfg->harden_glue =
791			(strcmp($2, "yes")==0);
792		free($2);
793	}
794	;
795server_harden_dnssec_stripped: VAR_HARDEN_DNSSEC_STRIPPED STRING_ARG
796	{
797		OUTYY(("P(server_harden_dnssec_stripped:%s)\n", $2));
798		if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
799			yyerror("expected yes or no.");
800		else cfg_parser->cfg->harden_dnssec_stripped =
801			(strcmp($2, "yes")==0);
802		free($2);
803	}
804	;
805server_harden_below_nxdomain: VAR_HARDEN_BELOW_NXDOMAIN STRING_ARG
806	{
807		OUTYY(("P(server_harden_below_nxdomain:%s)\n", $2));
808		if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
809			yyerror("expected yes or no.");
810		else cfg_parser->cfg->harden_below_nxdomain =
811			(strcmp($2, "yes")==0);
812		free($2);
813	}
814	;
815server_harden_referral_path: VAR_HARDEN_REFERRAL_PATH STRING_ARG
816	{
817		OUTYY(("P(server_harden_referral_path:%s)\n", $2));
818		if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
819			yyerror("expected yes or no.");
820		else cfg_parser->cfg->harden_referral_path =
821			(strcmp($2, "yes")==0);
822		free($2);
823	}
824	;
825server_use_caps_for_id: VAR_USE_CAPS_FOR_ID STRING_ARG
826	{
827		OUTYY(("P(server_use_caps_for_id:%s)\n", $2));
828		if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
829			yyerror("expected yes or no.");
830		else cfg_parser->cfg->use_caps_bits_for_id =
831			(strcmp($2, "yes")==0);
832		free($2);
833	}
834	;
835server_private_address: VAR_PRIVATE_ADDRESS STRING_ARG
836	{
837		OUTYY(("P(server_private_address:%s)\n", $2));
838		if(!cfg_strlist_insert(&cfg_parser->cfg->private_address, $2))
839			yyerror("out of memory");
840	}
841	;
842server_private_domain: VAR_PRIVATE_DOMAIN STRING_ARG
843	{
844		OUTYY(("P(server_private_domain:%s)\n", $2));
845		if(!cfg_strlist_insert(&cfg_parser->cfg->private_domain, $2))
846			yyerror("out of memory");
847	}
848	;
849server_prefetch: VAR_PREFETCH STRING_ARG
850	{
851		OUTYY(("P(server_prefetch:%s)\n", $2));
852		if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
853			yyerror("expected yes or no.");
854		else cfg_parser->cfg->prefetch = (strcmp($2, "yes")==0);
855		free($2);
856	}
857	;
858server_prefetch_key: VAR_PREFETCH_KEY STRING_ARG
859	{
860		OUTYY(("P(server_prefetch_key:%s)\n", $2));
861		if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
862			yyerror("expected yes or no.");
863		else cfg_parser->cfg->prefetch_key = (strcmp($2, "yes")==0);
864		free($2);
865	}
866	;
867server_unwanted_reply_threshold: VAR_UNWANTED_REPLY_THRESHOLD STRING_ARG
868	{
869		OUTYY(("P(server_unwanted_reply_threshold:%s)\n", $2));
870		if(atoi($2) == 0 && strcmp($2, "0") != 0)
871			yyerror("number expected");
872		else cfg_parser->cfg->unwanted_threshold = atoi($2);
873		free($2);
874	}
875	;
876server_do_not_query_address: VAR_DO_NOT_QUERY_ADDRESS STRING_ARG
877	{
878		OUTYY(("P(server_do_not_query_address:%s)\n", $2));
879		if(!cfg_strlist_insert(&cfg_parser->cfg->donotqueryaddrs, $2))
880			yyerror("out of memory");
881	}
882	;
883server_do_not_query_localhost: VAR_DO_NOT_QUERY_LOCALHOST STRING_ARG
884	{
885		OUTYY(("P(server_do_not_query_localhost:%s)\n", $2));
886		if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
887			yyerror("expected yes or no.");
888		else cfg_parser->cfg->donotquery_localhost =
889			(strcmp($2, "yes")==0);
890		free($2);
891	}
892	;
893server_access_control: VAR_ACCESS_CONTROL STRING_ARG STRING_ARG
894	{
895		OUTYY(("P(server_access_control:%s %s)\n", $2, $3));
896		if(strcmp($3, "deny")!=0 && strcmp($3, "refuse")!=0 &&
897			strcmp($3, "deny_non_local")!=0 &&
898			strcmp($3, "refuse_non_local")!=0 &&
899			strcmp($3, "allow")!=0 &&
900			strcmp($3, "allow_snoop")!=0) {
901			yyerror("expected deny, refuse, deny_non_local, "
902				"refuse_non_local, allow or allow_snoop "
903				"in access control action");
904		} else {
905			if(!cfg_str2list_insert(&cfg_parser->cfg->acls, $2, $3))
906				fatal_exit("out of memory adding acl");
907		}
908	}
909	;
910server_module_conf: VAR_MODULE_CONF STRING_ARG
911	{
912		OUTYY(("P(server_module_conf:%s)\n", $2));
913		free(cfg_parser->cfg->module_conf);
914		cfg_parser->cfg->module_conf = $2;
915	}
916	;
917server_val_override_date: VAR_VAL_OVERRIDE_DATE STRING_ARG
918	{
919		OUTYY(("P(server_val_override_date:%s)\n", $2));
920		if(strlen($2) == 0 || strcmp($2, "0") == 0) {
921			cfg_parser->cfg->val_date_override = 0;
922		} else if(strlen($2) == 14) {
923			cfg_parser->cfg->val_date_override =
924				cfg_convert_timeval($2);
925			if(!cfg_parser->cfg->val_date_override)
926				yyerror("bad date/time specification");
927		} else {
928			if(atoi($2) == 0)
929				yyerror("number expected");
930			cfg_parser->cfg->val_date_override = atoi($2);
931		}
932		free($2);
933	}
934	;
935server_val_sig_skew_min: VAR_VAL_SIG_SKEW_MIN STRING_ARG
936	{
937		OUTYY(("P(server_val_sig_skew_min:%s)\n", $2));
938		if(strlen($2) == 0 || strcmp($2, "0") == 0) {
939			cfg_parser->cfg->val_sig_skew_min = 0;
940		} else {
941			cfg_parser->cfg->val_sig_skew_min = atoi($2);
942			if(!cfg_parser->cfg->val_sig_skew_min)
943				yyerror("number expected");
944		}
945		free($2);
946	}
947	;
948server_val_sig_skew_max: VAR_VAL_SIG_SKEW_MAX STRING_ARG
949	{
950		OUTYY(("P(server_val_sig_skew_max:%s)\n", $2));
951		if(strlen($2) == 0 || strcmp($2, "0") == 0) {
952			cfg_parser->cfg->val_sig_skew_max = 0;
953		} else {
954			cfg_parser->cfg->val_sig_skew_max = atoi($2);
955			if(!cfg_parser->cfg->val_sig_skew_max)
956				yyerror("number expected");
957		}
958		free($2);
959	}
960	;
961server_cache_max_ttl: VAR_CACHE_MAX_TTL STRING_ARG
962	{
963		OUTYY(("P(server_cache_max_ttl:%s)\n", $2));
964		if(atoi($2) == 0 && strcmp($2, "0") != 0)
965			yyerror("number expected");
966		else cfg_parser->cfg->max_ttl = atoi($2);
967		free($2);
968	}
969	;
970server_cache_min_ttl: VAR_CACHE_MIN_TTL STRING_ARG
971	{
972		OUTYY(("P(server_cache_min_ttl:%s)\n", $2));
973		if(atoi($2) == 0 && strcmp($2, "0") != 0)
974			yyerror("number expected");
975		else cfg_parser->cfg->min_ttl = atoi($2);
976		free($2);
977	}
978	;
979server_bogus_ttl: VAR_BOGUS_TTL STRING_ARG
980	{
981		OUTYY(("P(server_bogus_ttl:%s)\n", $2));
982		if(atoi($2) == 0 && strcmp($2, "0") != 0)
983			yyerror("number expected");
984		else cfg_parser->cfg->bogus_ttl = atoi($2);
985		free($2);
986	}
987	;
988server_val_clean_additional: VAR_VAL_CLEAN_ADDITIONAL STRING_ARG
989	{
990		OUTYY(("P(server_val_clean_additional:%s)\n", $2));
991		if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
992			yyerror("expected yes or no.");
993		else cfg_parser->cfg->val_clean_additional =
994			(strcmp($2, "yes")==0);
995		free($2);
996	}
997	;
998server_val_permissive_mode: VAR_VAL_PERMISSIVE_MODE STRING_ARG
999	{
1000		OUTYY(("P(server_val_permissive_mode:%s)\n", $2));
1001		if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
1002			yyerror("expected yes or no.");
1003		else cfg_parser->cfg->val_permissive_mode =
1004			(strcmp($2, "yes")==0);
1005		free($2);
1006	}
1007	;
1008server_ignore_cd_flag: VAR_IGNORE_CD_FLAG STRING_ARG
1009	{
1010		OUTYY(("P(server_ignore_cd_flag:%s)\n", $2));
1011		if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
1012			yyerror("expected yes or no.");
1013		else cfg_parser->cfg->ignore_cd = (strcmp($2, "yes")==0);
1014		free($2);
1015	}
1016	;
1017server_val_log_level: VAR_VAL_LOG_LEVEL STRING_ARG
1018	{
1019		OUTYY(("P(server_val_log_level:%s)\n", $2));
1020		if(atoi($2) == 0 && strcmp($2, "0") != 0)
1021			yyerror("number expected");
1022		else cfg_parser->cfg->val_log_level = atoi($2);
1023		free($2);
1024	}
1025	;
1026server_val_nsec3_keysize_iterations: VAR_VAL_NSEC3_KEYSIZE_ITERATIONS STRING_ARG
1027	{
1028		OUTYY(("P(server_val_nsec3_keysize_iterations:%s)\n", $2));
1029		free(cfg_parser->cfg->val_nsec3_key_iterations);
1030		cfg_parser->cfg->val_nsec3_key_iterations = $2;
1031	}
1032	;
1033server_add_holddown: VAR_ADD_HOLDDOWN STRING_ARG
1034	{
1035		OUTYY(("P(server_add_holddown:%s)\n", $2));
1036		if(atoi($2) == 0 && strcmp($2, "0") != 0)
1037			yyerror("number expected");
1038		else cfg_parser->cfg->add_holddown = atoi($2);
1039		free($2);
1040	}
1041	;
1042server_del_holddown: VAR_DEL_HOLDDOWN STRING_ARG
1043	{
1044		OUTYY(("P(server_del_holddown:%s)\n", $2));
1045		if(atoi($2) == 0 && strcmp($2, "0") != 0)
1046			yyerror("number expected");
1047		else cfg_parser->cfg->del_holddown = atoi($2);
1048		free($2);
1049	}
1050	;
1051server_keep_missing: VAR_KEEP_MISSING STRING_ARG
1052	{
1053		OUTYY(("P(server_keep_missing:%s)\n", $2));
1054		if(atoi($2) == 0 && strcmp($2, "0") != 0)
1055			yyerror("number expected");
1056		else cfg_parser->cfg->keep_missing = atoi($2);
1057		free($2);
1058	}
1059	;
1060server_key_cache_size: VAR_KEY_CACHE_SIZE STRING_ARG
1061	{
1062		OUTYY(("P(server_key_cache_size:%s)\n", $2));
1063		if(!cfg_parse_memsize($2, &cfg_parser->cfg->key_cache_size))
1064			yyerror("memory size expected");
1065		free($2);
1066	}
1067	;
1068server_key_cache_slabs: VAR_KEY_CACHE_SLABS STRING_ARG
1069	{
1070		OUTYY(("P(server_key_cache_slabs:%s)\n", $2));
1071		if(atoi($2) == 0)
1072			yyerror("number expected");
1073		else {
1074			cfg_parser->cfg->key_cache_slabs = atoi($2);
1075			if(!is_pow2(cfg_parser->cfg->key_cache_slabs))
1076				yyerror("must be a power of 2");
1077		}
1078		free($2);
1079	}
1080	;
1081server_neg_cache_size: VAR_NEG_CACHE_SIZE STRING_ARG
1082	{
1083		OUTYY(("P(server_neg_cache_size:%s)\n", $2));
1084		if(!cfg_parse_memsize($2, &cfg_parser->cfg->neg_cache_size))
1085			yyerror("memory size expected");
1086		free($2);
1087	}
1088	;
1089server_local_zone: VAR_LOCAL_ZONE STRING_ARG STRING_ARG
1090	{
1091		OUTYY(("P(server_local_zone:%s %s)\n", $2, $3));
1092		if(strcmp($3, "static")!=0 && strcmp($3, "deny")!=0 &&
1093		   strcmp($3, "refuse")!=0 && strcmp($3, "redirect")!=0 &&
1094		   strcmp($3, "transparent")!=0 && strcmp($3, "nodefault")!=0
1095		   && strcmp($3, "typetransparent")!=0)
1096			yyerror("local-zone type: expected static, deny, "
1097				"refuse, redirect, transparent, "
1098				"typetransparent or nodefault");
1099		else if(strcmp($3, "nodefault")==0) {
1100			if(!cfg_strlist_insert(&cfg_parser->cfg->
1101				local_zones_nodefault, $2))
1102				fatal_exit("out of memory adding local-zone");
1103			free($3);
1104		} else {
1105			if(!cfg_str2list_insert(&cfg_parser->cfg->local_zones,
1106				$2, $3))
1107				fatal_exit("out of memory adding local-zone");
1108		}
1109	}
1110	;
1111server_local_data: VAR_LOCAL_DATA STRING_ARG
1112	{
1113		OUTYY(("P(server_local_data:%s)\n", $2));
1114		if(!cfg_strlist_insert(&cfg_parser->cfg->local_data, $2))
1115			fatal_exit("out of memory adding local-data");
1116	}
1117	;
1118server_local_data_ptr: VAR_LOCAL_DATA_PTR STRING_ARG
1119	{
1120		char* ptr;
1121		OUTYY(("P(server_local_data_ptr:%s)\n", $2));
1122		ptr = cfg_ptr_reverse($2);
1123		free($2);
1124		if(ptr) {
1125			if(!cfg_strlist_insert(&cfg_parser->cfg->
1126				local_data, ptr))
1127				fatal_exit("out of memory adding local-data");
1128		} else {
1129			yyerror("local-data-ptr could not be reversed");
1130		}
1131	}
1132	;
1133server_minimal_responses: VAR_MINIMAL_RESPONSES STRING_ARG
1134	{
1135		OUTYY(("P(server_minimal_responses:%s)\n", $2));
1136		if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
1137			yyerror("expected yes or no.");
1138		else cfg_parser->cfg->minimal_responses =
1139			(strcmp($2, "yes")==0);
1140		free($2);
1141	}
1142	;
1143server_rrset_roundrobin: VAR_RRSET_ROUNDROBIN STRING_ARG
1144	{
1145		OUTYY(("P(server_rrset_roundrobin:%s)\n", $2));
1146		if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
1147			yyerror("expected yes or no.");
1148		else cfg_parser->cfg->rrset_roundrobin =
1149			(strcmp($2, "yes")==0);
1150		free($2);
1151	}
1152	;
1153server_max_udp_size: VAR_MAX_UDP_SIZE STRING_ARG
1154	{
1155		OUTYY(("P(server_max_udp_size:%s)\n", $2));
1156		cfg_parser->cfg->max_udp_size = atoi($2);
1157		free($2);
1158	}
1159	;
1160stub_name: VAR_NAME STRING_ARG
1161	{
1162		OUTYY(("P(name:%s)\n", $2));
1163		if(cfg_parser->cfg->stubs->name)
1164			yyerror("stub name override, there must be one name "
1165				"for one stub-zone");
1166		free(cfg_parser->cfg->stubs->name);
1167		cfg_parser->cfg->stubs->name = $2;
1168	}
1169	;
1170stub_host: VAR_STUB_HOST STRING_ARG
1171	{
1172		OUTYY(("P(stub-host:%s)\n", $2));
1173		if(!cfg_strlist_insert(&cfg_parser->cfg->stubs->hosts, $2))
1174			yyerror("out of memory");
1175	}
1176	;
1177stub_addr: VAR_STUB_ADDR STRING_ARG
1178	{
1179		OUTYY(("P(stub-addr:%s)\n", $2));
1180		if(!cfg_strlist_insert(&cfg_parser->cfg->stubs->addrs, $2))
1181			yyerror("out of memory");
1182	}
1183	;
1184stub_first: VAR_STUB_FIRST STRING_ARG
1185	{
1186		OUTYY(("P(stub-first:%s)\n", $2));
1187		if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
1188			yyerror("expected yes or no.");
1189		else cfg_parser->cfg->stubs->isfirst=(strcmp($2, "yes")==0);
1190		free($2);
1191	}
1192	;
1193stub_prime: VAR_STUB_PRIME STRING_ARG
1194	{
1195		OUTYY(("P(stub-prime:%s)\n", $2));
1196		if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
1197			yyerror("expected yes or no.");
1198		else cfg_parser->cfg->stubs->isprime =
1199			(strcmp($2, "yes")==0);
1200		free($2);
1201	}
1202	;
1203forward_name: VAR_NAME STRING_ARG
1204	{
1205		OUTYY(("P(name:%s)\n", $2));
1206		if(cfg_parser->cfg->forwards->name)
1207			yyerror("forward name override, there must be one "
1208				"name for one forward-zone");
1209		free(cfg_parser->cfg->forwards->name);
1210		cfg_parser->cfg->forwards->name = $2;
1211	}
1212	;
1213forward_host: VAR_FORWARD_HOST STRING_ARG
1214	{
1215		OUTYY(("P(forward-host:%s)\n", $2));
1216		if(!cfg_strlist_insert(&cfg_parser->cfg->forwards->hosts, $2))
1217			yyerror("out of memory");
1218	}
1219	;
1220forward_addr: VAR_FORWARD_ADDR STRING_ARG
1221	{
1222		OUTYY(("P(forward-addr:%s)\n", $2));
1223		if(!cfg_strlist_insert(&cfg_parser->cfg->forwards->addrs, $2))
1224			yyerror("out of memory");
1225	}
1226	;
1227forward_first: VAR_FORWARD_FIRST STRING_ARG
1228	{
1229		OUTYY(("P(forward-first:%s)\n", $2));
1230		if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
1231			yyerror("expected yes or no.");
1232		else cfg_parser->cfg->forwards->isfirst=(strcmp($2, "yes")==0);
1233		free($2);
1234	}
1235	;
1236rcstart: VAR_REMOTE_CONTROL
1237	{
1238		OUTYY(("\nP(remote-control:)\n"));
1239	}
1240	;
1241contents_rc: contents_rc content_rc
1242	| ;
1243content_rc: rc_control_enable | rc_control_interface | rc_control_port |
1244	rc_server_key_file | rc_server_cert_file | rc_control_key_file |
1245	rc_control_cert_file
1246	;
1247rc_control_enable: VAR_CONTROL_ENABLE STRING_ARG
1248	{
1249		OUTYY(("P(control_enable:%s)\n", $2));
1250		if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
1251			yyerror("expected yes or no.");
1252		else cfg_parser->cfg->remote_control_enable =
1253			(strcmp($2, "yes")==0);
1254		free($2);
1255	}
1256	;
1257rc_control_port: VAR_CONTROL_PORT STRING_ARG
1258	{
1259		OUTYY(("P(control_port:%s)\n", $2));
1260		if(atoi($2) == 0)
1261			yyerror("control port number expected");
1262		else cfg_parser->cfg->control_port = atoi($2);
1263		free($2);
1264	}
1265	;
1266rc_control_interface: VAR_CONTROL_INTERFACE STRING_ARG
1267	{
1268		OUTYY(("P(control_interface:%s)\n", $2));
1269		if(!cfg_strlist_insert(&cfg_parser->cfg->control_ifs, $2))
1270			yyerror("out of memory");
1271	}
1272	;
1273rc_server_key_file: VAR_SERVER_KEY_FILE STRING_ARG
1274	{
1275		OUTYY(("P(rc_server_key_file:%s)\n", $2));
1276		free(cfg_parser->cfg->server_key_file);
1277		cfg_parser->cfg->server_key_file = $2;
1278	}
1279	;
1280rc_server_cert_file: VAR_SERVER_CERT_FILE STRING_ARG
1281	{
1282		OUTYY(("P(rc_server_cert_file:%s)\n", $2));
1283		free(cfg_parser->cfg->server_cert_file);
1284		cfg_parser->cfg->server_cert_file = $2;
1285	}
1286	;
1287rc_control_key_file: VAR_CONTROL_KEY_FILE STRING_ARG
1288	{
1289		OUTYY(("P(rc_control_key_file:%s)\n", $2));
1290		free(cfg_parser->cfg->control_key_file);
1291		cfg_parser->cfg->control_key_file = $2;
1292	}
1293	;
1294rc_control_cert_file: VAR_CONTROL_CERT_FILE STRING_ARG
1295	{
1296		OUTYY(("P(rc_control_cert_file:%s)\n", $2));
1297		free(cfg_parser->cfg->control_cert_file);
1298		cfg_parser->cfg->control_cert_file = $2;
1299	}
1300	;
1301pythonstart: VAR_PYTHON
1302	{
1303		OUTYY(("\nP(python:)\n"));
1304	}
1305	;
1306contents_py: contents_py content_py
1307	| ;
1308content_py: py_script
1309	;
1310py_script: VAR_PYTHON_SCRIPT STRING_ARG
1311	{
1312		OUTYY(("P(python-script:%s)\n", $2));
1313		free(cfg_parser->cfg->python_script);
1314		cfg_parser->cfg->python_script = $2;
1315	}
1316%%
1317
1318/* parse helper routines could be here */
1319