Selaa lähdekoodia

Split confline into confline and conffile.

The "conffile" module knows about includes and filesystem access,
whereas confline doesn't.  This will make it possible to put these
functions into libraries without introducing a cycle.
Nick Mathewson 5 vuotta sitten
vanhempi
commit
696f6f1569
7 muutettua tiedostoa jossa 209 lisäystä ja 166 poistoa
  1. 164 0
      src/common/conffile.c
  2. 17 0
      src/common/conffile.h
  3. 7 161
      src/common/confline.c
  4. 16 4
      src/common/confline.h
  5. 2 0
      src/common/include.am
  6. 1 0
      src/or/config.c
  7. 2 1
      src/test/test_config.c

+ 164 - 0
src/common/conffile.c

@@ -0,0 +1,164 @@
+/* Copyright (c) 2001 Matej Pfajfar.
+ * Copyright (c) 2001-2004, Roger Dingledine.
+ * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
+ * Copyright (c) 2007-2018, The Tor Project, Inc. */
+/* See LICENSE for licensing information */
+
+#include "common/compat.h"
+#include "common/confline.h"
+#include "common/conffile.h"
+#include "lib/log/torlog.h"
+#include "common/util.h"
+#include "lib/container/smartlist.h"
+
+static smartlist_t *config_get_file_list(const char *path,
+                                         smartlist_t *opened_files);
+static int config_get_included_config(const char *path, int recursion_level,
+                                      int extended, config_line_t **config,
+                                      config_line_t **config_last,
+                                      smartlist_t *opened_lst);
+static int config_process_include(const char *path, int recursion_level,
+                                  int extended, config_line_t **list,
+                                  config_line_t **list_last,
+                                  smartlist_t *opened_lst);
+
+/** Helper: parse the config string and strdup into key/value
+ * strings. Set *result to the list, or NULL if parsing the string
+ * failed. Set *has_include to 1 if <b>result</b> has values from
+ * %included files. <b>opened_lst</b> will have a list of opened files if
+ * provided. Return 0 on success, -1 on failure. Warn and ignore any
+ * misformatted lines.
+ *
+ * If <b>extended</b> is set, then treat keys beginning with / and with + as
+ * indicating "clear" and "append" respectively. */
+int
+config_get_lines_include(const char *string, config_line_t **result,
+                         int extended, int *has_include,
+                         smartlist_t *opened_lst)
+{
+  return config_get_lines_aux(string, result, extended, 1, has_include,
+                              opened_lst, 1, NULL, config_process_include);
+}
+
+/** Adds a list of configuration files present on <b>path</b> to
+ * <b>file_list</b>. <b>path</b> can be a file or a directory. If it is a file,
+ * only that file will be added to <b>file_list</b>. If it is a directory,
+ * all paths for files on that directory root (no recursion) except for files
+ * whose name starts with a dot will be added to <b>file_list</b>.
+ * <b>opened_files</b> will have a list of files opened by this function
+ * if provided. Return 0 on success, -1 on failure. Ignores empty files.
+ */
+static smartlist_t *
+config_get_file_list(const char *path, smartlist_t *opened_files)
+{
+  smartlist_t *file_list = smartlist_new();
+
+  if (opened_files) {
+    smartlist_add_strdup(opened_files, path);
+  }
+
+  file_status_t file_type = file_status(path);
+  if (file_type == FN_FILE) {
+    smartlist_add_strdup(file_list, path);
+    return file_list;
+  } else if (file_type == FN_DIR) {
+    smartlist_t *all_files = tor_listdir(path);
+    if (!all_files) {
+      smartlist_free(file_list);
+      return NULL;
+    }
+    smartlist_sort_strings(all_files);
+    SMARTLIST_FOREACH_BEGIN(all_files, char *, f) {
+      if (f[0] == '.') {
+        tor_free(f);
+        continue;
+      }
+
+      char *fullname;
+      tor_asprintf(&fullname, "%s"PATH_SEPARATOR"%s", path, f);
+      tor_free(f);
+
+      if (opened_files) {
+        smartlist_add_strdup(opened_files, fullname);
+      }
+
+      if (file_status(fullname) != FN_FILE) {
+        tor_free(fullname);
+        continue;
+      }
+      smartlist_add(file_list, fullname);
+    } SMARTLIST_FOREACH_END(f);
+    smartlist_free(all_files);
+    return file_list;
+  } else if (file_type == FN_EMPTY) {
+      return file_list;
+  } else {
+    smartlist_free(file_list);
+    return NULL;
+  }
+}
+
+/** Creates a list of config lines present on included <b>path</b>.
+ * Set <b>config</b> to the list and <b>config_last</b> to the last element of
+ * <b>config</b>. <b>opened_lst</b> will have a list of opened files if
+ * provided. Return 0 on success, -1 on failure. */
+static int
+config_get_included_config(const char *path, int recursion_level, int extended,
+                           config_line_t **config, config_line_t **config_last,
+                           smartlist_t *opened_lst)
+{
+  char *included_conf = read_file_to_str(path, 0, NULL);
+  if (!included_conf) {
+    return -1;
+  }
+
+  if (config_get_lines_aux(included_conf, config, extended, 1, NULL,
+                           opened_lst, recursion_level+1, config_last,
+                           config_process_include) < 0) {
+    tor_free(included_conf);
+    return -1;
+  }
+
+  tor_free(included_conf);
+  return 0;
+}
+
+/** Process an %include <b>path</b> in a config file. Set <b>list</b> to the
+ * list of configuration settings obtained and <b>list_last</b> to the last
+ * element of the same list. <b>opened_lst</b> will have a list of opened
+ * files if provided. Return 0 on success, -1 on failure. */
+static int
+config_process_include(const char *path, int recursion_level, int extended,
+                       config_line_t **list, config_line_t **list_last,
+                       smartlist_t *opened_lst)
+{
+  config_line_t *ret_list = NULL;
+  config_line_t **next = &ret_list;
+
+  smartlist_t *config_files = config_get_file_list(path, opened_lst);
+  if (!config_files) {
+    return -1;
+  }
+
+  int rv = -1;
+  SMARTLIST_FOREACH_BEGIN(config_files, const char *, config_file) {
+    config_line_t *included_config = NULL;
+    if (config_get_included_config(config_file, recursion_level, extended,
+                                   &included_config, list_last,
+                                   opened_lst) < 0) {
+      goto done;
+    }
+
+    *next = included_config;
+    if (*list_last)
+      next = &(*list_last)->next;
+
+  } SMARTLIST_FOREACH_END(config_file);
+  *list = ret_list;
+  rv = 0;
+
+ done:
+  SMARTLIST_FOREACH(config_files, char *, f, tor_free(f));
+  smartlist_free(config_files);
+  return rv;
+}

