]> git.ipfire.org Git - thirdparty/ntp.git/commitdiff
ntp_config.y:
authorSachin Kamboj <kamboj@cis.udel.edu>
Wed, 3 Jan 2007 04:16:36 +0000 (23:16 -0500)
committerSachin Kamboj <kamboj@cis.udel.edu>
Wed, 3 Jan 2007 04:16:36 +0000 (23:16 -0500)
  New BitKeeper file ``ntpd/ntp_config.y''

bk: 459b2e24vviDEInAc4vosxo4O_PWxw

ntpd/ntp_config.y [new file with mode: 0644]

diff --git a/ntpd/ntp_config.y b/ntpd/ntp_config.y
new file mode 100644 (file)
index 0000000..4bf9286
--- /dev/null
@@ -0,0 +1,917 @@
+/* config.y
+ *
+ * The parser for the NTP configuration file. 
+ *
+ * Written By: Sachin Kamboj
+ *             University of Delaware
+ *             Newark, DE 19711
+ * Copyright (c) 2006
+ */
+
+%union {
+    char   *String;
+    double  Double;
+    int     Integer;
+    void   *VoidPtr;
+    queue  *Queue;
+    struct attr_val *Attr_val;
+    struct address_node *Address_node;
+    struct setvar_node *Set_var;
+    /* Simulation types */
+    server_info *Sim_server;
+    script_info *Sim_script;
+}
+
+/*** TERMINALS ***/
+%token         T_Age
+%token         T_Allan
+%token         T_Auth
+%token         T_Autokey
+%token         T_Automax
+%token         T_Average
+%token         T_Bclient
+%token         T_Beacon
+%token         T_Broadcast
+%token         T_Broadcastclient
+%token         T_Broadcastdelay
+%token         T_Burst
+%token         T_Calibrate
+%token         T_Calldelay
+%token         T_Ceiling
+%token         T_Cert
+%token         T_Clockstats
+%token         T_Cohort
+%token         T_ControlKey
+%token         T_Crypto
+%token         T_Cryptostats
+%token         T_Day
+%token         T_Default
+%token         T_Disable
+%token         T_Discard
+%token         T_Dispersion
+%token <Double>        T_Double
+%token         T_Driftfile
+%token         T_Enable
+%token         T_End
+%token         T_False
+%token         T_File
+%token         T_Filegen
+%token         T_Flag1
+%token         T_Flag2
+%token         T_Flag3
+%token         T_Flag4
+%token         T_Floor
+%token         T_Freq
+%token         T_Fudge
+%token         T_Gqpar
+%token         T_Host
+%token         T_Huffpuff
+%token <String> T_IPv4_address
+%token <String> T_IPv6_address
+%token         T_Iburst
+%token         T_Ident
+%token         T_Iffpar
+%token         T_Ignore
+%token         T_Includefile
+%token         T_Integer
+%token         T_Interface
+%token         T_Kernel
+%token         T_Key
+%token         T_Keys
+%token         T_Keysdir
+%token         T_Kod
+%token         T_Leap
+%token         T_Limited
+%token         T_Link
+%token         T_Logconfig
+%token         T_Logfile
+%token         T_Loopstats
+%token         T_Lowpriotrap
+%token         T_Manycastclient
+%token         T_Manycastserver
+%token         T_Mask
+%token         T_Maxclock
+%token         T_Maxdist
+%token         T_Maxhop
+%token         T_Maxpoll
+%token         T_Minclock
+%token         T_Mindist
+%token         T_Minimum
+%token         T_Minpoll
+%token         T_Minsane
+%token          T_Mode
+%token         T_Monitor
+%token         T_Month
+%token         T_Multicastclient
+%token         T_Mvpar
+%token         T_Nolink
+%token         T_Nomodify
+%token         T_None
+%token         T_Nopeer
+%token         T_Noquery
+%token         T_Noselect
+%token         T_Noserve
+%token         T_Notrap
+%token         T_Notrust
+%token         T_Novolley
+%token         T_Ntp
+%token         T_Ntpport
+%token         T_Orphan
+%token         T_Panic
+%token         T_Peer
+%token         T_Peerstats
+%token         T_Phone
+%token         T_Pid
+%token         T_Pidfile
+%token          T_Pool
+%token         T_Port
+%token         T_Pps
+%token         T_Preempt
+%token         T_Prefer
+%token         T_Pw
+%token         T_RandFile
+%token         T_Rawstats
+%token         T_Refid
+%token         T_Requestkey
+%token         T_Restrict
+%token         T_Revoke
+%token         T_Server
+%token         T_Setvar
+%token         T_Sign
+%token         T_Statistics
+%token         T_Stats
+%token         T_Statsdir
+%token         T_Step
+%token         T_Stepout
+%token         T_Stratum
+%token <String> T_String
+%token         T_Sysstats
+%token         T_Tick
+%token         T_Time1
+%token         T_Time2
+%token         T_Tinker
+%token         T_Tos
+%token         T_Trap
+%token         T_True
+%token         T_Trustedkey
+%token         T_Ttl
+%token         T_Type
+%token         T_Version
+%token         T_Week
+%token         T_Year
+%token <Integer> T_Integer
+%token          T_Flag     /* Not an actual token */
+%token          T_Void     /* Not an actual token */
+%token          T_EOC
+
+/* NTP Simulator Tokens */
+%token     T_Simulate
+%token     T_Beep_Delay
+%token     T_Sim_Duration 
+%token     T_Server_Offset
+%token     T_Duration
+%token     T_Freq_Offset
+%token     T_Wander
+%token     T_Jitter
+%token     T_Prop_Delay
+%token     T_Proc_Delay
+
+
+/*** NON-TERMINALS ***/
+%type   <VoidPtr>       access_control_flag
+%type  <Queue>         ac_flag_list
+%type  <Address_node>  address
+%type  <Queue>         address_list
+%type  <Integer>       boolean
+%type  <Integer>       client_type
+%type  <Attr_val>      crypto_command
+%type  <Queue>         crypto_command_list
+%type  <Attr_val>      discard_option
+%type  <Queue>         discard_option_list
+%type  <Attr_val>      filegen_option
+%type  <Queue>         filegen_option_list
+%type  <Integer>       filegen_type
+%type  <Attr_val>      fudge_factor
+%type  <Queue>         fudge_factor_list
+%type  <Queue>         integer_list
+%type  <Address_node>  ip_address
+%type  <Attr_val>      log_config_command
+%type  <Queue>         log_config_list
+%type  <Integer>       log_config_prefix
+%type  <Double>        number
+%type  <Attr_val>      option
+%type  <Queue>         option_list
+%type   <VoidPtr>       stat
+%type  <Queue>         stats_list
+%type  <Queue>         string_list
+%type  <Attr_val>      system_option
+%type  <Queue>         system_option_list
+%type  <Attr_val>      tinker_option
+%type  <Queue>         tinker_option_list
+%type  <Attr_val>      tos_option
+%type  <Queue>         tos_option_list
+%type  <Attr_val>      trap_option
+%type  <Queue>         trap_option_list
+%type   <Set_var>       variable_assign
+
+/* NTP Simulator non-terminals */   
+%type   <Queue>         sim_init_statement_list 
+%type   <Attr_val>      sim_init_statement
+%type   <Queue>         sim_server_list             
+%type   <Sim_server>    sim_server         
+%type   <Double>        sim_server_offset   
+%type   <Address_node>  sim_server_name     
+%type   <Address_node>  sim_address
+%type   <Queue>         sim_act_list        
+%type   <Sim_script>    sim_act            
+%type   <Queue>         sim_act_stmt_list
+%type   <Attr_val>      sim_act_stmt
+
+%%
+
+/* ntp.conf
+ * Configuration File Grammar
+ * --------------------------
+ */
+
+configuration 
+       :       command_list
+       ;
+
+command_list
+       :       command_list command T_EOC  
+       |       command T_EOC 
+                /* I will need to incorporate much more fine grained
+                 * error messages. The following should suffice for
+                 * the time being.
+                 */
+        |       error T_EOC 
+                { 
+                    fprintf(stderr, "PARSE ERROR!! At Line: %d\n", 
+                            ip_file->line_no);
+                    fprintf(stderr, "Line Ignored!!\n");
+                }
+       ;
+
+command :      /* NULL STATEMENT */  
+       |       server_command  
+       |       other_mode_command  
+       |       authentication_command 
+       |       monitoring_command 
+       |       access_control_command 
+       |       orphan_mode_command 
+       |       fudge_command 
+       |       system_option_command 
+       |       tinker_command 
+       |       miscellaneous_command 
+        |       simulate_command
+       ;
+
+/* Server Commands 
+ * ---------------
+ */
+
+server_command 
+        :      client_type address option_list 
+                    { 
+                        struct peer_node *my_node =  create_peer_node($1, $2, $3); 
+                        if (my_node)
+                            enqueue(my_config.peers, my_node);                        
+                    } 
+        |      client_type address  
+                    { 
+                        struct peer_node *my_node = create_peer_node($1, $2, NULL); 
+                        if (my_node)
+                            enqueue(my_config.peers, my_node);                        
+                    }
+       ;
+
+client_type
+        :      T_Server          { $$ = T_Server; }
+        |       T_Pool            { $$ = T_Pool; }
+       |       T_Peer            { $$ = T_Peer; }
+        |      T_Broadcast       { $$ = T_Broadcast; }
+       |       T_Manycastclient  { $$ = T_Manycastclient; }
+       ;
+
+address 
+       :       ip_address   { $$ = $1; }
+        |      T_String  { $$ = create_address_node($1, default_ai_family); }
+        |       T_Integer T_String 
+                    {
+                        if ($1 == -4)
+                            $$ = create_address_node($2, AF_INET);
+                        else if ($1 == -6)
+                            $$ = create_address_node($2, AF_INET6);
+                        else {
+                            yyerror("Invalid address type specified. Assuming default.\n");
+                            $$ = create_address_node($2, default_ai_family);
+                        }
+                    }
+                            
+
+       ;
+
+ip_address
+        :      T_IPv4_address  { $$ = create_address_node($1, AF_INET); }
+        |      T_IPv6_address  { $$ = create_address_node($1, AF_INET6); }
+       ;
+
+option_list
+       :       option_list option         { $$ = enqueue($1, $2); }
+       |       option  { $$ = enqueue_in_new_queue($1); } 
+       ;
+
+option
+/*        :    /* Null Statement { $$ = NULL; } */
+        :      T_Autokey      { $$ = create_attr_ival(T_Flag, FLAG_SKEY | FLAG_AUTHENABLE); }
+       |       T_Burst        { $$ = create_attr_ival(T_Flag, FLAG_BURST); }
+       |       T_Iburst       { $$ = create_attr_ival(T_Flag, FLAG_IBURST); }
+       |       T_Key T_Integer      { $$ = create_attr_ival(T_Key, $2); }
+       |       T_Minpoll T_Integer  { $$ = create_attr_ival(T_Minpoll, $2); }
+       |       T_Maxpoll T_Integer  { $$ = create_attr_ival(T_Maxpoll, $2); }
+       |       T_Noselect     { $$ = create_attr_ival(T_Flag, FLAG_NOSELECT);}
+       |       T_Preempt      { $$ = create_attr_ival(T_Flag, FLAG_PREEMPT); }
+       |       T_Prefer       { $$ = create_attr_ival(T_Flag, FLAG_PREFER); }
+       |       T_True         { $$ = create_attr_ival(T_Flag, FLAG_TRUE); }
+       |       T_Ttl T_Integer     { $$ = create_attr_ival(T_Ttl, $2); }
+        |       T_Mode T_Integer    { $$ = create_attr_ival(T_Mode, $2); }
+       |       T_Version T_Integer { $$ = create_attr_ival(T_Version, $2); }
+       ;
+
+
+/* Other Modes 
+ * (broadcastclient manycastserver multicastclient)
+ * ------------------------------------------------
+ */
+
+other_mode_command
+        :      T_Broadcastclient  
+                    { my_config.broadcastclient = SIMPLE; }
+        |      T_Broadcastclient T_Novolley  
+                    { my_config.broadcastclient = NOVOLLEY;  }
+       |       T_Manycastserver address_list  
+                    { append_queue(my_config.manycastserver, $2);  }
+       |       T_Multicastclient address_list  
+                    { append_queue(my_config.multicastclient, $2);  }
+       ;
+
+
+
+/* Authentication Commands 
+ * -----------------------
+ */
+
+authentication_command
+       :       T_Autokey T_Integer  
+                    { my_config.auth.autokey = $2;  }
+        |      T_ControlKey T_Integer  
+                    { my_config.auth.control_key = $2;  }
+        |      T_Crypto crypto_command_list  
+                    { my_config.auth.crypto_cmd_list = $2;  }
+       |       T_Keys T_String  
+                    { my_config.auth.keys = $2;  }
+       |       T_Keysdir T_String  
+                    { my_config.auth.keysdir = $2;  }
+       |       T_Requestkey T_Integer  
+                    { my_config.auth.requested_key = $2;  }
+       |       T_Revoke T_Integer  
+                    { my_config.auth.revoke = $2;  }
+       |       T_Trustedkey integer_list  
+                    { my_config.auth.trusted_key_list = $2;  }
+       ;
+
+crypto_command_list
+        :      crypto_command_list crypto_command  { $$ = enqueue($1, $2); }
+       |       crypto_command { $$ = enqueue_in_new_queue($1); } 
+       ;
+
+crypto_command
+       :       T_Cert T_String  
+                    { $$ = create_attr_sval(CRYPTO_CONF_CERT, $2); }
+       |       T_Leap T_String  
+                    { $$ = create_attr_sval(CRYPTO_CONF_LEAP, $2); }
+       |       T_RandFile T_String 
+                    { $$ = create_attr_sval(CRYPTO_CONF_RAND, $2); }
+       |       T_Host  T_String  
+                    { $$ = create_attr_sval(CRYPTO_CONF_PRIV, $2); }
+       |       T_Sign  T_String  
+                    { $$ = create_attr_sval(CRYPTO_CONF_SIGN, $2); }
+       |       T_Ident T_String  
+                    { $$ = create_attr_sval(CRYPTO_CONF_IDENT, $2); }
+       |       T_Iffpar T_String 
+                    { $$ = create_attr_sval(CRYPTO_CONF_IFFPAR, $2); }
+       |       T_Gqpar T_String  
+                    { $$ = create_attr_sval(CRYPTO_CONF_GQPAR, $2); }
+       |       T_Mvpar T_String  
+                    { $$ = create_attr_sval(CRYPTO_CONF_MVPAR, $2); }
+       |       T_Pw T_String  
+                    { $$ = create_attr_sval(CRYPTO_CONF_PW, $2); }
+       ;
+
+
+/* Orphan Mode Commands 
+ * --------------------
+ */
+orphan_mode_command
+        :      T_Tos tos_option_list  
+                    { append_queue(my_config.orphan_cmds,$2);  }
+       ;
+
+tos_option_list
+        :      tos_option_list tos_option  { $$ = enqueue($1, $2); }
+       |       tos_option { $$ = enqueue_in_new_queue($1); }
+       ;
+
+tos_option
+       :       T_Ceiling T_Integer  
+                    { $$ = create_attr_dval(PROTO_CEILING, (double)$2); }
+       |       T_Floor T_Integer  
+                    { $$ = create_attr_dval(PROTO_FLOOR, (double)$2); }
+       |       T_Cohort boolean  
+                    { $$ = create_attr_dval(PROTO_COHORT, (double)$2); }
+       |       T_Orphan T_Integer  
+                    { $$ = create_attr_dval(PROTO_ORPHAN, (double)$2); }
+       |       T_Mindist number  
+                    { $$ = create_attr_dval(PROTO_MINDISP, $2); }
+       |       T_Maxdist number  
+                    { $$ = create_attr_dval(PROTO_MAXDIST, $2); }
+       |       T_Minclock number  
+                    { $$ = create_attr_dval(PROTO_MINCLOCK, $2); }
+       |       T_Maxclock number  
+                    { $$ = create_attr_dval(PROTO_MAXCLOCK, $2); }
+       |       T_Minsane T_Integer
+                    { $$ = create_attr_dval(PROTO_MINSANE, (double)$2); }
+       |       T_Beacon T_Integer 
+                    { $$ = create_attr_dval(PROTO_BEACON, (double)$2); }
+       |       T_Maxhop T_Integer 
+                    { $$ = create_attr_dval(PROTO_MAXHOP, (double)$2); }
+       ;
+       
+
+/* Monitoring Commands 
+ * -------------------
+ */
+
+monitoring_command
+        :      T_Statistics stats_list  
+                    { append_queue(my_config.stats_list, $2);  }
+       |       T_Statsdir T_String  
+                    { my_config.stats_dir = $2;  }
+       |       T_Filegen stat filegen_option_list  
+                    {
+                        enqueue(my_config.filegen_opts, 
+                                create_filegen_node($2, $3));                         
+                    }
+       ;
+
+stats_list
+       :       stats_list stat  { $$ = enqueue($1, $2); }
+       |       stat    { $$ = enqueue_in_new_queue($1); }
+       ;
+
+stat
+       :       T_Clockstats 
+                    { $$ = create_pval("clockstats"); }
+       |       T_Cryptostats
+                    { $$ = create_pval("cryptostats"); }
+       |       T_Loopstats  
+                    { $$ = create_pval("loopstats"); }
+       |       T_Peerstats  
+                    { $$ = create_pval("peerstats"); }
+       |       T_Rawstats   
+                    { $$ = create_pval("rawstats"); }
+        |      T_Sysstats     
+                    { $$ = create_pval("sysstats"); }
+       ;
+
+filegen_option_list
+       :       filegen_option_list filegen_option  { $$ = enqueue($1, $2); }
+       |       filegen_option  { $$ = enqueue_in_new_queue($1); }
+       ;
+
+filegen_option
+       :       T_File T_String     { $$ = create_attr_sval(T_File, $2); }
+       |       T_Type filegen_type { $$ = create_attr_ival(T_Type, $2); }
+        |      T_Link      { $$ = create_attr_ival(T_Flag, T_Link); }
+       |       T_Nolink    { $$ = create_attr_ival(T_Flag, T_Nolink); }
+       |       T_Enable    { $$ = create_attr_ival(T_Flag, T_Enable); }
+       |       T_Disable   { $$ = create_attr_ival(T_Flag, T_Disable); }
+       ;
+
+filegen_type
+       :       T_None     { $$ = FILEGEN_NONE; }
+        |      T_Pid      { $$ = FILEGEN_PID; }
+        |      T_Day      { $$ = FILEGEN_DAY; } 
+        |      T_Week     { $$ = FILEGEN_WEEK; }
+        |      T_Month    { $$ = FILEGEN_MONTH; }
+       |       T_Year     { $$ = FILEGEN_YEAR; } 
+       |       T_Age      { $$ = FILEGEN_AGE; }
+       ;
+
+
+/* Access Control Commands 
+ * -----------------------
+ */
+
+access_control_command
+        :      T_Discard discard_option_list  
+                    {   append_queue(my_config.discard_opts, $2); }
+        |      T_Restrict address ac_flag_list  
+                    { 
+                        enqueue(my_config.restrict_opts, 
+                                create_restrict_node($2, NULL, $3, ip_file->line_no));                          
+                    }
+        |       T_Restrict T_Default ac_flag_list
+                    { 
+                        enqueue(my_config.restrict_opts, 
+                                create_restrict_node(NULL, NULL, $3, ip_file->line_no)); 
+                    }
+       |       T_Restrict ip_address T_Mask ip_address ac_flag_list
+                    { 
+                        enqueue(my_config.restrict_opts, 
+                                create_restrict_node($2, $4, $5, ip_file->line_no)); 
+                    }
+       ;
+
+ac_flag_list
+        :      /* Null statement */ { $$ = create_queue(); }
+        |       ac_flag_list access_control_flag  { $$ = enqueue($1, $2); }
+       ;
+
+access_control_flag
+       :       T_Ignore       { $$ = create_ival(RES_IGNORE); }
+        |      T_Kod          { $$ = create_ival(RES_DEMOBILIZE); }
+       |       T_Limited      { $$ = create_ival(RES_LIMITED); }
+       |       T_Lowpriotrap  { $$ = create_ival(RES_LPTRAP); }
+       |       T_Nomodify     { $$ = create_ival(RES_NOMODIFY); }
+       |       T_Nopeer       { $$ = create_ival(RES_NOPEER); }
+       |       T_Noquery      { $$ = create_ival(RES_NOQUERY); }
+       |       T_Noserve      { $$ = create_ival(RES_DONTSERVE); }
+       |       T_Notrap       { $$ = create_ival(RES_NOTRAP); }
+       |       T_Notrust      { $$ = create_ival(RES_DONTTRUST); }
+       |       T_Ntpport      { $$ = create_ival(RESM_NTPONLY); }
+        |      T_Version      { $$ = create_ival(RES_VERSION); }
+       ;
+
+discard_option_list
+       :       discard_option_list discard_option  { $$ = enqueue($1, $2); }
+       |       discard_option  { $$ = enqueue_in_new_queue($1); }
+       ;
+
+discard_option
+        :      T_Average T_Integer   { $$ = create_attr_ival(T_Average, $2); }
+       |       T_Minimum T_Integer   { $$ = create_attr_ival(T_Minimum, $2); }
+       |       T_Monitor T_Integer   { $$ = create_attr_ival(T_Monitor, $2); }
+       ;
+
+/* Fudge Commands 
+ * --------------
+ */
+
+fudge_command 
+       :       T_Fudge address fudge_factor_list  
+                    { enqueue(my_config.fudge, create_addr_opts_node($2, $3));  }
+       ;
+
+fudge_factor_list
+       :       fudge_factor_list fudge_factor  { enqueue($1, $2); }
+       |       fudge_factor  { $$ = enqueue_in_new_queue($1); }
+       ;
+       
+fudge_factor
+       :       T_Time1 number  
+                    { $$ = create_attr_dval(CLK_HAVETIME1, $2); }
+       |       T_Time2 number  
+                    { $$ = create_attr_dval(CLK_HAVETIME2, $2); }
+       |       T_Stratum T_Integer  
+                    { $$ = create_attr_ival(CLK_HAVEVAL1,  $2); }
+       |       T_Refid T_String 
+                    { $$ = create_attr_sval(CLK_HAVEVAL2,  $2); }
+        |      T_Flag1 boolean  
+                    { $$ = create_attr_ival(CLK_HAVEFLAG1, $2); }
+       |       T_Flag2 boolean  
+                    { $$ = create_attr_ival(CLK_HAVEFLAG2, $2); }
+       |       T_Flag3 boolean  
+                    { $$ = create_attr_ival(CLK_HAVEFLAG3, $2); }
+        |      T_Flag4 boolean  
+                    { $$ = create_attr_ival(CLK_HAVEFLAG4, $2); }
+       ;
+
+/* Command for System Options 
+ * --------------------------
+ */
+
+system_option_command
+        :      T_Enable system_option_list  
+                    { append_queue(my_config.enable_opts,$2);  }
+       |       T_Disable system_option_list  
+                    { append_queue(my_config.disable_opts,$2);  }
+       ;
+
+system_option_list
+        :      system_option_list system_option  { $$ = enqueue($1, $2); }
+       |       system_option  { $$ = enqueue_in_new_queue($1); }
+       ;
+
+system_option
+        :      T_Auth      { $$ = create_attr_ival(T_Flag, PROTO_AUTHENTICATE); }
+       |       T_Bclient   { $$ = create_attr_ival(T_Flag, PROTO_BROADCLIENT); }
+       |       T_Calibrate { $$ = create_attr_ival(T_Flag, PROTO_CAL); }
+       |       T_Kernel    { $$ = create_attr_ival(T_Flag, PROTO_KERNEL); }
+       |       T_Monitor   { $$ = create_attr_ival(T_Flag, PROTO_MONITOR); }
+       |       T_Ntp       { $$ = create_attr_ival(T_Flag, PROTO_NTP); }
+/*     |       T_Pps  */
+       |       T_Stats     { $$ = create_attr_ival(T_Flag, PROTO_FILEGEN); }
+       ;
+
+/* Tinker Commands
+ * ---------------
+ */
+
+tinker_command
+        :      T_Tinker tinker_option_list  { append_queue(my_config.tinker, $2);  }
+       ;
+
+tinker_option_list
+       :       tinker_option_list tinker_option  { $$ = enqueue($1, $2); }
+       |       tinker_option { $$ = enqueue_in_new_queue($1); }
+       ;
+
+tinker_option
+        :      T_Allan number      { $$ = create_attr_dval(LOOP_ALLAN, $2); }
+       |       T_Dispersion number { $$ = create_attr_dval(LOOP_PHI, $2); }
+       |       T_Freq number       { $$ = create_attr_dval(LOOP_FREQ, $2); }
+       |       T_Huffpuff number   { $$ = create_attr_dval(LOOP_HUFFPUFF, $2); }
+       |       T_Panic number      { $$ = create_attr_dval(LOOP_PANIC, $2); }
+       |       T_Step number       { $$ = create_attr_dval(LOOP_MAX, $2); }
+       |       T_Stepout number    { $$ = create_attr_dval(LOOP_MINSTEP, $2); }
+       ;
+
+/* Miscellaneous Commands 
+ * ----------------------
+ */
+
+miscellaneous_command
+        :      T_Includefile T_String 
+                {
+                    if (curr_include_level >= MAXINCLUDELEVEL) {
+                        fprintf(stderr, "getconfig: Maximum include file level exceeded.\n");
+                        msyslog(LOG_INFO, "getconfig: Maximum include file level exceeded.");
+                    }
+                    else {
+                        fp[curr_include_level + 1] = F_OPEN(FindConfig($2), "r");
+                        if (fp[curr_include_level + 1] == NULL) {
+                            fprintf(stderr, "getconfig: Couldn't open <%s>\n", FindConfig($2));
+                            msyslog(LOG_INFO, "getconfig: Couldn't open <%s>", FindConfig($2));
+                        }
+                        else
+                            ++curr_include_level;
+                    }
+                }
+       |       T_End 
+                {
+                    while (curr_include_level != -1) 
+                        FCLOSE(fp[curr_include_level--]);
+                }
+
+        |      T_Broadcastdelay number 
+                    { enqueue(my_config.vars, create_attr_dval(T_Broadcastdelay, $2));  }
+       |       T_Calldelay T_Integer 
+                    { enqueue(my_config.vars, create_attr_ival(T_Calldelay, $2));  }
+       |       T_Tick number
+                    { enqueue(my_config.vars, create_attr_dval(T_Tick, $2));  }
+       |       T_Driftfile T_String
+                    { enqueue(my_config.vars, create_attr_sval(T_Driftfile, $2));  }
+       |       T_Pidfile T_String 
+                    { enqueue(my_config.vars, create_attr_sval(T_Pidfile, $2));  }
+       |       T_Logfile T_String 
+                    { enqueue(my_config.vars, create_attr_sval(T_Logfile, $2));  }
+       |       T_Automax T_Integer 
+                    { enqueue(my_config.vars, create_attr_ival(T_Automax, $2));  }
+
+        |      T_Logconfig log_config_list 
+                    { append_queue(my_config.logconfig, $2);  }
+       |       T_Phone string_list 
+                    { append_queue(my_config.phone, $2);  }
+       |       T_Setvar variable_assign
+                    { enqueue(my_config.setvar, $2);  }
+       |       T_Trap ip_address trap_option_list 
+                    { enqueue(my_config.trap, create_addr_opts_node($2, $3));  }
+       |       T_Ttl integer_list 
+                    { append_queue(my_config.ttl, $2); }
+       ;       
+
+variable_assign
+        :      T_String '=' T_String T_Default  
+                    { $$ = create_setvar_node($1, $3, DEF); }
+       |       T_String '=' T_String            
+                    { $$ = create_setvar_node($1, $3, 0); }
+       ;
+
+
+trap_option_list
+       :       trap_option_list trap_option { $$ = enqueue($1, $2); }
+       |       trap_option  { $$ = enqueue_in_new_queue($1); }
+       ;
+
+trap_option
+        :      T_Port T_Integer     { $$ = create_attr_ival(T_Port, $2); }
+       |       T_Interface ip_address { $$ = create_attr_pval(T_Interface, $2); }
+       ;
+
+       
+log_config_list 
+       :       log_config_list log_config_command { $$ = enqueue($1, $2); }
+       |       log_config_command  { $$ = enqueue_in_new_queue($1); }
+       ;
+
+log_config_command
+        :      log_config_prefix T_String { $$ = create_attr_sval($1, $2); }
+        |       T_String  
+                { 
+                    /* YUCK!! This is needed because '+' and '-' are not special characters 
+                     * while '=' is. 
+                     * We really need a better way of defining strings
+                     */
+                    char prefix = $1[0];
+                    char *type = &($1[1]);
+                    if (prefix != '+' && prefix != '-') {
+                        yyerror("Logconfig prefix is not '+', '-' or '='\n");
+                    }
+                    else
+                        $$ = create_attr_sval(prefix, type);
+                }
+       ;
+
+log_config_prefix 
+       :       '+' { $$ = '+'; }
+       |       '-' { $$ = '-'; }
+       |       '=' { $$ = '='; }
+       ;
+
+
+/* Miscellaneous Rules 
+ * -------------------
+ */
+
+integer_list
+        :      integer_list T_Integer  { $$ = enqueue($1, create_ival($2)); }
+        |      T_Integer { $$ = enqueue_in_new_queue(create_ival($1)); }
+       ;
+
+string_list
+        :      string_list T_String   { $$ = enqueue($1, create_pval($2)); }
+        |      T_String { $$ = enqueue_in_new_queue(create_pval($1)); }
+       ;
+
+address_list
+        :      address_list address  { $$ = enqueue($1, $2); }
+        |      address { $$ = enqueue_in_new_queue($1); }
+       ;
+
+boolean 
+        :      T_Integer
+                { 
+                    if ($1 != 0 && $1 != 1) {
+                        yyerror("Integer value is not boolean (0 or 1). Assuming 1");
+                        $$ = 1;
+                    }
+                    else
+                        $$ = $1; 
+                }
+        |      T_True     { $$ = 1; }
+        |      T_False    { $$ = 0; }
+       ;
+
+number  
+        :      T_Integer { $$ = (double)$1; } 
+        |      T_Double  { $$ = $1; } 
+       ;
+
+/* Simulator Configuration Commands 
+ * --------------------------------
+ */
+
+simulate_command 
+        :    sim_conf_start '{' sim_init_statement_list sim_server_list '}'
+             {
+                 my_config.sim_details = create_sim_node($3, $4);
+
+                 /* Reset the old_config_style variable */
+                 old_config_style = 1;
+             }
+        ;
+
+/* The following is a terrible hack to get the configuration file to 
+ * treat newlines as whitespace characters within the simulation. 
+ * This is needed because newlines are significant in the rest of the 
+ * configuration file. 
+ */
+sim_conf_start
+        :    T_Simulate { old_config_style = 0; }
+        ;
+
+sim_init_statement_list 
+        :    sim_init_statement_list sim_init_statement T_EOC { $$ = enqueue($1, $2); }
+        |    sim_init_statement T_EOC                         { $$ = enqueue_in_new_queue($1); }
+        ;
+
+sim_init_statement
+        :    T_Beep_Delay '=' number   { $$ = create_attr_dval(T_Beep_Delay, $3); }
+        |    T_Sim_Duration '=' number { $$ = create_attr_dval(T_Sim_Duration, $3); }
+        ;
+
+sim_server_list     
+        :    sim_server_list sim_server { $$ = enqueue($1, $2); }
+        |    sim_server                 { $$ = enqueue_in_new_queue($1); }
+        ;
+        
+sim_server         
+        :    sim_server_name '{' sim_server_offset sim_act_list '}' 
+                 {  $$ = create_sim_server($1, $3, $4); }
+        ;
+
+sim_server_offset   
+        :    T_Server_Offset '=' number T_EOC { $$ = $3; }
+        ;
+
+sim_server_name     
+        :    T_Server '=' sim_address { $$ = $3; }
+        ;
+
+sim_address
+        :    ip_address { $$ = $1; }
+        |    T_String   { $$ = create_address_node($1, T_String); }
+        ;
+
+sim_act_list        
+        :    sim_act_list  sim_act { $$ = enqueue($1, $2); }
+        |    sim_act               { $$ = enqueue_in_new_queue($1); }
+        ;
+        
+sim_act            
+        :    T_Duration '=' number '{' sim_act_stmt_list '}'  
+                 { $$ = create_sim_script_info($3, $5); }
+        ;
+
+sim_act_stmt_list
+        :    sim_act_stmt_list sim_act_stmt T_EOC { $$ = enqueue($1, $2); }
+        |    sim_act_stmt T_EOC                   { $$ = enqueue_in_new_queue($1); }
+        ;
+    
+sim_act_stmt
+        :    T_Freq_Offset '=' number  
+                 { $$ = create_attr_dval(T_Freq_Offset, $3); }
+        |    T_Wander '=' number 
+                 { $$ = create_attr_dval(T_Wander, $3); }
+        |    T_Jitter '=' number       
+                 { $$ = create_attr_dval(T_Jitter, $3); }
+        |    T_Prop_Delay '=' number   
+                 { $$ = create_attr_dval(T_Prop_Delay, $3); }
+        |    T_Proc_Delay '=' number   
+                 { $$ = create_attr_dval(T_Proc_Delay, $3); }
+        ; 
+
+
+%%
+
+/* KEYWORDS
+ * --------
+ */
+
+void yyerror (char *msg)
+{
+    int retval;
+    if (input_from_file)
+        fprintf(stderr, "%s\n", msg);
+    else {
+        /* Save the error message in the correct buffer */
+        retval = snprintf(remote_config.err_msg + remote_config.err_pos, 
+                          MAXLINE - remote_config.err_pos, 
+                          "%s\n", msg);
+
+        /* Increment the value of err_pos */
+        if (retval > 0)
+            remote_config.err_pos += retval;
+        
+        /* Increment the number of errors */
+        ++remote_config.no_errors;
+    }
+}
+
+/* Initial Testing function -- ignore 
+int main(int argc, char *argv[])
+{
+    ip_file = FOPEN(argv[1], "r");
+    if (!ip_file) {
+        fprintf(stderr, "ERROR!! Could not open file: %s\n", argv[1]);
+    }
+    key_scanner = create_keyword_scanner(keyword_list);
+    print_keyword_scanner(key_scanner, 0);
+    yyparse();
+    return 0;
+}
+*/
+