[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