Annotation of embedaddon/ntp/ntpd/ntp_parser.y, revision 1.1.1.1
1.1 misho 1: /* ntp_parser.y
2: *
3: * The parser for the NTP configuration file.
4: *
5: * Written By: Sachin Kamboj
6: * University of Delaware
7: * Newark, DE 19711
8: * Copyright (c) 2006
9: */
10:
11: %{
12: #ifdef HAVE_CONFIG_H
13: # include <config.h>
14: #endif
15:
16: #include "ntp.h"
17: #include "ntpd.h"
18: #include "ntp_machine.h"
19: #include "ntp_stdlib.h"
20: #include "ntp_filegen.h"
21: #include "ntp_data_structures.h"
22: #include "ntp_scanner.h"
23: #include "ntp_config.h"
24: #include "ntp_crypto.h"
25:
26: #include "ntpsim.h" /* HMS: Do we really want this all the time? */
27: /* SK: It might be a good idea to always
28: include the simulator code. That way
29: someone can use the same configuration file
30: for both the simulator and the daemon
31: */
32:
33:
34: struct FILE_INFO *ip_file; /* Pointer to the configuration file stream */
35:
36: #define YYMALLOC emalloc
37: #define YYFREE free
38: #define YYERROR_VERBOSE
39: #define YYMAXDEPTH 1000 /* stop the madness sooner */
40: void yyerror(const char *msg);
41: extern int input_from_file; /* 0=input from ntpq :config */
42: %}
43:
44: /*
45: * Enable generation of token names array even without YYDEBUG.
46: * We access via token_name() defined below.
47: */
48: %token-table
49:
50: %union {
51: char *String;
52: double Double;
53: int Integer;
54: void *VoidPtr;
55: queue *Queue;
56: struct attr_val *Attr_val;
57: struct address_node *Address_node;
58: struct setvar_node *Set_var;
59:
60: /* Simulation types */
61: server_info *Sim_server;
62: script_info *Sim_script;
63: }
64:
65: /* TERMINALS (do not appear left of colon) */
66: %token <Integer> T_Age
67: %token <Integer> T_All
68: %token <Integer> T_Allan
69: %token <Integer> T_Auth
70: %token <Integer> T_Autokey
71: %token <Integer> T_Automax
72: %token <Integer> T_Average
73: %token <Integer> T_Bclient
74: %token <Integer> T_Beacon
75: %token <Integer> T_Bias
76: %token <Integer> T_Broadcast
77: %token <Integer> T_Broadcastclient
78: %token <Integer> T_Broadcastdelay
79: %token <Integer> T_Burst
80: %token <Integer> T_Calibrate
81: %token <Integer> T_Calldelay
82: %token <Integer> T_Ceiling
83: %token <Integer> T_Clockstats
84: %token <Integer> T_Cohort
85: %token <Integer> T_ControlKey
86: %token <Integer> T_Crypto
87: %token <Integer> T_Cryptostats
88: %token <Integer> T_Day
89: %token <Integer> T_Default
90: %token <Integer> T_Digest
91: %token <Integer> T_Disable
92: %token <Integer> T_Discard
93: %token <Integer> T_Dispersion
94: %token <Double> T_Double
95: %token <Integer> T_Driftfile
96: %token <Integer> T_Drop
97: %token <Integer> T_Ellipsis /* "..." not "ellipsis" */
98: %token <Integer> T_Enable
99: %token <Integer> T_End
100: %token <Integer> T_False
101: %token <Integer> T_File
102: %token <Integer> T_Filegen
103: %token <Integer> T_Flag1
104: %token <Integer> T_Flag2
105: %token <Integer> T_Flag3
106: %token <Integer> T_Flag4
107: %token <Integer> T_Flake
108: %token <Integer> T_Floor
109: %token <Integer> T_Freq
110: %token <Integer> T_Fudge
111: %token <Integer> T_Host
112: %token <Integer> T_Huffpuff
113: %token <Integer> T_Iburst
114: %token <Integer> T_Ident
115: %token <Integer> T_Ignore
116: %token <Integer> T_Includefile
117: %token <Integer> T_Integer
118: %token <Integer> T_Interface
119: %token <Integer> T_Ipv4
120: %token <Integer> T_Ipv4_flag
121: %token <Integer> T_Ipv6
122: %token <Integer> T_Ipv6_flag
123: %token <Integer> T_Kernel
124: %token <Integer> T_Key
125: %token <Integer> T_Keys
126: %token <Integer> T_Keysdir
127: %token <Integer> T_Kod
128: %token <Integer> T_Mssntp
129: %token <Integer> T_Leapfile
130: %token <Integer> T_Limited
131: %token <Integer> T_Link
132: %token <Integer> T_Listen
133: %token <Integer> T_Logconfig
134: %token <Integer> T_Logfile
135: %token <Integer> T_Loopstats
136: %token <Integer> T_Lowpriotrap
137: %token <Integer> T_Manycastclient
138: %token <Integer> T_Manycastserver
139: %token <Integer> T_Mask
140: %token <Integer> T_Maxclock
141: %token <Integer> T_Maxdist
142: %token <Integer> T_Maxpoll
143: %token <Integer> T_Minclock
144: %token <Integer> T_Mindist
145: %token <Integer> T_Minimum
146: %token <Integer> T_Minpoll
147: %token <Integer> T_Minsane
148: %token <Integer> T_Mode
149: %token <Integer> T_Monitor
150: %token <Integer> T_Month
151: %token <Integer> T_Multicastclient
152: %token <Integer> T_Nic
153: %token <Integer> T_Nolink
154: %token <Integer> T_Nomodify
155: %token <Integer> T_None
156: %token <Integer> T_Nopeer
157: %token <Integer> T_Noquery
158: %token <Integer> T_Noselect
159: %token <Integer> T_Noserve
160: %token <Integer> T_Notrap
161: %token <Integer> T_Notrust
162: %token <Integer> T_Ntp
163: %token <Integer> T_Ntpport
164: %token <Integer> T_NtpSignDsocket
165: %token <Integer> T_Orphan
166: %token <Integer> T_Panic
167: %token <Integer> T_Peer
168: %token <Integer> T_Peerstats
169: %token <Integer> T_Phone
170: %token <Integer> T_Pid
171: %token <Integer> T_Pidfile
172: %token <Integer> T_Pool
173: %token <Integer> T_Port
174: %token <Integer> T_Preempt
175: %token <Integer> T_Prefer
176: %token <Integer> T_Protostats
177: %token <Integer> T_Pw
178: %token <Integer> T_Qos
179: %token <Integer> T_Randfile
180: %token <Integer> T_Rawstats
181: %token <Integer> T_Refid
182: %token <Integer> T_Requestkey
183: %token <Integer> T_Restrict
184: %token <Integer> T_Revoke
185: %token <Integer> T_Saveconfigdir
186: %token <Integer> T_Server
187: %token <Integer> T_Setvar
188: %token <Integer> T_Sign
189: %token <Integer> T_Statistics
190: %token <Integer> T_Stats
191: %token <Integer> T_Statsdir
192: %token <Integer> T_Step
193: %token <Integer> T_Stepout
194: %token <Integer> T_Stratum
195: %token <String> T_String
196: %token <Integer> T_Sysstats
197: %token <Integer> T_Tick
198: %token <Integer> T_Time1
199: %token <Integer> T_Time2
200: %token <Integer> T_Timingstats
201: %token <Integer> T_Tinker
202: %token <Integer> T_Tos
203: %token <Integer> T_Trap
204: %token <Integer> T_True
205: %token <Integer> T_Trustedkey
206: %token <Integer> T_Ttl
207: %token <Integer> T_Type
208: %token <Integer> T_Unconfig
209: %token <Integer> T_Unpeer
210: %token <Integer> T_Version
211: %token <Integer> T_WanderThreshold /* Not a token */
212: %token <Integer> T_Week
213: %token <Integer> T_Wildcard
214: %token <Integer> T_Xleave
215: %token <Integer> T_Year
216: %token <Integer> T_Flag /* Not an actual token */
217: %token <Integer> T_Void /* Not an actual token */
218: %token <Integer> T_EOC
219:
220:
221: /* NTP Simulator Tokens */
222: %token <Integer> T_Simulate
223: %token <Integer> T_Beep_Delay
224: %token <Integer> T_Sim_Duration
225: %token <Integer> T_Server_Offset
226: %token <Integer> T_Duration
227: %token <Integer> T_Freq_Offset
228: %token <Integer> T_Wander
229: %token <Integer> T_Jitter
230: %token <Integer> T_Prop_Delay
231: %token <Integer> T_Proc_Delay
232:
233:
234:
235: /*** NON-TERMINALS ***/
236: %type <Integer> access_control_flag
237: %type <Queue> ac_flag_list
238: %type <Address_node> address
239: %type <Integer> address_fam
240: %type <Queue> address_list
241: %type <Integer> boolean
242: %type <Integer> client_type
243: %type <Attr_val> crypto_command
244: %type <Queue> crypto_command_list
245: %type <Integer> crypto_str_keyword
246: %type <Attr_val> discard_option
247: %type <Integer> discard_option_keyword
248: %type <Queue> discard_option_list
249: %type <Integer> enable_disable
250: %type <Attr_val> filegen_option
251: %type <Queue> filegen_option_list
252: %type <Integer> filegen_type
253: %type <Attr_val> fudge_factor
254: %type <Integer> fudge_factor_bool_keyword
255: %type <Integer> fudge_factor_dbl_keyword
256: %type <Queue> fudge_factor_list
257: %type <Queue> integer_list
258: %type <Queue> integer_list_range
259: %type <Attr_val> integer_list_range_elt
260: %type <Attr_val> integer_range
261: %type <Integer> nic_rule_action
262: %type <Integer> interface_command
263: %type <Integer> interface_nic
264: %type <Address_node> ip_address
265: %type <Integer> link_nolink
266: %type <Attr_val> log_config_command
267: %type <Queue> log_config_list
268: %type <Integer> misc_cmd_dbl_keyword
269: %type <Integer> misc_cmd_str_keyword
270: %type <Integer> misc_cmd_str_lcl_keyword
271: %type <Integer> nic_rule_class
272: %type <Double> number
273: %type <Attr_val> option
274: %type <Attr_val> option_flag
275: %type <Integer> option_flag_keyword
276: %type <Queue> option_list
277: %type <Attr_val> option_int
278: %type <Integer> option_int_keyword
279: %type <Integer> stat
280: %type <Queue> stats_list
281: %type <Queue> string_list
282: %type <Attr_val> system_option
283: %type <Integer> system_option_flag_keyword
284: %type <Queue> system_option_list
285: %type <Integer> t_default_or_zero
286: %type <Integer> tinker_option_keyword
287: %type <Attr_val> tinker_option
288: %type <Queue> tinker_option_list
289: %type <Attr_val> tos_option
290: %type <Integer> tos_option_dbl_keyword
291: %type <Integer> tos_option_int_keyword
292: %type <Queue> tos_option_list
293: %type <Attr_val> trap_option
294: %type <Queue> trap_option_list
295: %type <Integer> unpeer_keyword
296: %type <Set_var> variable_assign
297:
298: /* NTP Simulator non-terminals */
299: %type <Queue> sim_init_statement_list
300: %type <Attr_val> sim_init_statement
301: %type <Queue> sim_server_list
302: %type <Sim_server> sim_server
303: %type <Double> sim_server_offset
304: %type <Address_node> sim_server_name
305: %type <Queue> sim_act_list
306: %type <Sim_script> sim_act
307: %type <Queue> sim_act_stmt_list
308: %type <Attr_val> sim_act_stmt
309:
310: %%
311:
312: /* ntp.conf
313: * Configuration File Grammar
314: * --------------------------
315: */
316:
317: configuration
318: : command_list
319: ;
320:
321: command_list
322: : command_list command T_EOC
323: | command T_EOC
324: | error T_EOC
325: {
326: /* I will need to incorporate much more fine grained
327: * error messages. The following should suffice for
328: * the time being.
329: */
330: msyslog(LOG_ERR,
331: "syntax error in %s line %d, column %d",
332: ip_file->fname,
333: ip_file->err_line_no,
334: ip_file->err_col_no);
335: }
336: ;
337:
338: command : /* NULL STATEMENT */
339: | server_command
340: | unpeer_command
341: | other_mode_command
342: | authentication_command
343: | monitoring_command
344: | access_control_command
345: | orphan_mode_command
346: | fudge_command
347: | system_option_command
348: | tinker_command
349: | miscellaneous_command
350: | simulate_command
351: ;
352:
353: /* Server Commands
354: * ---------------
355: */
356:
357: server_command
358: : client_type address option_list
359: {
360: struct peer_node *my_node = create_peer_node($1, $2, $3);
361: if (my_node)
362: enqueue(cfgt.peers, my_node);
363: }
364: | client_type address
365: {
366: struct peer_node *my_node = create_peer_node($1, $2, NULL);
367: if (my_node)
368: enqueue(cfgt.peers, my_node);
369: }
370: ;
371:
372: client_type
373: : T_Server
374: | T_Pool
375: | T_Peer
376: | T_Broadcast
377: | T_Manycastclient
378: ;
379:
380: address
381: : ip_address
382: | address_fam T_String
383: { $$ = create_address_node($2, $1); }
384: ;
385:
386: ip_address
387: : T_String
388: { $$ = create_address_node($1, 0); }
389: ;
390:
391: address_fam
392: : T_Ipv4_flag
393: { $$ = AF_INET; }
394: | T_Ipv6_flag
395: { $$ = AF_INET6; }
396: ;
397:
398: option_list
399: : option_list option { $$ = enqueue($1, $2); }
400: | option { $$ = enqueue_in_new_queue($1); }
401: ;
402:
403: option
404: : option_flag
405: | option_int
406: | T_Bias number
407: { $$ = create_attr_dval($1, $2); }
408: ;
409:
410: option_flag
411: : option_flag_keyword
412: { $$ = create_attr_ival(T_Flag, $1); }
413: ;
414:
415: option_flag_keyword
416: : T_Autokey
417: | T_Burst
418: | T_Iburst
419: | T_Noselect
420: | T_Preempt
421: | T_Prefer
422: | T_True
423: | T_Xleave
424: ;
425:
426: option_int
427: : option_int_keyword T_Integer
428: { $$ = create_attr_ival($1, $2); }
429: ;
430:
431: option_int_keyword
432: : T_Key
433: | T_Minpoll
434: | T_Maxpoll
435: | T_Ttl
436: | T_Mode
437: | T_Version
438: ;
439:
440:
441:
442: /* unpeer commands
443: * ---------------
444: */
445:
446: unpeer_command
447: : unpeer_keyword address
448: {
449: struct unpeer_node *my_node = create_unpeer_node($2);
450: if (my_node)
451: enqueue(cfgt.unpeers, my_node);
452: }
453: ;
454: unpeer_keyword
455: : T_Unconfig
456: | T_Unpeer
457: ;
458:
459:
460: /* Other Modes
461: * (broadcastclient manycastserver multicastclient)
462: * ------------------------------------------------
463: */
464:
465: other_mode_command
466: : T_Broadcastclient
467: { cfgt.broadcastclient = 1; }
468: | T_Manycastserver address_list
469: { append_queue(cfgt.manycastserver, $2); }
470: | T_Multicastclient address_list
471: { append_queue(cfgt.multicastclient, $2); }
472: ;
473:
474:
475:
476: /* Authentication Commands
477: * -----------------------
478: */
479:
480: authentication_command
481: : T_Automax T_Integer
482: { enqueue(cfgt.vars, create_attr_ival($1, $2)); }
483: | T_ControlKey T_Integer
484: { cfgt.auth.control_key = $2; }
485: | T_Crypto crypto_command_list
486: {
487: cfgt.auth.cryptosw++;
488: append_queue(cfgt.auth.crypto_cmd_list, $2);
489: }
490: | T_Keys T_String
491: { cfgt.auth.keys = $2; }
492: | T_Keysdir T_String
493: { cfgt.auth.keysdir = $2; }
494: | T_Requestkey T_Integer
495: { cfgt.auth.request_key = $2; }
496: | T_Revoke T_Integer
497: { cfgt.auth.revoke = $2; }
498: | T_Trustedkey integer_list_range
499: { cfgt.auth.trusted_key_list = $2; }
500: | T_NtpSignDsocket T_String
501: { cfgt.auth.ntp_signd_socket = $2; }
502: ;
503:
504: crypto_command_list
505: : /* empty list */
506: { $$ = create_queue(); }
507: | crypto_command_list crypto_command
508: {
509: if ($2 != NULL)
510: $$ = enqueue($1, $2);
511: else
512: $$ = $1;
513: }
514: ;
515:
516: crypto_command
517: : crypto_str_keyword T_String
518: { $$ = create_attr_sval($1, $2); }
519: | T_Revoke T_Integer
520: {
521: $$ = NULL;
522: cfgt.auth.revoke = $2;
523: msyslog(LOG_WARNING,
524: "'crypto revoke %d' is deprecated, "
525: "please use 'revoke %d' instead.",
526: cfgt.auth.revoke, cfgt.auth.revoke);
527: }
528: ;
529:
530: crypto_str_keyword
531: : T_Host
532: | T_Ident
533: | T_Pw
534: | T_Randfile
535: | T_Sign
536: | T_Digest
537: ;
538:
539:
540: /* Orphan Mode Commands
541: * --------------------
542: */
543:
544: orphan_mode_command
545: : T_Tos tos_option_list
546: { append_queue(cfgt.orphan_cmds,$2); }
547: ;
548:
549: tos_option_list
550: : tos_option_list tos_option { $$ = enqueue($1, $2); }
551: | tos_option { $$ = enqueue_in_new_queue($1); }
552: ;
553:
554: tos_option
555: : tos_option_int_keyword T_Integer
556: { $$ = create_attr_dval($1, (double)$2); }
557: | tos_option_dbl_keyword number
558: { $$ = create_attr_dval($1, $2); }
559: | T_Cohort boolean
560: { $$ = create_attr_dval($1, (double)$2); }
561: ;
562:
563: tos_option_int_keyword
564: : T_Ceiling
565: | T_Floor
566: | T_Orphan
567: | T_Minsane
568: | T_Beacon
569: ;
570:
571: tos_option_dbl_keyword
572: : T_Mindist
573: | T_Maxdist
574: | T_Minclock
575: | T_Maxclock
576: ;
577:
578:
579: /* Monitoring Commands
580: * -------------------
581: */
582:
583: monitoring_command
584: : T_Statistics stats_list
585: { append_queue(cfgt.stats_list, $2); }
586: | T_Statsdir T_String
587: {
588: if (input_from_file) {
589: cfgt.stats_dir = $2;
590: } else {
591: YYFREE($2);
592: yyerror("statsdir remote configuration ignored");
593: }
594: }
595: | T_Filegen stat filegen_option_list
596: {
597: enqueue(cfgt.filegen_opts,
598: create_filegen_node($2, $3));
599: }
600: ;
601:
602: stats_list
603: : stats_list stat { $$ = enqueue($1, create_ival($2)); }
604: | stat { $$ = enqueue_in_new_queue(create_ival($1)); }
605: ;
606:
607: stat
608: : T_Clockstats
609: | T_Cryptostats
610: | T_Loopstats
611: | T_Peerstats
612: | T_Rawstats
613: | T_Sysstats
614: | T_Timingstats
615: | T_Protostats
616: ;
617:
618: filegen_option_list
619: : /* empty list */
620: { $$ = create_queue(); }
621: | filegen_option_list filegen_option
622: {
623: if ($2 != NULL)
624: $$ = enqueue($1, $2);
625: else
626: $$ = $1;
627: }
628: ;
629:
630: filegen_option
631: : T_File T_String
632: {
633: if (input_from_file) {
634: $$ = create_attr_sval($1, $2);
635: } else {
636: $$ = NULL;
637: YYFREE($2);
638: yyerror("filegen file remote config ignored");
639: }
640: }
641: | T_Type filegen_type
642: {
643: if (input_from_file) {
644: $$ = create_attr_ival($1, $2);
645: } else {
646: $$ = NULL;
647: yyerror("filegen type remote config ignored");
648: }
649: }
650: | link_nolink
651: {
652: const char *err;
653:
654: if (input_from_file) {
655: $$ = create_attr_ival(T_Flag, $1);
656: } else {
657: $$ = NULL;
658: if (T_Link == $1)
659: err = "filegen link remote config ignored";
660: else
661: err = "filegen nolink remote config ignored";
662: yyerror(err);
663: }
664: }
665: | enable_disable
666: { $$ = create_attr_ival(T_Flag, $1); }
667: ;
668:
669: link_nolink
670: : T_Link
671: | T_Nolink
672: ;
673:
674: enable_disable
675: : T_Enable
676: | T_Disable
677: ;
678:
679: filegen_type
680: : T_None
681: | T_Pid
682: | T_Day
683: | T_Week
684: | T_Month
685: | T_Year
686: | T_Age
687: ;
688:
689:
690: /* Access Control Commands
691: * -----------------------
692: */
693:
694: access_control_command
695: : T_Discard discard_option_list
696: {
697: append_queue(cfgt.discard_opts, $2);
698: }
699: | T_Restrict address ac_flag_list
700: {
701: enqueue(cfgt.restrict_opts,
702: create_restrict_node($2, NULL, $3, ip_file->line_no));
703: }
704: | T_Restrict T_Default ac_flag_list
705: {
706: enqueue(cfgt.restrict_opts,
707: create_restrict_node(NULL, NULL, $3, ip_file->line_no));
708: }
709: | T_Restrict T_Ipv4_flag T_Default ac_flag_list
710: {
711: enqueue(cfgt.restrict_opts,
712: create_restrict_node(
713: create_address_node(
714: estrdup("0.0.0.0"),
715: AF_INET),
716: create_address_node(
717: estrdup("0.0.0.0"),
718: AF_INET),
719: $4,
720: ip_file->line_no));
721: }
722: | T_Restrict T_Ipv6_flag T_Default ac_flag_list
723: {
724: enqueue(cfgt.restrict_opts,
725: create_restrict_node(
726: create_address_node(
727: estrdup("::"),
728: AF_INET6),
729: create_address_node(
730: estrdup("::"),
731: AF_INET6),
732: $4,
733: ip_file->line_no));
734: }
735: | T_Restrict ip_address T_Mask ip_address ac_flag_list
736: {
737: enqueue(cfgt.restrict_opts,
738: create_restrict_node($2, $4, $5, ip_file->line_no));
739: }
740: ;
741:
742: ac_flag_list
743: : /* empty list is allowed */
744: { $$ = create_queue(); }
745: | ac_flag_list access_control_flag
746: { $$ = enqueue($1, create_ival($2)); }
747: ;
748:
749: access_control_flag
750: : T_Flake
751: | T_Ignore
752: | T_Kod
753: | T_Mssntp
754: | T_Limited
755: | T_Lowpriotrap
756: | T_Nomodify
757: | T_Nopeer
758: | T_Noquery
759: | T_Noserve
760: | T_Notrap
761: | T_Notrust
762: | T_Ntpport
763: | T_Version
764: ;
765:
766: discard_option_list
767: : discard_option_list discard_option
768: { $$ = enqueue($1, $2); }
769: | discard_option
770: { $$ = enqueue_in_new_queue($1); }
771: ;
772:
773: discard_option
774: : discard_option_keyword T_Integer
775: { $$ = create_attr_ival($1, $2); }
776: ;
777:
778: discard_option_keyword
779: : T_Average
780: | T_Minimum
781: | T_Monitor
782: ;
783:
784:
785: /* Fudge Commands
786: * --------------
787: */
788:
789: fudge_command
790: : T_Fudge address fudge_factor_list
791: { enqueue(cfgt.fudge, create_addr_opts_node($2, $3)); }
792: ;
793:
794: fudge_factor_list
795: : fudge_factor_list fudge_factor
796: { enqueue($1, $2); }
797: | fudge_factor
798: { $$ = enqueue_in_new_queue($1); }
799: ;
800:
801: fudge_factor
802: : fudge_factor_dbl_keyword number
803: { $$ = create_attr_dval($1, $2); }
804: | fudge_factor_bool_keyword boolean
805: { $$ = create_attr_ival($1, $2); }
806: | T_Stratum T_Integer
807: { $$ = create_attr_ival($1, $2); }
808: | T_Refid T_String
809: { $$ = create_attr_sval($1, $2); }
810: ;
811:
812: fudge_factor_dbl_keyword
813: : T_Time1
814: | T_Time2
815: ;
816:
817: fudge_factor_bool_keyword
818: : T_Flag1
819: | T_Flag2
820: | T_Flag3
821: | T_Flag4
822: ;
823:
824:
825: /* Command for System Options
826: * --------------------------
827: */
828:
829: system_option_command
830: : T_Enable system_option_list
831: { append_queue(cfgt.enable_opts, $2); }
832: | T_Disable system_option_list
833: { append_queue(cfgt.disable_opts, $2); }
834: ;
835:
836: system_option_list
837: : system_option_list system_option
838: {
839: if ($2 != NULL)
840: $$ = enqueue($1, $2);
841: else
842: $$ = $1;
843: }
844: | system_option
845: {
846: if ($1 != NULL)
847: $$ = enqueue_in_new_queue($1);
848: else
849: $$ = create_queue();
850: }
851: ;
852:
853: system_option
854: : system_option_flag_keyword
855: { $$ = create_attr_ival(T_Flag, $1); }
856: | T_Stats
857: {
858: if (input_from_file) {
859: $$ = create_attr_ival(T_Flag, $1);
860: } else {
861: $$ = NULL;
862: yyerror("enable/disable stats remote config ignored");
863: }
864: }
865: ;
866:
867: system_option_flag_keyword
868: : T_Auth
869: | T_Bclient
870: | T_Calibrate
871: | T_Kernel
872: | T_Monitor
873: | T_Ntp
874: ;
875:
876:
877: /* Tinker Commands
878: * ---------------
879: */
880:
881: tinker_command
882: : T_Tinker tinker_option_list { append_queue(cfgt.tinker, $2); }
883: ;
884:
885: tinker_option_list
886: : tinker_option_list tinker_option { $$ = enqueue($1, $2); }
887: | tinker_option { $$ = enqueue_in_new_queue($1); }
888: ;
889:
890: tinker_option
891: : tinker_option_keyword number
892: { $$ = create_attr_dval($1, $2); }
893: ;
894:
895: tinker_option_keyword
896: : T_Allan
897: | T_Dispersion
898: | T_Freq
899: | T_Huffpuff
900: | T_Panic
901: | T_Step
902: | T_Stepout
903: ;
904:
905:
906: /* Miscellaneous Commands
907: * ----------------------
908: */
909:
910: miscellaneous_command
911: : interface_command
912: | misc_cmd_dbl_keyword number
913: {
914: struct attr_val *av;
915:
916: av = create_attr_dval($1, $2);
917: enqueue(cfgt.vars, av);
918: }
919: | misc_cmd_str_keyword T_String
920: {
921: struct attr_val *av;
922:
923: av = create_attr_sval($1, $2);
924: enqueue(cfgt.vars, av);
925: }
926: | misc_cmd_str_lcl_keyword T_String
927: {
928: char error_text[64];
929: struct attr_val *av;
930:
931: if (input_from_file) {
932: av = create_attr_sval($1, $2);
933: enqueue(cfgt.vars, av);
934: } else {
935: YYFREE($2);
936: snprintf(error_text, sizeof(error_text),
937: "%s remote config ignored",
938: keyword($1));
939: yyerror(error_text);
940: }
941: }
942: | T_Includefile T_String command
943: {
944: if (!input_from_file) {
945: yyerror("remote includefile ignored");
946: break;
947: }
948: if (curr_include_level >= MAXINCLUDELEVEL) {
949: fprintf(stderr, "getconfig: Maximum include file level exceeded.\n");
950: msyslog(LOG_ERR, "getconfig: Maximum include file level exceeded.\n");
951: } else {
952: fp[curr_include_level + 1] = F_OPEN(FindConfig($2), "r");
953: if (fp[curr_include_level + 1] == NULL) {
954: fprintf(stderr, "getconfig: Couldn't open <%s>\n", FindConfig($2));
955: msyslog(LOG_ERR, "getconfig: Couldn't open <%s>\n", FindConfig($2));
956: } else {
957: ip_file = fp[++curr_include_level];
958: }
959: }
960: }
961: | T_End
962: {
963: while (curr_include_level != -1)
964: FCLOSE(fp[curr_include_level--]);
965: }
966: | T_Calldelay T_Integer
967: { enqueue(cfgt.vars, create_attr_ival($1, $2)); }
968: | T_Driftfile drift_parm
969: { /* Null action, possibly all null parms */ }
970: | T_Logconfig log_config_list
971: { append_queue(cfgt.logconfig, $2); }
972: | T_Phone string_list
973: { append_queue(cfgt.phone, $2); }
974: | T_Setvar variable_assign
975: { enqueue(cfgt.setvar, $2); }
976: | T_Trap ip_address
977: { enqueue(cfgt.trap, create_addr_opts_node($2, NULL)); }
978: | T_Trap ip_address trap_option_list
979: { enqueue(cfgt.trap, create_addr_opts_node($2, $3)); }
980: | T_Ttl integer_list
981: { append_queue(cfgt.ttl, $2); }
982: ;
983:
984: misc_cmd_dbl_keyword
985: : T_Broadcastdelay
986: | T_Tick
987: ;
988:
989: misc_cmd_str_keyword
990: : T_Leapfile
991: | T_Pidfile
992: | T_Qos
993: ;
994:
995: misc_cmd_str_lcl_keyword
996: : T_Logfile
997: | T_Saveconfigdir
998: ;
999:
1000: drift_parm
1001: : T_String
1002: { enqueue(cfgt.vars, create_attr_sval(T_Driftfile, $1)); }
1003: | T_String T_Double
1004: { enqueue(cfgt.vars, create_attr_dval(T_WanderThreshold, $2));
1005: enqueue(cfgt.vars, create_attr_sval(T_Driftfile, $1)); }
1006: | /* Null driftfile, indicated by null string "\0" */
1007: { enqueue(cfgt.vars, create_attr_sval(T_Driftfile, "\0")); }
1008: ;
1009:
1010: variable_assign
1011: : T_String '=' T_String t_default_or_zero
1012: { $$ = create_setvar_node($1, $3, $4); }
1013: ;
1014:
1015: t_default_or_zero
1016: : T_Default
1017: | /* empty, no "default" modifier */
1018: { $$ = 0; }
1019: ;
1020:
1021: trap_option_list
1022: : trap_option_list trap_option
1023: { $$ = enqueue($1, $2); }
1024: | trap_option { $$ = enqueue_in_new_queue($1); }
1025: ;
1026:
1027: trap_option
1028: : T_Port T_Integer { $$ = create_attr_ival($1, $2); }
1029: | T_Interface ip_address { $$ = create_attr_pval($1, $2); }
1030: ;
1031:
1032: log_config_list
1033: : log_config_list log_config_command { $$ = enqueue($1, $2); }
1034: | log_config_command { $$ = enqueue_in_new_queue($1); }
1035: ;
1036:
1037: log_config_command
1038: : T_String
1039: {
1040: char prefix = $1[0];
1041: char *type = $1 + 1;
1042:
1043: if (prefix != '+' && prefix != '-' && prefix != '=') {
1044: yyerror("Logconfig prefix is not '+', '-' or '='\n");
1045: }
1046: else
1047: $$ = create_attr_sval(prefix, estrdup(type));
1048: YYFREE($1);
1049: }
1050: ;
1051:
1052: interface_command
1053: : interface_nic nic_rule_action nic_rule_class
1054: {
1055: enqueue(cfgt.nic_rules,
1056: create_nic_rule_node($3, NULL, $2));
1057: }
1058: | interface_nic nic_rule_action T_String
1059: {
1060: enqueue(cfgt.nic_rules,
1061: create_nic_rule_node(0, $3, $2));
1062: }
1063: ;
1064:
1065: interface_nic
1066: : T_Interface
1067: | T_Nic
1068: ;
1069:
1070: nic_rule_class
1071: : T_All
1072: | T_Ipv4
1073: | T_Ipv6
1074: | T_Wildcard
1075: ;
1076:
1077: nic_rule_action
1078: : T_Listen
1079: | T_Ignore
1080: | T_Drop
1081: ;
1082:
1083:
1084:
1085: /* Miscellaneous Rules
1086: * -------------------
1087: */
1088:
1089: integer_list
1090: : integer_list T_Integer { $$ = enqueue($1, create_ival($2)); }
1091: | T_Integer { $$ = enqueue_in_new_queue(create_ival($1)); }
1092: ;
1093:
1094: integer_list_range
1095: : integer_list_range integer_list_range_elt
1096: { $$ = enqueue($1, $2); }
1097: | integer_list_range_elt
1098: { $$ = enqueue_in_new_queue($1); }
1099: ;
1100:
1101: integer_list_range_elt
1102: : T_Integer
1103: { $$ = create_attr_ival('i', $1); }
1104: | integer_range /* default of $$ = $1 is good */
1105: ;
1106:
1107: integer_range /* limited to unsigned shorts */
1108: : '(' T_Integer T_Ellipsis T_Integer ')'
1109: { $$ = create_attr_shorts('-', $2, $4); }
1110: ;
1111:
1112: string_list
1113: : string_list T_String { $$ = enqueue($1, create_pval($2)); }
1114: | T_String { $$ = enqueue_in_new_queue(create_pval($1)); }
1115: ;
1116:
1117: address_list
1118: : address_list address { $$ = enqueue($1, $2); }
1119: | address { $$ = enqueue_in_new_queue($1); }
1120: ;
1121:
1122: boolean
1123: : T_Integer
1124: {
1125: if ($1 != 0 && $1 != 1) {
1126: yyerror("Integer value is not boolean (0 or 1). Assuming 1");
1127: $$ = 1;
1128: } else {
1129: $$ = $1;
1130: }
1131: }
1132: | T_True { $$ = 1; }
1133: | T_False { $$ = 0; }
1134: ;
1135:
1136: number
1137: : T_Integer { $$ = (double)$1; }
1138: | T_Double
1139: ;
1140:
1141:
1142: /* Simulator Configuration Commands
1143: * --------------------------------
1144: */
1145:
1146: simulate_command
1147: : sim_conf_start '{' sim_init_statement_list sim_server_list '}'
1148: {
1149: cfgt.sim_details = create_sim_node($3, $4);
1150:
1151: /* Reset the old_config_style variable */
1152: old_config_style = 1;
1153: }
1154: ;
1155:
1156: /* The following is a terrible hack to get the configuration file to
1157: * treat newlines as whitespace characters within the simulation.
1158: * This is needed because newlines are significant in the rest of the
1159: * configuration file.
1160: */
1161: sim_conf_start
1162: : T_Simulate { old_config_style = 0; }
1163: ;
1164:
1165: sim_init_statement_list
1166: : sim_init_statement_list sim_init_statement T_EOC { $$ = enqueue($1, $2); }
1167: | sim_init_statement T_EOC { $$ = enqueue_in_new_queue($1); }
1168: ;
1169:
1170: sim_init_statement
1171: : T_Beep_Delay '=' number { $$ = create_attr_dval($1, $3); }
1172: | T_Sim_Duration '=' number { $$ = create_attr_dval($1, $3); }
1173: ;
1174:
1175: sim_server_list
1176: : sim_server_list sim_server { $$ = enqueue($1, $2); }
1177: | sim_server { $$ = enqueue_in_new_queue($1); }
1178: ;
1179:
1180: sim_server
1181: : sim_server_name '{' sim_server_offset sim_act_list '}'
1182: { $$ = create_sim_server($1, $3, $4); }
1183: ;
1184:
1185: sim_server_offset
1186: : T_Server_Offset '=' number T_EOC { $$ = $3; }
1187: ;
1188:
1189: sim_server_name
1190: : T_Server '=' address { $$ = $3; }
1191: ;
1192:
1193: sim_act_list
1194: : sim_act_list sim_act { $$ = enqueue($1, $2); }
1195: | sim_act { $$ = enqueue_in_new_queue($1); }
1196: ;
1197:
1198: sim_act
1199: : T_Duration '=' number '{' sim_act_stmt_list '}'
1200: { $$ = create_sim_script_info($3, $5); }
1201: ;
1202:
1203: sim_act_stmt_list
1204: : sim_act_stmt_list sim_act_stmt T_EOC { $$ = enqueue($1, $2); }
1205: | sim_act_stmt T_EOC { $$ = enqueue_in_new_queue($1); }
1206: ;
1207:
1208: sim_act_stmt
1209: : T_Freq_Offset '=' number
1210: { $$ = create_attr_dval($1, $3); }
1211: | T_Wander '=' number
1212: { $$ = create_attr_dval($1, $3); }
1213: | T_Jitter '=' number
1214: { $$ = create_attr_dval($1, $3); }
1215: | T_Prop_Delay '=' number
1216: { $$ = create_attr_dval($1, $3); }
1217: | T_Proc_Delay '=' number
1218: { $$ = create_attr_dval($1, $3); }
1219: ;
1220:
1221:
1222: %%
1223:
1224: void
1225: yyerror(
1226: const char *msg
1227: )
1228: {
1229: int retval;
1230:
1231: ip_file->err_line_no = ip_file->prev_token_line_no;
1232: ip_file->err_col_no = ip_file->prev_token_col_no;
1233:
1234: msyslog(LOG_ERR,
1235: "line %d column %d %s",
1236: ip_file->err_line_no,
1237: ip_file->err_col_no,
1238: msg);
1239: if (!input_from_file) {
1240: /* Save the error message in the correct buffer */
1241: retval = snprintf(remote_config.err_msg + remote_config.err_pos,
1242: MAXLINE - remote_config.err_pos,
1243: "column %d %s",
1244: ip_file->err_col_no, msg);
1245:
1246: /* Increment the value of err_pos */
1247: if (retval > 0)
1248: remote_config.err_pos += retval;
1249:
1250: /* Increment the number of errors */
1251: ++remote_config.no_errors;
1252: }
1253: }
1254:
1255:
1256: /*
1257: * token_name - Convert T_ token integers to text.
1258: * Example: token_name(T_Server) returns "T_Server".
1259: * see also keyword(T_Server) which returns "server".
1260: */
1261: const char *
1262: token_name(
1263: int token
1264: )
1265: {
1266: return yytname[YYTRANSLATE(token)];
1267: }
1268:
1269:
1270: /* Initial Testing function -- ignore
1271: int main(int argc, char *argv[])
1272: {
1273: ip_file = FOPEN(argv[1], "r");
1274: if (!ip_file) {
1275: fprintf(stderr, "ERROR!! Could not open file: %s\n", argv[1]);
1276: }
1277: key_scanner = create_keyword_scanner(keyword_list);
1278: print_keyword_scanner(key_scanner, 0);
1279: yyparse();
1280: return 0;
1281: }
1282: */
1283:
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>