Pārlūkot izejas kodu

Lower responsibility for listing changed options into confparse.c

Nick Mathewson 4 gadi atpakaļ
vecāks
revīzija
89a3051365
3 mainītis faili ar 49 papildinājumiem un 29 dzēšanām
  1. 7 29
      src/app/config/config.c
  2. 40 0
      src/app/config/confparse.c
  3. 2 0
      src/app/config/confparse.h

+ 7 - 29
src/app/config/config.c

@@ -964,9 +964,6 @@ get_options_defaults(void)
 int
 set_options(or_options_t *new_val, char **msg)
 {
-  int i;
-  smartlist_t *elements;
-  config_line_t *line;
   or_options_t *old_options = global_options;
   global_options = new_val;
   /* Note that we pass the *old* options below, for comparison. It
@@ -988,35 +985,16 @@ set_options(or_options_t *new_val, char **msg)
   /* Issues a CONF_CHANGED event to notify controller of the change. If Tor is
    * just starting up then the old_options will be undefined. */
   if (old_options && old_options != global_options) {
-    elements = smartlist_new();
-    for (i=0; options_format.vars[i].member.name; ++i) {
-      const config_var_t *var = &options_format.vars[i]; // XXXX 29211
-      const char *var_name = var->member.name;
-      if (config_var_is_contained(var)) {
-        /* something else will check this var, or it doesn't need checking */
-        continue;
-      }
-      if (!config_is_same(get_options_mgr(), new_val, old_options, var_name)) {
-        line = config_get_assigned_option(get_options_mgr(), new_val,
-                                          var_name, 1);
-
-        if (line) {
-          config_line_t *next;
-          for (; line; line = next) {
-            next = line->next;
-            smartlist_add(elements, line->key);
-            smartlist_add(elements, line->value);
-            tor_free(line);
-          }
-        } else {
-          smartlist_add_strdup(elements, options_format.vars[i].member.name);
-          smartlist_add(elements, NULL);
-        }
-      }
+    smartlist_t *elements = smartlist_new();
+    config_line_t *changes =
+      config_get_changes(get_options_mgr(), old_options, new_val);
+    for (config_line_t *line = changes; line; line = line->next) {
+      smartlist_add(elements, line->key);
+      smartlist_add(elements, line->value);
     }
     control_event_conf_changed(elements);
-    SMARTLIST_FOREACH(elements, char *, cp, tor_free(cp));
     smartlist_free(elements);
+    config_free_lines(changes);
   }
 
   if (old_options != global_options) {

+ 40 - 0
src/app/config/confparse.c

@@ -738,6 +738,46 @@ config_is_same(const config_mgr_t *mgr,
   return struct_var_eq(obj1, obj2, &var->cvar->member);
 }
 
+/**
+ * Return a list of the options which have changed between <b>options1</b> and
+ * <b>options2</b>. If an option has reverted to its default value, it has a
+ * value entry of NULL.
+ **/
+config_line_t *
+config_get_changes(const config_mgr_t *mgr,
+                   const void *options1, const void *options2)
+{
+  config_line_t *result = NULL;
+  config_line_t **next = &result;
+  SMARTLIST_FOREACH_BEGIN(mgr->all_vars, managed_var_t *, mv) {
+    if (config_var_is_contained(mv->cvar)) {
+      /* something else will check this var, or it doesn't need checking */
+      continue;
+    }
+    const void *obj1 = config_mgr_get_obj(mgr, options1, mv->object_idx);
+    const void *obj2 = config_mgr_get_obj(mgr, options2, mv->object_idx);
+
+    if (struct_var_eq(obj1, obj2, &mv->cvar->member)) {
+      continue;
+    }
+
+    const char *varname = mv->cvar->member.name;
+    config_line_t *line =
+      config_get_assigned_option(mgr, options2, varname, 1);
+
+    if (line) {
+      *next = line;
+    } else {
+      *next = tor_malloc_zero(sizeof(config_line_t));
+      (*next)->key = tor_strdup(varname);
+    }
+    while (*next)
+      next = &(*next)->next;
+  } SMARTLIST_FOREACH_END(mv);
+
+  return result;
+}
+
 /** Copy storage held by <b>old</b> into a new or_options_t and return it. */
 void *
 config_dup(const config_mgr_t *mgr, const void *old)

+ 2 - 0
src/app/config/confparse.h

@@ -100,6 +100,8 @@ struct config_line_t *config_get_assigned_option(const config_mgr_t *mgr,
 int config_is_same(const config_mgr_t *fmt,
                    const void *o1, const void *o2,
                    const char *name);
+struct config_line_t *config_get_changes(const config_mgr_t *mgr,
+                                  const void *options1, const void *options2);
 void config_init(const config_mgr_t *mgr, void *options);
 void *config_dup(const config_mgr_t *mgr, const void *old);
 char *config_dump(const config_mgr_t *mgr, const void *default_options,