Initial import.
authorMark Wooding <mdw@distorted.org.uk>
Mon, 4 Feb 2013 21:34:45 +0000 (21:34 +0000)
committerMark Wooding <mdw@distorted.org.uk>
Mon, 4 Feb 2013 21:34:45 +0000 (21:34 +0000)
.gitignore [new file with mode: 0644]
bin/update [new file with mode: 0755]

diff --git a/.gitignore b/.gitignore
new file mode 100644 (file)
index 0000000..aa88922
--- /dev/null
@@ -0,0 +1,2 @@
+.ssh/
+dyndns.conf
diff --git a/bin/update b/bin/update
new file mode 100755 (executable)
index 0000000..a9c2716
--- /dev/null
@@ -0,0 +1,90 @@
+#! /bin/sh
+
+set -e
+. ./dyndns.conf
+
+## Check that the environment is set up properly.
+for i in DYNDNS_ZONE DYNDNS_HOST DYNDNS_SERVER DYNDNS_KEY SSH_CLIENT; do
+  eval havep=\${$i+t}\${$i-nil}
+  case $havep in nil) echo >&2 "$0: variable $i unset"; exit 2 ;; esac
+done
+
+## Find the client address.  This may be useful.
+set -- $SSH_CLIENT; client=$1
+
+## Parse the commad line.
+set -- $SSH_ORIGINAL_COMMAND
+
+fail_usage () {
+  cat >&2 <<EOF
+usage: $0 COMMAND ARGS...
+
+Commands:
+       set [-force] HOST [ADDR]
+       unset HOST
+EOF
+  exit 1
+}
+getarg='case $# in 0) fail_usage ;; esac; arg=$1; shift'
+doneargs='case $# in 0) ;; *) fail_usage ;; esac'
+
+checkhost () {
+  host=$1
+
+  matchp=nil
+  for pat in $DYNDNS_HOST; do
+    case "$host" in $pat) matchp=t ;; esac
+  done
+  case $matchp in nil) echo >&2 "$0: hostname not permitted"; exit 2 ;; esac
+}
+
+doupdate () {
+  cmd=$1
+
+nsupdate -k "$DYNDNS_KEY" <<EOF
+server $DYNDNS_SERVER
+zone $DYNDNS_ZONE
+$cmd
+send
+EOF
+}
+
+eval $getarg; cmd=$arg
+case "$cmd" in
+  set)
+    forcep=nil
+    eval $getarg
+    case "$arg" in -force) forcep=t; eval $getarg ;; esac
+    host=$arg
+    case "$#,$forcep,$1" in
+      0,nil,*) addr=$client ;;
+      0,t,*) fail_usage ;;
+      *,nil,"$client" | *,t,*) addr=$1; shift ;;
+      *)
+       echo >&2 "$0: incorrect address (wanted = $2; found = $addr)"
+       exit 3
+       ;;
+    esac
+    eval $doneargs
+    checkhost "$host"
+    case $addr in
+      *:*) rrtype=AAAA ;;
+      *.*) rrtype=A ;;
+      *) echo >&2 "$0: failed to parse new address"; exit 2 ;;
+    esac
+    name=$host.$DYNDNS_ZONE
+    doupdate "
+       update delete $name IN $rrtype
+       update add $name ${DYNDNS_TTL-14400} IN $rrtype $addr"
+    ;;
+  unset)
+    eval $getarg; host=$arg
+    eval $doneargs
+    checkhost "$host"
+    name=$host.$DYNDNS_ZONE
+    doupdate "update delete $name IN"
+    ;;
+  *)
+    fail_usage
+    ;;
+esac