xref: /netbsd-src/external/bsd/ntp/dist/ntpd/ntp_parser.y (revision eabc0478de71e4e011a5b4e0392741e01d491794)
1 /*	$NetBSD: ntp_parser.y,v 1.20 2024/08/18 20:47:17 christos Exp $	*/
2 
3 /* ntp_parser.y
4  *
5  * The parser for the NTP configuration file.
6  *
7  * Written By:	Sachin Kamboj
8  *		University of Delaware
9  *		Newark, DE 19711
10  * Copyright (c) 2006
11  */
12 
13 %{
14   #ifdef HAVE_CONFIG_H
15   # include <config.h>
16   #endif
17 
18   #include "ntp.h"
19   #include "ntpd.h"
20   #include "ntp_machine.h"
21   #include "ntp_stdlib.h"
22   #include "ntp_filegen.h"
23   #include "ntp_scanner.h"
24   #include "ntp_config.h"
25   #include "ntp_crypto.h"
26   #include "ntp_calendar.h"
27 
28   #include "ntpsim.h"		/* HMS: Do we really want this all the time? */
29 				/* SK: It might be a good idea to always
30 				   include the simulator code. That way
31 				   someone can use the same configuration file
32 				   for both the simulator and the daemon
33 				*/
34 
35   #define YYMALLOC	emalloc
36   #define YYFREE	free
37   #define YYERROR_VERBOSE
38   #define YYMAXDEPTH	1000	/* stop the madness sooner */
39   void yyerror(const char *msg);
40 
41   #ifdef SIM
42   #  define ONLY_SIM(a)	(a)
43   #else
44   #  define ONLY_SIM(a)	NULL
45   #endif
46 %}
47 
48 /*
49  * Enable generation of token names array even without YYDEBUG.
50  * We access via token_name() defined below.
51  */
52 %token-table
53 
54 %union {
55 	char *			String;
56 	double			Double;
57 	int			Integer;
58 	unsigned		U_int;
59 	gen_fifo *		Generic_fifo;
60 	attr_val *		Attr_val;
61 	attr_val_fifo *		Attr_val_fifo;
62 	int_fifo *		Int_fifo;
63 	string_fifo *		String_fifo;
64 	address_node *		Address_node;
65 	address_fifo *		Address_fifo;
66 	setvar_node *		Set_var;
67 	server_info *		Sim_server;
68 	server_info_fifo *	Sim_server_fifo;
69 	script_info *		Sim_script;
70 	script_info_fifo *	Sim_script_fifo;
71 }
72 
73 /* TERMINALS (do not appear left of colon) */
74 %token	<Integer>	T_Abbrev
75 %token	<Integer>	T_Age
76 %token	<Integer>	T_All
77 %token	<Integer>	T_Allan
78 %token	<Integer>	T_Allpeers
79 %token	<Integer>	T_Auth
80 %token	<Integer>	T_Autokey
81 %token	<Integer>	T_Automax
82 %token	<Integer>	T_Average
83 %token	<Integer>	T_Basedate
84 %token	<Integer>	T_Bclient
85 %token	<Integer>	T_Bcpollbstep
86 %token	<Integer>	T_Beacon
87 %token	<Integer>	T_Broadcast
88 %token	<Integer>	T_Broadcastclient
89 %token	<Integer>	T_Broadcastdelay
90 %token	<Integer>	T_Burst
91 %token	<Integer>	T_Calibrate
92 %token	<Integer>	T_Ceiling
93 %token	<Integer>	T_Checkhash
94 %token	<Integer>	T_Clockstats
95 %token	<Integer>	T_Cohort
96 %token	<Integer>	T_ControlKey
97 %token	<Integer>	T_Crypto
98 %token	<Integer>	T_Cryptostats
99 %token	<Integer>	T_Ctl
100 %token	<Integer>	T_Day
101 %token	<Integer>	T_Default
102 %token	<Integer>	T_Delrestrict
103 %token	<Integer>	T_Device
104 %token	<Integer>	T_Digest
105 %token	<Integer>	T_Disable
106 %token	<Integer>	T_Discard
107 %token	<Integer>	T_Dispersion
108 %token	<Double>	T_Double		/* not a token */
109 %token	<Integer>	T_Driftfile
110 %token	<Integer>	T_Drop
111 %token	<Integer>	T_Dscp
112 %token	<Integer>	T_Ellipsis	/* "..." not "ellipsis" */
113 %token	<Integer>	T_Enable
114 %token	<Integer>	T_End
115 %token	<Integer>	T_Epeer
116 %token	<Integer>	T_False
117 %token	<Integer>	T_File
118 %token	<Integer>	T_Filegen
119 %token	<Integer>	T_Filenum
120 %token	<Integer>	T_Flag1
121 %token	<Integer>	T_Flag2
122 %token	<Integer>	T_Flag3
123 %token	<Integer>	T_Flag4
124 %token	<Integer>	T_Flake
125 %token	<Integer>	T_Floor
126 %token	<Integer>	T_Freq
127 %token	<Integer>	T_Fudge
128 %token	<Integer>	T_Fuzz
129 %token	<Integer>	T_Host
130 %token	<Integer>	T_Huffpuff
131 %token	<Integer>	T_Iburst
132 %token	<Integer>	T_Ident
133 %token	<Integer>	T_Ignore
134 %token	<Integer>	T_Ignorehash
135 %token	<Integer>	T_Incalloc
136 %token	<Integer>	T_Incmem
137 %token	<Integer>	T_Initalloc
138 %token	<Integer>	T_Initmem
139 %token	<Integer>	T_Includefile
140 %token	<Integer>	T_Integer		/* not a token */
141 %token	<Integer>	T_Interface
142 %token	<Integer>	T_Intrange		/* not a token */
143 %token	<Integer>	T_Io
144 %token	<Integer>	T_Ippeerlimit
145 %token	<Integer>	T_Ipv4
146 %token	<Integer>	T_Ipv4_flag
147 %token	<Integer>	T_Ipv6
148 %token	<Integer>	T_Ipv6_flag
149 %token	<Integer>	T_Kernel
150 %token	<Integer>	T_Key
151 %token	<Integer>	T_Keys
152 %token	<Integer>	T_Keysdir
153 %token	<Integer>	T_Kod
154 %token	<Integer>	T_Leapfile
155 %token	<Integer>	T_Leapsmearinterval
156 %token	<Integer>	T_Limited
157 %token	<Integer>	T_Link
158 %token	<Integer>	T_Listen
159 %token	<Integer>	T_Logconfig
160 %token	<Integer>	T_Logfile
161 %token	<Integer>	T_Loopstats
162 %token	<Integer>	T_Lowpriotrap
163 %token	<Integer>	T_Manycastclient
164 %token	<Integer>	T_Manycastserver
165 %token	<Integer>	T_Mask
166 %token	<Integer>	T_Maxage
167 %token	<Integer>	T_Maxclock
168 %token	<Integer>	T_Maxdepth
169 %token	<Integer>	T_Maxdist
170 %token	<Integer>	T_Maxmem
171 %token	<Integer>	T_Maxpoll
172 %token	<Integer>	T_Mdnstries
173 %token	<Integer>	T_Mem
174 %token	<Integer>	T_Memlock
175 %token	<Integer>	T_Minclock
176 %token	<Integer>	T_Mindepth
177 %token	<Integer>	T_Mindist
178 %token	<Integer>	T_Minimum
179 %token	<Integer>	T_Minjitter
180 %token	<Integer>	T_Minpoll
181 %token	<Integer>	T_Minsane
182 %token	<Integer>	T_Mode
183 %token	<Integer>	T_Mode7
184 %token	<Integer>	T_Monitor
185 %token	<Integer>	T_Month
186 %token	<Integer>	T_Mru
187 %token	<Integer>	T_Mssntp
188 %token	<Integer>	T_Multicastclient
189 %token	<Integer>	T_Nic
190 %token	<Integer>	T_Nolink
191 %token	<Integer>	T_Nomodify
192 %token	<Integer>	T_Nomrulist
193 %token	<Integer>	T_None
194 %token	<Integer>	T_Nonvolatile
195 %token	<Integer>	T_Noepeer
196 %token	<Integer>	T_Nopeer
197 %token	<Integer>	T_Noquery
198 %token	<Integer>	T_Noselect
199 %token	<Integer>	T_Noserve
200 %token	<Integer>	T_Notrap
201 %token	<Integer>	T_Notrust
202 %token	<Integer>	T_Ntp
203 %token	<Integer>	T_Ntpport
204 %token	<Integer>	T_NtpSignDsocket
205 %token	<Integer>	T_Orphan
206 %token	<Integer>	T_Orphanwait
207 %token	<Integer>	T_PCEdigest
208 %token	<Integer>	T_Panic
209 %token	<Integer>	T_Peer
210 %token	<Integer>	T_Peerstats
211 %token	<Integer>	T_Phone
212 %token	<Integer>	T_Pid
213 %token	<Integer>	T_Pidfile
214 %token	<Integer>	T_Poll
215 %token	<Integer>	T_PollSkewList
216 %token	<Integer>	T_Pool
217 %token	<Integer>	T_Port
218 %token	<Integer>	T_PpsData
219 %token	<Integer>	T_Preempt
220 %token	<Integer>	T_Prefer
221 %token	<Integer>	T_Protostats
222 %token	<Integer>	T_Pw
223 %token	<Integer>	T_Randfile
224 %token	<Integer>	T_Rawstats
225 %token	<Integer>	T_Refid
226 %token	<Integer>	T_Requestkey
227 %token	<Integer>	T_Reset
228 %token	<Integer>	T_Restrict
229 %token	<Integer>	T_Revoke
230 %token	<Integer>	T_Rlimit
231 %token	<Integer>	T_Saveconfigdir
232 %token	<Integer>	T_Server
233 %token	<Integer>	T_Serverresponse
234 %token	<Integer>	T_ServerresponseFuzz	/* Not a token */
235 %token	<Integer>	T_Setvar
236 %token	<Integer>	T_Source
237 %token	<Integer>	T_Stacksize
238 %token	<Integer>	T_Statistics
239 %token	<Integer>	T_Stats
240 %token	<Integer>	T_Statsdir
241 %token	<Integer>	T_Step
242 %token	<Integer>	T_Stepback
243 %token	<Integer>	T_Stepfwd
244 %token	<Integer>	T_Stepout
245 %token	<Integer>	T_Stratum
246 %token	<String>	T_String		/* not a token */
247 %token	<Integer>	T_Sys
248 %token	<Integer>	T_Sysstats
249 %token	<Integer>	T_Tick
250 %token	<Integer>	T_Time1
251 %token	<Integer>	T_Time2
252 %token	<Integer>	T_TimeData
253 %token	<Integer>	T_Timer
254 %token	<Integer>	T_Timingstats
255 %token	<Integer>	T_Tinker
256 %token	<Integer>	T_Tos
257 %token	<Integer>	T_Trap
258 %token	<Integer>	T_True
259 %token	<Integer>	T_Trustedkey
260 %token	<Integer>	T_Ttl
261 %token	<Integer>	T_Type
262 %token	<Integer>	T_U_int			/* Not a token */
263 %token	<Integer>	T_UEcrypto
264 %token	<Integer>	T_UEcryptonak
265 %token	<Integer>	T_UEdigest
266 %token	<Integer>	T_Unconfig
267 %token	<Integer>	T_Unpeer
268 %token	<Integer>	T_Version
269 %token	<Integer>	T_WanderThreshold	/* Not a token */
270 %token	<Integer>	T_Week
271 %token	<Integer>	T_Wildcard
272 %token	<Integer>	T_Xleave
273 %token	<Integer>	T_Xmtnonce
274 %token	<Integer>	T_Year
275 %token	<Integer>	T_Flag			/* Not a token */
276 %token	<Integer>	T_EOC
277 
278 
279 /* NTP Simulator Tokens */
280 %token	<Integer>	T_Simulate
281 %token	<Integer>	T_Beep_Delay
282 %token	<Integer>	T_Sim_Duration
283 %token	<Integer>	T_Server_Offset
284 %token	<Integer>	T_Duration
285 %token	<Integer>	T_Freq_Offset
286 %token	<Integer>	T_Wander
287 %token	<Integer>	T_Jitter
288 %token	<Integer>	T_Prop_Delay
289 %token	<Integer>	T_Proc_Delay
290 
291 
292 
293 /*** NON-TERMINALS ***/
294 %type	<Integer>	access_control_flag
295 %type	<Attr_val_fifo>	ac_flag_list
296 %type	<Address_node>	address
297 %type	<Integer>	address_fam
298 %type	<Address_fifo>	address_list
299 %type	<Integer>	basedate
300 %type	<Integer>	boolean
301 %type	<Integer>	client_type
302 %type	<Integer>	counter_set_keyword
303 %type	<Int_fifo>	counter_set_list
304 %type	<Attr_val>	crypto_command
305 %type	<Attr_val_fifo>	crypto_command_list
306 %type	<Integer>	crypto_str_keyword
307 %type	<Attr_val>	device_item
308 %type	<Integer>	device_item_path_keyword
309 %type	<Attr_val_fifo>	device_item_list
310 %type	<Attr_val>	discard_option
311 %type	<Integer>	discard_option_keyword
312 %type	<Attr_val_fifo>	discard_option_list
313 %type	<Integer>	enable_disable
314 %type	<Attr_val>	filegen_option
315 %type	<Attr_val_fifo>	filegen_option_list
316 %type	<Integer>	filegen_type
317 %type	<Attr_val>	fudge_factor
318 %type	<Integer>	fudge_factor_bool_keyword
319 %type	<Integer>	fudge_factor_dbl_keyword
320 %type	<Attr_val_fifo>	fudge_factor_list
321 %type	<Attr_val_fifo>	integer_list
322 %type	<Attr_val_fifo>	integer_list_range
323 %type	<Attr_val>	integer_list_range_elt
324 %type	<Attr_val>	integer_range
325 %type	<Integer>	nic_rule_action
326 %type	<Integer>	interface_command
327 %type	<Integer>	interface_nic
328 %type	<Address_node>	ip_address
329 %type	<Integer>	res_ippeerlimit
330 %type	<Integer>	link_nolink
331 %type	<Attr_val>	log_config_command
332 %type	<Attr_val_fifo>	log_config_list
333 %type	<Integer>	misc_cmd_dbl_keyword
334 %type	<Integer>	misc_cmd_int_keyword
335 %type	<Integer>	misc_cmd_str_keyword
336 %type	<Integer>	misc_cmd_str_lcl_keyword
337 %type	<Attr_val>	mru_option
338 %type	<Integer>	mru_option_keyword
339 %type	<Attr_val_fifo>	mru_option_list
340 %type	<Integer>	nic_rule_class
341 %type	<Double>	number
342 %type	<Integer>	opt_hash_check
343 %type	<Attr_val>	option
344 %type	<Attr_val>	option_flag
345 %type	<Integer>	option_flag_keyword
346 %type	<Attr_val_fifo>	option_list
347 %type	<Attr_val>	option_int
348 %type	<Integer>	option_int_keyword
349 %type	<Attr_val>	option_str
350 %type	<Integer>	option_str_keyword
351 %type	<Attr_val_fifo>	pollskew_list
352 %type	<Attr_val>	pollskew_cycle
353 %type	<Attr_val>	pollskew_spec
354 %type	<Integer>	reset_command
355 %type	<Address_node>	restrict_mask
356 %type	<Integer>	rlimit_option_keyword
357 %type	<Attr_val>	rlimit_option
358 %type	<Attr_val_fifo>	rlimit_option_list
359 %type	<Integer>	stat
360 %type	<Int_fifo>	stats_list
361 %type	<String_fifo>	string_list
362 %type	<Attr_val>	system_option
363 %type	<Integer>	system_option_flag_keyword
364 %type	<Integer>	system_option_local_flag_keyword
365 %type	<Attr_val_fifo>	system_option_list
366 %type	<Integer>	t_default_or_zero
367 %type	<Integer>	tinker_option_keyword
368 %type	<Attr_val>	tinker_option
369 %type	<Attr_val_fifo>	tinker_option_list
370 %type	<Attr_val>	tos_option
371 %type	<Integer>	tos_option_dbl_keyword
372 %type	<Integer>	tos_option_int_keyword
373 %type	<Attr_val_fifo>	tos_option_list
374 %type	<Attr_val>	trap_option
375 %type	<Attr_val_fifo>	trap_option_list
376 %type	<Integer>	unpeer_keyword
377 %type	<Set_var>	variable_assign
378 
379 /* NTP Simulator non-terminals */
380 %type	<Attr_val>		sim_init_statement
381 %type	<Attr_val_fifo>		sim_init_statement_list
382 %type	<Integer>		sim_init_keyword
383 %type	<Sim_server_fifo>	sim_server_list
384 %type	<Sim_server>		sim_server
385 %type	<Double>		sim_server_offset
386 %type	<Address_node>		sim_server_name
387 %type	<Sim_script>		sim_act
388 %type	<Sim_script_fifo>	sim_act_list
389 %type	<Integer>		sim_act_keyword
390 %type	<Attr_val_fifo>		sim_act_stmt_list
391 %type	<Attr_val>		sim_act_stmt
392 
393 %%
394 
395 /* ntp.conf
396  * Configuration File Grammar
397  * --------------------------
398  */
399 
400 configuration
401 	:	command_list
402 	;
403 
404 command_list
405 	:	command_list command T_EOC
406 	|	command T_EOC
407 	|	error T_EOC
408 		{
409 			/* I will need to incorporate much more fine grained
410 			 * error messages. The following should suffice for
411 			 * the time being.
412 			 */
413 			struct FILE_INFO * ip_ctx = lex_current();
414 			msyslog(LOG_ERR,
415 				"syntax error in %s line %d, column %d",
416 				ip_ctx->fname,
417 				ip_ctx->errpos.nline,
418 				ip_ctx->errpos.ncol);
419 		}
420 	;
421 
422 command :	/* NULL STATEMENT */
423 	|	server_command
424 	|	unpeer_command
425 	|	other_mode_command
426 	|	authentication_command
427 	|	monitoring_command
428 	|	access_control_command
429 	|	orphan_mode_command
430 	|	fudge_command
431 	|	rlimit_command
432 	|	system_option_command
433 	|	tinker_command
434 	|	miscellaneous_command
435 	|	simulate_command
436 	|	device_command
437 	;
438 
439 /* Server Commands
440  * ---------------
441  */
442 
443 server_command
444 	:	client_type address option_list
445 		{
446 			peer_node *my_node;
447 
448 			my_node = create_peer_node($1, $2, $3);
449 			APPEND_G_FIFO(cfgt.peers, my_node);
450 		}
451 	;
452 
453 client_type
454 	:	T_Server
455 	|	T_Pool
456 	|	T_Peer
457 	|	T_Broadcast
458 	|	T_Manycastclient
459 	;
460 
461 address
462 	:	ip_address
463 	|	address_fam T_String
464 			{ $$ = create_address_node($2, $1); }
465 	;
466 
467 ip_address
468 	:	T_String
469 			{ $$ = create_address_node($1, AF_UNSPEC); }
470 	;
471 
472 address_fam
473 	:	T_Ipv4_flag
474 			{ $$ = AF_INET; }
475 	|	T_Ipv6_flag
476 			{ $$ = AF_INET6; }
477 	;
478 
479 option_list
480 	:	/* empty list */
481 			{ $$ = NULL; }
482 	|	option_list option
483 		{
484 			$$ = $1;
485 			APPEND_G_FIFO($$, $2);
486 		}
487 	;
488 
489 option
490 	:	option_flag
491 	|	option_int
492 	|	option_str
493 	;
494 
495 option_flag
496 	:	option_flag_keyword
497 			{ $$ = create_attr_ival(T_Flag, $1); }
498 	;
499 
500 option_flag_keyword
501 	:	T_Autokey
502 	|	T_Burst
503 	|	T_Iburst
504 	|	T_Noselect
505 	|	T_Preempt
506 	|	T_Prefer
507 	|	T_True
508 	|	T_Xleave
509 	|	T_Xmtnonce
510 	;
511 
512 option_int
513 	:	option_int_keyword T_Integer
514 			{ $$ = create_attr_ival($1, $2); }
515 	|	option_int_keyword T_U_int
516 			{ $$ = create_attr_uval($1, $2); }
517 	;
518 
519 option_int_keyword
520 	:	T_Key
521 	|	T_Minpoll
522 	|	T_Maxpoll
523 	|	T_Ttl
524 	|	T_Mode
525 	|	T_Version
526 	;
527 
528 option_str
529 	:	option_str_keyword T_String
530 			{ $$ = create_attr_sval($1, $2); }
531 	;
532 
533 option_str_keyword
534 	:	T_Ident
535 	;
536 
537 
538 /* unpeer commands
539  * ---------------
540  */
541 
542 unpeer_command
543 	:	unpeer_keyword address
544 		{
545 			unpeer_node *my_node;
546 
547 			my_node = create_unpeer_node($2);
548 			if (my_node)
549 				APPEND_G_FIFO(cfgt.unpeers, my_node);
550 		}
551 	;
552 unpeer_keyword
553 	:	T_Unconfig
554 	|	T_Unpeer
555 	;
556 
557 
558 /* Other Modes
559  * (broadcastclient manycastserver multicastclient)
560  * ------------------------------------------------
561  */
562 
563 other_mode_command
564 	:	T_Broadcastclient
565 			{ cfgt.broadcastclient = 1; }
566 	|	T_Manycastserver address_list
567 			{ CONCAT_G_FIFOS(cfgt.manycastserver, $2); }
568 	|	T_Multicastclient address_list
569 			{ CONCAT_G_FIFOS(cfgt.multicastclient, $2); }
570 	|	T_Mdnstries T_Integer
571 			{ cfgt.mdnstries = $2; }
572 	;
573 
574 
575 
576 /* Authentication Commands
577  * -----------------------
578  */
579 
580 authentication_command
581 	:	T_Automax T_Integer
582 		{
583 			attr_val *atrv;
584 
585 			atrv = create_attr_ival($1, $2);
586 			APPEND_G_FIFO(cfgt.vars, atrv);
587 		}
588 	|	T_ControlKey T_Integer
589 			{ cfgt.auth.control_key = $2; }
590 	|	T_Crypto crypto_command_list
591 		{
592 			cfgt.auth.cryptosw++;
593 			CONCAT_G_FIFOS(cfgt.auth.crypto_cmd_list, $2);
594 		}
595 	|	T_Keys T_String
596 			{ cfgt.auth.keys = $2; }
597 	|	T_Keysdir T_String
598 			{ cfgt.auth.keysdir = $2; }
599 	|	T_Requestkey T_Integer
600 			{ cfgt.auth.request_key = $2; }
601 	|	T_Revoke T_Integer
602 			{ cfgt.auth.revoke = $2; }
603 	|	T_Trustedkey integer_list_range
604 		{
605 			/* [Bug 948] leaves it open if appending or
606 			 * replacing the trusted key list is the right
607 			 * way. In any case, either alternative should
608 			 * be coded correctly!
609 			 */
610 			DESTROY_G_FIFO(cfgt.auth.trusted_key_list, destroy_attr_val); /* remove for append */
611 			CONCAT_G_FIFOS(cfgt.auth.trusted_key_list, $2);
612 		}
613 	|	T_NtpSignDsocket T_String
614 			{ cfgt.auth.ntp_signd_socket = $2; }
615 	;
616 
617 crypto_command_list
618 	:	/* empty list */
619 			{ $$ = NULL; }
620 	|	crypto_command_list crypto_command
621 		{
622 			$$ = $1;
623 			APPEND_G_FIFO($$, $2);
624 		}
625 	;
626 
627 crypto_command
628 	:	crypto_str_keyword T_String
629 			{ $$ = create_attr_sval($1, $2); }
630 	|	T_Revoke T_Integer
631 		{
632 			$$ = NULL;
633 			cfgt.auth.revoke = $2;
634 			msyslog(LOG_WARNING,
635 				"'crypto revoke %d' is deprecated, "
636 				"please use 'revoke %d' instead.",
637 				cfgt.auth.revoke, cfgt.auth.revoke);
638 		}
639 	;
640 
641 crypto_str_keyword
642 	:	T_Host
643 	|	T_Ident
644 	|	T_Pw
645 	|	T_Randfile
646 	|	T_Digest
647 	;
648 
649 
650 /* Orphan Mode Commands
651  * --------------------
652  */
653 
654 orphan_mode_command
655 	:	T_Tos tos_option_list
656 			{ CONCAT_G_FIFOS(cfgt.orphan_cmds, $2); }
657 	;
658 
659 tos_option_list
660 	:	tos_option_list tos_option
661 		{
662 			$$ = $1;
663 			APPEND_G_FIFO($$, $2);
664 		}
665 	|	tos_option
666 		{
667 			$$ = NULL;
668 			APPEND_G_FIFO($$, $1);
669 		}
670 	;
671 
672 tos_option
673 	:	tos_option_int_keyword T_Integer
674 			{ $$ = create_attr_dval($1, (double)$2); }
675 	|	tos_option_dbl_keyword number
676 			{ $$ = create_attr_dval($1, $2); }
677 	|	T_Cohort boolean
678 			{ $$ = create_attr_dval($1, (double)$2); }
679 	|	basedate
680 			{ $$ = create_attr_ival(T_Basedate, $1); }
681 	;
682 
683 tos_option_int_keyword
684 	:	T_Bcpollbstep
685 	|	T_Beacon
686 	|	T_Ceiling
687 	|	T_Floor
688 	|	T_Maxclock
689 	|	T_Minclock
690 	|	T_Minsane
691 	|	T_Orphan
692 	|	T_Orphanwait
693 	;
694 
695 tos_option_dbl_keyword
696 	:	T_Mindist
697 	|	T_Maxdist
698 	;
699 
700 
701 /* Monitoring Commands
702  * -------------------
703  */
704 
705 monitoring_command
706 	:	T_Statistics stats_list
707 			{ CONCAT_G_FIFOS(cfgt.stats_list, $2); }
708 	|	T_Statsdir T_String
709 		{
710 			if (lex_from_file()) {
711 				cfgt.stats_dir = $2;
712 			} else {
713 				YYFREE($2);
714 				yyerror("statsdir remote configuration ignored");
715 			}
716 		}
717 	|	T_Filegen stat filegen_option_list
718 		{
719 			filegen_node *fgn;
720 
721 			fgn = create_filegen_node($2, $3);
722 			APPEND_G_FIFO(cfgt.filegen_opts, fgn);
723 		}
724 	;
725 
726 stats_list
727 	:	stats_list stat
728 		{
729 			$$ = $1;
730 			APPEND_G_FIFO($$, create_int_node($2));
731 		}
732 	|	stat
733 		{
734 			$$ = NULL;
735 			APPEND_G_FIFO($$, create_int_node($1));
736 		}
737 	;
738 
739 stat
740 	:	T_Clockstats
741 	|	T_Cryptostats
742 	|	T_Loopstats
743 	|	T_Peerstats
744 	|	T_Rawstats
745 	|	T_Sysstats
746 	|	T_Timingstats
747 	|	T_Protostats
748 	;
749 
750 filegen_option_list
751 	:	/* empty list */
752 			{ $$ = NULL; }
753 	|	filegen_option_list filegen_option
754 		{
755 			$$ = $1;
756 			APPEND_G_FIFO($$, $2);
757 		}
758 	;
759 
760 filegen_option
761 	:	T_File T_String
762 		{
763 			if (lex_from_file()) {
764 				$$ = create_attr_sval($1, $2);
765 			} else {
766 				$$ = NULL;
767 				YYFREE($2);
768 				yyerror("filegen file remote config ignored");
769 			}
770 		}
771 	|	T_Type filegen_type
772 		{
773 			if (lex_from_file()) {
774 				$$ = create_attr_ival($1, $2);
775 			} else {
776 				$$ = NULL;
777 				yyerror("filegen type remote config ignored");
778 			}
779 		}
780 	|	link_nolink
781 		{
782 			const char *err;
783 
784 			if (lex_from_file()) {
785 				$$ = create_attr_ival(T_Flag, $1);
786 			} else {
787 				$$ = NULL;
788 				if (T_Link == $1)
789 					err = "filegen link remote config ignored";
790 				else
791 					err = "filegen nolink remote config ignored";
792 				yyerror(err);
793 			}
794 		}
795 	|	enable_disable
796 			{ $$ = create_attr_ival(T_Flag, $1); }
797 	;
798 
799 link_nolink
800 	:	T_Link
801 	|	T_Nolink
802 	;
803 
804 enable_disable
805 	:	T_Enable
806 	|	T_Disable
807 	;
808 
809 filegen_type
810 	:	T_None
811 	|	T_Pid
812 	|	T_Day
813 	|	T_Week
814 	|	T_Month
815 	|	T_Year
816 	|	T_Age
817 	;
818 
819 
820 /* Access Control Commands
821  * -----------------------
822  */
823 
824 access_control_command
825 	:	T_Discard discard_option_list
826 		{
827 			CONCAT_G_FIFOS(cfgt.discard_opts, $2);
828 		}
829 	|	T_Mru mru_option_list
830 		{
831 			CONCAT_G_FIFOS(cfgt.mru_opts, $2);
832 		}
833 	|	T_Restrict address restrict_mask res_ippeerlimit ac_flag_list
834 		{
835 			restrict_node *rn;
836 
837 			rn = create_restrict_node($2, $3, $4, $5, FALSE,
838 						  lex_current()->curpos.nline,
839 						  lex_current()->curpos.ncol);
840 			APPEND_G_FIFO(cfgt.restrict_opts, rn);
841 		}
842 	|	T_Restrict T_Default res_ippeerlimit ac_flag_list
843 		{
844 			restrict_node *rn;
845 
846 			rn = create_restrict_node(NULL, NULL, $3, $4, FALSE,
847 						  lex_current()->curpos.nline,
848 						  lex_current()->curpos.ncol);
849 			APPEND_G_FIFO(cfgt.restrict_opts, rn);
850 		}
851 	|	T_Restrict T_Ipv4_flag T_Default res_ippeerlimit ac_flag_list
852 		{
853 			restrict_node *rn;
854 
855 			rn = create_restrict_node(
856 				create_address_node(
857 					estrdup("0.0.0.0"),
858 					AF_INET),
859 				create_address_node(
860 					estrdup("0.0.0.0"),
861 					AF_INET),
862 				$4, $5, FALSE,
863 				lex_current()->curpos.nline,
864 				lex_current()->curpos.ncol);
865 			APPEND_G_FIFO(cfgt.restrict_opts, rn);
866 		}
867 	|	T_Restrict T_Ipv6_flag T_Default res_ippeerlimit ac_flag_list
868 		{
869 			restrict_node *rn;
870 
871 			rn = create_restrict_node(
872 				create_address_node(
873 					estrdup("::"),
874 					AF_INET6),
875 				create_address_node(
876 					estrdup("::"),
877 					AF_INET6),
878 				$4, $5, FALSE,
879 				lex_current()->curpos.nline,
880 				lex_current()->curpos.ncol);
881 			APPEND_G_FIFO(cfgt.restrict_opts, rn);
882 		}
883 	|	T_Restrict T_Source res_ippeerlimit ac_flag_list
884 		{
885 			restrict_node *	rn;
886 
887 			APPEND_G_FIFO($4, create_attr_ival($2, 1));
888 			rn = create_restrict_node(NULL, NULL, $3, $4, FALSE,
889 						  lex_current()->curpos.nline,
890 						  lex_current()->curpos.ncol);
891 			APPEND_G_FIFO(cfgt.restrict_opts, rn);
892 		}
893 	|	T_Delrestrict ip_address restrict_mask
894 		{
895 			restrict_node *	rn;
896 
897 			rn = create_restrict_node($2, $3, -1, NULL, TRUE,
898 						  lex_current()->curpos.nline,
899 						  lex_current()->curpos.ncol);
900 			APPEND_G_FIFO(cfgt.restrict_opts, rn);
901 		}
902 	|	T_Delrestrict T_Source ip_address
903 		{
904 			restrict_node *	rn;
905 			attr_val_fifo * avf;
906 
907 			avf = NULL;
908 			APPEND_G_FIFO(avf, create_attr_ival($2, 1));
909 			rn = create_restrict_node($3, NULL, -1, avf, TRUE,
910 						  lex_current()->curpos.nline,
911 						  lex_current()->curpos.ncol);
912 			APPEND_G_FIFO(cfgt.restrict_opts, rn);
913 		}
914 	;
915 
916 restrict_mask
917 	:	/* no mask is allowed */
918 			{ $$ = NULL; }
919 	|	T_Mask ip_address
920 		{
921 			$$ = $2;
922 		}
923 	;
924 
925 res_ippeerlimit
926 	:	/* empty ippeerlimit defaults to -1 (unlimited) */
927 			{ $$ = -1; }
928 	|	T_Ippeerlimit  T_Integer
929 		{
930 			if (($2 < -1) || ($2 > 100)) {
931 				struct FILE_INFO * ip_ctx;
932 
933 				ip_ctx = lex_current();
934 				msyslog(LOG_ERR,
935 					"Unreasonable ippeerlimit value (%d) in %s line %d, column %d.  Using 0.",
936 					$2,
937 					ip_ctx->fname,
938 					ip_ctx->curpos.nline,
939 					ip_ctx->curpos.ncol);
940 				$2 = 0;
941 			}
942 			$$ = $2;
943 		}
944 	;
945 
946 ac_flag_list
947 	:	/* empty list is allowed */
948 			{ $$ = NULL; }
949 	|	ac_flag_list access_control_flag
950 		{
951 			attr_val *av;
952 
953 			$$ = $1;
954 			av = create_attr_ival($2, 1);
955 			APPEND_G_FIFO($$, av);
956 		}
957 	|	ac_flag_list T_Serverresponse T_Fuzz
958 		{
959 			attr_val *av;
960 
961 			$$ = $1;
962 			av = create_attr_ival(T_ServerresponseFuzz, 1);
963 			APPEND_G_FIFO($$, av);
964 		}
965 	;
966 
967 access_control_flag
968 	:	T_Epeer
969 	|	T_Flake
970 	|	T_Ignore
971 	|	T_Kod
972 	|	T_Limited
973 	|	T_Lowpriotrap
974 	|	T_Mssntp
975 	|	T_Noepeer
976 	|	T_Nomodify
977 	|	T_Nomrulist
978 	|	T_Nopeer
979 	|	T_Noquery
980 	|	T_Noserve
981 	|	T_Notrap
982 	|	T_Notrust
983 	|	T_Ntpport
984 	|	T_Version
985 	;
986 
987 discard_option_list
988 	:	discard_option_list discard_option
989 		{
990 			$$ = $1;
991 			APPEND_G_FIFO($$, $2);
992 		}
993 	|	discard_option
994 		{
995 			$$ = NULL;
996 			APPEND_G_FIFO($$, $1);
997 		}
998 	;
999 
1000 discard_option
1001 	:	discard_option_keyword T_Integer
1002 			{ $$ = create_attr_ival($1, $2); }
1003 	;
1004 
1005 discard_option_keyword
1006 	:	T_Average
1007 	|	T_Minimum
1008 	|	T_Monitor
1009 	;
1010 
1011 mru_option_list
1012 	:	mru_option_list mru_option
1013 		{
1014 			$$ = $1;
1015 			APPEND_G_FIFO($$, $2);
1016 		}
1017 	|	mru_option
1018 		{
1019 			$$ = NULL;
1020 			APPEND_G_FIFO($$, $1);
1021 		}
1022 	;
1023 
1024 mru_option
1025 	:	mru_option_keyword T_Integer
1026 			{ $$ = create_attr_ival($1, $2); }
1027 	;
1028 
1029 mru_option_keyword
1030 	:	T_Incalloc
1031 	|	T_Incmem
1032 	|	T_Initalloc
1033 	|	T_Initmem
1034 	|	T_Maxage
1035 	|	T_Maxdepth
1036 	|	T_Maxmem
1037 	|	T_Mindepth
1038 	;
1039 
1040 /* Fudge Commands
1041  * --------------
1042  */
1043 
1044 fudge_command
1045 	:	T_Fudge address fudge_factor_list
1046 		{
1047 			addr_opts_node *aon;
1048 
1049 			aon = create_addr_opts_node($2, $3);
1050 			APPEND_G_FIFO(cfgt.fudge, aon);
1051 		}
1052 	;
1053 
1054 fudge_factor_list
1055 	:	fudge_factor_list fudge_factor
1056 		{
1057 			$$ = $1;
1058 			APPEND_G_FIFO($$, $2);
1059 		}
1060 	|	fudge_factor
1061 		{
1062 			$$ = NULL;
1063 			APPEND_G_FIFO($$, $1);
1064 		}
1065 	;
1066 
1067 fudge_factor
1068 	:	fudge_factor_dbl_keyword number
1069 			{ $$ = create_attr_dval($1, $2); }
1070 	|	fudge_factor_bool_keyword boolean
1071 			{ $$ = create_attr_ival($1, $2); }
1072 	|	T_Stratum T_Integer
1073 		{
1074 			if ($2 >= 0 && $2 <= 16) {
1075 				$$ = create_attr_ival($1, $2);
1076 			} else {
1077 				$$ = NULL;
1078 				yyerror("fudge factor: stratum value not in [0..16], ignored");
1079 			}
1080 		}
1081 	|	T_Abbrev T_String
1082 			{ $$ = create_attr_sval($1, $2); }
1083 	|	T_Refid T_String
1084 			{ $$ = create_attr_sval($1, $2); }
1085 	;
1086 
1087 fudge_factor_dbl_keyword
1088 	:	T_Time1
1089 	|	T_Time2
1090 	|	T_Minjitter
1091 	;
1092 
1093 fudge_factor_bool_keyword
1094 	:	T_Flag1
1095 	|	T_Flag2
1096 	|	T_Flag3
1097 	|	T_Flag4
1098 	;
1099 
1100 /* Device Commands
1101  * --------------
1102  */
1103 
1104 device_command
1105 	:	T_Device address device_item_list
1106 		{
1107 			addr_opts_node *aon;
1108 
1109 			aon = create_addr_opts_node($2, $3);
1110 			APPEND_G_FIFO(cfgt.device, aon);
1111 		}
1112 	;
1113 
1114 device_item_list
1115 	:	device_item_list device_item
1116 		{
1117 			$$ = $1;
1118 			APPEND_G_FIFO($$, $2);
1119 		}
1120 	|	device_item
1121 		{
1122 			$$ = NULL;
1123 			APPEND_G_FIFO($$, $1);
1124 		}
1125 	;
1126 
1127 device_item
1128 	:	device_item_path_keyword T_String
1129 			{ $$ = create_attr_sval($1, $2); }
1130 	;
1131 
1132 device_item_path_keyword
1133 	:	T_TimeData
1134 	|	T_PpsData
1135 	;
1136 
1137 /* rlimit Commands
1138  * ---------------
1139  */
1140 
1141 rlimit_command
1142 	:	T_Rlimit rlimit_option_list
1143 			{ CONCAT_G_FIFOS(cfgt.rlimit, $2); }
1144 	;
1145 
1146 rlimit_option_list
1147 	:	rlimit_option_list rlimit_option
1148 		{
1149 			$$ = $1;
1150 			APPEND_G_FIFO($$, $2);
1151 		}
1152 	|	rlimit_option
1153 		{
1154 			$$ = NULL;
1155 			APPEND_G_FIFO($$, $1);
1156 		}
1157 	;
1158 
1159 rlimit_option
1160 	:	rlimit_option_keyword T_Integer
1161 			{ $$ = create_attr_ival($1, $2); }
1162 	;
1163 
1164 rlimit_option_keyword
1165 	:	T_Memlock
1166 	|	T_Stacksize
1167 	|	T_Filenum
1168 	;
1169 
1170 
1171 /* Command for System Options
1172  * --------------------------
1173  */
1174 
1175 system_option_command
1176 	:	T_Enable system_option_list
1177 			{ CONCAT_G_FIFOS(cfgt.enable_opts, $2); }
1178 	|	T_Disable system_option_list
1179 			{ CONCAT_G_FIFOS(cfgt.disable_opts, $2); }
1180 	;
1181 
1182 system_option_list
1183 	:	system_option_list system_option
1184 		{
1185 			$$ = $1;
1186 			APPEND_G_FIFO($$, $2);
1187 		}
1188 	|	system_option
1189 		{
1190 			$$ = NULL;
1191 			APPEND_G_FIFO($$, $1);
1192 		}
1193 	;
1194 
1195 system_option
1196 	:	system_option_flag_keyword
1197 			{ $$ = create_attr_ival(T_Flag, $1); }
1198 	|	system_option_local_flag_keyword
1199 		{
1200 			if (lex_from_file()) {
1201 				$$ = create_attr_ival(T_Flag, $1);
1202 			} else {
1203 				char err_str[128];
1204 
1205 				$$ = NULL;
1206 				snprintf(err_str, sizeof(err_str),
1207 					 "enable/disable %s remote configuration ignored",
1208 					 keyword($1));
1209 				yyerror(err_str);
1210 			}
1211 		}
1212 	;
1213 
1214 system_option_flag_keyword
1215 	:	T_Auth
1216 	|	T_Bclient
1217 	|	T_Calibrate
1218 	|	T_Kernel
1219 	|	T_Monitor
1220 	|	T_Ntp
1221 	;
1222 
1223 system_option_local_flag_keyword
1224 	:	T_Mode7
1225 	|	T_PCEdigest
1226 	|	T_Stats
1227 	|	T_UEcrypto
1228 	|	T_UEcryptonak
1229 	|	T_UEdigest
1230 	;
1231 
1232 /* Tinker Commands
1233  * ---------------
1234  */
1235 
1236 tinker_command
1237 	:	T_Tinker tinker_option_list
1238 			{ CONCAT_G_FIFOS(cfgt.tinker, $2); }
1239 	;
1240 
1241 tinker_option_list
1242 	:	tinker_option_list tinker_option
1243 		{
1244 			$$ = $1;
1245 			APPEND_G_FIFO($$, $2);
1246 		}
1247 	|	tinker_option
1248 		{
1249 			$$ = NULL;
1250 			APPEND_G_FIFO($$, $1);
1251 		}
1252 	;
1253 
1254 tinker_option
1255 	:	tinker_option_keyword number
1256 			{ $$ = create_attr_dval($1, $2); }
1257 	;
1258 
1259 tinker_option_keyword
1260 	:	T_Allan
1261 	|	T_Dispersion
1262 	|	T_Freq
1263 	|	T_Huffpuff
1264 	|	T_Panic
1265 	|	T_Step
1266 	|	T_Stepback
1267 	|	T_Stepfwd
1268 	|	T_Stepout
1269 	|	T_Tick
1270 	;
1271 
1272 
1273 /* Miscellaneous Commands
1274  * ----------------------
1275  */
1276 
1277 miscellaneous_command
1278 	:	interface_command
1279 	|	reset_command
1280 	|	misc_cmd_dbl_keyword number
1281 		{
1282 			attr_val *av;
1283 
1284 			av = create_attr_dval($1, $2);
1285 			APPEND_G_FIFO(cfgt.vars, av);
1286 		}
1287 	|	misc_cmd_int_keyword T_Integer
1288 		{
1289 			attr_val *av;
1290 
1291 			av = create_attr_ival($1, $2);
1292 			APPEND_G_FIFO(cfgt.vars, av);
1293 		}
1294 	|	misc_cmd_str_keyword T_String
1295 		{
1296 			attr_val *av;
1297 
1298 			av = create_attr_sval($1, $2);
1299 			APPEND_G_FIFO(cfgt.vars, av);
1300 		}
1301 	|	misc_cmd_str_lcl_keyword T_String
1302 		{
1303 			char error_text[64];
1304 			attr_val *av;
1305 
1306 			if (lex_from_file()) {
1307 				av = create_attr_sval($1, $2);
1308 				APPEND_G_FIFO(cfgt.vars, av);
1309 			} else {
1310 				YYFREE($2);
1311 				snprintf(error_text, sizeof(error_text),
1312 					 "%s remote config ignored",
1313 					 keyword($1));
1314 				yyerror(error_text);
1315 			}
1316 		}
1317 	|	T_Includefile T_String command
1318 		{
1319 			if (!lex_from_file()) {
1320 				YYFREE($2); /* avoid leak */
1321 				yyerror("remote includefile ignored");
1322 				break;
1323 			}
1324 			if (lex_level() > MAXINCLUDELEVEL) {
1325 				fprintf(stderr, "getconfig: Maximum include file level exceeded.\n");
1326 				msyslog(LOG_ERR, "getconfig: Maximum include file level exceeded.");
1327 			} else {
1328 				const char * path = FindConfig($2); /* might return $2! */
1329 				if (!lex_push_file(path, "r")) {
1330 					fprintf(stderr, "getconfig: Couldn't open <%s>\n", path);
1331 					msyslog(LOG_ERR, "getconfig: Couldn't open <%s>", path);
1332 				}
1333 			}
1334 			YYFREE($2); /* avoid leak */
1335 		}
1336 	|	T_Leapfile T_String opt_hash_check
1337 		{
1338 			attr_val *av;
1339 
1340 			av = create_attr_sval($1, $2);
1341 			av->flag = $3;
1342 			APPEND_G_FIFO(cfgt.vars, av);
1343 		}
1344 	|	T_End
1345 			{ lex_flush_stack(); }
1346 	|	T_Driftfile drift_parm
1347 			{ /* see drift_parm below for actions */ }
1348 	|	T_Logconfig log_config_list
1349 			{ CONCAT_G_FIFOS(cfgt.logconfig, $2); }
1350 	|	T_Phone string_list
1351 			{ CONCAT_G_FIFOS(cfgt.phone, $2); }
1352 	|	T_PollSkewList pollskew_list
1353 			{ CONCAT_G_FIFOS(cfgt.pollskewlist, $2); }
1354 	|	T_Setvar variable_assign
1355 			{ APPEND_G_FIFO(cfgt.setvar, $2); }
1356 	|	T_Trap ip_address trap_option_list
1357 		{
1358 			addr_opts_node *aon;
1359 
1360 			aon = create_addr_opts_node($2, $3);
1361 			APPEND_G_FIFO(cfgt.trap, aon);
1362 		}
1363 	|	T_Ttl integer_list
1364 			{ CONCAT_G_FIFOS(cfgt.ttl, $2); }
1365 	;
1366 
1367 misc_cmd_dbl_keyword
1368 	:	T_Broadcastdelay
1369 	|	T_Nonvolatile
1370 	|	T_Tick
1371 	;
1372 
1373 misc_cmd_int_keyword
1374 	:	T_Dscp
1375 	;
1376 
1377 misc_cmd_int_keyword
1378 	:	T_Leapsmearinterval
1379 		{
1380 #ifndef LEAP_SMEAR
1381 			yyerror("Built without LEAP_SMEAR support.");
1382 #endif
1383 		}
1384 	;
1385 
1386 opt_hash_check
1387 	:	T_Ignorehash
1388 			{ $$ = FALSE; }
1389 	|	T_Checkhash
1390 			{ $$ = TRUE; }
1391 	|	/*EMPTY*/
1392 			{  $$ = TRUE; }
1393 	;
1394 
1395 misc_cmd_str_keyword
1396 	:	T_Ident
1397 	;
1398 
1399 misc_cmd_str_lcl_keyword
1400 	:	T_Logfile
1401 	|	T_Pidfile
1402 	|	T_Saveconfigdir
1403 	;
1404 
1405 drift_parm
1406 	:	T_String
1407 		{
1408 			if (lex_from_file()) {
1409 				attr_val *av;
1410 				av = create_attr_sval(T_Driftfile, $1);
1411 				APPEND_G_FIFO(cfgt.vars, av);
1412 			} else {
1413 				YYFREE($1);
1414 				yyerror("driftfile remote configuration ignored");
1415 			}
1416 		}
1417 	|	T_String T_Double
1418 		{
1419 			if (lex_from_file()) {
1420 				attr_val *av;
1421 				av = create_attr_sval(T_Driftfile, $1);
1422 				APPEND_G_FIFO(cfgt.vars, av);
1423 				av = create_attr_dval(T_WanderThreshold, $2);
1424 				APPEND_G_FIFO(cfgt.vars, av);
1425 			msyslog(LOG_WARNING,
1426 				"'driftfile FILENAME WanderValue' is deprecated, "
1427 				"please use separate 'driftfile FILENAME' and "
1428 				"'nonvolatile WanderValue' lines instead.");
1429 			} else {
1430 				YYFREE($1);
1431 				yyerror("driftfile remote configuration ignored");
1432 			}
1433 		}
1434 	|	/* Null driftfile,  indicated by empty string "" */
1435 		{
1436 			if (lex_from_file()) {
1437 				attr_val *av;
1438 				av = create_attr_sval(T_Driftfile, estrdup(""));
1439 				APPEND_G_FIFO(cfgt.vars, av);
1440 			} else {
1441 				yyerror("driftfile remote configuration ignored");
1442 			}
1443 		}
1444 	;
1445 
1446 pollskew_list
1447 	:	/* empty */
1448 			{ $$ = NULL; }
1449 	|	pollskew_list pollskew_spec
1450 			{ $$ = append_gen_fifo($1, $2); }
1451 	;
1452 
1453 pollskew_spec
1454 	:	pollskew_cycle T_Integer '|' T_Integer
1455 		{
1456 			if ($2 < 0 || $4 < 0) {
1457 				/* bad numbers */
1458 				yyerror("pollskewlist: skew values must be >=0");
1459 				destroy_attr_val($1);
1460 				$1 = NULL;
1461 			} else if ($1 == NULL) {
1462 				yyerror("pollskewlist: poll value must be 3-17, inclusive");
1463 			} else if ($1->attr <= 0) {
1464 				/* process default range */
1465 				$1->value.r.first = $2;
1466 				$1->value.r.last  = $4;
1467 			} else if ($2 < (1 << ($1->attr - 1)) && $4 < (1 << ($1->attr - 1))) {
1468 				$1->value.r.first = $2;
1469 				$1->value.r.last  = $4;
1470 			} else {
1471 				yyerror("pollskewlist: randomization limit must be <= half the poll interval");
1472 				destroy_attr_val($1);
1473 				$1 = NULL;
1474 			}
1475 			$$ = $1;
1476 		}
1477 	;
1478 
1479 pollskew_cycle
1480 	:	T_Integer
1481 		{
1482 			$$ = ($1 >= NTP_MINPOLL && $1 <= NTP_MAXPOLL)
1483 				? create_attr_rval($1, 0, 0)
1484 				: NULL;
1485 		}
1486 	|	T_Default { $$ = create_attr_rval(-1, 0, 0); }
1487 	;
1488 
1489 
1490 variable_assign
1491 	:	T_String '=' T_String t_default_or_zero
1492 			{ $$ = create_setvar_node($1, $3, $4); }
1493 	;
1494 
1495 t_default_or_zero
1496 	:	T_Default
1497 	|	/* empty, no "default" modifier */
1498 			{ $$ = 0; }
1499 	;
1500 
1501 trap_option_list
1502 	:	/* empty list */
1503 			{ $$ = NULL; }
1504 	|	trap_option_list trap_option
1505 		{
1506 			$$ = $1;
1507 			APPEND_G_FIFO($$, $2);
1508 		}
1509 	;
1510 
1511 trap_option
1512 	:	T_Port T_Integer
1513 			{ $$ = create_attr_ival($1, $2); }
1514 	|	T_Interface ip_address
1515 		{
1516 			$$ = create_attr_sval($1, estrdup($2->address));
1517 			destroy_address_node($2);
1518 		}
1519 	;
1520 
1521 log_config_list
1522 	:	log_config_list log_config_command
1523 		{
1524 			$$ = $1;
1525 			APPEND_G_FIFO($$, $2);
1526 		}
1527 	|	log_config_command
1528 		{
1529 			$$ = NULL;
1530 			APPEND_G_FIFO($$, $1);
1531 		}
1532 	;
1533 
1534 log_config_command
1535 	:	T_String
1536 		{
1537 			char	prefix;
1538 			char *	type;
1539 
1540 			switch ($1[0]) {
1541 
1542 			case '+':
1543 			case '-':
1544 			case '=':
1545 				prefix = $1[0];
1546 				type = $1 + 1;
1547 				break;
1548 
1549 			default:
1550 				prefix = '=';
1551 				type = $1;
1552 			}
1553 
1554 			$$ = create_attr_sval(prefix, estrdup(type));
1555 			YYFREE($1);
1556 		}
1557 	;
1558 
1559 interface_command
1560 	:	interface_nic nic_rule_action nic_rule_class
1561 		{
1562 			nic_rule_node *nrn;
1563 
1564 			nrn = create_nic_rule_node($3, NULL, $2);
1565 			APPEND_G_FIFO(cfgt.nic_rules, nrn);
1566 		}
1567 	|	interface_nic nic_rule_action T_String
1568 		{
1569 			nic_rule_node *nrn;
1570 
1571 			nrn = create_nic_rule_node(0, $3, $2);
1572 			APPEND_G_FIFO(cfgt.nic_rules, nrn);
1573 		}
1574 	;
1575 
1576 interface_nic
1577 	:	T_Interface
1578 	|	T_Nic
1579 	;
1580 
1581 nic_rule_class
1582 	:	T_All
1583 	|	T_Ipv4
1584 	|	T_Ipv6
1585 	|	T_Wildcard
1586 	;
1587 
1588 nic_rule_action
1589 	:	T_Listen
1590 	|	T_Ignore
1591 	|	T_Drop
1592 	;
1593 
1594 reset_command
1595 	:	T_Reset counter_set_list
1596 			{ CONCAT_G_FIFOS(cfgt.reset_counters, $2); }
1597 	;
1598 
1599 counter_set_list
1600 	:	counter_set_list counter_set_keyword
1601 		{
1602 			$$ = $1;
1603 			APPEND_G_FIFO($$, create_int_node($2));
1604 		}
1605 	|	counter_set_keyword
1606 		{
1607 			$$ = NULL;
1608 			APPEND_G_FIFO($$, create_int_node($1));
1609 		}
1610 	;
1611 
1612 counter_set_keyword
1613 	:	T_Allpeers
1614 	|	T_Auth
1615 	|	T_Ctl
1616 	|	T_Io
1617 	|	T_Mem
1618 	|	T_Sys
1619 	|	T_Timer
1620 	;
1621 
1622 
1623 
1624 /* Miscellaneous Rules
1625  * -------------------
1626  */
1627 
1628 integer_list
1629 	:	integer_list T_Integer
1630 		{
1631 			$$ = $1;
1632 			APPEND_G_FIFO($$, create_int_node($2));
1633 		}
1634 	|	T_Integer
1635 		{
1636 			$$ = NULL;
1637 			APPEND_G_FIFO($$, create_int_node($1));
1638 		}
1639 	;
1640 
1641 integer_list_range
1642 	:	integer_list_range integer_list_range_elt
1643 		{
1644 			$$ = $1;
1645 			APPEND_G_FIFO($$, $2);
1646 		}
1647 	|	integer_list_range_elt
1648 		{
1649 			$$ = NULL;
1650 			APPEND_G_FIFO($$, $1);
1651 		}
1652 	;
1653 
1654 integer_list_range_elt
1655 	:	T_Integer
1656 			{ $$ = create_attr_ival('i', $1); }
1657 	|	integer_range
1658 	;
1659 
1660 integer_range
1661 	:	'(' T_Integer T_Ellipsis T_Integer ')'
1662 			{ $$ = create_attr_rval('-', $2, $4); }
1663 	;
1664 
1665 string_list
1666 	:	string_list T_String
1667 		{
1668 			$$ = $1;
1669 			APPEND_G_FIFO($$, create_string_node($2));
1670 		}
1671 	|	T_String
1672 		{
1673 			$$ = NULL;
1674 			APPEND_G_FIFO($$, create_string_node($1));
1675 		}
1676 	;
1677 
1678 address_list
1679 	:	address_list address
1680 		{
1681 			$$ = $1;
1682 			APPEND_G_FIFO($$, $2);
1683 		}
1684 	|	address
1685 		{
1686 			$$ = NULL;
1687 			APPEND_G_FIFO($$, $1);
1688 		}
1689 	;
1690 
1691 boolean
1692 	:	T_Integer
1693 		{
1694 			if ($1 != 0 && $1 != 1) {
1695 				yyerror("Integer value is not boolean (0 or 1). Assuming 1");
1696 				$$ = 1;
1697 			} else {
1698 				$$ = $1;
1699 			}
1700 		}
1701 	|	T_True	{ $$ = 1; }
1702 	|	T_False	{ $$ = 0; }
1703 	;
1704 
1705 number
1706 	:	T_Integer	{ $$ = (double)$1; }
1707 	|	T_Double
1708 	;
1709 
1710 basedate
1711 	:	T_Basedate T_String
1712 			{ $$ = basedate_eval_string($2); YYFREE($2); }
1713 
1714 /* Simulator Configuration Commands
1715  * --------------------------------
1716  */
1717 
1718 simulate_command
1719 	:	sim_conf_start '{' sim_init_statement_list sim_server_list '}'
1720 		{
1721 			sim_node *sn;
1722 
1723 			sn =  create_sim_node($3, $4);
1724 			APPEND_G_FIFO(cfgt.sim_details, sn);
1725 
1726 			/* Revert from ; to \n for end-of-command */
1727 			old_config_style = 1;
1728 		}
1729 	;
1730 
1731 /* The following is a terrible hack to get the configuration file to
1732  * treat newlines as whitespace characters within the simulation.
1733  * This is needed because newlines are significant in the rest of the
1734  * configuration file.
1735  */
1736 sim_conf_start
1737 	:	T_Simulate { old_config_style = 0; }
1738 	;
1739 
1740 sim_init_statement_list
1741 	:	sim_init_statement_list sim_init_statement T_EOC
1742 		{
1743 			$$ = $1;
1744 			APPEND_G_FIFO($$, $2);
1745 		}
1746 	|	sim_init_statement T_EOC
1747 		{
1748 			$$ = NULL;
1749 			APPEND_G_FIFO($$, $1);
1750 		}
1751 	;
1752 
1753 sim_init_statement
1754 	:	sim_init_keyword '=' number
1755 			{ $$ = create_attr_dval($1, $3); }
1756 	;
1757 
1758 sim_init_keyword
1759 	:	T_Beep_Delay
1760 	|	T_Sim_Duration
1761 	;
1762 
1763 sim_server_list
1764 	:	sim_server_list sim_server
1765 		{
1766 			$$ = $1;
1767 			APPEND_G_FIFO($$, $2);
1768 		}
1769 	|	sim_server
1770 		{
1771 			$$ = NULL;
1772 			APPEND_G_FIFO($$, $1);
1773 		}
1774 	;
1775 
1776 sim_server
1777 	:	sim_server_name '{' sim_server_offset sim_act_list '}'
1778 			{ $$ = ONLY_SIM(create_sim_server($1, $3, $4)); }
1779 	;
1780 
1781 sim_server_offset
1782 	:	T_Server_Offset '=' number T_EOC
1783 			{ $$ = $3; }
1784 	;
1785 
1786 sim_server_name
1787 	:	T_Server '=' address
1788 			{ $$ = $3; }
1789 	;
1790 
1791 sim_act_list
1792 	:	sim_act_list sim_act
1793 		{
1794 			$$ = $1;
1795 			APPEND_G_FIFO($$, $2);
1796 		}
1797 	|	sim_act
1798 		{
1799 			$$ = NULL;
1800 			APPEND_G_FIFO($$, $1);
1801 		}
1802 	;
1803 
1804 sim_act
1805 	:	T_Duration '=' number '{' sim_act_stmt_list '}'
1806 			{ $$ = ONLY_SIM(create_sim_script_info($3, $5)); }
1807 	;
1808 
1809 sim_act_stmt_list
1810 	:	sim_act_stmt_list sim_act_stmt T_EOC
1811 		{
1812 			$$ = $1;
1813 			APPEND_G_FIFO($$, $2);
1814 		}
1815 	|	sim_act_stmt T_EOC
1816 		{
1817 			$$ = NULL;
1818 			APPEND_G_FIFO($$, $1);
1819 		}
1820 	;
1821 
1822 sim_act_stmt
1823 	:	sim_act_keyword '=' number
1824 			{ $$ = create_attr_dval($1, $3); }
1825 	;
1826 
1827 sim_act_keyword
1828 	:	T_Freq_Offset
1829 	|	T_Wander
1830 	|	T_Jitter
1831 	|	T_Prop_Delay
1832 	|	T_Proc_Delay
1833 	;
1834 
1835 %%
1836 
1837 void
1838 yyerror(
1839 	const char *msg
1840 	)
1841 {
1842 	int retval;
1843 	struct FILE_INFO * ip_ctx;
1844 
1845 	ip_ctx = lex_current();
1846 	ip_ctx->errpos = ip_ctx->tokpos;
1847 
1848 	msyslog(LOG_ERR, "line %d column %d %s",
1849 		ip_ctx->errpos.nline, ip_ctx->errpos.ncol, msg);
1850 	if (!lex_from_file()) {
1851 		/* Save the error message in the correct buffer */
1852 		retval = snprintf(remote_config.err_msg + remote_config.err_pos,
1853 				  sizeof remote_config.err_msg - remote_config.err_pos,
1854 				  "column %d %s",
1855 				  ip_ctx->errpos.ncol, msg);
1856 
1857 		/* Increment the value of err_pos */
1858 		if (retval > 0)
1859 			remote_config.err_pos += retval;
1860 
1861 		/* Increment the number of errors */
1862 		++remote_config.no_errors;
1863 	}
1864 }
1865 
1866 
1867 /*
1868  * token_name - convert T_ token integers to text
1869  *		example: token_name(T_Server) returns "T_Server"
1870  */
1871 const char *
1872 token_name(
1873 	int token
1874 	)
1875 {
1876 	return yytname[YYTRANSLATE(token)];
1877 }
1878 
1879 
1880 /* Initial Testing function -- ignore */
1881 #if 0
1882 int main(int argc, char *argv[])
1883 {
1884 	ip_file = FOPEN(argv[1], "r");
1885 	if (!ip_file)
1886 		fprintf(stderr, "ERROR!! Could not open file: %s\n", argv[1]);
1887 	yyparse();
1888 	return 0;
1889 }
1890 #endif
1891 
1892