summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatthias Schiffer <mschiffer@universe-factory.net>2012-03-29 04:25:30 +0200
committerMatthias Schiffer <mschiffer@universe-factory.net>2012-03-29 04:25:30 +0200
commitd2bf3c09479e5956dfcc0914c99082e6ea6f94dc (patch)
treee9c1324b9b71beaa75c38282c8c4e00ccd30ac4e
parenteb0c48b789bbf41745287adb6b2949f84e7e9171 (diff)
downloadfastd-d2bf3c09479e5956dfcc0914c99082e6ea6f94dc.tar
fastd-d2bf3c09479e5956dfcc0914c99082e6ea6f94dc.zip
Add support for Tinc-like peer directory configurations
-rw-r--r--src/config.c59
-rw-r--r--src/config.l2
-rw-r--r--src/config.y6
-rw-r--r--src/fastd.h1
4 files changed, 67 insertions, 1 deletions
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 <config.h>
#include <arpa/inet.h>
+#include <dirent.h>
#include <libgen.h>
#include <stdarg.h>
+#include <sys/stat.h>
+#include <sys/types.h>
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 <addr> TOK_ADDR
%token <addr6> 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[]);