From 8371e21c10bdb5d5353cc581efba7e09e4ce7a91 Mon Sep 17 00:00:00 2001
From: tv <tv@krebsco.de>
Date: Sun, 10 Feb 2019 14:22:54 +0100
Subject: [PATCH 1/6] tv iptables: add extra{4,6}

---
 tv/3modules/iptables.nix | 55 ++++++++++++++++++++++++++++++----------
 1 file changed, 42 insertions(+), 13 deletions(-)

diff --git a/tv/3modules/iptables.nix b/tv/3modules/iptables.nix
index 56861dc74..3f1df9220 100644
--- a/tv/3modules/iptables.nix
+++ b/tv/3modules/iptables.nix
@@ -9,6 +9,33 @@ let {
     config = lib.mkIf cfg.enable imp;
   };
 
+  extraTypes = {
+    rules = types.submodule {
+      options = {
+        nat.OUTPUT = mkOption {
+          type = with types; listOf str;
+          default = [];
+        };
+        nat.PREROUTING = mkOption {
+          type = with types; listOf str;
+          default = [];
+        };
+        nat.POSTROUTING = mkOption {
+          type = with types; listOf str;
+          default = [];
+        };
+        filter.FORWARD = mkOption {
+          type = with types; listOf str;
+          default = [];
+        };
+        filter.INPUT = mkOption {
+          type = with types; listOf str;
+          default = [];
+        };
+      };
+    };
+  };
+
   api = {
     enable = mkEnableOption "tv.iptables";
 
@@ -37,19 +64,19 @@ let {
       default = [];
     };
 
-    extra = {
-      nat.POSTROUTING = mkOption {
-        type = with types; listOf str;
-        default = [];
-      };
-      filter.FORWARD = mkOption {
-        type = with types; listOf str;
-        default = [];
-      };
-      filter.INPUT = mkOption {
-        type = with types; listOf str;
-        default = [];
-      };
+    extra = mkOption {
+      default = {};
+      type = extraTypes.rules;
+    };
+
+    extra4 = mkOption {
+      default = {};
+      type = extraTypes.rules;
+    };
+
+    extra6 = mkOption {
+      default = {};
+      type = extraTypes.rules;
     };
   };
 
@@ -112,6 +139,7 @@ let {
         "-o lo -p tcp -m tcp --dport 11423 -j REDIRECT --to-ports 22"
       ]}
       ${formatTable cfg.extra.nat}
+      ${formatTable cfg."extra${toString iptables-version}".nat}
       COMMIT
       *filter
       :INPUT DROP [0:0]
@@ -129,6 +157,7 @@ let {
         ++ ["-i retiolum -j Retiolum"]
       )}
       ${formatTable cfg.extra.filter}
+      ${formatTable cfg."extra${toString iptables-version}".filter}
       ${concatMapStringsSep "\n" (rule: "-A Retiolum ${rule}") ([]
         ++ optional (cfg.accept-echo-request == "retiolum") accept-echo-request
         ++ map accept-tcp (unique (map toString cfg.input-retiolum-accept-tcp))

From bc534f38aa3885d654175e747774dcbad243c08d Mon Sep 17 00:00:00 2001
From: tv <tv@krebsco.de>
Date: Sun, 10 Feb 2019 14:36:31 +0100
Subject: [PATCH 2/6] tv iptables extraTypes: add Retiolum

---
 tv/3modules/iptables.nix | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/tv/3modules/iptables.nix b/tv/3modules/iptables.nix
index 3f1df9220..3974760d5 100644
--- a/tv/3modules/iptables.nix
+++ b/tv/3modules/iptables.nix
@@ -32,6 +32,10 @@ let {
           type = with types; listOf str;
           default = [];
         };
+        filter.Retiolum = mkOption {
+          type = with types; listOf str;
+          default = [];
+        };
       };
     };
   };

From 174b3ee6bef292d3270823006f806f847dc5a264 Mon Sep 17 00:00:00 2001
From: tv <tv@krebsco.de>
Date: Sat, 16 Feb 2019 15:39:17 +0100
Subject: [PATCH 3/6] lib.warnOldVersion: init

---
 lib/default.nix | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/lib/default.nix b/lib/default.nix
index 347830e8c..75086f864 100644
--- a/lib/default.nix
+++ b/lib/default.nix
@@ -145,6 +145,11 @@ let
     in
       filter (x: x != []) ([acc.chunk] ++ acc.chunks);
 
+    warnOldVersion = oldName: newName:
+      if compareVersions oldName newName != -1 then
+        trace "Upstream `${oldName}' gets overridden by `${newName}'." newName
+      else
+        newName;
   };
 in
 

From c69c75f2c63b350615ec8026538c879b91b7a6ea Mon Sep 17 00:00:00 2001
From: tv <tv@krebsco.de>
Date: Sat, 16 Feb 2019 16:01:03 +0100
Subject: [PATCH 4/6] tv bash-fzf-history: use overrideDerivation

---
 tv/5pkgs/simple/bash-fzf-history.nix | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/tv/5pkgs/simple/bash-fzf-history.nix b/tv/5pkgs/simple/bash-fzf-history.nix