+ 17 - 0
src/common/conffile.h

@@ -0,0 +1,17 @@
+/* Copyright (c) 2001 Matej Pfajfar.
+ * Copyright (c) 2001-2004, Roger Dingledine.
+ * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
+ * Copyright (c) 2007-2018, The Tor Project, Inc. */
+/* See LICENSE for licensing information */
+
+#ifndef TOR_CONFFILE_H
+#define TOR_CONFFILE_H
+
+struct smartlist_t;
+struct config_line_t;
+
+int config_get_lines_include(const char *string, struct config_line_t **result,
+                             int extended, int *has_include,
+                             struct smartlist_t *opened_lst);
+
+#endif /* !defined(TOR_CONFLINE_H) */

+ 7 - 161
src/common/confline.c

@@ -10,21 +10,6 @@
 #include "common/util.h"
 #include "lib/container/smartlist.h"
 
-static int config_get_lines_aux(const char *string, config_line_t **result,
-                                int extended, int allow_include,
-                                int *has_include, smartlist_t *opened_lst,
-                                int recursion_level, config_line_t **last);
-static smartlist_t *config_get_file_list(const char *path,
-                                         smartlist_t *opened_files);
-static int config_get_included_config(const char *path, int recursion_level,
-                                      int extended, config_line_t **config,
-                                      config_line_t **config_last,
-                                      smartlist_t *opened_lst);
-static int config_process_include(const char *path, int recursion_level,
-                                  int extended, config_line_t **list,
-                                  config_line_t **list_last,
-                                  smartlist_t *opened_lst);
-
 /** Helper: allocate a new configuration option mapping 'key' to 'val',
  * append it to *<b>lst</b>. */
 void
@@ -86,11 +71,12 @@ config_line_find(const config_line_t *lines,
  * <b>opened_lst</b> will have a list of opened files if provided.
  * Returns the a pointer to the last element of the <b>result</b> in
  * <b>last</b>. */
-static int
+int
 config_get_lines_aux(const char *string, config_line_t **result, int extended,
                      int allow_include, int *has_include,
                      smartlist_t *opened_lst, int recursion_level,
-                     config_line_t **last)
+                     config_line_t **last,
+                     include_handler_fn handle_include)
 {
   config_line_t *list = NULL, **next, *list_last = NULL;
   char *k, *v;
@@ -133,13 +119,13 @@ config_get_lines_aux(const char *string, config_line_t **result, int extended,
         }
       }
 
