]> git.ipfire.org Git - thirdparty/ntp.git/commitdiff
ntp_data_structures.h:
authorJohannes Maximilian Kuehn <kuehn@ntp.org>
Tue, 4 Aug 2009 15:31:42 +0000 (17:31 +0200)
committerJohannes Maximilian Kuehn <kuehn@ntp.org>
Tue, 4 Aug 2009 15:31:42 +0000 (17:31 +0200)
  Added singly-linked list datatype s_list
ntp_data_structures.c:
  Added functions for dealing with singly linked lists
ntp_config.c:
  Added config dumper and functions dealing with the linked-list copy of the configuration tree
ntpq-subs.c:
  Added config dumper bindings
ntp_config.h:
  Added config dumper prototypes

bk: 4a78545esvi19Qxo310CZWWLsADuxA

include/ntp_config.h
include/ntp_data_structures.h
ntpd/ntp_config.c
ntpd/ntp_data_structures.c
ntpq/ntpq-subs.c

index ba5c2bbc2f19fbc71c141e5d0c3f0967a84f1238..c28a51ba3acf0c924e30234ef728b04e786293ca 100644 (file)
@@ -125,6 +125,47 @@ enum broadcastclienttype {
     NOVOLLEY
 };
 
+/* A fix for now to prevent the configuration from being consumed before
+ * it could be ever dumped
+ */
+struct config_tree_list {
+    s_list *peers;
+    s_list *unpeers;
+
+    /* Other Modes */
+    int broadcastclient;
+    s_list *manycastserver;
+    s_list *multicastclient;
+
+    s_list *orphan_cmds;
+
+    /* Monitoring Configuration */
+    s_list *stats_list;
+    char *stats_dir;
+    s_list *filegen_opts;
+
+    /* Access Control Configuration */
+    s_list *discard_opts;
+    s_list *restrict_opts;
+
+    s_list *fudge;
+    s_list *tinker;
+    s_list *enable_opts;
+    s_list *disable_opts;
+    struct auth_node auth;
+
+    s_list *logconfig;
+    s_list *qos;
+    s_list *phone;
+    s_list *setvar;
+    s_list *ttl;
+    s_list *trap;
+    s_list *vars;
+
+    struct sim_node *sim_details;
+};
+
+
 /* The syntax tree */
 struct config_tree {
     queue *peers;
@@ -197,5 +238,7 @@ server_info *create_sim_server(struct address_node *addr, double server_offset,
 extern struct REMOTE_CONFIG_INFO remote_config;
 void config_remotely(void);
 
+int dump_config_dumper(const char *filename);
+
 
 #endif
index d72f6b586925cbeb75938e067947aeccdd3068d9..c9d6c9d9b3dad8df9c89eb38b690e8dbb1c071b9 100644 (file)
@@ -32,6 +32,14 @@ typedef struct Queue {
     int no_of_elements;
 } queue;
 
+/* Singly-linked structure to hold the same data as a priorithy queue
+ * ------------------------------------------------------------------
+ */
+
+typedef struct s_list {
+       void *value;
+       struct s_list *next;
+} s_list;
 
 /* FUNCTION PROTOTYPES
  * -------------------
@@ -47,5 +55,7 @@ int get_no_of_elements(queue *my_queue);
 void append_queue(queue *q1, queue *q2);
 int get_fifo_order(void *el1, void *el2);
 queue *create_queue(void);
+s_list *clone_queue(queue *my_queue);
+void free_s_list(s_list *my_list);
 
 #endif
index 5be1e3af5a7d30805fbb2e9e3cf4c21fa25ac2bf..f403c50d0b62404a99b349593ace13d2282763f0 100644 (file)
@@ -131,6 +131,7 @@ int curr_include_level;                     /* The current include level */
 struct FILE_INFO *fp[MAXINCLUDELEVEL+1];
 FILE *res_fp;
 struct config_tree my_config;          /* Root of the configuration tree */
+struct config_tree_list my_config_list;
 #if 0
 short default_ai_family = AF_UNSPEC;   /* Default either IPv4 or IPv6 */
 #else
@@ -240,6 +241,8 @@ static void config_sim(void);
 static void config_ntpdsim(void);
 #endif
 void getconfig(int argc,char *argv[]);
+void clone_config(struct config_tree *config, struct config_tree_list *list);
+
 enum gnn_type {
        t_UNK,          /* Unknown */
        t_REF,          /* Refclock */
@@ -264,6 +267,7 @@ static void abort_resolve(void);
 static void do_resolve_internal(void);
 
 
+
 /* FUNCTIONS FOR INITIALIZATION
  * ----------------------------
  */
@@ -399,6 +403,839 @@ free_syntax_tree(void)
 }
 #endif /* DEBUG */
 
+/* Make a copy of the config tree and store that in a singly linked list */
+
+void
+clone_config (
+               struct config_tree *config,
+               struct config_tree_list *list
+            )
+{
+       list->peers = clone_queue(config->peers);
+       list->unpeers = clone_queue(config->unpeers);
+       list->orphan_cmds = clone_queue(config->orphan_cmds);
+
+       list->manycastserver = clone_queue(config->manycastserver);
+       list->multicastclient = clone_queue(config->multicastclient);
+       
+       list->stats_list = clone_queue(config->stats_list);
+       list->filegen_opts = clone_queue(config->filegen_opts);
+       
+       list->discard_opts = clone_queue(config->discard_opts);
+       list->restrict_opts = clone_queue(config->restrict_opts);
+       
+       list->enable_opts = clone_queue(config->enable_opts);
+       list->disable_opts = clone_queue(config->disable_opts);
+       list->tinker = clone_queue(config->tinker);
+       list->fudge = clone_queue(config->fudge);
+       
+       list->logconfig = clone_queue(config->logconfig);
+       list->phone = clone_queue(config->phone);
+       list->qos = clone_queue(config->qos);
+       list->setvar = clone_queue(config->setvar);
+       list->ttl = clone_queue(config->ttl);
+       list->trap = clone_queue(config->trap);
+       list->vars = clone_queue(config->vars);
+}
+
+/* The config dumper */
+int
+dump_config_dumper (
+               const char *filename
+               )
+{
+       printf("dump_config_dumper:\n");
+       s_list *list_ptr = NULL;
+
+       struct peer_node *peers = NULL;
+       struct unpeer_node *unpeers = NULL;
+       struct attr_val *atrv = NULL;
+       struct address_node *addr = NULL;
+       struct filegen_node *fgen_node = NULL;
+       struct restrict_node *rest_node = NULL;
+       struct addr_opts_node *addr_opts = NULL;
+       struct setvar_node *setv_node = NULL;
+
+       char **string = NULL;
+       int *integer = NULL;
+       
+       FILE *df = fopen(filename, "w");
+
+       if(df == NULL) 
+               return -1;
+
+
+       if(my_config_list.peers != NULL) {
+               list_ptr = my_config_list.peers;
+
+               for(;   list_ptr != NULL;
+                       list_ptr = list_ptr->next) {
+
+                       peers = (struct peer_node *) list_ptr->value; 
+               
+                       /* Add other attributes to output of struct peer_node */
+                       fprintf(df, "peer %s\n", (peers->addr)->address);
+               }
+       }
+       
+       if(my_config_list.unpeers != NULL) {
+               list_ptr = my_config_list.unpeers;
+               
+               for(;   list_ptr != NULL;
+                       list_ptr = list_ptr->next) {
+                       
+                       unpeers = (struct unpeer_node *) list_ptr->value;
+                       
+                       fprintf(df, "unpeer %s\n", (unpeers->addr)->address);
+               }
+       }
+
+       if(my_config_list.orphan_cmds != NULL) {
+               list_ptr = my_config_list.orphan_cmds;
+
+               fprintf(df, "tos");
+
+               for(;   list_ptr != NULL;
+                       list_ptr = list_ptr->next) {
+
+                       atrv = (struct attr_val *) list_ptr->value;
+
+                       switch(atrv->attr) {
+                               case T_Ceiling:
+                               fprintf(df, " ceiling %i", (int) atrv->value.d);
+                               break;
+
+                               case T_Floor:
+                               fprintf(df, " floor %i", (int) atrv->value.d);
+                               break;
+
+                               case T_Cohort:
+                               fprintf(df, " cohort ");
+
+                               if(atrv->value.d) 
+                                       fprintf(df, "1");
+                               else
+                                       fprintf(df, "0");
+                               break;
+
+                               case T_Orphan:
+                               fprintf(df, " orphan %i", (int) atrv->value.d);
+                               break;
+
+                               case T_Mindist: 
+                               fprintf(df, " mindist %f", atrv->value.d);
+                               break;
+                               
+                               case T_Maxdist:
+                               fprintf(df, " maxdist %f", atrv->value.d);
+                               break;
+
+                               case T_Minclock:
+                               fprintf(df, " minclock %f", atrv->value.d);
+                               break;
+
+                               case T_Maxclock:
+                               fprintf(df, " maxclock %f", atrv->value.d);
+                               break;
+
+                               case T_Minsane:
+                               fprintf(df, " minsane %i", (int) atrv->value.d);
+                               break;
+
+                               case T_Beacon:
+                               fprintf(df, " beacon %i", (int) atrv->value.d);
+                               break;
+
+                               case T_Maxhop:
+                               fprintf(df, " maxhop %i", (int) atrv->value.d);
+                               break;
+                       }
+               }
+
+               fprintf(df, "\n");
+       }
+
+       if(my_config_list.manycastserver != NULL) {
+               list_ptr = my_config_list.manycastserver;
+
+               for(;   list_ptr != NULL;
+                       list_ptr = list_ptr->next) {
+
+                       addr = (struct address_node *) list_ptr->value;
+
+                       fprintf(df, "manycastserver %s\n", addr->address);
+               }
+       }
+
+       if(my_config_list.multicastclient != NULL) {
+               list_ptr = my_config_list.multicastclient;
+
+               for(;   list_ptr != NULL;
+                       list_ptr = list_ptr->next) {
+
+                       addr = (struct address_node *) list_ptr->value;
+
+                       fprintf(df, "multicastclient %s\n", addr->address);
+               }
+       }
+
+       if(my_config_list.stats_list != NULL) {
+               list_ptr = my_config_list.stats_list;
+
+               fprintf(df, "statistics ");
+               for(;   list_ptr != NULL;
+                       list_ptr = list_ptr->next) {
+
+                       string = (char **) list_ptr->value;
+                               
+                       /* FIXME Find keyword and type of information */
+                       
+                       fprintf(df, "%s ", *string);    
+               }
+
+               fprintf(df, "\n");
+       }
+
+       if(my_config_list.filegen_opts != NULL) {
+               list_ptr = my_config_list.filegen_opts;
+
+               for(;   list_ptr != NULL;
+                       list_ptr = list_ptr->next) {
+
+                       fprintf(df, "filegen ");
+
+                       fgen_node = (struct filegen_node *) list_ptr->value;
+
+                       s_list *options = clone_queue(fgen_node->options);
+                       s_list *opt_ptr = options;
+
+                       for(;   opt_ptr != NULL;
+                               opt_ptr = opt_ptr->next) {
+                               
+                               atrv = (struct attr_val *) opt_ptr->value;
+
+                               switch(atrv->type) {
+                                       case T_File:
+                                       fprintf(df, " file %s", atrv->value.s);
+                                       break;
+
+                                       case T_Type:
+                                       fprintf(df, " type ");
+                                       
+                                       switch(atrv->value.i) {
+                                               case T_Day:
+                                               fprintf(df, "day");
+                                               break;
+
+                                               case T_Month:
+                                               fprintf(df, "month");
+                                               break;
+
+                                               case T_None:
+                                               fprintf(df, "none");
+                                               break;
+
+                                               case T_Pid:
+                                               fprintf(df, "pid");
+                                               break;
+
+                                               case T_Week:
+                                               fprintf(df, "week");
+                                               break;
+
+                                               case T_Year:
+                                               fprintf(df, "year");
+                                               break;
+                                       }
+                                       break;
+
+                                       case T_Flag:
+                                       switch (atrv->value.i) {
+                                               case T_Link:
+                                               fprintf(df, " link");
+                                               break;
+
+                                               case T_Nolink:
+                                               fprintf(df, " nolink");
+                                               break;
+
+                                               case T_Enable:
+                                               fprintf(df, " enable");
+                                               break;
+
+                                               case T_Disable:
+                                               fprintf(df, " disable");
+                                               break;
+                                       }
+                                       break;
+                               }
+
+                       }
+
+                       fprintf(df, "\n");
+               }
+       }
+
+       if(my_config_list.discard_opts != NULL) {
+               list_ptr = my_config_list.discard_opts;
+
+               for(;   list_ptr != NULL;
+                       list_ptr = list_ptr->next) {
+
+                       atrv = (struct attr_val *) list_ptr->value;
+
+                       /* FIXME! Not a line for each option */
+                       fprintf(df, "discard ");
+
+                       switch(atrv->attr) {
+                               case T_Average:
+                                       fprintf(df, "average %i\n", atrv->value.i);
+                                       break;
+
+                               case T_Minimum:
+                                       fprintf(df, "minimum %i\n", atrv->value.i);
+                                       break;
+
+                               case T_Monitor:
+                                       fprintf(df, "monitor %i\n", atrv->value.i);
+                       }
+
+                       fprintf(df, "\n");
+               }
+       }
+
+       if(my_config_list.restrict_opts != NULL) {
+               list_ptr = my_config_list.restrict_opts;
+
+               for(;   list_ptr != NULL; 
+                       list_ptr = list_ptr->next) {
+
+                       rest_node = (struct restrict_node *) list_ptr->value;
+
+                       fprintf(df, "restrict %s", rest_node->addr->address);
+
+                       if(rest_node->mask != NULL) 
+                               fprintf(df, " %s", rest_node->mask->address);
+
+                       s_list *flags = clone_queue(rest_node->flags);
+                       
+                       for(;   flags != NULL; flags = flags->next) {
+                               int *curr_flag = flags->value;
+
+                               switch(*curr_flag) {
+                                       case T_Flake:
+                                               fprintf(df, " flake");
+                                               break;
+
+                                       case T_Ignore:
+                                               fprintf(df, " ignore");
+                                               break;
+
+                                       case T_Limited:
+                                               fprintf(df, " limited");
+                                               break;
+
+                                       case T_Kod:
+                                               fprintf(df, " kod");
+                                               break;
+
+                                       case T_Lowpriotrap:
+                                               fprintf(df, " lowpriotrap");
+                                               break;
+
+                                       case T_Nomodify:
+                                               fprintf(df, " nomodify");
+                                               break;
+
+                                       case T_Noquery:
+                                               fprintf(df, " noquery");
+                                               break;
+
+                                       case T_Nopeer:
+                                               fprintf(df, " nopeer");
+                                               break;
+
+                                       case T_Noserve:
+                                               fprintf(df, " noserve");
+                                               break;
+
+                                       case T_Notrap:
+                                               fprintf(df, " notrap");
+                                               break;
+
+                                       case T_Notrust:
+                                               fprintf(df, " notrust");
+                                               break;
+
+                                       case T_Ntpport:
+                                               fprintf(df, " ntpport");
+                                               break;
+
+                                       case T_Version:
+                                               fprintf(df, " version");
+                                               break;
+
+                                       case T_Default:
+                                               fprintf(df, " default");
+                                               break;
+                               }
+                       }
+                       
+                       fprintf(df, "\n");
+               }
+       }
+
+       
+       if(my_config_list.enable_opts != NULL) {
+               list_ptr = my_config_list.enable_opts;
+
+               for(;   list_ptr != NULL;
+                       list_ptr = list_ptr->next) {
+
+                       atrv = (struct attr_val *) list_ptr->value;
+
+                       fprintf(df, "enable");
+
+                       switch(atrv->attr) {
+                               case T_Autokey: 
+                               fprintf(df, " autokey");        
+                               break;
+
+                               case T_Bias: 
+                               fprintf(df, " bias");
+                               break;
+
+                               case T_Burst: 
+                               fprintf(df, " burst");
+                               break;
+
+                               case T_Iburst: 
+                               fprintf(df, " iburst");
+                               break;
+
+                               case T_Key: 
+                               fprintf(df, " key");
+                               break;
+
+                               case T_Maxpoll: 
+                               fprintf(df, " maxpoll");
+                               break;
+
+                               case T_Minpoll: 
+                               fprintf(df, " minpoll");
+                               break;
+
+                               case T_Mode: 
+                               fprintf(df, " mode");
+                               break;
+
+                               case T_Noselect: 
+                               fprintf(df, " noselect");
+                               break;
+
+                               case T_Preempt: 
+                               fprintf(df, " preempt");
+                               break;
+
+                               case T_True: 
+                               fprintf(df, " true");
+                               break;
+
+                               case T_Prefer: 
+                               fprintf(df, " prefer");
+                               break;
+
+                               case T_Ttl: 
+                               fprintf(df, " ttl");
+                               break;
+
+                               case T_Version: 
+                               fprintf(df, " version");
+                               break;
+
+                               case T_Xleave: 
+                               fprintf(df, " xleave");
+                               break;
+                       }
+               }
+       }
+
+       if(my_config_list.disable_opts != NULL) {
+               list_ptr = my_config_list.disable_opts;
+
+               fprintf(df, "disable");
+
+               for(;   list_ptr != NULL;
+                       list_ptr = list_ptr->next) {
+
+                       atrv = (struct attr_val *) list_ptr->value;
+
+                       switch(atrv->attr) {
+                               case T_Autokey: 
+                               fprintf(df, " autokey");        
+                               break;
+
+                               case T_Bias: 
+                               fprintf(df, " bias");
+                               break;
+
+                               case T_Burst: 
+                               fprintf(df, " burst");
+                               break;
+
+                               case T_Iburst: 
+                               fprintf(df, " iburst");
+                               break;
+
+                               case T_Key: 
+                               fprintf(df, " key");
+                               break;
+
+                               case T_Maxpoll: 
+                               fprintf(df, " maxpoll");
+                               break;
+
+                               case T_Minpoll: 
+                               fprintf(df, " minpoll");
+                               break;
+
+                               case T_Mode: 
+                               fprintf(df, " mode");
+                               break;
+
+                               case T_Noselect: 
+                               fprintf(df, " noselect");
+                               break;
+
+                               case T_Preempt: 
+                               fprintf(df, " preempt");
+                               break;
+
+                               case T_True: 
+                               fprintf(df, " true");
+                               break;
+
+                               case T_Prefer: 
+                               fprintf(df, " prefer");
+                               break;
+
+                               case T_Ttl: 
+                               fprintf(df, " ttl");
+                               break;
+
+                               case T_Version: 
+                               fprintf(df, " version");
+                               break;
+
+                               case T_Xleave: 
+                               fprintf(df, " xleave");
+                               break;
+                       }
+               }
+
+       }
+
+       if(my_config_list.tinker != NULL) {
+               list_ptr = my_config_list.tinker;
+
+               fprintf(df, "tinker");
+
+               for(;   list_ptr != NULL;
+                       list_ptr = list_ptr->next) {
+
+                       atrv = (struct attr_val *) list_ptr->value;
+
+                       switch(atrv->attr) {
+                               case T_Step:    
+                                    fprintf(df, " step");
+                                    break;
+
+                               case T_Panic: 
+                                    fprintf(df, " panic");
+                                    break;
+
+                               case T_Dispersion: 
+                                    fprintf(df, " dispersion");
+                                    break;
+
+                               case T_Stepout: 
+                                    fprintf(df, " stepout");
+                                    break;
+
+                               case T_Allan: 
+                                    fprintf(df, " allan");
+                                    break;
+
+                               case T_Huffpuff: 
+                                    fprintf(df, " huffpuff");
+                                    break;
+
+                               case T_Freq: 
+                                    fprintf(df, " freq");
+                                    break;
+                       }
+
+                       fprintf(df, " %f", atrv->value.d);
+               }
+
+               fprintf(df, "\n");
+       }
+
+       if(my_config_list.fudge != NULL) {
+               list_ptr = my_config_list.fudge;
+
+               for(;   list_ptr != NULL;
+                       list_ptr = list_ptr->next) {
+
+                       fprintf(df, "fudge");
+
+                       addr_opts = (struct addr_opts_node *) list_ptr->value;
+
+                       fprintf(df, "%s", addr_opts->addr->address);
+
+                       s_list *opts = clone_queue(addr_opts->options);
+
+                       for(; opts != NULL; opts = opts->next) {
+                               atrv = (struct attr_val *) opts->value; 
+                               
+                               switch(atrv->attr) {
+                                       case CLK_HAVETIME1:
+                                       fprintf(df, " time1 %f", atrv->value.d);
+                                       break;
+                               
+                                       case CLK_HAVETIME2:
+                                       fprintf(df, " time2 %f", atrv->value.d);
+                                       break;
+               
+                                       case CLK_HAVEVAL1:
+                                       fprintf(df, " stratum %i", atrv->value.i);
+                                       break;
+
+                                       /* FIXME what the... is this semi-colon needed for? */
+                                       case CLK_HAVEVAL2:;
+                                       char refid[] = {0, 0, 0, 0, '\0'};
+
+                                       memcpy(refid,
+                                       atrv->value.s,
+                                       min(strlen(atrv->value.s), 4));
+                                       
+                                       fprintf(df, " refid %s", refid);
+                                       break;
+
+                                       case CLK_HAVEFLAG1:
+                                       if (atrv->value.i)
+                                               fprintf(df, " flag1 1");
+                                       else 
+                                               fprintf(df, " flag1 0");
+                                       break;
+                           
+                                       case CLK_HAVEFLAG2:
+                                       if (atrv->value.i)
+                                               fprintf(df, " flag2 1");
+                                       else 
+                                               fprintf(df, " flag2 0");
+                                       break;
+                           
+                                       case CLK_HAVEFLAG3:
+                                       if (atrv->value.i)
+                                               fprintf(df, " flag3 1");
+                                       else 
+                                               fprintf(df, " flag3 0");
+
+                                       break;
+                           
+                                       case CLK_HAVEFLAG4:
+                                       if (atrv->value.i)
+                                               fprintf(df, " flag4 1");
+                                       else 
+                                               fprintf(df, " flag4 0");
+                                       break;
+                               }
+                       }
+
+                       fprintf(df, "\n");
+               }
+       }
+
+       if(my_config_list.logconfig != NULL) {
+               list_ptr = my_config_list.logconfig;
+               
+               fprintf(df, "logconfig");
+
+               for(;   list_ptr != NULL;
+                       list_ptr = list_ptr->next) {
+                       atrv = (struct attr_val *) list_ptr->value;
+
+                       fprintf(df, " %c%s", atrv->attr, atrv->value.s);
+               }
+
+               fprintf(df, "\n");
+       }
+
+       if(my_config_list.phone != NULL) {
+               list_ptr = my_config_list.phone;
+
+               fprintf(df, "phone");
+
+               for(;   list_ptr != NULL;
+                       list_ptr = list_ptr->next) {
+                       string = list_ptr->value;
+
+                       fprintf(df, " %s", *string);
+               }
+
+               fprintf(df, "\n");
+       }
+
+       if(my_config_list.qos != NULL) {
+               list_ptr = my_config_list.qos;
+               
+               fprintf(df, "qos");
+
+               for(;   list_ptr != NULL;
+                       list_ptr = list_ptr->next) {
+                       atrv = (struct attr_val *) list_ptr->value;
+
+                       fprintf(df, " %s", atrv->value.s);
+               }
+
+               fprintf(df, "\n");
+       }
+
+       if(my_config_list.setvar != NULL) {
+               list_ptr = my_config_list.setvar;
+
+               fprintf(df, "setvar");
+
+               for(;   list_ptr != NULL;
+                       list_ptr = list_ptr->next) {
+                       int a = 0;
+                       char *data = NULL;
+
+                       setv_node = (struct setvar_node *) list_ptr->value;
+                       data = setv_node->data;
+
+                       fprintf(df, " ");
+
+                       for(a=0; a<setv_node->len; a++) 
+                               if(data[a] == '=') 
+                                       fprintf(df, " ");
+                               else
+                                       fprintf(df, "%c", data[a]);
+
+                       if(setv_node->def)
+                               fprintf(df, " default");
+               }
+       }
+
+       if(my_config_list.ttl != NULL) {
+               list_ptr = my_config_list.ttl;
+
+               fprintf(df, "ttl");
+
+               for(;   list_ptr != NULL;
+                       list_ptr = list_ptr->next) {
+                       integer = (int *) list_ptr->value;
+
+                       fprintf(df, " %i", *integer);
+               }
+               
+               fprintf(df, "\n");
+       }
+       
+       if(my_config_list.trap != NULL) {
+               list_ptr = my_config_list.trap;
+
+               for(;   list_ptr != NULL;
+                       list_ptr = list_ptr->next) {
+
+                       addr_opts = (struct addr_opts_node *) list_ptr->value;
+                       addr = addr_opts->addr;
+
+                       fprintf(df, "trap %s", addr->address);
+
+                       s_list *options = clone_queue(addr_opts->options);
+
+                       for(;   options != NULL; 
+                               options = options->next) {
+
+                               atrv = (struct attr_val *) options->value;
+
+                               if(atrv->attr == T_Port) {
+                                       fprintf(df, " port %i", atrv->value.i);
+                               }
+                               else {
+                                       if(atrv->attr == T_Interface) {
+                                               addr = (struct address_node *) atrv->value.p;
+
+                                               fprintf(df, " interface %s", addr->address);
+                                       }
+                               }
+                       }
+
+                       free_s_list(options);
+
+                       fprintf(df, "\n");
+               }
+       }
+
+       /* For options I didn't find documentation I'll just output its name and the cor. value */
+       if(my_config_list.vars != NULL) {
+               list_ptr = my_config_list.vars;
+
+               for(;   list_ptr != NULL;
+                       list_ptr = list_ptr->next) {
+
+                       atrv = (struct attr_val *) list_ptr->value;
+
+                       switch (atrv->attr) {
+                               case T_Broadcastdelay:
+                               fprintf(df, "broadcastdelay %f\n", atrv->value.d);
+                               break;
+                               
+                               case T_Calldelay:
+                               fprintf(df, "calldelay %i\n", atrv->value.i);
+                               break;
+
+                               case T_Tick:
+                               fprintf(df, "tick %f\n", atrv->value.d);
+                               break;
+
+                               case T_Driftfile:
+                               fprintf(df, "driftfile %s\n", atrv->value.s);
+                               break;
+                       
+                               case T_WanderThreshold:
+                               fprintf(df, "wander_threshold %f\n", atrv->value.d);
+                               break;
+       
+                               case T_Leapfile:
+                               fprintf(df, "leapfile %s\n", atrv->value.s);
+                               break;
+
+                               case T_Pidfile:
+                               fprintf(df, "pidfile %s\n", atrv->value.s);
+                               break;
+
+                               case T_Logfile:
+                               fprintf(df, "logfile %s\n", atrv->value.s);
+                               break;
+#ifdef OPENSSL
+                               case T_Automax:
+                               fprintf(df, "automax %i\n", atrv->value.i);
+                               break;
+#endif
+                       }
+               }
+       }
+
+       fclose(df);
+
+       return 0;
+}
+
+       
+
 /* FUNCTIONS FOR CREATING NODES ON THE SYNTAX TREE
  * -----------------------------------------------
  */
@@ -900,6 +1737,23 @@ create_sim_node(
 }
 
 
+/* Lookup the keyword associated with token */
+/*
+char *
+token_to_str (
+               int token
+           )
+{
+       register int a = 0;
+
+       for(; a<sizeof(keyword_list)/sizeof(struct key_tok); a++) 
+               if(keyword_list[a]->token == token)
+                       return keyword_list[a]->keyword;
+
+       return NULL;
+}*/
+
+
 struct key_tok keyword_list[] = {
        { "automax",            T_Automax,         NO_ARG },
        { "broadcast",          T_Broadcast,       SINGLE_ARG },
@@ -1299,47 +2153,47 @@ config_monitor(void)
 
                        switch (my_opts->attr) {
 
-                       case T_File:
-                               filegen_file = my_opts->value.p;
-                               break;
-
-                       case T_Type:
-                               filegen_type = my_opts->value.i;
-                               break;
+               case T_File:
+                       filegen_file = my_opts->value.p;
+                       break;
 
-                       case T_Flag:
-                               switch (my_opts->value.i) {
+               case T_Type:
+                       filegen_type = my_opts->value.i;
+                       break;
 
-                               case T_Link:
-                                       filegen_flag |= FGEN_FLAG_LINK;
-                                       break;
+               case T_Flag:
+                       switch (my_opts->value.i) {
 
-                               case T_Nolink:
-                                       filegen_flag &= ~FGEN_FLAG_LINK;
-                                       break;
+                       case T_Link:
+                               filegen_flag |= FGEN_FLAG_LINK;
+                               break;
 
-                               case T_Enable:
-                                       filegen_flag |= FGEN_FLAG_ENABLED;
-                                       break;
+                       case T_Nolink:
+                               filegen_flag &= ~FGEN_FLAG_LINK;
+                               break;
 
-                               case T_Disable:
-                                       filegen_flag &= ~FGEN_FLAG_ENABLED;
-                                       break;
+                       case T_Enable:
+                               filegen_flag |= FGEN_FLAG_ENABLED;
+                               break;
 
-                               default:
-                                       msyslog(LOG_ERR, 
-                                               "Unknown filegen flag "
-                                               "token %d",
-                                               my_opts->value.i);
-                                       exit(1);
-                               }
+                       case T_Disable:
+                               filegen_flag &= ~FGEN_FLAG_ENABLED;
                                break;
+
                        default:
-                               msyslog(LOG_ERR,
-                                       "Unknown filegen option token "
-                                       "%d", my_opts->attr);
+                               msyslog(LOG_ERR, 
+                                       "Unknown filegen flag "
+                                       "token %d",
+                                       my_opts->value.i);
                                exit(1);
                        }
+                       break;
+               default:
+                       msyslog(LOG_ERR,
+                               "Unknown filegen option token "
+                               "%d", my_opts->attr);
+                       exit(1);
+               }
                        filegen_config(filegen, filegen_file, 
                                       filegen_type, filegen_flag);
                        free_node(my_opts);
@@ -2363,6 +3217,12 @@ getconfig(
        init_syntax_tree();
        key_scanner = create_keyword_scanner(keyword_list);
        yyparse();
+       
+       /* Create a clone of the configuration in a singly linked list before it is
+        * consumed. Only the information held by the priority queue is being saved.
+        */
+       clone_config(&my_config, &my_config_list);
+
        delete_keyword_scanner(key_scanner);
        key_scanner = NULL;
 
index 091ef1e7ec12853e4aeb6fa37677b6a63b77cba3..3eecc9eb29ac2c11cde55eaec190c777c1176020 100644 (file)
@@ -106,6 +106,50 @@ queue *enqueue(queue *my_queue, void *my_node)
     return my_queue;
 }
 
+/* Create a singly-linked list copy of a priority queue 
+ */
+
+s_list *
+clone_queue (
+               queue *my_queue
+           )
+{
+       if(empty(my_queue)) 
+               return NULL;
+
+       s_list *list = (s_list *) malloc(sizeof(s_list));
+       s_list *list_ptr = list;
+       node *my_node = my_queue->front;
+
+       list->value = (void *)(my_node + 1);
+
+       for(my_node = my_node->node_next; my_node != NULL; my_node = my_node->node_next) {
+               list_ptr->next = (s_list *) malloc(sizeof(s_list));
+               list_ptr = list_ptr->next;
+               list_ptr->value = (void *)(my_node + 1);
+               list_ptr->next = NULL;
+       }
+
+       return list;
+}
+
+
+/* Free singly-linked list 
+ */
+
+void
+free_s_list (
+               s_list *my_list
+           )
+{
+       s_list *list_next = NULL;
+
+       for(; my_list != NULL; my_list = list_next) {
+               list_next = my_list->next;
+               free(my_list);
+       }
+}
+
 
 /* Define a function to dequeue the first element from the priority
  * queue and return it
index bd747f6f21be02c4ec5fd98af4c9a0a147ab9a37..e78a7f2ada9902182256f24decce237fee83b205 100644 (file)
@@ -64,6 +64,7 @@ static        void    doopeers        (int, FILE *, int);
 static void    opeers          (struct parse *, FILE *);
 static void    lopeers         (struct parse *, FILE *);
 static  void    config          (struct parse *, FILE *);
+static         void    dumpcfg         (struct parse *, FILE *);
 static  void    config_from_file (struct parse *, FILE *);
 
 
@@ -71,6 +72,9 @@ static  void    config_from_file (struct parse *, FILE *);
  * Commands we understand.     Ntpdc imports this.
  */
 struct xcmd opcmds[] = {
+       { "dumpcfg", dumpcfg, { NO, NO, NO, NO },
+               { "", "", "", ""}, 
+               "dump ntp server configuration"},
        { "associations", associations, {  NO, NO, NO, NO },
          { "", "", "", "" },
          "print list of association ID's and statuses for the server's peers" },
@@ -451,7 +455,6 @@ doprintvlist(
        }
 }
 
-
 /*
  * addvars - add variables to the variable list
  */
@@ -1165,6 +1168,35 @@ lpassociations(
 }
 
 
+/*
+ *  * dumpcfg - dump ntp server configuration
+ */
+static void
+dumpcfg(
+       struct parse *pcmd,
+       FILE *fp
+       )
+{
+       char *datap;
+       int res;
+       int dsize;
+       u_short rstatus;
+       register int a = 0;
+
+       printf("%s\n", pcmd->keyword);
+
+       for(; a<pcmd->nargs; a++) 
+               printf("%s\n", pcmd->argval[a]);
+
+
+       /* For now let's just send a "signal" and have it realize the dump op */
+       res = doquery(CTL_OP_DUMPCONFIG, 0, 0, 0, (char *)0, &rstatus,
+                       &dsize, &datap);
+
+       printf("ntpq: res = %i %s\n", res, datap);
+}
+
+
 #ifdef UNUSED
 /*
  * radiostatus - print the radio status returned by the server