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