#!/bin/sh
#
# Script to update every forwarding djbdns dnscache instance running
# on the local machine
#
# this script sets up every FORWARDONLY dnscache managed by either
# daemontools or runit on this machine to use the dynamically-offered
# nameservers for the default '@'
# 
# Assumption: On entry, PWD contains the resolv.conf-type files
#
# If no nameservers are offered, we ask the dnscache instances to fall
# back to the root nameservers listed in /etc/dnsroots.global
#
# Licensed under the GNU GPL.  See /usr/share/doc/resolvconf/copyright.
#
# Written by Daniel Kahn Gillmor <dkg-debian.org@fifthhorseman.net>
# based on similar scripts by Thomas Hood

set -e
PATH=/usr/sbin:/usr/bin:/sbin:/bin

[ -x /usr/bin/dnscache ] || exit 0
[ -x /lib/resolvconf/list-records ] || exit 1

ETC=/etc
ETCRESOLVCONF="${ETC}/resolvconf"
TMPFILE="${ETCRESOLVCONF}/run/dnscache_new.$$"
DEFAULTROOTS="${ETC}/dnsroots.global"

CACHES=""

# Which directories do we scan?
# /var/lib/svscan: daemontools, built "the debian way" (LFS-compliant)
# /service: daemontools, built "the djb way"
# /var/service: runit

for SERVICEDIR in /var/lib/svscan /service /etc/service ; do
	# We'll only manage caches actually managed by daemontools or runit.
	if [ -d "$SERVICEDIR" ] ; then
		OLDCWD=`pwd`
		cd "$SERVICEDIR"
		for SVC in * ; do
			SVC="$SERVICEDIR/$SVC"
			if \
				[ -d "$SVC" ] \
				&& [ -f "$SVC/run" ] \
				&& [ ! -f "$SVC/down" ] \
				&& [ -d "$SVC/root" ] \
				&& [ -d "$SVC/root/servers" ] \
				&& [ -d "$SVC/root/ip" ] \
				&& [ -s "$SVC/env/FORWARDONLY" ] \
				&& grep -q dnscache "$SVC/run"
			then
				CACHES="$SVC $CACHES"
			fi
		done
		cd "$OLDCWD"
	fi
done

# Stores arguments (minus duplicates) in RSLT, separated by spaces
# Doesn't work properly if an argument itself contain whitespace
uniquify()
{
	RSLT=""
	while [ "$1" ] ; do
		for E in $RSLT ; do
			[ "$1" = "$E" ] && { shift ; continue 2 ; }
		done
		RSLT="${RSLT:+$RSLT }$1"
		shift
	done
}

RSLVCNFFILES="$(/lib/resolvconf/list-records)"

### Compile list of nameservers ###
NMSRVRS=""
if [ "$RSLVCNFFILES" ] ; then
	uniquify $(sed -n 's/^[[:space:]]*nameserver[[:space:]]\+//p' $RSLVCNFFILES)
	NMSRVRS="$RSLT"
fi

clean_up() { rm -f "$TMPFILE" ; }
trap clean_up EXIT
clean_up

# If no nameservers were present, use the default root nameservers
# provided by the djbdns package:
if [ -z "$NMSRVRS" ] && [ -e "$DEFAULTROOTS" ] ; then
	cp "$DEFAULTROOTS" "$TMPFILE"
else
	: > "$TMPFILE"
	for N in $NMSRVRS ; do
		echo "$N" >> "$TMPFILE"
	done
fi

# svc is the daemontools service controller
SVC_CMD="$(which svc)" || :
[ ! "$SVC_CMD" ] && [ -x /command/svc ] && SVC_CMD=/command/svc

# sv is the runit service controller
SV_CMD="$(which sv)" || :

for CACHE in $CACHES ; do
	cp "$TMPFILE" "$CACHE/root/servers/@"
	# Restart the cache if it's already running:
        if [ "$SV_CMD" ] && \
	    [ -e "$CACHE/supervise/pid" ] && \
	    [ -e "$CACHE/supervise/stat" ]; then
            # services managed by runit have supervise/{pid,stat}
            "$SV_CMD" restart "$CACHE"
        else
            # otherwise, it is probably managed by daemontools
            [ "$SVC_CMD" ] && "$SVC_CMD" -t "$CACHE"
        fi
done

