summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/common/conffile.c164
-rw-r--r--src/common/conffile.h17
-rw-r--r--src/common/confline.c168
-rw-r--r--src/common/confline.h20
-rw-r--r--src/common/include.am2
-rw-r--r--src/or/config.c1
-rw-r--r--src/test/test_config.c3
7 files changed, 209 insertions, 166 deletions
diff --git a/src/common/conffile.c b/src/common/conffile.c
new file mode 100644
index 0000000000..bfb78c35c6
--- /dev/null
+++ b/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;
+}
diff --git a/src/common/conffile.h b/src/common/conffile.h
new file mode 100644
index 0000000000..bd8250b002
--- /dev/null
+++ b/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) */
diff --git a/src/common/confline.c b/src/common/confline.c
index 9e37bfbdb7..80e5994ce8 100644
--- a/src/common/confline.c
+++ b/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);
}
/**
diff --git a/src/common/confline.h b/src/common/confline.h
index d1f6fdb7e5..f03faed5eb 100644
--- a/src/common/confline.h
+++ b/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) */
diff --git a/src/common/include.am b/src/common/include.am
index 2360c7f775..4fd3284abc 100644
--- a/src/common/include.am
+++ b/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 \
diff --git a/src/or/config.c b/src/or/config.c
index 98f3ff77b0..b0141b9c0e 100644
--- a/src/or/config.c
+++ b/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"
diff --git a/src/test/test_config.c b/src/test/test_config.c
index 5abc97fc3b..dcdaa2ed59 100644
--- a/src/test/test_config.c
+++ b/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
};
-