diff options
-rw-r--r-- | src/config.c | 94 | ||||
-rw-r--r-- | src/config.l | 2 | ||||
-rw-r--r-- | src/config.y | 2 | ||||
-rw-r--r-- | src/fastd.c | 4 | ||||
-rw-r--r-- | src/fastd.h | 21 | ||||
-rw-r--r-- | src/peer.c | 1 | ||||
-rw-r--r-- | src/types.h | 2 |
7 files changed, 74 insertions, 52 deletions
diff --git a/src/config.c b/src/config.c index b745251..aa10b10 100644 --- a/src/config.c +++ b/src/config.c @@ -102,51 +102,61 @@ void fastd_read_config_dir(fastd_context *ctx, fastd_config *conf, const char *d char *oldcwd = get_current_dir_name(); - if (chdir(dir)) - exit_error(ctx, "change from directory `%s' to `%s' failed: %s", oldcwd, dir, strerror(errno)); - - DIR *dirh = opendir("."); + if (!chdir(dir)) { + char *newdir = get_current_dir_name(); + conf->peer_dirs = fastd_string_stack_push(conf->peer_dirs, newdir); + free(newdir); + + DIR *dirh = opendir("."); + + if (dirh) { + while (true) { + struct dirent entry, *result; + int ret; + + ret = readdir_r(dirh, &entry, &result); + if (ret) { + pr_error(ctx, "readdir_r: %s", strerror(ret)); + break; + } - if (!dirh) - exit_error(ctx, "opendir for `%s' failed: %s", dir, strerror(errno)); + if (!result) + break; + if (result->d_name[0] == '.') + continue; - while (true) { - struct dirent entry, *result; - int ret; + struct stat statbuf; + if (stat(result->d_name, &statbuf)) { + pr_warn(ctx, "ignoring file `%s': stat failed: %s", result->d_name, strerror(errno)); + continue; + } + if ((statbuf.st_mode & S_IFMT) != S_IFREG) { + pr_info(ctx, "ignoring file `%s': no regular file", result->d_name); + continue; + } - ret = readdir_r(dirh, &entry, &result); - if (ret) - exit_error(ctx, "readdir_r: %s", strerror(ret)); + fastd_peer_config_new(ctx, conf); + conf->peers->name = strdup(result->d_name); + conf->peers->config_source_dir = strdup(dir); - if (!result) - break; - if (result->d_name[0] == '.') - continue; + if (!fastd_read_config(ctx, conf, result->d_name, true, depth)) { + pr_warn(ctx, "peer config `%s' will be ignored", result->d_name); + fastd_peer_config_delete(ctx, conf); + } + } - struct stat statbuf; - if (stat(result->d_name, &statbuf)) { - pr_info(ctx, "ignoring file `%s': stat failed: %s", result->d_name, strerror(errno)); - continue; + closedir(dirh); } - if ((statbuf.st_mode & S_IFMT) != S_IFREG) { - pr_info(ctx, "ignoring file `%s': no regular file", result->d_name); - continue; + else { + pr_error(ctx, "opendir for `%s' failed: %s", dir, strerror(errno)); } - fastd_peer_config_new(ctx, conf); - conf->peers->name = strdup(result->d_name); - conf->peers->config_source_dir = strdup(dir); - - if (!fastd_read_config(ctx, conf, result->d_name, true, depth)) { - pr_warn(ctx, "peer config %s will be ignored", result->d_name); - fastd_peer_config_delete(ctx, conf); - } + chdir(oldcwd); + free(oldcwd); + } + else { + pr_error(ctx, "change from directory `%s' to `%s' failed: %s", oldcwd, dir, strerror(errno)); } - - closedir(dirh); - - chdir(oldcwd); - free(oldcwd); } bool fastd_read_config(fastd_context *ctx, fastd_config *conf, const char *filename, bool peer_config, int depth) { @@ -160,7 +170,7 @@ bool fastd_read_config(fastd_context *ctx, fastd_config *conf, const char *filen FILE *file; yyscan_t scanner; fastd_config_pstate *ps; - fastd_config_str *strings = NULL; + fastd_string_stack *strings = NULL; fastd_config_yylex_init(&scanner); ps = fastd_config_pstate_new(); @@ -222,7 +232,7 @@ bool fastd_read_config(fastd_context *ctx, fastd_config *conf, const char *filen ret = false; end_free: - fastd_config_str_free(strings); + fastd_string_stack_free(strings); fastd_config_pstate_delete(ps); fastd_config_yylex_destroy(scanner); @@ -491,8 +501,12 @@ void fastd_configure(fastd_context *ctx, fastd_config *conf, int argc, char *con } } - if (conf->mode == MODE_TUN && (!conf->peers || conf->peers->next)) - exit_error(ctx, "config error: for tun mode exactly one peer must be configured"); + if (conf->mode == MODE_TUN) { + if (!conf->peers || conf->peers->next) + exit_error(ctx, "config error: for tun mode exactly one peer must be configured"); + if (conf->peer_dirs) + exit_error(ctx, "config error: for tun mode peer directories can't be used"); + } conf->protocol->init(ctx, conf); } diff --git a/src/config.l b/src/config.l index 546bd8d..49c0117 100644 --- a/src/config.l +++ b/src/config.l @@ -116,7 +116,7 @@ no { UPDATE_LOCATION; return TOK_NO; } yytext[i-esc] = yytext[i]; } yytext[yyleng-esc-1] = 0; - yylval->str = fastd_config_str_dup(yytext); + yylval->str = fastd_string_stack_dup(yytext); BEGIN(INITIAL); yylloc->last_column++; return TOK_STRING; diff --git a/src/config.y b/src/config.y index df46f20..8b5e49e 100644 --- a/src/config.y +++ b/src/config.y @@ -43,7 +43,7 @@ %union { int num; - fastd_config_str *str; + fastd_string_stack *str; char *error; bool boolean; struct in_addr addr; diff --git a/src/fastd.c b/src/fastd.c index 939c651..3185186 100644 --- a/src/fastd.c +++ b/src/fastd.c @@ -81,10 +81,10 @@ static void init_socket(fastd_context *ctx) { struct sockaddr_in6 addr_in6 = ctx->conf->bind_addr_in6; if (addr_in.sin_family == AF_UNSPEC && addr_in6.sin6_family == AF_UNSPEC) { - if (ctx->conf->n_floating || ctx->conf->n_v4) + if (ctx->conf->n_floating || ctx->conf->peer_dirs || ctx->conf->n_v4) addr_in.sin_family = AF_INET; - if (ctx->conf->n_floating || ctx->conf->n_v6) + if (ctx->conf->n_floating || ctx->conf->peer_dirs || ctx->conf->n_v6) addr_in6.sin6_family = AF_INET6; } diff --git a/src/fastd.h b/src/fastd.h index 6eab856..4a4bd49 100644 --- a/src/fastd.h +++ b/src/fastd.h @@ -99,6 +99,7 @@ struct _fastd_config { unsigned key_valid; unsigned key_refresh; + fastd_string_stack *peer_dirs; fastd_peer_config *peers; unsigned n_floating; @@ -132,8 +133,8 @@ struct _fastd_context { unsigned int randseed; }; -struct _fastd_config_str { - fastd_config_str *next; +struct _fastd_string_stack { + fastd_string_stack *next; char str[]; }; @@ -230,17 +231,25 @@ static inline size_t fastd_max_packet_size(const fastd_context *ctx) { } } -static inline fastd_config_str* fastd_config_str_dup(const char *str) { - fastd_config_str *ret = malloc(sizeof(fastd_config_str) + strlen(str) + 1); +static inline fastd_string_stack* fastd_string_stack_dup(const char *str) { + fastd_string_stack *ret = malloc(sizeof(fastd_string_stack) + strlen(str) + 1); ret->next = NULL; strcpy(ret->str, str); return ret; } -static inline void fastd_config_str_free(fastd_config_str *str) { +static inline fastd_string_stack* fastd_string_stack_push(fastd_string_stack *stack, const char *str) { + fastd_string_stack *ret = malloc(sizeof(fastd_string_stack) + strlen(str) + 1); + ret->next = stack; + strcpy(ret->str, str); + + return ret; +} + +static inline void fastd_string_stack_free(fastd_string_stack *str) { while(str) { - fastd_config_str *next = str->next; + fastd_string_stack *next = str->next; free(str); str = next; } @@ -118,7 +118,6 @@ void fastd_peer_reset(fastd_context *ctx, fastd_peer *peer) { } - static fastd_peer* add_peer(fastd_context *ctx) { fastd_peer *peer = malloc(sizeof(fastd_peer)); diff --git a/src/types.h b/src/types.h index 390b145..504b6dd 100644 --- a/src/types.h +++ b/src/types.h @@ -69,7 +69,7 @@ typedef struct _fastd_protocol fastd_protocol; typedef struct _fastd_handshake fastd_handshake; -typedef struct _fastd_config_str fastd_config_str; +typedef struct _fastd_string_stack fastd_string_stack; /* May be defined by the protocol however it likes */ typedef struct _fastd_protocol_config fastd_protocol_config; |