index b603dedd9..88a8e9e4a 100644
--- a/tv/5pkgs/simple/bash-fzf-history.nix
+++ b/tv/5pkgs/simple/bash-fzf-history.nix
@@ -97,7 +97,6 @@ with import <stockholm/lib>;
     bind -s | ${pkgs.gnugrep}/bin/grep __fzf_ >&2
   '';
 in
-  script //
-  rec {
+  script.overrideAttrs (old: rec {
     bind = /* sh */ ''bind -x '"${load-keyseq}": . ${script}' '';
-  }
+  })

From 763a81ac08da6d20b0ea3bbd8423df3e64f934dc Mon Sep 17 00:00:00 2001
From: tv <tv@krebsco.de>
Date: Fri, 20 Mar 2015 10:36:12 +0100
Subject: [PATCH 5/6] lib.xml: init

---
 lib/default.nix |  1 +
 lib/xml.nix     | 84 +++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 85 insertions(+)
 create mode 100644 lib/xml.nix

diff --git a/lib/default.nix b/lib/default.nix
index 75086f864..8ba55b571 100644
--- a/lib/default.nix
+++ b/lib/default.nix
@@ -9,6 +9,7 @@ let
     krops = import ../submodules/krops/lib;
     shell = import ./shell.nix { inherit lib; };
     types = nixpkgs-lib.types // import ./types.nix { inherit lib; };
+    xml = import ./xml.nix { inherit lib; };
 
     eq = x: y: x == y;
     ne = x: y: x != y;
diff --git a/lib/xml.nix b/lib/xml.nix
new file mode 100644
index 000000000..92f552154
--- /dev/null
+++ b/lib/xml.nix
@@ -0,0 +1,84 @@
+{ lib }:
+with lib;
+with builtins;
+rec {
+
+  # Use `term` to construct XML.
+  #
+  # Examples:
+  #
+  #   (term "bool" null null)
+  #   (term "cool" null [])
+  #   (term "fool" { hurr = "durr"; } null)
+  #   (term "hool" null [
+  #     (term "tool" null null)
+  #   ])
+  #
+  # See `render` for how these get transformed into actuall XML documents.
+  #
+  term = name: attrs: content: {
+    inherit name attrs content;
+  };
+
+  empty = term null null null;
+
+  # Ref http://www.w3.org/TR/xml/#syntax
+  #
+  # Example:
+  #
+  #   (quote "<cheez!>")                 #===>   &lt;cheez!&gt;
+  #
+  quote = let
+    sub = {
+      "&" = "&amp;";
+      "<" = "&lt;";
+      ">" = "&gt;";
+      "'" = "&apos;";
+      "\"" = "&quot;";
+    };
+  in
+    stringAsChars (c: sub.${c} or c);
+
+  # Turn an XML element to an XML document string.
+  doc = t:
+    "<?xml version='1.0' encoding='UTF-8'?>${render t}";
+
+  # Render an XML element to a string.
+  #
+  # Rendering `empty` yields the empty string.
+  #
+  # Examples:
+  #
+  #   (term "bool" null null)                 #===>   <bool/>
+  #   (term "cool" null [])                   #===>   <cool></cool>
+  #   (term "fool" { hurr = "durr"; } null)   #===>   <fool hurr="durr"/>
+  #   (term "hool" null [
+  #     (term "tool" null null)
+  #   ])                                      #===>   <hool><tool/></hool>
+  #
+  render = let
+    render-attrs = attrs:
+      getAttr (typeOf attrs) {
+        null = "";
+        set = concatStrings (mapAttrsToList (n: v: " ${n}=\"${v}\"") attrs);
+      };
+
+    render-content = content:
+      getAttr (typeOf content) {
+        bool = toJSON content;
+        int = toJSON content;
+        list = concatMapStrings render content;
+        string = content;
+      };
+  in
+    { name, attrs, content }:
+    if name == null
+      then ""
+      else let
+        attrs' = render-attrs attrs;
+        content' = render-content content;
+      in
+        if content == null
+          then "<${name}${attrs'}/>"
+          else "<${name}${attrs'}>${content'}</${name}>";
+}

From 270ceb7676e867c9dff5f5faa765666b58aaa371 Mon Sep 17 00:00:00 2001
From: tv <tv@krebsco.de>
Date: Fri, 20 Mar 2015 10:58:11 +0100
Subject: [PATCH 6/6] lib.xml.render-term: quote strings

---
 lib/xml.nix | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/lib/xml.nix b/lib/xml.nix
index 92f552154..16052445b 100644
--- a/lib/xml.nix
+++ b/lib/xml.nix
@@ -68,12 +68,16 @@ rec {
         bool = toJSON content;
         int = toJSON content;
         list = concatMapStrings render content;
-        string = content;
+        string = quote content;
       };
   in
     { name, attrs, content }:
+    # XXX we're currently encoding too much information with `null`..
     if name == null
-      then ""
+      then
+        if content == null
+          then ""
+          else content
       else let
         attrs' = render-attrs attrs;
         content' = render-content content;