summaryrefslogtreecommitdiffstats
path: root/src/config.c
diff options
context:
space:
mode:
authorMatthias Schiffer <mschiffer@universe-factory.net>2014-06-10 20:46:52 +0200
committerMatthias Schiffer <mschiffer@universe-factory.net>2014-06-10 20:46:52 +0200
commit6b139d613ae6fa127bdce1be5c634ed4b53b1efd (patch)
treefe55f6e36831ee0e2702ea085fab0e29aff8a578 /src/config.c
parent65a09a09d6cc3e26be9488e69895154ab2ae14fd (diff)
downloadfastd-6b139d613ae6fa127bdce1be5c634ed4b53b1efd.tar
fastd-6b139d613ae6fa127bdce1be5c634ed4b53b1efd.zip
Clean up peer config loading
Instead of changing the peer list and peer group in the main conf during (re-)loading, add a parser state which contains this information.
Diffstat (limited to 'src/config.c')
-rw-r--r--src/config.c88
1 files changed, 46 insertions, 42 deletions
diff --git a/src/config.c b/src/config.c
index 21c30c4..1e6cff7 100644
--- a/src/config.c
+++ b/src/config.c
@@ -143,22 +143,22 @@ void fastd_config_bind_address(const fastd_peer_address_t *address, const char *
}
/** Handles the start of a peer group configuration */
-void fastd_config_peer_group_push(const char *name) {
+void fastd_config_peer_group_push(fastd_parser_state_t *state, const char *name) {
fastd_peer_group_t *group = calloc(1, sizeof(fastd_peer_group_t));
group->name = strdup(name);
group->max_connections = -1;
- group->parent = conf.peer_group;
+ group->parent = state->peer_group;
group->next = group->parent->children;
group->parent->children = group;
- conf.peer_group = group;
+ state->peer_group = group;
}
/** Handles the end of a peer group configuration */
-void fastd_config_peer_group_pop(void) {
- conf.peer_group = conf.peer_group->parent;
+void fastd_config_peer_group_pop(fastd_parser_state_t *state) {
+ state->peer_group = state->peer_group->parent;
}
/** Frees a peer group and its children */
@@ -189,7 +189,7 @@ static bool has_peer_group_peer_dirs(const fastd_peer_group_t *group) {
}
/** Reads and processes all peer definitions in the current directory (which must also be supplied as the argument) */
-static void read_peer_dir(const char *dir) {
+static void read_peer_dir(fastd_peer_config_t **peers, fastd_peer_group_t *group, const char *dir) {
DIR *dirh = opendir(".");
if (dirh) {
@@ -221,13 +221,17 @@ static void read_peer_dir(const char *dir) {
continue;
}
- fastd_peer_config_new();
- conf.peers->name = strdup(result->d_name);
- conf.peers->config_source_dir = dir;
+ fastd_peer_config_t *peer = fastd_peer_config_new(group);
+ peer->name = strdup(result->d_name);
+ peer->config_source_dir = dir;
- if (!fastd_read_config(result->d_name, true, 0)) {
+ if (fastd_config_read(result->d_name, group, peer, 0)) {
+ peer->next = *peers;
+ *peers = peer;
+ }
+ else {
pr_warn("peer config `%s' will be ignored", result->d_name);
- fastd_peer_config_delete();
+ fastd_peer_config_free(peer);
}
}
@@ -240,14 +244,14 @@ static void read_peer_dir(const char *dir) {
}
}
-/** Reads all peer configured directories */
-static void read_peer_dirs(void) {
+/** Reads all configured peer directories for a peer grup */
+static void read_peer_dirs(fastd_peer_config_t **peers, fastd_peer_group_t *group) {
char *oldcwd = get_current_dir_name();
fastd_string_stack_t *dir;
- for (dir = conf.peer_group->peer_dirs; dir; dir = dir->next) {
+ for (dir = group->peer_dirs; dir; dir = dir->next) {
if (!chdir(dir->str))
- read_peer_dir(dir->str);
+ read_peer_dir(peers, group, dir->str);
else
pr_error("change from directory `%s' to `%s' failed: %s", oldcwd, dir->str, strerror(errno));
}
@@ -259,15 +263,15 @@ static void read_peer_dirs(void) {
}
/** Adds a peer directory to the configuration */
-void fastd_add_peer_dir(const char *dir) {
+void fastd_config_add_peer_dir(fastd_peer_group_t *group, const char *dir) {
char *oldcwd = get_current_dir_name();
if (!chdir(dir)) {
char *newdir = get_current_dir_name();
- conf.peer_group->peer_dirs = fastd_string_stack_push(conf.peer_group->peer_dirs, newdir);
+ group->peer_dirs = fastd_string_stack_push(group->peer_dirs, newdir);
free(newdir);
- if(chdir(oldcwd))
+ if (chdir(oldcwd))
pr_error("can't chdir to `%s': %s", oldcwd, strerror(errno));
}
else {
@@ -278,7 +282,7 @@ void fastd_add_peer_dir(const char *dir) {
}
/** Reads and processes a configuration file */
-bool fastd_read_config(const char *filename, bool peer_config, int depth) {
+bool fastd_config_read(const char *filename, fastd_peer_group_t *peer_group, fastd_peer_config_t *peer_config, int depth) {
if (depth >= MAX_CONFIG_DEPTH)
exit_error("maximum config include depth exceeded");
@@ -321,15 +325,21 @@ bool fastd_read_config(const char *filename, bool peer_config, int depth) {
int token;
YYSTYPE token_val;
YYLTYPE loc = {1, 0, 1, 0};
+ fastd_parser_state_t state = {
+ .peer_group = peer_group,
+ .peer = peer_config,
+ .filename = filename,
+ .depth = depth+1,
+ };
if (peer_config)
token = START_PEER_CONFIG;
else
- token = conf.peer_group->parent ? START_PEER_GROUP_CONFIG : START_CONFIG;
+ token = peer_group->parent ? START_PEER_GROUP_CONFIG : START_CONFIG;
- int parse_ret = fastd_config_push_parse(ps, token, &token_val, &loc, filename, depth+1);
+ int parse_ret = fastd_config_push_parse(ps, token, &token_val, &loc, &state);
- while(parse_ret == YYPUSH_MORE) {
+ while (parse_ret == YYPUSH_MORE) {
token = fastd_lex(&token_val, &loc, lex);
if (token < 0) {
@@ -343,7 +353,7 @@ bool fastd_read_config(const char *filename, bool peer_config, int depth) {
strings = token_val.str;
}
- parse_ret = fastd_config_push_parse(ps, token, &token_val, &loc, filename, depth+1);
+ parse_ret = fastd_config_push_parse(ps, token, &token_val, &loc, &state);
}
if (parse_ret)
@@ -559,17 +569,13 @@ void fastd_config_verify(void) {
conf.protocol->peer_verify(peer);
}
-/** Reads the peer dirs of the current peer group and its children */
-static void peer_dirs_read_peer_group(void) {
- read_peer_dirs();
-
- fastd_peer_group_t *base = conf.peer_group, *group;
- for (group = conf.peer_group->children; group; group = group->next) {
- conf.peer_group = group;
- peer_dirs_read_peer_group();
- }
+/** Reads the peer dirs of a peer group and its children */
+static void peer_dirs_read_peer_group(fastd_peer_config_t **peers, fastd_peer_group_t *group) {
+ read_peer_dirs(peers, group);
- conf.peer_group = base;
+ fastd_peer_group_t *child;
+ for (child = group->children; child; child = child->next)
+ peer_dirs_read_peer_group(peers, child);
}
/** Deletes peer configs that have disappeared from a peer dir on reconfiguration */
@@ -632,13 +638,8 @@ static void peer_dirs_handle_new_peers(fastd_peer_config_t **peers, fastd_peer_c
/** Refreshes the peer configurations from the configured peer dirs */
void fastd_config_load_peer_dirs(void) {
- fastd_peer_config_t *old_peers = conf.peers;
- conf.peers = NULL;
-
- peer_dirs_read_peer_group();
-
- fastd_peer_config_t *new_peers = conf.peers;
- conf.peers = old_peers;
+ fastd_peer_config_t *new_peers = NULL;
+ peer_dirs_read_peer_group(&new_peers, conf.peer_group);
peer_dirs_handle_old_peers(&conf.peers, &new_peers);
peer_dirs_handle_new_peers(&conf.peers, new_peers);
@@ -648,8 +649,11 @@ void fastd_config_load_peer_dirs(void) {
/** Frees all resources used by the global configuration */
void fastd_config_release(void) {
- while (conf.peers)
- fastd_peer_config_delete();
+ while (conf.peers) {
+ fastd_peer_config_t *peer = conf.peers, *next = peer->next;
+ fastd_peer_config_free(peer);
+ conf.peers = next;
+ }
while (conf.bind_addrs) {
fastd_bind_address_t *next = conf.bind_addrs->next;