From d2bf3c09479e5956dfcc0914c99082e6ea6f94dc Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Thu, 29 Mar 2012 04:25:30 +0200 Subject: Add support for Tinc-like peer directory configurations --- src/config.c | 59 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++- src/config.l | 2 ++ src/config.y | 6 ++++++ src/fastd.h | 1 + 4 files changed, 67 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/config.c b/src/config.c index 8ba8c0a..5da6abe 100644 --- a/src/config.c +++ b/src/config.c @@ -34,8 +34,11 @@ #include #include +#include #include #include +#include +#include extern fastd_protocol fastd_protocol_null; @@ -86,6 +89,54 @@ static bool config_match(const char *opt, ...) { return match; } +void fastd_read_config_dir(fastd_context *ctx, fastd_config *conf, const char *dir, int depth) { + if (depth >= MAX_CONFIG_DEPTH) + exit_error(ctx, "maximum config include depth exceeded"); + + 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 (!dirh) + exit_error(ctx, "opendir for `%s' failed: %s", dir, strerror(errno)); + + while (true) { + struct dirent entry, *result; + int ret; + + ret = readdir_r(dirh, &entry, &result); + if (ret) + exit_error(ctx, "readdir_r: %s", strerror(ret)); + + if (!result) + break; + if (result->d_name[0] == '.') + continue; + + struct stat statbuf; + if (stat(result->d_name, &statbuf)) { + pr_info(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; + } + + fastd_peer_config_new(ctx, conf); + conf->peers->name = strdup(result->d_name); + fastd_read_config(ctx, conf, result->d_name, true, depth); + } + + closedir(dirh); + + chdir(oldcwd); + free(oldcwd); +} + void fastd_read_config(fastd_context *ctx, fastd_config *conf, const char *filename, bool peer_config, int depth) { if (depth >= MAX_CONFIG_DEPTH) exit_error(ctx, "maximum config include depth exceeded"); @@ -107,7 +158,8 @@ void fastd_read_config(fastd_context *ctx, fastd_config *conf, const char *filen char *filename2 = strdup(filename); char *dir = dirname(filename2); - chdir(dir); + if (chdir(dir)) + exit_error(ctx, "change from directory `%s' to `%s' failed", oldcwd, dir); yyscan_t scanner; fastd_config_yylex_init(&scanner); @@ -178,6 +230,11 @@ void fastd_configure(fastd_context *ctx, fastd_config *conf, int argc, char *con continue; } + IF_OPTION_ARG("--config-peer-dir") { + fastd_read_config_dir(ctx, conf, arg, 0); + continue; + } + IF_OPTION_ARG("-i", "--interface") { free(conf->ifname); conf->ifname = strdup(arg); diff --git a/src/config.l b/src/config.l index f232aee..6ed07bb 100644 --- a/src/config.l +++ b/src/config.l @@ -66,6 +66,8 @@ tap { UPDATE_LOCATION; return TOK_TAP; } tun { UPDATE_LOCATION; return TOK_TUN; } on { UPDATE_LOCATION; return TOK_ON; } up { UPDATE_LOCATION; return TOK_UP; } +peers { UPDATE_LOCATION; return TOK_PEERS; } +from { UPDATE_LOCATION; return TOK_FROM; } [0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3} { UPDATE_LOCATION; diff --git a/src/config.y b/src/config.y index 1e75da8..fd60d0d 100644 --- a/src/config.y +++ b/src/config.y @@ -70,6 +70,8 @@ %token TOK_TUN %token TOK_ON %token TOK_UP +%token TOK_PEERS +%token TOK_FROM %token TOK_ADDR %token TOK_ADDR6 @@ -212,6 +214,10 @@ include: TOK_PEER TOK_STRING maybe_as { fastd_read_config(ctx, conf, $2, true, depth); free($2); } + | TOK_PEERS TOK_FROM TOK_STRING { + fastd_read_config_dir(ctx, conf, $3, depth); + free($3); + } | TOK_STRING { fastd_read_config(ctx, conf, $1, false, depth); free($1); } ; diff --git a/src/fastd.h b/src/fastd.h index dbf9e61..ba5aed0 100644 --- a/src/fastd.h +++ b/src/fastd.h @@ -126,6 +126,7 @@ struct _fastd_context { void fastd_printf(const fastd_context *ctx, const char *format, ...); +void fastd_read_config_dir(fastd_context *ctx, fastd_config *conf, const char *dir, int depth); void fastd_read_config(fastd_context *ctx, fastd_config *conf, const char *filename, bool peer_config, int depth); void fastd_configure(fastd_context *ctx, fastd_config *conf, int argc, char *const argv[]); -- cgit v1.2.3