chiark / gitweb /
config: Substitutions prefer %{...} to %(...)s, document, etc.
[hippotat.git] / src / config.rs
index e6d7e5920590b70838c64c3cc27790ed0818782b..4b94b3ed73357db4659e2c3fde777e4e67b13e66 100644 (file)
@@ -54,11 +54,11 @@ max_batch_up = 4000
 http_retry = 5
 port = 80
 vroutes = ''
-ifname_client = hippo%%d
-ifname_server = shippo%%d
+ifname_client = hippo%d
+ifname_server = shippo%d
 max_clock_skew = 300
 
-ipif = userv root ipif %(local)s,%(peer)s,%(mtu)s,slip,%(ifname)s '%(rnets)s'
+ipif = userv root ipif %{local},%{peer},%{mtu},slip,%{ifname} '%{rnets}'
 
 mtu = 1500
 
@@ -694,11 +694,11 @@ impl InstanceConfig {
         .collect::<HashMap<String, String>>();
       let bad = parking_lot::Mutex::new(vec![]);
       *var = regex_replace_all!(
-        r#"%(?:%|\((\w+)\)s|.)"#,
+        r#"%(?:%|\((\w+)\)s|\{(\w+)\}|.)"#,
         &var,
-        |whole, k| (|| Ok::<_,String>({
+        |whole, k1, k2| (|| Ok::<_,String>({
           if whole == "%%" { "%" }
-          else if k != "" {
+          else if let Some(&k) = [k1,k2].iter().find(|&&s| s != "") {
             substs.get(k).ok_or_else(
               || format!("unknown key %({})s", k)
             )?
@@ -713,34 +713,33 @@ impl InstanceConfig {
       }
     }
 
-    let ifname = match match end {
-      LinkEnd::Client => (&mut self.ifname_client, "ifname_client"),
-      LinkEnd::Server => (&mut self.ifname_server, "ifname_server"),
-    } { (var,name) => {
-      subst(var, &mut iter::empty()).context(name).context("interface name")?;
-      var
-    } };
-
     {
       use LinkEnd::*;
       type DD<'d> = &'d dyn Display;
       fn dv<T:Display>(v: &[T]) -> String {
         format!("{}", v.iter().format(" "))
       }
-      let vnetwork = dv(&self.vnetwork);
-      let vroutes  = dv(&self.vroutes);
-      
-      let keys = &["local",               "peer",       "rnets",    "ifname"];
+      let mut ipif = mem::take(&mut self.ipif); // lets us borrow all of self
+      let s = &self; // just for abbreviation, below
+      let vnetwork = dv(&s.vnetwork);
+      let vroutes  = dv(&s.vroutes);
+
+      let keys = &["local",       "peer",    "rnets",   "ifname"];
       let values = match end {
       Server => [&self.vaddr as DD      , &self.vrelay, &vnetwork, ifname],
       Client => [&self.link.client as DD, &self.vaddr,  &vroutes,  ifname],
Server => [&s.vaddr as DD      , &s.vrelay, &vnetwork, &s.ifname_server],
Client => [&s.link.client as DD, &s.vaddr,  &vroutes,  &s.ifname_client],
       };
+      let always = [
+        ( "mtu",     &s.mtu as DD ),
+      ];
+
       subst(
-        &mut self.ipif,
+        &mut ipif,
         &mut keys.iter().cloned()
           .zip_eq(values)
-          .chain([( "mtu", &self.mtu as DD )].iter().cloned()),
+          .chain(always.iter().cloned()),
       ).context("ipif")?;
+      self.ipif = ipif;
     }
   }
 }