-      if (allow_include && !strcmp(k, "%include")) {
+      if (allow_include && !strcmp(k, "%include") && handle_include) {
         tor_free(k);
         include_used = 1;
 
         config_line_t *include_list;
-        if (config_process_include(v, recursion_level, extended, &include_list,
-                                   &list_last, opened_lst) < 0) {
+        if (handle_include(v, recursion_level, extended, &include_list,
+                           &list_last, opened_lst) < 0) {
           log_warn(LD_CONFIG, "Error reading included configuration "
                    "file or directory: \"%s\".", v);
           config_free_lines(list);
@@ -178,152 +164,12 @@ config_get_lines_aux(const char *string, config_line_t **result, int extended,
   return 0;
 }
 
-/** Helper: parse the config string and strdup into key/value
- * strings. Set *result to the list, or NULL if parsing the string
- * failed. Set *has_include to 1 if <b>result</b> has values from
- * %included files. <b>opened_lst</b> will have a list of opened files if
- * provided. Return 0 on success, -1 on failure. Warn and ignore any
- * misformatted lines.
- *
- * If <b>extended</b> is set, then treat keys beginning with / and with + as
- * indicating "clear" and "append" respectively. */
-int
-config_get_lines_include(const char *string, config_line_t **result,
-                         int extended, int *has_include,
-                         smartlist_t *opened_lst)
-{
-  return config_get_lines_aux(string, result, extended, 1, has_include,
-                              opened_lst, 1, NULL);
-}
-
 /** Same as config_get_lines_include but does not allow %include */
 int
 config_get_lines(const char *string, config_line_t **result, int extended)
 {
   return config_get_lines_aux(string, result, extended, 0, NULL, NULL, 1,
-                              NULL);
-}
-
-/** Adds a list of configuration files present on <b>path</b> to
- * <b>file_list</b>. <b>path</b> can be a file or a directory. If it is a file,
- * only that file will be added to <b>file_list</b>. If it is a directory,
- * all paths for files on that directory root (no recursion) except for files
- * whose name starts with a dot will be added to <b>file_list</b>.
- * <b>opened_files</b> will have a list of files opened by this function
- * if provided. Return 0 on success, -1 on failure. Ignores empty files.
- */
-static smartlist_t *
-config_get_file_list(const char *path, smartlist_t *opened_files)
-{
-  smartlist_t *file_list = smartlist_new();
-
-  if (opened_files) {
-    smartlist_add_strdup(opened_files, path);
-  }
-
-  file_status_t file_type = file_status(path);
-  if (file_type == FN_FILE) {
-    smartlist_add_strdup(file_list, path);
-    return file_list;
-  } else if (file_type == FN_DIR) {
-    smartlist_t *all_files = tor_listdir(path);
-    if (!all_files) {
-      smartlist_free(file_list);
-      return NULL;
-    }
-    smartlist_sort_strings(all_files);
-    SMARTLIST_FOREACH_BEGIN(all_files, char *, f) {
-      if (f[0] == '.') {
-        tor_free(f);
-        continue;
-      }
-
-      char *fullname;
-      tor_asprintf(&fullname, "%s"PATH_SEPARATOR"%s", path, f);
-      tor_free(f);
-
-      if (opened_files) {
-        smartlist_add_strdup(opened_files, fullname);
-      }
-
-      if (file_status(fullname) != FN_FILE) {
-        tor_free(fullname);
-        continue;
-      }
-      smartlist_add(file_list, fullname);
-    } SMARTLIST_FOREACH_END(f);
-    smartlist_free(all_files);
-    return file_list;
-  } else if (file_type == FN_EMPTY) {
-      return file_list;
-  } else {
-    smartlist_free(file_list);
-    return NULL;
-  }
-}
-
-/** Creates a list of config lines present on included <b>path</b>.
- * Set <b>config</b> to the list and <b>config_last</b> to the last element of
- * <b>config</b>. <b>opened_lst</b> will have a list of opened files if
- * provided. Return 0 on success, -1 on failure. */
-static int
-config_get_included_config(const char *path, int recursion_level, int extended,
-                           config_line_t **config, config_line_t **config_last,
-                           smartlist_t *opened_lst)
-{
-  char *included_conf = read_file_to_str(path, 0, NULL);
-  if (!included_conf) {
-    return -1;
-  }
-
-  if (config_get_lines_aux(included_conf, config, extended, 1, NULL,
-                           opened_lst, recursion_level+1, config_last) < 0) {
-    tor_free(included_conf);
-    return -1;
-  }
-
-  tor_free(included_conf);
-  return 0;
-}
-
-/** Process an %include <b>path</b> in a config file. Set <b>list</b> to the
- * list of configuration settings obtained and <b>list_last</b> to the last
- * element of the same list. <b>opened_lst</b> will have a list of opened
- * files if provided. Return 0 on success, -1 on failure. */
-static int
-config_process_include(const char *path, int recursion_level, int extended,
-                       config_line_t **list, config_line_t **list_last,
-                       smartlist_t *opened_lst)
-{
-  config_line_t *ret_list = NULL;
-  config_line_t **next = &ret_list;
-
-  smartlist_t *config_files = config_get_file_list(path, opened_lst);
-  if (!config_files) {
-    return -1;
-  }
-
-  int rv = -1;
-  SMARTLIST_FOREACH_BEGIN(config_files, const char *, config_file) {
-    config_line_t *included_config = NULL;
-    if (config_get_included_config(config_file, recursion_level, extended,
-                                   &included_config, list_last,
-                                   opened_lst) < 0) {
-      goto done;
-    }
-
-    *next = included_config;
-    if (*list_last)
-      next = &(*list_last)->next;
-
-  } SMARTLIST_FOREACH_END(config_file);
-  *list = ret_list;
-  rv = 0;
-
- done:
-  SMARTLIST_FOREACH(config_files, char *, f, tor_free(f));
-  smartlist_free(config_files);
-  return rv;
+                              NULL, NULL);
 }
 
 /**

+ 16 - 4
src/common/confline.h

@@ -44,10 +44,6 @@ const config_line_t *config_line_find(const config_line_t *lines,
                                       const char *key);
 int config_lines_eq(config_line_t *a, config_line_t *b);
 int config_count_key(const config_line_t *a, const char *key);
-int config_get_lines(const char *string, config_line_t **result, int extended);
-int config_get_lines_include(const char *string, config_line_t **result,
-                             int extended, int *has_include,
-                             struct smartlist_t *opened_lst);
 void config_free_lines_(config_line_t *front);
 #define config_free_lines(front) \
   do {                           \
@@ -57,4 +53,20 @@ void config_free_lines_(config_line_t *front);
 const char *parse_config_line_from_str_verbose(const char *line,
                                        char **key_out, char **value_out,
                                        const char **err_out);
+
+int config_get_lines(const char *string, struct config_line_t **result,
+                     int extended);
+
+typedef int (*include_handler_fn)(const char *, int, int,
+                                  struct config_line_t **,
+                                  struct config_line_t **,
+                                  struct smartlist_t *);
+
+int config_get_lines_aux(const char *string, struct config_line_t **result,
+                         int extended,
+                         int allow_include, int *has_include,
+                         struct smartlist_t *opened_lst, int recursion_level,
+                         config_line_t **last,
+                         include_handler_fn handle_include);
+
 #endif /* !defined(TOR_CONFLINE_H) */

+ 2 - 0
src/common/include.am

@@ -37,6 +37,7 @@ LIBOR_A_SRC = \
   src/common/compat_threads.c				\
   src/common/compat_time.c				\
   src/common/confline.c					\
+  src/common/conffile.c					\
   src/common/memarea.c					\
   src/common/util.c					\
   src/common/util_process.c				\
@@ -79,6 +80,7 @@ COMMONHEADERS = \
   src/common/compat_libevent.h			\
   src/common/compat_threads.h			\
   src/common/compat_time.h			\
+  src/common/conffile.h				\
   src/common/confline.h				\
   src/common/handles.h				\
   src/common/memarea.h				\

+ 1 - 0
src/or/config.c

@@ -111,6 +111,7 @@
 #include <shlobj.h>
 #endif
 
+#include "common/conffile.h"
 #include "common/procmon.h"
 
 #include "or/dirauth/dirvote.h"

+ 2 - 1
src/test/test_config.c

@@ -48,6 +48,8 @@
 #include "or/port_cfg_st.h"
 #include "or/routerinfo_st.h"
 
+#include "common/conffile.h"
+
 static void
 test_config_addressmap(void *arg)
 {
@@ -5731,4 +5733,3 @@ struct testcase_t config_tests[] = {
   CONFIG_TEST(compute_max_mem_in_queues, 0),
   END_OF_TESTCASES
 };
-