[PATCH] Gate boolean protocol options on filename.
João Taveira Araújo
joao.taveira at gmail.com
Mon May 23 01:50:12 CEST 2016
Toggling session parameters currently requires editing the configuration
file and reloading BIRD. Doing so programatically requires keeping up
with the syntax and layout of a particular configuration.
This commit introduces an alternative method for gating configuration of
boolean protocol properties. In addition to the keywords on/off and
yes/no, a user can instead provide a filename on which to predicate
whether the flag is set.
In particular, this makes toggling protocols programatically much simpler,
since we can decouple state from configuration more cleanly, i.e:
protocol kernel {
disabled filename "/etc/disable-kernel";
}
---
conf/cf-lex.l | 23 +++++++++++++++++++++++
conf/conf.h | 1 +
conf/confbase.Y | 3 ++-
doc/bird.sgml | 5 +++--
4 files changed, 29 insertions(+), 3 deletions(-)
diff --git a/conf/cf-lex.l b/conf/cf-lex.l
index 5a2a4d6..af85291 100644
--- a/conf/cf-lex.l
+++ b/conf/cf-lex.l
@@ -693,6 +693,29 @@ cf_symbol_class_name(struct symbol *sym)
}
}
+/**
+ * cf_file_exists - check if expanded filename exists
+ * @arg: filename
+ *
+ * This function expands relative filenames and returns
+ * whether file is present.
+ */
+int
+cf_file_exists(char *arg)
+{
+ char *patt = arg;
+
+ if (*arg != '/')
+ {
+ int dlen = strlen(ifs->file_name);
+ char *dir = alloca(dlen + 1);
+ patt = alloca(dlen + strlen(arg) + 2);
+ memcpy(dir, ifs->file_name, dlen + 1);
+ sprintf(patt, "%s/%s", dirname(dir), arg);
+ }
+
+ return access(patt, F_OK) != -1;
+}
/**
* DOC: Parser
diff --git a/conf/conf.h b/conf/conf.h
index 89a2c5b..6f6a33d 100644
--- a/conf/conf.h
+++ b/conf/conf.h
@@ -160,6 +160,7 @@ char *cf_symbol_class_name(struct symbol *sym);
static inline int cf_symbol_is_constant(struct symbol *sym)
{ return (sym->class & 0xff00) == SYM_CONSTANT; }
+int cf_file_exists(char *arg);
/* Parser */
diff --git a/conf/confbase.Y b/conf/confbase.Y
index 5f487c1..7ee26f3 100644
--- a/conf/confbase.Y
+++ b/conf/confbase.Y
@@ -88,7 +88,7 @@ CF_DECLS
%left '!'
%nonassoc '.'
-CF_KEYWORDS(DEFINE, ON, OFF, YES, NO, S, MS, US, PORT)
+CF_KEYWORDS(DEFINE, ON, OFF, YES, NO, S, MS, US, PORT, FILENAME)
CF_GRAMMAR
@@ -143,6 +143,7 @@ bool:
| YES { $$ = 1; }
| OFF { $$ = 0; }
| NO { $$ = 0; }
+ | FILENAME text { $$ = cf_file_exists($2); }
| /* Silence means agreement */ { $$ = 1; }
;
diff --git a/doc/bird.sgml b/doc/bird.sgml
index a0b45f4..03682cb 100644
--- a/doc/bird.sgml
+++ b/doc/bird.sgml
@@ -493,8 +493,9 @@ protocol (see sections talking about the protocols).
<p>Several options use a <m/switch/ argument. It can be either <cf/on/,
<cf/yes/ or a numeric expression with a non-zero value for the option to be
enabled or <cf/off/, <cf/no/ or a numeric expression evaluating to zero to
-disable it. An empty <m/switch/ is equivalent to <cf/on/ ("silence means
-agreement").
+disable it. Alternatively you can gate the value of <m/switch/ on the presence
+of a file through the <cf/filename/ "<m/name/" directive. An empty <m/switch/
+is equivalent to <cf/on/ ("silence means agreement").
<descrip>
<tag>preference <m/expr/</tag>
--
2.8.1
More information about the Bird-users
mailing list