[Midnightbsd-cvs] src [11161] trunk/contrib/openresolv: update

laffer1 at midnightbsd.org laffer1 at midnightbsd.org
Wed Jun 27 08:58:34 EDT 2018


Revision: 11161
          http://svnweb.midnightbsd.org/src/?rev=11161
Author:   laffer1
Date:     2018-06-27 08:58:34 -0400 (Wed, 27 Jun 2018)
Log Message:
-----------
update

Modified Paths:
--------------
    trunk/contrib/openresolv/Makefile
    trunk/contrib/openresolv/configure
    trunk/contrib/openresolv/dnsmasq.in
    trunk/contrib/openresolv/libc.in
    trunk/contrib/openresolv/named.in
    trunk/contrib/openresolv/pdnsd.in
    trunk/contrib/openresolv/resolvconf.8.in
    trunk/contrib/openresolv/resolvconf.conf.5.in
    trunk/contrib/openresolv/resolvconf.in
    trunk/contrib/openresolv/unbound.in

Added Paths:
-----------
    trunk/contrib/openresolv/GNUmakefile
    trunk/contrib/openresolv/config-null.mk
    trunk/contrib/openresolv/pdns_recursor.in

Added: trunk/contrib/openresolv/GNUmakefile
===================================================================
--- trunk/contrib/openresolv/GNUmakefile	                        (rev 0)
+++ trunk/contrib/openresolv/GNUmakefile	2018-06-27 12:58:34 UTC (rev 11161)
@@ -0,0 +1,4 @@
+# Nasty hack so that make clean works without configure being run
+CONFIG_MK?=$(shell test -e config.mk && echo config.mk || echo config-null.mk)
+
+include Makefile

Modified: trunk/contrib/openresolv/Makefile
===================================================================
--- trunk/contrib/openresolv/Makefile	2018-06-27 12:57:52 UTC (rev 11160)
+++ trunk/contrib/openresolv/Makefile	2018-06-27 12:58:34 UTC (rev 11161)
@@ -1,9 +1,21 @@
-include config.mk
+# $MidnightBSD$
+PKG=		openresolv
+VERSION=	3.7.0
 
-NAME=		openresolv
-VERSION=	3.4.1
-PKG=		${NAME}-${VERSION}
+# Nasty hack so that make clean works without configure being run
+_CONFIG_MK!=	test -e config.mk && echo config.mk || echo config-null.mk
+CONFIG_MK?=	${_CONFIG_MK}
+include		${CONFIG_MK}
 
+SBINDIR?=	/sbin
+SYSCONFDIR?=	/etc
+LIBEXECDIR?=	/libexec/resolvconf
+VARDIR?=	/var/run/resolvconf
+RCDIR?=		/etc/rc.d
+RESTARTCMD?=	if ${RCDIR}/\1 status >/dev/null 2>\&1; then \
+			${RCDIR}/\1 restart; \
+		fi
+
 INSTALL?=	install
 SED?=		sed
 
@@ -17,7 +29,7 @@
 SRCS=		${TARGET:C,$,.in,} # pmake
 SRCS:=		${TARGET:=.in} # gmake
 
-SED_PREFIX=		-e 's:@PREFIX@:${PREFIX}:g'
+SED_SBINDIR=		-e 's:@SBINDIR@:${SBINDIR}:g'
 SED_SYSCONFDIR=		-e 's:@SYSCONFDIR@:${SYSCONFDIR}:g'
 SED_LIBEXECDIR=		-e 's:@LIBEXECDIR@:${LIBEXECDIR}:g'
 SED_VARDIR=		-e 's:@VARDIR@:${VARDIR}:g'
@@ -24,24 +36,29 @@
 SED_RCDIR=		-e 's:@RCDIR@:${RCDIR}:g'
 SED_RESTARTCMD=		-e 's:@RESTARTCMD \(.*\)@:${RESTARTCMD}:g'
 
+DISTPREFIX?=	${PKG}-${VERSION}
+DISTFILEGZ?=	${DISTPREFIX}.tar.gz
+DISTFILE?=	${DISTPREFIX}.tar.bz2
+FOSSILID?=	current
+
 .SUFFIXES: .in
 
 all: ${TARGET}
 
 .in:
-	${SED}	${SED_PREFIX} ${SED_SYSCONFDIR} ${SED_LIBEXECDIR} \
+	${SED}	${SED_SBINDIR} ${SED_SYSCONFDIR} ${SED_LIBEXECDIR} \
 		${SED_VARDIR} ${SED_RCDIR} ${SED_RESTARTCMD} \
 		$< > $@
 
 clean:
-	rm -f ${TARGET} openresolv-${VERSION}.tar.bz2
+	rm -f ${TARGET}
 
 distclean: clean
-	rm -f config.mk
+	rm -f config.mk ${DISTFILE}
 
 installdirs:
 
-install: ${TARGET}
+proginstall: ${TARGET}
 	${INSTALL} -d ${DESTDIR}${SBINDIR}
 	${INSTALL} -m ${BINMODE} resolvconf ${DESTDIR}${SBINDIR}
 	${INSTALL} -d ${DESTDIR}${SYSCONFDIR}
@@ -49,18 +66,21 @@
 	${INSTALL} -m ${DOCMODE} resolvconf.conf ${DESTDIR}${SYSCONFDIR}
 	${INSTALL} -d ${DESTDIR}${LIBEXECDIR}
 	${INSTALL} -m ${DOCMODE} ${SUBSCRIBERS} ${DESTDIR}${LIBEXECDIR}
+
+maninstall:
 	${INSTALL} -d ${DESTDIR}${MANDIR}/man8
 	${INSTALL} -m ${MANMODE} resolvconf.8 ${DESTDIR}${MANDIR}/man8
 	${INSTALL} -d ${DESTDIR}${MANDIR}/man5
 	${INSTALL} -m ${MANMODE} resolvconf.conf.5 ${DESTDIR}${MANDIR}/man5
 
+install: proginstall maninstall
+
 import:
-	rm -rf /tmp/${PKG}
-	${INSTALL} -d /tmp/${PKG}
-	cp README ${SRCS} /tmp/${PKG}
+	rm -rf /tmp/${DISTPREFIX}
+	${INSTALL} -d /tmp/${DISTPREFIX}
+	cp README ${SRCS} /tmp/${DISPREFIX}
 
-dist: import
-	cp configure Makefile resolvconf.conf /tmp/${PKG}
-	tar cvjpf ${PKG}.tar.bz2 -C /tmp ${PKG} 
-	rm -rf /tmp/${PKG} 
-	ls -l ${PKG}.tar.bz2
+dist:
+	fossil tarball --name ${DISTPREFIX} ${FOSSILID} ${DISTFILEGZ}
+	gunzip -c ${DISTFILEGZ} |  bzip2 >${DISTFILE}
+	rm ${DISTFILEGZ}

Added: trunk/contrib/openresolv/config-null.mk
===================================================================
--- trunk/contrib/openresolv/config-null.mk	                        (rev 0)
+++ trunk/contrib/openresolv/config-null.mk	2018-06-27 12:58:34 UTC (rev 11161)
@@ -0,0 +1,2 @@
+# $MidnightBSD$
+# This space left intentionally blank


Property changes on: trunk/contrib/openresolv/config-null.mk
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Modified: trunk/contrib/openresolv/configure
===================================================================
--- trunk/contrib/openresolv/configure	2018-06-27 12:57:52 UTC (rev 11160)
+++ trunk/contrib/openresolv/configure	2018-06-27 12:58:34 UTC (rev 11161)
@@ -9,7 +9,7 @@
 RESTARTCMD=
 RCDIR=
 
-for x; do
+for x do
 	opt=${x%%=*}
 	var=${x#*=}
 	case "$opt" in
@@ -18,7 +18,7 @@
 	--debug) DEBUG=$var;;
 	--disable-debug) DEBUG=no;;
 	--enable-debug) DEBUG=yes;;
-	--prefix) prefix=$var;;
+	--prefix) PREFIX=$var;;
 	--sysconfdir) SYSCONFDIR=$var;;
 	--bindir|--sbindir) SBINDIR=$var;;
 	--libexecdir) LIBEXECDIR=$var;;
@@ -41,12 +41,32 @@
 	esac
 done
 
+if [ -z "$LIBEXECDIR" ]; then
+	printf "Checking for directory /libexec ... "
+	if [ -d /libexec ]; then
+		echo "yes"
+		LIBEXECDIR=$PREFIX/libexec/resolvconf
+	else
+		echo "no"
+		LIBEXECDIR=$PREFIX/lib/resolvconf
+	fi
+fi
+if [ -z "$RUNDIR" ]; then
+	printf "Checking for directory /run ... "
+	if [ -d /run ]; then
+		echo "yes"
+		RUNDIR=/run
+	else
+		echo "no"
+		RUNDIR=/var/run
+	fi
+fi	
+
 : ${SED:=sed}
 
-: ${PREFIX:=$prefix}
 : ${SYSCONFDIR:=$PREFIX/etc}
 : ${SBINDIR:=$PREFIX/sbin}
-: ${LIBEXECDIR:=$PREFIX/libexec}
+: ${LIBEXECDIR:=$PREFIX/libexec/resolvconf}
 : ${STATEDIR:=/var}
 : ${RUNDIR:=$STATEDIR/run}
 : ${MANDIR:=${PREFIX:-/usr}/share/man}
@@ -53,7 +73,7 @@
 
 eval SYSCONFDIR="$SYSCONFDIR"
 eval SBINDIR="$SBINDIR"
-eval LIBEXECDIR="$LIBEXECDIR/resolvconf"
+eval LIBEXECDIR="$LIBEXECDIR"
 eval VARDIR="$RUNDIR/resolvconf"
 eval MANDIR="$MANDIR"
 
@@ -60,49 +80,37 @@
 CONFIG_MK=config.mk
 
 if [ -z "$BUILD" ]; then
-	BUILD=`uname -m`-`uname -s | tr '[:upper:]' '[:lower:]'`
+	# autoconf target triplet: cpu-vendor-os
+	BUILD=$(uname -m)-unknown-$(uname -s | tr '[:upper:]' '[:lower:]')
 fi
-if [ -z "$HOST" ]; then
-	[ -z "$TARGET" ] && TARGET=$BUILD
-	HOST=$TARGET
-fi
-if [ -z "$TARGET" ]; then
-	[ -z "$HOST" ] && HOST=$BUILD
-	TARGET=$HOST
-fi
+: ${HOST:=$BUILD}
 
-# Debian and Slackware have linux in different places when dealing with
-# autoconf, so we deal with that here.
 if [ -z "$OS" ]; then
-	case "$TARGET" in
-	*-linux-*|linux-*|*-linux|linux) OS=linux;;
-	esac
-fi
-
-if [ -z "$OS" ]; then
-	# Derive OS from cpu-manufacturer-os-kernel
-	CPU=${TARGET%%-*}
-	REST=${TARGET#*-}
+	echo "Deriving operating system from ... $HOST"
+	# Derive OS from cpu-vendor-[kernel-]os
+	CPU=${HOST%%-*}
+	REST=${HOST#*-}
 	if [ "$CPU" != "$REST" ]; then
-		MANU=${REST%%-*}
+		VENDOR=${REST%%-*}
 		REST=${REST#*-}
-		if [ "$MANU" != "$REST" ]; then
+		if [ "$VENDOR" != "$REST" ]; then
+			# Use kernel if given, otherwise os
 			OS=${REST%%-*}
-			REST=${REST#*-}
-			if [ "$OS" != "$REST" ]; then
-				KERNEL=${REST%%-*}
-			else
-				# 3 tupple
-				KERNEL=$OS
-				OS=$MANU
-				MANU=
-			fi
 		else
 			# 2 tupple
-			OS=$MANU
-			MANU=
+			OS=$VENDOR
+			VENDOR=
 		fi
 	fi
+
+        # Work with cpu-kernel-os, ie Debian
+	case "$VENDOR" in
+	linux*|kfreebsd*) OS=$VENDOR; VENDOR= ;;
+	esac
+	# Special case
+	case "$OS" in
+	gnu*) OS=hurd;; # No HURD support as yet
+	esac
 fi
 
 echo "Configuring openresolv for ... $OS"
@@ -118,17 +126,36 @@
 	echo "$x=$t	$v" >>$CONFIG_MK
 done
 
-if [ -e /etc/arch-release -a -d /etc/rc.d ]; then
-	echo "Overriding service status check for Arch Linux"
-	RCDIR=/etc/rc.d
-	RESTARTCMD="[ -e /var/run/daemons/\1 ] \&\& /etc/rc.d/\1 restart"
-	echo "yes"
+if [ -z "$RESTARTCMD" ]; then
+	printf "Checking for systemd ... "
+	if [ -x /bin/systemctl ]; then
+		RESTARTCMD="/bin/systemctl try-restart \1"
+		echo "yes"
+	elif [ -x /usr/bin/systemctl ]; then
+		RESTARTCMD="/usr/bin/systemctl try-restart \1"
+		echo "yes"
+	else
+		echo "no"
+	fi
 fi
 
+# Arch upgraded to systemd, so this check has to be just after systemd
+# but higher than the others
 if [ -z "$RESTARTCMD" ]; then
+	printf "Checking for Arch ... "
+	if [ -e /etc/arch-release -a -d /etc/rc.d ]; then
+		RCDIR=/etc/rc.d
+		RESTARTCMD="[ -e /var/run/daemons/\1 ] \&\& /etc/rc.d/\1 restart"
+		echo "yes"
+	else
+		echo "no"
+	fi
+fi
+
+if [ -z "$RESTARTCMD" ]; then
 	printf "Checking for OpenRC ... "
 	if [ -x /sbin/rc-service ]; then
-		RESTARTCMD="/sbin/rc-service -e \1 \&\& /sbin/rc-service \1 -- -Ds restart"
+		RESTARTCMD="if /sbin/rc-service -e \1; then /sbin/rc-service \1 -- -Ds restart; fi"
 		echo "yes"
 	else
 		echo "no"
@@ -138,7 +165,7 @@
 	printf "Checking for invoke-rc.d ... "
 	if [ -x /usr/sbin/invoke-rc.d ]; then
 		RCDIR=/etc/init.d
-		RESTARTCMD="/usr/sbin/invoke-rc.d --quiet \1 status >/dev/null 2>\&1 \&\& /usr/sbin/invoke-rc.d \1 restart"
+		RESTARTCMD="if /usr/sbin/invoke-rc.d --quiet \1 status >/dev/null 2>\&1; then /usr/sbin/invoke-rc.d \1 restart; fi"
 		echo "yes"
 	else
 		echo "no"
@@ -148,7 +175,7 @@
 	printf "Checking for service ... "
 	if [ -x /sbin/service ]; then
 		RCDIR=/etc/init.d
-		RESTARTCMD="/sbin/service \1 \&\& /sbin/service \1 restart"
+		RESTARTCMD="if /sbin/service \1; then /sbin/service \1 restart; fi"
 		echo "yes"
 	else
 		echo "no"
@@ -155,11 +182,23 @@
 	fi
 fi
 if [ -z "$RESTARTCMD" ]; then
+	printf "Checking for runit... "
+	if [ -x /bin/sv ]; then
+		RESTARTCMD="/bin/sv try-restart \1"
+		echo "yes"
+	elif [ -x /usr/bin/sv ]; then
+		RESTARTCMD="/usr/bin/sv try-restart \1"
+		echo "yes"
+	else
+		echo "no"
+	fi
+fi
+if [ -z "$RESTARTCMD" ]; then
 	for x in /etc/init.d/rc.d /etc/rc.d /etc/init.d; do
 		printf "Checking for $x ... "
 		if [ -d $x ]; then
 			RCDIR=$x
-			RESTARTCMD="$x/\1 status >/dev/null 2>\&1 \&\& $x/\1 restart"
+			RESTARTCMD="if $x/\1 status >/dev/null 2>\&1; then $x/\1 restart; fi"
 			echo "yes"
 			break
 		else
@@ -169,7 +208,7 @@
 fi
 
 if [ -z "$RESTARTCMD" ]; then
-	echo "WARNING! No means of interacting with system services detected!"
+	echo "$0: WARNING: No means of interacting with system services detected!"
 	exit 1
 fi
 

Modified: trunk/contrib/openresolv/dnsmasq.in
===================================================================
--- trunk/contrib/openresolv/dnsmasq.in	2018-06-27 12:57:52 UTC (rev 11160)
+++ trunk/contrib/openresolv/dnsmasq.in	2018-06-27 12:58:34 UTC (rev 11161)
@@ -1,5 +1,5 @@
 #!/bin/sh
-# Copyright (c) 2007-2009 Roy Marples
+# Copyright (c) 2007-2012 Roy Marples
 # All rights reserved
 
 # dnsmasq subscriber for resolvconf
@@ -29,12 +29,13 @@
 [ -f "@SYSCONFDIR@"/resolvconf.conf ] || exit 0
 . "@SYSCONFDIR@/resolvconf.conf" || exit 1
 [ -z "$dnsmasq_conf" -a -z "$dnsmasq_resolv" ] && exit 0
-[ -z "$RESOLVCONF" ] && eval "$(@PREFIX@/sbin/resolvconf -v)"
+[ -z "$RESOLVCONF" ] && eval "$(@SBINDIR@/resolvconf -v)"
 NL="
 "
 
 : ${dnsmasq_pid:=/var/run/dnsmasq.pid}
 [ -s "$dnsmasq_pid" ] || dnsmasq_pid=/var/run/dnsmasq/dnsmasq.pid
+[ -s "$dnsmasq_pid" ] || unset dnsmasq_pid
 : ${dnsmasq_service:=dnsmasq}
 : ${dnsmasq_restart:=@RESTARTCMD ${dnsmasq_service}@}
 newconf="# Generated by resolvconf$NL"
@@ -46,21 +47,18 @@
 # so we need to validate a few things first.
 # Check for DBus support in the binary
 dbus=false
-: ${dbus_pid:=/var/run/dbus/dbus.pid}
-[ -s "$dbus_pid" ] || dbus_pid=/var/run/dbus.pid
-[ -s "$dbus_pid" ] || dbus_pid=/var/run/dbus/pid
-if [ -s "$dbus_pid" -a -s "$dnsmasq_pid" ]; then
-	if dnsmasq --version 2>/dev/null | \
-		grep -q "^Compile time options.*[[:space:]]DBus[[:space:]]"
+dbus_ex=false
+dbus_introspect=$(dbus-send --print-reply --system \
+	--dest=uk.org.thekelleys.dnsmasq \
+	/uk/org/thekelleys/dnsmasq \
+	org.freedesktop.DBus.Introspectable.Introspect \
+	2>/dev/null)
+if [ $? = 0 ]; then
+	dbus=true
+	if printf %s "$dbus_introspect" | \
+	    grep -q '<method name="SetDomainServers">'
 	then
-		# Sanity - check that dnsmasq and dbus are running
-		if kill -0 $(cat "$dbus_pid") 2>/dev/null && \
-			kill -0 $(cat "$dnsmasq_pid") 2>/dev/null
-		then
-			dbus=true
-			newconf="$newconf$NL# Domain specific servers will"
-			newconf="$newconf be sent over dbus${NL}enable-dbus$NL"
-		fi
+		dbus_ex=true
 	fi
 fi
 
@@ -69,30 +67,97 @@
 done
 
 dbusdest=
+dbusdest_ex=
+conf=
 for d in $DOMAINS; do
 	dn="${d%%:*}"
 	ns="${d#*:}"
 	while [ -n "$ns" ]; do
-		if $dbus; then
-			SIFS=${IFS-y} OIFS=$IFS
-			IFS=.
-			set -- ${ns%%,*}
-			num="0x$(printf %02x $1 $2 $3 $4)"
-			if [ "$SIFS" = yi ]; then
-				unset IFS
-			else
-				IFS=$OIFS
-			fi
-			dbusdest="$dbusdest uint32:$(printf %u $num)"
-			dbusdest="$dbusdest string:$dn"
-		else
-			newconf="${newconf}server=/$dn/${ns%%,*}$NL"
+		n="${ns%%,*}"
+		if $dbus && ! $dbus_ex; then
+			case "$n" in
+			*.*.*.*)
+				SIFS=${IFS-y} OIFS=$IFS
+				IFS=.
+				set -- $n
+				num="0x$(printf %02x $1 $2 $3 $4)"
+				if [ "$SIFS" = y ]; then
+					unset IFS
+				else
+					IFS=$OIFS
+				fi
+				dbusdest="$dbusdest uint32:$(printf %u $num)"
+				dbusdest="$dbusdest string:$dn"
+				;;
+			*:*%*)
+				# This version of dnsmasq won't accept
+				# scoped IPv6 addresses
+				dbus=false
+				;;
+			*:*)
+				SIFS=${IFS-y} OIFS=$IFS bytes= front= back=
+				empty=false i=0
+				IFS=:
+				set -- $n
+				while [ -n "$1" -o -n "$2" ]; do
+					addr="$1"
+					shift
+					if [ -z "$addr" ]; then
+						empty=true
+						continue
+					fi
+					i=$(($i + 1))
+					while [ ${#addr} -lt 4 ]; do
+						addr="0${addr}"
+					done
+					byte1="$(printf %d 0x${addr%??})"
+					byte2="$(printf %d 0x${addr#??})"
+					if $empty; then
+						back="$back byte:$byte1 byte:$byte2"
+					else
+						front="$front byte:$byte1 byte:$byte2"
+					fi
+				done
+				while [ $i != 8 ]; do
+				i=$(($i + 1))
+					front="$front byte:0 byte:0"
+				done
+				front="${front}$back"
+				if [ "$SIFS" = y ]; then
+					unset IFS
+				else
+					IFS=$OIFS
+				fi
+				dbusdest="${dbusdest}$front string:$dn"
+				;;
+			*)
+				if ! $dbus_ex; then
+					dbus=false
+				fi
+				;;
+			esac
 		fi
+		dbusdest_ex="$dbusdest_ex${dbusdest_ex:+,}/$dn/$n"
+		conf="${conf}server=/$dn/$n$NL"
 		[ "$ns" = "${ns#*,}" ] && break
 		ns="${ns#*,}"
 	done
 done
 
+if $dbus; then
+	newconf="$newconf$NL# Domain specific servers will"
+	newconf="$newconf be sent over dbus${NL}"
+else
+	newconf="$newconf$conf"
+fi
+
+# Try to ensure that config dirs exist
+if type config_mkdirs >/dev/null 2>&1; then
+	config_mkdirs "$dnsmasq_conf" "$dnsmasq_resolv"
+else
+	@SBINDIR@/resolvconf -D "$dnsmasq_conf" "$dnsmasq_resolv"
+fi
+
 changed=false
 if [ -n "$dnsmasq_conf" ]; then
 	if [ ! -f "$dnsmasq_conf" ] || \
@@ -103,14 +168,13 @@
 	fi
 fi
 if [ -n "$dnsmasq_resolv" ]; then
+	# dnsmasq polls this file so no need to set changed=true
 	if [ -f "$dnsmasq_resolv" ]; then
 		if [ "$(cat "$dnsmasq_resolv")" != "$(printf %s "$newresolv")" ]
 		then
-			changed=true
 			printf %s "$newresolv" >"$dnsmasq_resolv"
 		fi
 	else
-		# dnsmasq polls this file so no need to set changed=true
 		printf %s "$newresolv" >"$dnsmasq_resolv"
 	fi
 fi
@@ -119,9 +183,20 @@
 	eval $dnsmasq_restart
 fi
 if $dbus; then
-	$changed || kill -HUP $(cat "$dnsmasq_pid")
+	if [ -s "$dnsmasq_pid" ]; then
+        	$changed || kill -HUP $(cat "$dnsmasq_pid")
+	fi
 	# Send even if empty so old servers are cleared
+	if $dbus_ex; then
+		method=SetDomainServers
+		if [ -n "$dbusdest_ex" ]; then
+			dbusdest_ex="array:string:$dbusdest_ex"
+		fi
+		dbusdest="$dbusdest_ex"
+	else
+		method=SetServers
+	fi
 	dbus-send --system --dest=uk.org.thekelleys.dnsmasq \
- 		/uk/org/thekelleys/dnsmasq uk.org.thekelleys.SetServers \
+ 		/uk/org/thekelleys/dnsmasq uk.org.thekelleys.$method \
   		$dbusdest
 fi

Modified: trunk/contrib/openresolv/libc.in
===================================================================
--- trunk/contrib/openresolv/libc.in	2018-06-27 12:57:52 UTC (rev 11160)
+++ trunk/contrib/openresolv/libc.in	2018-06-27 12:58:34 UTC (rev 11161)
@@ -1,5 +1,5 @@
 #!/bin/sh
-# Copyright (c) 2007-2009 Roy Marples
+# Copyright (c) 2007-2014 Roy Marples
 # All rights reserved
 
 # libc subscriber for resolvconf
@@ -36,18 +36,18 @@
 # sed may not be available, and this is faster on small files
 key_get_value()
 {
-	local key="$1" value= x= line=
+	local key="$1" x= line=
 
 	shift
 	if [ $# -eq 0 ]; then
-		while read line; do
+		while read -r line; do
 			case "$line" in
 			"$key"*) echo "${line##$key}";;
 			esac
 		done
 	else
-		for x; do
-			while read line; do
+		for x do
+			while read -r line; do
 				case "$line" in
 				"$key"*) echo "${line##$key}";;
 				esac
@@ -56,6 +56,24 @@
 	fi
 }
 
+keys_remove()
+{
+	local key x line found
+
+	while read -r line; do
+		found=false
+		for key do
+			case "$line" in
+			"$key"*|"#"*|" "*|"	"*|"") found=true;;
+			esac
+			$found && break
+		done
+		$found || echo "$line"
+	done
+}
+
+local_nameservers="127.* 0.0.0.0 255.255.255.255 ::1"
+
 # Support original resolvconf configuration layout
 # as well as the openresolv config file
 if [ -f "$SYSCONFDIR"/resolvconf.conf ]; then
@@ -64,12 +82,11 @@
 	SYSCONFDIR="$SYSCONFDIR/resolvconf/resolv.conf.d"
 	base="$SYSCONFDIR/resolv.conf.d/base"
 	if [ -f "$base" ]; then
-		name_servers="$(key_get_value "nameserver " "$base")"
-		search_domains="$(key_get_value "search " "$base")"
-		if [ -z "$search_domains" ]; then
-			search_domains="$(key_get_value "domain " "$base")"
-		fi
+		prepend_nameservers="$(key_get_value "nameserver " "$base")"
+		domain="$(key_get_value "domain " "$base")"
+		prepend_search="$(key_get_value "search " "$base")"
 		resolv_conf_options="$(key_get_value "options " "$base")"
+		resolv_conf_sortlist="$(key_get_value "sortlist " "$base")"
 	fi
 	if [ -f "$SYSCONFDIR"/resolv.conf.d/head ]; then
 		resolv_conf_head="$(cat "${SYSCONFDIR}"/resolv.conf.d/head)"
@@ -81,7 +98,7 @@
 : ${resolv_conf:=/etc/resolv.conf}
 : ${libc_service:=nscd}
 : ${libc_restart:=@RESTARTCMD ${libc_service}@}
-: ${list_resolv:=@PREFIX@/sbin/resolvconf -l}
+: ${list_resolv:=@SBINDIR@/resolvconf -l}
 if [ "${resolv_conf_head-x}" = x -a -f "$SYSCONFDIR"/resolv.conf.head ]; then
 	resolv_conf_head="$(cat "${SYSCONFDIR}"/resolv.conf.head)"
 fi
@@ -89,6 +106,9 @@
 	resolv_conf_tail="$(cat "$SYSCONFDIR"/resolv.conf.tail)"
 fi
 
+backup=true
+signature="# Generated by resolvconf"
+ 
 uniqify()
 {
 	local result=
@@ -104,6 +124,7 @@
 
 case "${resolv_conf_passthrough:-NO}" in
 [Yy][Ee][Ss]|[Tt][Rr][Uu][Ee]|[Oo][Nn]|1)
+	backup=false
 	newest=
 	for conf in "$IFACEDIR"/*; do
 		if [ -z "$newest" -o "$conf" -nt "$newest" ]; then
@@ -113,33 +134,72 @@
 	[ -z "$newest" ] && exit 0
 	newconf="$(cat "$newest")$NL"
 	;;
+/dev/null|[Nn][Uu][Ll][Ll])
+	: ${resolv_conf_local_only:=NO}
+	if [ "$local_nameservers" = "127.* 0.0.0.0 255.255.255.255 ::1" ]; then
+		local_nameservers=
+	fi
+	# Need to overwrite our variables.
+	eval "$(@SBINDIR@/resolvconf -V)"
+	;;
+
 *)
-	[ -z "$RESOLVCONF" ] && eval "$(@PREFIX@/sbin/resolvconf -v)"
-	newsearch="$(uniqify $search_domains $SEARCH $search_domains_append)"
+	[ -z "$RESOLVCONF" ] && eval "$(@SBINDIR@/resolvconf -v)"
+	;;
+esac
+case "${resolv_conf_passthrough:-NO}" in
+[Yy][Ee][Ss]|[Tt][Rr][Uu][Ee]|[Oo][Nn]|1) ;;
+*)
+	: ${domain:=$DOMAIN}
+	newsearch="$(uniqify $prepend_search $SEARCH $append_search)"
 	NS="$LOCALNAMESERVERS $NAMESERVERS"
-	newns="$(uniqify $name_servers $NS $name_servers_append)"
+	newns=
+	gotlocal=false
+	for n in $(uniqify $prepend_nameservers $NS $append_nameservers); do
+		add=true
+		islocal=false
+		for l in $local_nameservers; do
+			case "$n" in
+			$l) islocal=true; gotlocal=true; break;;
+			esac
+		done
+		if ! $islocal; then
+			case "${resolv_conf_local_only:-YES}" in
+			[Yy][Ee][Ss]|[Tt][Rr][Uu][Ee]|[Oo][Nn]|1)
+				$gotlocal && add=false;;
+			esac
+		fi
+		$add && newns="$newns $n"
+	done
 
 	# Hold our new resolv.conf in a variable to save on temporary files
-	newconf="# Generated by resolvconf$NL"
+	newconf="$signature$NL"
 	if [ -n "$resolv_conf_head" ]; then
 		newconf="$newconf$resolv_conf_head$NL"
 	fi
-	[ -n "$newsearch" ] && newconf="${newconf}search $newsearch$NL"
+
+	[ -n "$domain" ] && newconf="${newconf}domain $domain$NL"
+	if [ -n "$newsearch" -a "$newsearch" != "$domain" ]; then
+		newconf="${newconf}search $newsearch$NL"
+	fi
 	for n in $newns; do
 		newconf="${newconf}nameserver $n$NL"
 	done
 
-	# Now get any configured options
-	opts="$resolv_conf_options${resolv_conf_options:+ }"
-	opts="$opts$($list_resolv | key_get_value "options ")"
-	if [ -n "$opts" ]; then
-		newconf="${newconf}options"
-		for opt in $(uniqify $opts); do
-			newconf="${newconf} $opt"
-		done
-		newconf="$newconf$NL"
+	# Now add anything we don't care about such as sortlist and options
+	stuff="$($list_resolv | keys_remove nameserver domain search)"
+	if [ -n "$stuff" ]; then
+		newconf="$newconf$stuff$NL"
 	fi
 
+	# Append any user defined ones
+	if [ -n "$resolv_conf_options" ]; then
+		newconf="${newconf}options $resolv_conf_options$NL"
+	fi
+	if [ -n "$resolv_conf_sortlist" ]; then
+		newconf="${newconf}sortlist $resolv_conf_sortlist$NL"
+	fi
+
 	if [ -n "$resolv_conf_tail" ]; then
 		newconf="$newconf$resolv_conf_tail$NL"
 	fi
@@ -151,6 +211,22 @@
 	[ "$(cat "$resolv_conf")" = "$(printf %s "$newconf")" ] && exit 0
 fi
 
+# Change is good.
+# If the old file does not have our signature, back it up.
+# If the new file just has our signature, restore the backup.
+if $backup; then
+	if [ "$newconf" = "$signature$NL" ]; then
+		if [ -e "$resolv_conf.bak" ]; then
+			newconf="$(cat "$resolv_conf.bak")"
+		fi
+	elif [ -e "$resolv_conf" ]; then
+		read line <"$resolv_conf"
+		if [ "$line" != "$signature" ]; then
+			cp "$resolv_conf" "$resolv_conf.bak"
+		fi
+	fi
+fi
+
 # Create our resolv.conf now
 (umask 022; echo "$newconf" >"$resolv_conf")
 eval $libc_restart
@@ -162,7 +238,7 @@
 		if [ -x "$script" ]; then
 			"$script" "$@"
 		else
-			(. "$script" "$@")
+			(. "$script")
 		fi
 		retval=$(($retval + $?))
 	fi

Modified: trunk/contrib/openresolv/named.in
===================================================================
--- trunk/contrib/openresolv/named.in	2018-06-27 12:57:52 UTC (rev 11160)
+++ trunk/contrib/openresolv/named.in	2018-06-27 12:58:34 UTC (rev 11161)
@@ -1,5 +1,5 @@
 #!/bin/sh
-# Copyright (c) 2007-2009 Roy Marples
+# Copyright (c) 2007-2012 Roy Marples
 # All rights reserved
 
 # named subscriber for resolvconf
@@ -29,7 +29,7 @@
 [ -f "@SYSCONFDIR@"/resolvconf.conf ] || exit 0
 . "@SYSCONFDIR@/resolvconf.conf" || exit 1
 [ -z "$named_zones" -a -z "$named_options" ] && exit 0
-[ -z "$RESOLVCONF" ] && eval "$(@PREFIX@/sbin/resolvconf -v)"
+[ -z "$RESOLVCONF" ] && eval "$(@SBINDIR@/resolvconf -v)"
 NL="
 "
 
@@ -40,6 +40,9 @@
 	if [ -x "@RCDIR@"/bind9 ]; then
 		# Debian and derivatives
 		named_service=bind9
+	elif [ -x "@RCDIR@"/rc.bind ]; then
+		# Slackware
+		named_service=rc.bind
 	fi
 fi
 : ${named_service:=named}
@@ -71,6 +74,13 @@
 	newzones="$newzones	};$NL};$NL"
 done
 
+# Try to ensure that config dirs exist
+if type config_mkdirs >/dev/null 2>&1; then
+	config_mkdirs "$named_options" "$named_zones"
+else
+	@SBINDIR@/resolvconf -D "$named_options" "$named_zones"
+fi
+
 # No point in changing files or reloading bind if the end result has not
 # changed
 changed=false

Added: trunk/contrib/openresolv/pdns_recursor.in
===================================================================
--- trunk/contrib/openresolv/pdns_recursor.in	                        (rev 0)
+++ trunk/contrib/openresolv/pdns_recursor.in	2018-06-27 12:58:34 UTC (rev 11161)
@@ -0,0 +1,72 @@
+#!/bin/sh
+# Copyright (c) 2009-2011 Roy Marples
+# All rights reserved
+
+# PowerDNS Recursor subscriber for resolvconf
+
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#     * Redistributions of source code must retain the above copyright
+#       notice, this list of conditions and the following disclaimer.
+#     * Redistributions in binary form must reproduce the above
+#       copyright notice, this list of conditions and the following
+#       disclaimer in the documentation and/or other materials provided
+#       with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+[ -f "@SYSCONFDIR@"/resolvconf.conf ] || exit 0
+. "@SYSCONFDIR@/resolvconf.conf" || exit 1
+[ -z "$pdns_zones" ] && exit 0
+[ -z "$RESOLVCONF" ] && eval "$(@SBINDIR@/resolvconf -v)"
+NL="
+"
+
+: ${pdns_service:=pdns_recursor}
+: ${pdns_restart:=@RESTARTCMD ${pdns_service}@}
+
+newzones=
+
+# pds_recursor does not present support global forward servers, which
+# does limit it's usefulness somewhat.
+# If it did, the below code can be enabled, or something like it.
+#for n in $NAMESERVERS; do
+#	newzones="$newzones${newzones:+,}$n"
+#done
+#[ -n "$newzones" ] && newzones=".=$newzones$NL"
+
+for d in $DOMAINS; do
+	newns=
+	ns="${d#*:}"
+	while [ -n "$ns" ]; do
+		newns="$newns${newns:+,}${ns%%,*}"
+		[ "$ns" = "${ns#*,}" ] && break
+		ns="${ns#*,}"
+	done
+	[ -n "$newns" ] && newzones="$newzones${d%%:*}=$newns$NL"
+done
+
+# Try to ensure that config dirs exist
+if type config_mkdirs >/dev/null 2>&1; then
+	config_mkdirs "$pdnsd_zones"
+else
+	@SBINDIR@/resolvconf -D "$pdnsd_zones"
+fi
+
+if [ ! -f "$pdns_zones" ] || \
+	[ "$(cat "$pdns_zones")" != "$(printf %s "$newzones")" ]
+then
+	printf %s "$newzones" >"$pdns_zones"
+	eval $pdns_restart
+fi


Property changes on: trunk/contrib/openresolv/pdns_recursor.in
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Modified: trunk/contrib/openresolv/pdnsd.in
===================================================================
--- trunk/contrib/openresolv/pdnsd.in	2018-06-27 12:57:52 UTC (rev 11160)
+++ trunk/contrib/openresolv/pdnsd.in	2018-06-27 12:58:34 UTC (rev 11161)
@@ -1,5 +1,5 @@
 #!/bin/sh
-# Copyright (c) 2010 Roy Marples
+# Copyright (c) 2010-2013 Roy Marples
 # All rights reserved
 
 # pdnsd subscriber for resolvconf
@@ -29,7 +29,9 @@
 [ -f "@SYSCONFDIR@"/resolvconf.conf ] || exit 0
 . "@SYSCONFDIR@/resolvconf.conf" || exit 1
 [ -z "$pdnsd_conf" -a -z "$pdnsd_resolv" ] && exit 0
-[ -z "$RESOLVCONF" ] && eval "$(@PREFIX@/sbin/resolvconf -v)"
+[ -z "$RESOLVCONF" ] && eval "$(@SBINDIR@/resolvconf -v)"
+NL="
+"
 
 : ${pdnsd_restart:=pdnsd-ctl config $pdnsd_conf}
 signature="# Generated by resolvconf"
@@ -46,7 +48,7 @@
 		sed "/^$m1/,/^$m2/d" $@
 	else
 		for x; do
-			while read line; do
+			while read -r line; do
 				case "$line" in
 				"$m1"*) in_marker=1;;
 				"$m2"*) in_marker=0;;
@@ -80,24 +82,32 @@
 	return 0
 }
 
-newresolv="# Generated by resolvconf\n"
+newresolv="# Generated by resolvconf$NL"
 changed=false
 
+# Try to ensure that config dirs exist
+if type config_mkdirs >/dev/null 2>&1; then
+	config_mkdirs "$pdnsd_resolv" "$pdnsd_conf"
+else
+	@SBINDIR@/resolvconf -D "$pdnsd_resolv" "$pdnsd_conf"
+fi
+
 if [ -n "$pdnsd_resolv" ]; then
 	for n in $NAMESERVERS; do
-		newresolv="${newresolv}nameserver $n\n"
+		newresolv="${newresolv}nameserver $n$NL"
 	done
 fi
 
-if [ -n "$pdnsd_conf" ]; then
+# Only modify the configuration if it exists and we can write to it
+if [ -w "$pdnsd_conf" ]; then
 	cf="$pdnsd_conf.new"
 	newconf=
 
 	if [ -z "$pdnsd_resolv" ]; then
-		newconf="${newconf}server {\n"
-		newconf="${newconf}\tlabel=resolvconf;\n"
+		newconf="${newconf}server {$NL"
+		newconf="${newconf}	label=resolvconf;$NL"
 		if [ -n "$NAMESERVERS" ]; then
-			newconf="${newconf}\tip="
+			newconf="${newconf}	ip="
 			first=true
 			for n in $NAMESERVERS; do
 				if $first; then
@@ -107,16 +117,16 @@
 				fi
 				newconf="$newconf$n"
 			done
-			newconf="${newconf};\n"
+			newconf="${newconf};$NL"
 		fi
-		newconf="${newconf}}\n"
+		newconf="${newconf}}$NL"
 	fi
 
 	for d in $DOMAINS; do
-		newconf="${newconf}server {\n"
-		newconf="${newconf}\tinclude=.${d%%:*}.;\n"
-		newconf="${newconf}\tpolicy=excluded;\n"
-		newconf="${newconf}\tip="
+		newconf="${newconf}server {$NL"
+		newconf="${newconf}	include=.${d%%:*}.;$NL"
+		newconf="${newconf}	policy=excluded;$NL"
+		newconf="${newconf}	ip="
 		ns="${d#*:}"
 		while [ -n "$ns" ]; do
 			newconf="${newconf}${ns%%,*}"
@@ -124,7 +134,7 @@
 			ns="${ns#*,}"
 			newconf="${newconf},"
 		done
-		newconf="${newconf};\n}\n"
+		newconf="${newconf};$NL}$NL"
 	done
 
 	rm -f "$cf"
@@ -136,7 +146,7 @@
 	fi
 	if change_file "$pdnsd_conf" "$cf"; then
 		changed=true
-	fi	
+	fi
 fi
 
 if [ -n "$pdnsd_resolv" ]; then

Modified: trunk/contrib/openresolv/resolvconf.8.in
===================================================================
--- trunk/contrib/openresolv/resolvconf.8.in	2018-06-27 12:57:52 UTC (rev 11160)
+++ trunk/contrib/openresolv/resolvconf.8.in	2018-06-27 12:58:34 UTC (rev 11161)
@@ -1,4 +1,4 @@
-.\" Copyright (c) 2007-2009 Roy Marples
+.\" Copyright (c) 2007-2015 Roy Marples
 .\" All rights reserved
 .\"
 .\" Redistribution and use in source and binary forms, with or without
@@ -22,8 +22,8 @@
 .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 .\" SUCH DAMAGE.
 .\"
-.Dd December 3, 2009
-.Dt RESOLVCONF 8 SMM
+.Dd April 27, 2014
+.Dt RESOLVCONF 8
 .Os
 .Sh NAME
 .Nm resolvconf
@@ -34,11 +34,14 @@
 .Nm
 .Op Fl m Ar metric
 .Op Fl p
-.Fl a Ar interface No < Ns Pa file
+.Op Fl x
+.Fl a Ar interface Ns Op Ar .protocol
+.No < Ns Pa file
 .Nm
 .Op Fl f
-.Fl d Ar interface
+.Fl d Ar interface Ns Op Ar .protocol
 .Nm
+.Op Fl x
 .Fl il Ar pattern
 .Nm
 .Fl u
@@ -63,7 +66,7 @@
 via
 .Xr stdin 3
 with the argument
-.Fl a Ar interface
+.Fl a Ar interface Ns Op Ar .protocol
 instead of the filesystem.
 .Nm
 then updates
@@ -78,6 +81,20 @@
 will supply files that the resolver should be configured to include.
 .Pp
 .Nm
+assumes it has a job to do.
+In some situations
+.Nm
+needs to act as a deterrent to writing to
+.Pa /etc/resolv.conf .
+Where this file cannot be made immutable or you just need to toggle this
+behaviour,
+.Nm
+can be disabled by adding
+.Sy resolvconf Ns = Ns NO
+to
+.Xr resolvconf.conf 5 .
+.Pp
+.Nm
 can mark an interfaces
 .Pa resolv.conf
 as private.
@@ -91,13 +108,21 @@
 .Nm
 to use a local name server.
 .Pp
+.Nm
+can mark an interfaces
+.Pa resolv.conf
+as exclusive.
+Only the latest exclusive interface is used for processing, otherwise all are.
+.Pp
 When an interface goes down, it should then call
 .Nm
 with
-.Fl d Ar interface
+.Fl d Ar interface.*
 arguments to delete the
 .Pa resolv.conf
-file for the
+file(s) for all the
+.Ar protocols
+on the
 .Ar interface .
 .Pp
 Here are some more options that
@@ -119,7 +144,7 @@
 Ignore non existant interfaces.
 Only really useful for deleting interfaces.
 .It Fl i Ar pattern
-List the interfaces, optionally matching
+List the interfaces and protocols, optionally matching
 .Ar pattern ,
 we have
 .Pa resolv.conf
@@ -130,7 +155,8 @@
 files we have.
 If
 .Ar pattern
-is specified then we list the files for the interfaces that match it.
+is specified then we list the files for the interfaces and protocols
+that match it.
 .It Fl m Ar metric
 Set the metric of the interface when adding it, default of 0.
 Lower metrics take precedence.
@@ -142,18 +168,28 @@
 .It Fl u
 Force
 .Nm
-to update all it's subscribers.
+to update all its subscribers.
 .Nm
 does not update the subscribers when adding a resolv.conf that matches
 what it already has for that interface.
+.It Fl x
+Mark the interface
+.Pa resolv.conf
+as exclusive when adding, otherwise only use the latest exclusive interface.
 .El
 .Pp
 .Nm
-also has some options designed to be used by it's subscribers:-
+also has some options designed to be used by its subscribers:-
 .Bl -tag -width indent
 .It Fl v
 Echo variables DOMAINS, SEARCH and NAMESERVERS so that the subscriber can
 configure the resolver easily.
+.It Fl V
+Same as
+.Fl v
+except that only the information configured in
+.Xr resolvconf.conf 5
+is set.
 .El
 .Sh INTERFACE ORDERING
 For
@@ -170,6 +206,29 @@
 See
 .Xr resolvconf.conf 5
 for details on these lists.
+.Sh PROTOCOLS
+Here are some suggested protocol tags to use for each
+.Pa resolv.conf
+file registered on an
+.Ar interface Ns No :-
+.Bl -tag -width indent
+.It dhcp
+Dynamic Host Configuration Protocol.
+Initial versions of
+.Nm
+did not recommend a
+.Ar protocol
+tag be appended to the
+.Ar interface
+name.
+When the protocol is absent, it is assumed to be the DHCP protocol.
+.It ppp
+Point-to-Point Protocol.
+.It ra
+IPv6 Router Advertisement.
+.It dhcp6
+Dynamic Host Configuration Protocol, version 6.
+.El
 .Sh IMPLEMENTATION NOTES
 If a subscriber has the executable bit then it is executed otherwise it is
 assumed to be a shell script and sourced into the current environment in a
@@ -197,9 +256,15 @@
 Marks the interface
 .Pa resolv.conf
 as private.
+.It Va IF_EXCLUSIVE
+Marks the interface
+.Pa resolv.conf
+as exclusive.
 .El
 .Sh FILES
 .Bl -ohang
+.It Pa /etc/resolv.conf.bak
+Backup file of the original resolv.conf.
 .It Pa @SYSCONFDIR@/resolvconf.conf
 Configuration file for
 .Nm .
@@ -218,7 +283,17 @@
 .Nm
 is called openresolv and is fully command line compatible with Debian's
 resolvconf, as written by Thomas Hood.
+.Sh SEE ALSO
+.Xr resolv.conf 5 ,
+.Xr resolvconf.conf 5 ,
+.Xr resolver 3 ,
+.Xr stdin 3
+.Sh AUTHORS
+.An Roy Marples Aq Mt roy at marples.name
 .Sh BUGS
+Please report them to
+.Lk http://roy.marples.name/projects/openresolv
+.Pp
 .Nm
 does not validate any of the files given to it.
 .Pp
@@ -229,12 +304,3 @@
 You should consult
 .Xr resolvconf.conf 5
 for instructions on how to configure your resolver.
-.Sh SEE ALSO
-.Xr resolv.conf 5 ,
-.Xr resolvconf.conf 5 ,
-.Xr resolver 3 ,
-.Xr stdin 3
-.Sh AUTHORS
-.An Roy Marples Aq roy at marples.name
-.Sh BUGS
-Please report them to http://roy.marples.name/projects/openresolv

Modified: trunk/contrib/openresolv/resolvconf.conf.5.in
===================================================================
--- trunk/contrib/openresolv/resolvconf.conf.5.in	2018-06-27 12:57:52 UTC (rev 11160)
+++ trunk/contrib/openresolv/resolvconf.conf.5.in	2018-06-27 12:58:34 UTC (rev 11161)
@@ -1,4 +1,4 @@
-.\" Copyright (c) 2009-2010 Roy Marples
+.\" Copyright (c) 2009-2015 Roy Marples
 .\" All rights reserved
 .\"
 .\" Redistribution and use in source and binary forms, with or without
@@ -22,8 +22,8 @@
 .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 .\" SUCH DAMAGE.
 .\"
-.Dd October 29, 2010
-.Dt RESOLVCONF.CONF 5 SMM
+.Dd March 20, 2015
+.Dt RESOLVCONF.CONF 5
 .Os
 .Sh NAME
 .Nm resolvconf.conf
@@ -42,12 +42,22 @@
 Listed below are the standard
 .Nm
 variables that may be set.
+If the values contain white space for special shell characters,
+ensure they are quoted and escaped correctly.
 .Pp
 After updating this file, you may wish to run
 .Nm resolvconf -u
 to apply the new configuration.
+.Pp
+When a dynamically generated list is appended or prepended to, the whole
+is made unique where left-most wins.
 .Sh RESOLVCONF OPTIONS
 .Bl -tag -width indent
+.It Sy resolvconf
+Set to NO to disable
+.Nm resolvconf
+from running any subscribers.
+Defaults to YES.
 .It Sy interface_order
 These interfaces will always be processed first.
 If unset, defaults to the following:-
@@ -56,10 +66,17 @@
 These interfaces will be processed next, unless they have a metric.
 If unset, defaults to the following:-
 .D1 tap[0-9]* tun[0-9]* vpn vpn[0-9]* ppp[0-9]* ippp[0-9]*
+.It Sy local_nameservers
+If unset, defaults to the following:-
+.D1 127.* 0.0.0.0 255.255.255.255 ::1
 .It Sy search_domains
 Prepend search domains to the dynamically generated list.
 .It Sy search_domains_append
 Append search domains to the dynamically generated list.
+.It Sy domain_blacklist
+A list of domains to be removed from consideration.
+To remove a domain, you can use foo.*
+To remove a sub domain, you can use *.bar
 .It Sy name_servers
 Prepend name servers to the dynamically generated list.
 You should set this to 127.0.0.1 if you use a local name server other than
@@ -66,6 +83,10 @@
 libc.
 .It Sy name_servers_append
 Append name servers to the dynamically generated list.
+.It Sy name_server_blacklist
+A list of name servers to be removed from consideration.
+The default is 0.0.0.0 as some faulty routers send it via DHCP.
+To remove a block, you can use 192.168.*
 .It Sy private_interfaces
 These interfaces name servers will only be queried for the domains listed
 in their resolv.conf.
@@ -73,6 +94,34 @@
 This is equivalent to the
 .Nm resolvconf -p
 option.
+.It Sy replace
+Is a space separated list of replacement keywords. The syntax is this:
+.Va $keyword Ns / Ns Va $match Ns / Ns Va $replacement
+.Pp
+Example, given this resolv.conf:
+.D1 domain foo.org
+.D1 search foo.org dead.beef
+.D1 nameserver 1.2.3.4
+.D1 nameserver 2.3.4.5
+and this configuaration:
+.D1 replace="search/foo*/bar.com nameserver/1.2.3.4/5.6.7.8 nameserver/2.3.4.5/"
+you would get this resolv.conf instead:
+.D1 domain foo.org
+.D1 search bar.com
+.D1 nameserver 5.6.7.8
+.It Sy replace_sub
+Works the same way as
+.Sy replace
+except it works on each space separated value rather than the whole line,
+so it's useful for the replacing a single domain within the search directive.
+Using the same example resolv.conf and changing
+.Sy replace
+to
+.Sy replace_sub ,
+you would get this resolv.conf instead:
+.D1 domain foo.org
+.D1 search bar.com dead.beef
+.D1 nameserver 5.6.7.8
 .It Sy state_dir
 Override the default state directory of
 .Pa @VARDIR@ .
@@ -96,6 +145,32 @@
 When set to YES the latest resolv.conf is written to
 .Sy resolv_conf
 without any alteration.
+When set to /dev/null or NULL,
+.Sy resolv_conf_local_only
+is defaulted to NO,
+.Sy local_nameservers
+is unset unless overriden and only the information set in
+.Nm
+is written to
+.Sy resolv_conf .
+.It Sy resolv_conf_sortlist
+A libc resolver sortlist, as specified in
+.Xr resolv.conf 5 .
+.It Sy resolv_conf_local_only
+If a local name server is configured then the default is just to specify that
+and ignore all other entries as they will be configured for the local
+name server.
+Set this to NO to also list non-local nameservers.
+This will give you working DNS even if the local nameserver stops functioning
+at the expense of duplicated server queries.
+.It Sy append_nameservers
+Append name servers to the dynamically generated list.
+.It Sy prepend_nameservers
+Prepend name servers to the dynamically generated list.
+.It Sy append_search
+Append search domains to the dynamically generated list.
+.It Sy prepend_search
+Prepend search domains to the dynamically generated list.
 .El
 .Sh SUBSCRIBER OPTIONS
 openresolv ships with subscribers for the name servers
@@ -106,11 +181,15 @@
 .Xr unbound 8 .
 Each subscriber can create configuration files which should be included in
 in the subscribers main configuration file.
+.Pp
+To disable a subscriber, simply set it's name to NO.
+For example, to disable the libc subscriber you would set:
+.D1 libc=NO
 .Bl -tag -width indent
 .It Sy dnsmasq_conf
-This file tells dnsmasq which nameservers to use for specific domains.
+This file tells dnsmasq which name servers to use for specific domains.
 .It Sy dnsmasq_resolv
-This file tells dnsmasq which nameservers to use for global lookups.
+This file tells dnsmasq which name servers to use for global lookups.
 .Pp
 Example resolvconf.conf for dnsmasq:
 .D1 name_servers=127.0.0.1
@@ -119,14 +198,17 @@
 .Pp
 Example dnsmasq.conf:
 .D1 listen-address=127.0.0.1
+.D1 # If dnsmasq is compiled for DBus then we can take
+.D1 # advantage of not having to restart dnsmasq.
+.D1 enable-dbus
 .D1 conf-file=/etc/dnsmasq-conf.conf
 .D1 resolv-file=/etc/dnsmasq-resolv.conf
 .It Sy named_options
 Include this file in the named options block.
-This file tells named which nameservers to use for global lookups.
+This file tells named which name servers to use for global lookups.
 .It Sy named_zones
 Include this file in the named global scope, after the options block.
-This file tells named which nameservers to use for specific domains.
+This file tells named which name servers to use for specific domains.
 .Pp
 Example resolvconf.conf for named:
 .D1 name_servers=127.0.0.1
@@ -147,7 +229,7 @@
 .Pa pdnsd_resolv
 as documented below.
 .It Sy pdnsd_resolv
-This file tells pdnsd about global nameservers.
+This file tells pdnsd about global name servers.
 If this variable is not set then it's written to
 .Pa pdnsd_conf .
 .Pp
@@ -168,7 +250,9 @@
 .D1 	# file="/etc/pdnsd-resolv.conf";
 .D1 }
 .It Sy unbound_conf
-This file tells unbound about specific and global nameservers.
+This file tells unbound about specific and global name servers.
+.It Sy unbound_insecure
+When set to YES, unbound marks the domains as insecure, thus ignoring DNSSEC.
 .Pp
 Example resolvconf.conf for unbound:
 .D1 name_servers=127.0.0.1
@@ -177,11 +261,53 @@
 Example unbound.conf:
 .D1 include: /etc/unbound-resolvconf.conf
 .El
+.Sh SUBSCRIBER INTEGRATION
+Not all distributions store the files the subscribers need in the same
+locations.
+For example, named service scripts have been called named, bind and rc.bind
+and they could be located in a directory called /etc/rc.d, /etc/init.d or
+similar.
+Each subscriber attempts to automatically configure itself, but not every
+distribution has been catered for.
+Also, users could equally want to use a different version from the one
+installed by default, such as bind8 and bind9.
+To accomodate this, the subscribers have these files in configurable
+variables, documented below.
+.Pp
+.Bl -tag -width indent
+.It Sy dnsmasq_service
+Location of the dnsmasq service.
+.It Sy dnsmasq_restart
+Command to restart the dnsmasq service.
+.It Sy dnsmasq_pid
+Location of the dnsmasq pidfile.
+.It Sy libc_service
+Location of the libc service.
+.It Sy libc_restart
+Command to restart the libc service.
+.It Sy named_service
+Location of the named service.
+.It Sy named_restart
+Command to restart the named service.
+.It Sy pdnsd_restart
+Command to restart the pdnsd service.
+.It Sy unbound_service
+Location of the unbound service.
+.It Sy unbound_restart
+Command to restart the unbound service.
+.It Sy unbound_pid
+Location of the unbound pidfile.
+.El
 .Sh SEE ALSO
-.Xr resolv.conf 5
+.Xr resolv.conf 5 ,
+.Xr resolvconf 8
 and
-.Xr resolvconf 8 .
+.Xr sh 1 .
 .Sh AUTHORS
-.An Roy Marples Aq roy at marples.name
+.An Roy Marples Aq Mt roy at marples.name
 .Sh BUGS
-Please report them to http://roy.marples.name/projects/openresolv
+Each distribution is a special snowflake and likes to name the same thing
+differently, namely the named service script.
+.Pp
+Please report them to
+.Lk http://roy.marples.name/projects/openresolv

Modified: trunk/contrib/openresolv/resolvconf.in
===================================================================
--- trunk/contrib/openresolv/resolvconf.in	2018-06-27 12:57:52 UTC (rev 11160)
+++ trunk/contrib/openresolv/resolvconf.in	2018-06-27 12:58:34 UTC (rev 11161)
@@ -1,5 +1,5 @@
 #!/bin/sh
-# Copyright (c) 2007-2009 Roy Marples
+# Copyright (c) 2007-2015 Roy Marples
 # All rights reserved
 
 # Redistribution and use in source and binary forms, with or without
@@ -28,6 +28,17 @@
 SYSCONFDIR=@SYSCONFDIR@
 LIBEXECDIR=@LIBEXECDIR@
 VARDIR=@VARDIR@
+
+# Disregard dhcpcd setting
+unset interface_order state_dir
+
+# If you change this, change the test in VFLAG and libc.in as well
+local_nameservers="127.* 0.0.0.0 255.255.255.255 ::1"
+
+dynamic_order="tap[0-9]* tun[0-9]* vpn vpn[0-9]* ppp[0-9]* ippp[0-9]*"
+interface_order="lo lo[0-9]*"
+name_server_blacklist="0.0.0.0"
+
 # Support original resolvconf configuration layout
 # as well as the openresolv config file
 if [ -f "$SYSCONFDIR"/resolvconf.conf ]; then
@@ -39,12 +50,17 @@
 		interface_order="$(cat "$SYSCONFDIR"/interface-order)"
 	fi
 fi
+TMPDIR="$VARDIR/tmp"
 IFACEDIR="$VARDIR/interfaces"
 METRICDIR="$VARDIR/metrics"
 PRIVATEDIR="$VARDIR/private"
+EXCLUSIVEDIR="$VARDIR/exclusive"
+LOCKDIR="$VARDIR/lock"
 
-: ${dynamic_order:=tap[0-9]* tun[0-9]* vpn vpn[0-9]* ppp[0-9]* ippp[0-9]*}
-: ${interface_order:=lo lo[0-9]*}
+warn()
+{
+	echo "$*" >&2
+}
 
 error_exit()
 {
@@ -64,6 +80,7 @@
 	                   (DNS supplied via stdin in resolv.conf format)
 	  -m metric        Give the added DNS information a metric
 	  -p               Mark the interface as private
+	  -x               Mark the interface as exclusive
 	  -d \$INTERFACE    Delete DNS information from the specified interface
 	  -f               Ignore non existant interfaces
 	  -I               Init the state dir
@@ -84,16 +101,23 @@
 
 echo_resolv()
 {
-	local line=
-	[ -n "$1" -a -e "$IFACEDIR/$1" ] || return 1
+	local line= OIFS="$IFS"
+
+	[ -n "$1" -a -f "$IFACEDIR/$1" ] || return 1
 	echo "# resolv.conf from $1"
 	# Our variable maker works of the fact each resolv.conf per interface
 	# is separated by blank lines.
 	# So we remove them when echoing them.
-	while read line; do
-		[ -n "$line" ] && echo "$line"
+	while read -r line; do
+		IFS="$OIFS"
+		if [ -n "$line" ]; then
+			# We need to set IFS here to preserve any whitespace
+			IFS=''
+			printf "%s\n" "$line"
+		fi
 	done < "$IFACEDIR/$1"
 	echo
+	IFS="$OIFS"
 }
 
 # Parse resolv.conf's and make variables
@@ -101,22 +125,11 @@
 parse_resolv()
 {
 	local line= ns= ds= search= d= n= newns=
-	local new=true iface= private=false p=
+	local new=true iface= private=false p= domain= l= islocal=
 
-	echo "DOMAINS="
-	echo "SEARCH=\"$search_domains\""
-	# let our subscribers know about global nameservers
-	for n in $name_servers; do
-		case "$n" in
-		127.*|0.0.0.0|255.255.255.255|::1) :;;
-		*) newns="$newns${newns:+ }$n";;
-		esac
-	done
-	echo "NAMESERVERS=\"$newns\""
-	echo "LOCALNAMESERVERS="
 	newns=
 
-	while read line; do
+	while read -r line; do
 		case "$line" in
 		"# resolv.conf from "*)
 			if ${new}; then
@@ -129,26 +142,36 @@
 					cd "$IFACEDIR"
 					private=false
 					for p in $private_interfaces; do
-						if [ "$p" = "$iface" ]; then
-							private=true
-							break
-						fi
+						case "$iface" in
+						"$p"|"$p":*) private=true; break;;
+						esac
 					done
 				fi
 			fi
 			;;
 		"nameserver "*)
-			case "${line#* }" in
-			127.*|0.0.0.0|255.255.255.255|::1)
-				echo "LOCALNAMESERVERS=\"\$LOCALNAMESERVERS ${line#* }\""
-				continue
-				;;
-			esac
-			ns="$ns${line#* } "
+			islocal=false
+			for l in $local_nameservers; do
+				case "${line#* }" in
+				$l)
+					islocal=true
+					echo "LOCALNAMESERVERS=\"\$LOCALNAMESERVERS ${line#* }\""
+					break
+					;;
+				esac
+			done
+			$islocal || ns="$ns${line#* } "
 			;;
-		"domain "*|"search "*)
+		"domain "*)
+			if [ -z "$domain" ]; then
+				domain="${line#* }"
+				echo "DOMAIN=\"$domain\""
+			fi
 			search="${line#* }"
 			;;
+		"search "*)
+			search="${line#* }"
+			;;
 		*)
 			[ -n "$line" ] && continue
 			if [ -n "$ns" -a -n "$search" ]; then
@@ -187,32 +210,93 @@
 	echo "${result# *}"
 }
 
+dirname()
+{
+	local dir= OIFS="$IFS"
+	local IFS=/
+	set -- $@
+	IFS="$OIFS"
+	if [ -n "$1" ]; then
+		printf %s .
+	else
+		shift
+	fi
+	while [ -n "$2" ]; do
+		printf "/%s" "$1"
+		shift
+	done
+	printf "\n"
+}
+
+config_mkdirs()
+{
+	local e=0 f d
+	for f; do
+		[ -n "$f" ] || continue
+		d="$(dirname "$f")"
+		if [ ! -d "$d" ]; then
+			if type install >/dev/null 2>&1; then
+				install -d "$d" || e=$?
+			else
+				mkdir "$d" || e=$?
+			fi
+		fi
+	done
+	return $e
+}
+
 list_resolv()
 {
 	[ -d "$IFACEDIR" ] || return 0
 
-	local report=false list= retval=0 cmd="$1"
+	local report=false list= retval=0 cmd="$1" excl=
 	shift
 
+	case "$IF_EXCLUSIVE" in
+	[Yy][Ee][Ss]|[Tt][Rr][Uu][Ee]|[Oo][Nn]|1)
+		if [ -d "$EXCLUSIVEDIR" ]; then
+			cd "$EXCLUSIVEDIR"
+			for i in *; do
+				if [ -f "$i" ]; then
+					list="${i#* }"
+					break
+				fi
+			done
+		fi
+		excl=true
+		;;
+	*)
+		excl=false
+		;;
+	esac
+
 	# If we have an interface ordering list, then use that.
 	# It works by just using pathname expansion in the interface directory.
 	if [ -n "$1" ]; then
-		list="$@"
+		list="$*"
 		$force || report=true
-	else
+	elif ! $excl; then
 		cd "$IFACEDIR"
 		for i in $interface_order; do
-			[ -e "$i" ] && list="$list $i"
+			[ -f "$i" ] && list="$list $i"
+			for ii in "$i":* "$i".*; do
+				[ -f "$ii" ] && list="$list $ii"
+			done
 		done
 		for i in $dynamic_order; do
 			if [ -e "$i" -a ! -e "$METRICDIR/"*" $i" ]; then
 				list="$list $i"
 			fi
+			for ii in "$i":* "$i".*; do
+				if [ -f "$ii" -a ! -e "$METRICDIR/"*" $ii" ]; then
+					list="$list $ii"
+				fi
+			done
 		done
 		if [ -d "$METRICDIR" ]; then
 			cd "$METRICDIR"
 			for i in *; do
-				list="$list ${i#* }"
+				[ -f "$i" ] && list="$list ${i#* }"
 			done
 		fi
 		list="$list *"
@@ -219,38 +303,150 @@
 	fi
 
 	cd "$IFACEDIR"
+	retval=1
 	for i in $(uniqify $list); do
 		# Only list interfaces which we really have
-		if ! [ -e "$i" ]; then
+		if ! [ -f "$i" ]; then
 			if $report; then
 				echo "No resolv.conf for interface $i" >&2
-				retval=$(($retval + 1))
+				retval=2
 			fi
 			continue
 		fi
 		
 		if [ "$cmd" = i -o "$cmd" = "-i" ]; then
-			printf "$i "
+			printf %s "$i "
 		else
 			echo_resolv "$i"
 		fi
+		[ $? = 0 -a "$retval" = 1 ] && retval=0
 	done
 	[ "$cmd" = i -o "$cmd" = "-i" ] && echo
 	return $retval
 }
 
+list_remove() {
+	local list= e= l= result= found= retval=0
+
+	[ -z "$2" ] && return 0
+	eval list=\"\$$1\"
+	shift
+
+	set -f
+	for e; do
+		found=false
+		for l in $list; do
+			case "$e" in
+			$l) found=true;;
+			esac
+			$found && break
+		done
+		if $found; then
+			retval=$(($retval + 1))
+		else
+			result="$result $e"
+		fi
+	done
+	set +f
+	echo "${result# *}"
+	return $retval
+}
+
+echo_prepend()
+{
+	echo "# Generated by resolvconf"
+	if [ -n "$search_domains" ]; then
+		echo "search $search_domains"
+	fi
+	for n in $name_servers; do
+		echo "nameserver $n"
+	done
+	echo
+}
+
+echo_append()
+{
+	echo "# Generated by resolvconf"
+	if [ -n "$search_domains_append" ]; then
+		echo "search $search_domains_append"
+	fi
+	for n in $name_servers_append; do
+		echo "nameserver $n"
+	done
+	echo
+}
+
+replace()
+{
+	local r= k= f= v= val= sub=
+
+	while read -r keyword value; do
+		for r in $replace; do
+			k="${r%%/*}"
+			r="${r#*/}"
+			f="${r%%/*}"
+			r="${r#*/}"
+			v="${r%%/*}"
+			case "$keyword" in
+			$k)
+				case "$value" in
+				$f) value="$v";;
+				esac
+				;;
+			esac
+		done
+		val=
+		for sub in $value; do
+			for r in $replace_sub; do
+				k="${r%%/*}"
+				r="${r#*/}"
+				f="${r%%/*}"
+				r="${r#*/}"
+				v="${r%%/*}"
+				case "$keyword" in
+				$k)
+					case "$sub" in
+					$f) sub="$v";;
+					esac
+					;;
+				esac
+			done
+			val="$val${val:+ }$sub"
+		done
+		printf "%s %s\n" "$keyword" "$val"
+	done
+}
+
 make_vars()
 {
-	eval "$(list_resolv -l "$@" | parse_resolv)"
+	local newdomains= d= dn= newns= ns=
 
+	# Clear variables
+	DOMAIN=
+	DOMAINS=
+	SEARCH=
+	NAMESERVERS=
+	LOCALNAMESERVERS=
+	
+	if [ -n "$name_servers" -o -n "$search_domains" ]; then
+		eval "$(echo_prepend | parse_resolv)"
+	fi
+	if [ -z "$VFLAG" ]; then
+		IF_EXCLUSIVE=1
+		list_resolv -i "$@" >/dev/null || IF_EXCLUSIVE=0
+		eval "$(list_resolv -l "$@" | replace | parse_resolv)"
+	fi
+	if [ -n "$name_servers_append" -o -n "$search_domains_append" ]; then
+		eval "$(echo_append | parse_resolv)"
+	fi
+
 	# Ensure that we only list each domain once
-	newdomains=
 	for d in $DOMAINS; do
 		dn="${d%%:*}"
+		list_remove domain_blacklist "$dn" >/dev/null || continue
 		case " $newdomains" in
 		*" ${dn}:"*) continue;;
 		esac
-		newdomains="$newdomains${newdomains:+ }$dn:"
 		newns=
 		for nd in $DOMAINS; do
 			if [ "$dn" = "${nd%%:*}" ]; then
@@ -258,7 +454,9 @@
 				while [ -n "$ns" ]; do
 					case ",$newns," in
 					*,${ns%%,*},*) ;;
-					*) newns="$newns${newns:+,}${ns%%,*}";;
+					*) list_remove name_server_blacklist \
+						"${ns%%,*}" >/dev/null \
+					&& newns="$newns${newns:+,}${ns%%,*}";;
 					esac
 					[ "$ns" = "${ns#*,}" ] && break
 					ns="${ns#*,}"
@@ -265,27 +463,47 @@
 				done
 			fi
 		done
-		newdomains="$newdomains$newns"
+		if [ -n "$newns" ]; then
+			newdomains="$newdomains${newdomains:+ }$dn:$newns"
+		fi
 	done
+	DOMAIN="$(list_remove domain_blacklist $DOMAIN)"
+	SEARCH="$(uniqify $SEARCH)"
+	SEARCH="$(list_remove domain_blacklist $SEARCH)"
+	NAMESERVERS="$(uniqify $NAMESERVERS)"
+	NAMESERVERS="$(list_remove name_server_blacklist $NAMESERVERS)"
+	LOCALNAMESERVERS="$(uniqify $LOCALNAMESERVERS)"
+	LOCALNAMESERVERS="$(list_remove name_server_blacklist $LOCALNAMESERVERS)"
+	echo "DOMAIN='$DOMAIN'"
+	echo "SEARCH='$SEARCH'"
+	echo "NAMESERVERS='$NAMESERVERS'"
+	echo "LOCALNAMESERVERS='$LOCALNAMESERVERS'"
 	echo "DOMAINS='$newdomains'"
-	echo "SEARCH='$(uniqify $SEARCH)'"
-	echo "NAMESERVERS='$(uniqify $NAMESERVERS)'"
-	echo "LOCALNAMESERVERS='$(uniqify $LOCALNAMESERVERS)'"
 }
 
 force=false
-while getopts a:d:fhIilm:puv OPT; do
+VFLAG=
+while getopts a:Dd:fhIilm:puvVx OPT; do
 	case "$OPT" in
 	f) force=true;;
 	h) usage;;
 	m) IF_METRIC="$OPTARG";;
 	p) IF_PRIVATE=1;;
+	V)
+		VFLAG=1
+		if [ "$local_nameservers" = \
+		    "127.* 0.0.0.0 255.255.255.255 ::1" ]
+		then
+			local_nameservers=
+		fi
+		;;
+	x) IF_EXCLUSIVE=1;;
 	'?') ;;
 	*) cmd="$OPT"; iface="$OPTARG";;
 	esac
 done
 shift $(($OPTIND - 1))
-args="$iface${iface:+ }$@"
+args="$iface${iface:+ }$*"
 
 # -I inits the state dir
 if [ "$cmd" = I ]; then
@@ -295,6 +513,12 @@
 	exit $?
 fi
 
+# -D ensures that the listed config file base dirs exist
+if [ "$cmd" = D ]; then
+	config_mkdirs "$@"
+	exit $?
+fi
+
 # -l lists our resolv files, optionally for a specific interface
 if [ "$cmd" = l -o "$cmd" = i ]; then
 	list_resolv "$cmd" "$args"
@@ -302,7 +526,7 @@
 fi
 
 # Not normally needed, but subscribers should be able to run independently
-if [ "$cmd" = v ]; then
+if [ "$cmd" = v -o -n "$VFLAG" ]; then
 	make_vars "$iface"
 	exit $?
 fi
@@ -316,6 +540,7 @@
 	[ -n "$cmd" -a "$cmd" != h ] && usage "Unknown option $cmd"
 	usage
 fi
+
 if [ "$cmd" = a ]; then
 	for x in '/' \\ ' ' '*'; do
 		case "$iface" in
@@ -331,63 +556,104 @@
 	[ "$cmd" = a -a -t 0 ] && error_exit "No file given via stdin"
 fi
 
-if [ ! -d "$IFACEDIR" ]; then
-	if [ ! -d "$VARDIR" ]; then
-		if [ -L "$VARDIR" ]; then
-			dir="$(readlink "$VARDIR")"
-			# link maybe relative
-			cd "${VARDIR%/*}"
-			if ! mkdir -m 0755 -p "$dir"; then
-				error_exit "Failed to create needed" \
-					"directory $dir"
-			fi
-		else
-			if ! mkdir -m 0755 -p "$VARDIR"; then
-				error_exit "Failed to create needed" \
-					"directory $VARDIR"
-			fi
+if [ ! -d "$VARDIR" ]; then
+	if [ -L "$VARDIR" ]; then
+		dir="$(readlink "$VARDIR")"
+		# link maybe relative
+		cd "${VARDIR%/*}"
+		if ! mkdir -m 0755 -p "$dir"; then
+			error_exit "Failed to create needed" \
+				"directory $dir"
 		fi
+	else
+		if ! mkdir -m 0755 -p "$VARDIR"; then
+			error_exit "Failed to create needed" \
+				"directory $VARDIR"
+		fi
 	fi
+fi
+
+if [ ! -d "$IFACEDIR" ]; then
 	mkdir -m 0755 -p "$IFACEDIR" || \
 		error_exit "Failed to create needed directory $IFACEDIR"
-else
-	# Delete any existing information about the interface
 	if [ "$cmd" = d ]; then
-		cd "$IFACEDIR"
-		for i in $args; do
-			if [ "$cmd" = d -a ! -e "$i" ]; then
-				$force && continue
-				error_exit "No resolv.conf for" \
-					"interface $i"
-			fi
-			rm -f "$i" "$METRICDIR/"*" $i" \
-				"$PRIVATEDIR/$i" || exit $?
-		done
+		# Provide the same error messages as below
+		if ! ${force}; then
+			cd "$IFACEDIR"
+			for i in $args; do
+				warn "No resolv.conf for interface $i"
+			done
+		fi
+		${force}
+		exit $?
 	fi
 fi
 
-if [ "$cmd" = a ]; then
+# An interface was added, changed, deleted or a general update was called.
+# Due to exclusivity we need to ensure that this is an atomic operation.
+# Our subscribers *may* need this as well if the init system is sub par.
+# As such we spinlock at this point as best we can.
+# We don't use flock(1) because it's not widely available and normally resides
+# in /usr which we do our very best to operate without.
+[ -w "$VARDIR" ] || error_exit "Cannot write to $LOCKDIR"
+: ${lock_timeout:=10}
+while true; do
+	if mkdir "$LOCKDIR" 2>/dev/null; then
+		trap 'rm -rf "$LOCKDIR";' EXIT
+		trap 'rm -rf "$LOCKDIR"; exit 1' INT QUIT ABRT SEGV ALRM TERM
+		echo $$ >"$LOCKDIR/pid"
+		break
+	fi
+	pid=$(cat "$LOCKDIR/pid")
+	if ! kill -0 "$pid"; then
+		warn "clearing stale lock pid $pid"
+		rm -rf "$LOCKDIR"
+		continue
+	fi
+	lock_timeout=$(($lock_timeout - 1))
+	if [ "$lock_timeout" -le 0 ]; then
+		error_exit "timed out waiting for lock from pid $pid"
+	fi
+	sleep 1
+done
+
+case "$cmd" in
+a)
 	# Read resolv.conf from stdin
 	resolv="$(cat)"
+	changed=false
+	changedfile=false
 	# If what we are given matches what we have, then do nothing
 	if [ -e "$IFACEDIR/$iface" ]; then
-		if [ "$(echo "$resolv")" = \
+		if [ "$(echo "$resolv")" != \
 			"$(cat "$IFACEDIR/$iface")" ]
 		then
-			exit 0
+			changed=true
+			changedfile=true
 		fi
-		rm "$IFACEDIR/$iface"
+	else
+		changed=true
+		changedfile=true
 	fi
-	echo "$resolv" >"$IFACEDIR/$iface" || exit $?
+
+	# Set metric and private before creating the interface resolv.conf file
+	# to ensure that it will have the correct flags
 	[ ! -d "$METRICDIR" ] && mkdir "$METRICDIR"
-	rm -f "$METRICDIR/"*" $iface"
+	oldmetric="$METRICDIR/"*" $iface"
+	newmetric=
 	if [ -n "$IF_METRIC" ]; then
 		# Pad metric to 6 characters, so 5 is less than 10
 		while [ ${#IF_METRIC} -le 6 ]; do
 			IF_METRIC="0$IF_METRIC"
 		done
-		echo " " >"$METRICDIR/$IF_METRIC $iface"
+		newmetric="$METRICDIR/$IF_METRIC $iface"
 	fi
+	rm -f "$METRICDIR/"*" $iface"
+	[ "$oldmetric" != "$newmetric" -a \
+	    "$oldmetric" != "$METRICDIR/* $iface" ] &&
+		changed=true
+	[ -n "$newmetric" ] && echo " " >"$newmetric"
+
 	case "$IF_PRIVATE" in
 	[Yy][Ee][Ss]|[Tt][Rr][Uu][Ee]|[Oo][Nn]|1)
 		if [ ! -d "$PRIVATEDIR" ]; then
@@ -394,16 +660,95 @@
 			[ -e "$PRIVATEDIR" ] && rm "$PRIVATEDIR"
 			mkdir "$PRIVATEDIR"
 		fi
+		[ -e "$PRIVATEDIR/$iface" ] || changed=true
 		[ -d "$PRIVATEDIR" ] && echo " " >"$PRIVATEDIR/$iface"
 		;;
 	*)
 		if [ -e "$PRIVATEDIR/$iface" ]; then
 			rm -f "$PRIVATEDIR/$iface"
+			changed=true
 		fi
 		;;
 	esac
-fi
 
+	oldexcl=
+	for x in "$EXCLUSIVEDIR/"*" $iface"; do
+		if [ -f "$x" ]; then
+			oldexcl="$x"
+			break
+		fi
+	done
+	case "$IF_EXCLUSIVE" in
+	[Yy][Ee][Ss]|[Tt][Rr][Uu][Ee]|[Oo][Nn]|1)
+		if [ ! -d "$EXCLUSIVEDIR" ]; then
+			[ -e "$EXCLUSIVEDIR" ] && rm "$EXCLUSIVEDIR"
+			mkdir "$EXCLUSIVEDIR"
+		fi
+		cd "$EXCLUSIVEDIR"
+		for x in *; do
+			[ -f "$x" ] && break
+		done
+		if [ "${x#* }" != "$iface" ]; then
+			if [ "$x" = "${x% *}" ]; then
+				x=10000000
+			else
+				x="${x% *}"
+			fi
+			if [ "$x" = "0000000" ]; then
+				warn "exclusive underflow"
+			else
+				x=$(($x - 1))
+			fi
+			if [ -d "$EXCLUSIVEDIR" ]; then
+				echo " " >"$EXCLUSIVEDIR/$x $iface"
+			fi
+			changed=true
+		fi
+		;;
+	*)
+		if [ -f "$oldexcl" ]; then
+			rm -f "$oldexcl"
+			changed=true
+		fi
+		;;
+	esac
+
+	if $changedfile; then
+		printf "%s\n" "$resolv" >"$IFACEDIR/$iface" || exit $?
+	elif ! $changed; then
+		exit 0
+	fi
+	unset changed changedfile oldmetric newmetric x oldexcl
+	;;
+
+d)
+	# Delete any existing information about the interface
+	cd "$IFACEDIR"
+	changed=false
+	for i in $args; do
+		if [ -e "$i" ]; then
+			changed=true
+		elif ! ${force}; then
+			warn "No resolv.conf for interface $i"
+		fi
+		rm -f "$i" "$METRICDIR/"*" $i" \
+			"$PRIVATEDIR/$i" \
+			"$EXCLUSIVEDIR/"*" $i" || exit $?
+	done
+	if ! ${changed}; then
+		# Set the return code based on the forced flag
+		${force}
+		exit $?
+	fi
+	unset changed i
+	;;
+esac
+
+case "${resolvconf:-YES}" in
+[Yy][Ee][Ss]|[Tt][Rr][Uu][Ee]|[Oo][Nn]|1) ;;
+*) exit 0;;
+esac
+
 eval "$(make_vars)"
 export RESOLVCONF DOMAINS SEARCH NAMESERVERS LOCALNAMESERVERS
 : ${list_resolv:=list_resolv -l}
@@ -410,10 +755,15 @@
 retval=0
 for script in "$LIBEXECDIR"/*; do
 	if [ -f "$script" ]; then
+		eval script_enabled="\$${script##*/}"
+		case "${script_enabled:-YES}" in
+		[Yy][Ee][Ss]|[Tt][Rr][Uu][Ee]|[Oo][Nn]|1) ;;
+		*) continue;;
+		esac
 		if [ -x "$script" ]; then
 			"$script" "$cmd" "$iface"
 		else
-			(. "$script" "$cmd" "$iface")
+			(set -- "$cmd" "$iface"; . "$script")
 		fi
 		retval=$(($retval + $?))
 	fi

Modified: trunk/contrib/openresolv/unbound.in
===================================================================
--- trunk/contrib/openresolv/unbound.in	2018-06-27 12:57:52 UTC (rev 11160)
+++ trunk/contrib/openresolv/unbound.in	2018-06-27 12:58:34 UTC (rev 11161)
@@ -1,5 +1,5 @@
 #!/bin/sh
-# Copyright (c) 2009 Roy Marples
+# Copyright (c) 2009-2014 Roy Marples
 # All rights reserved
 
 # unbound subscriber for resolvconf
@@ -26,10 +26,12 @@
 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
+unbound_insecure=
+
 [ -f "@SYSCONFDIR@"/resolvconf.conf ] || exit 0
 . "@SYSCONFDIR@/resolvconf.conf" || exit 1
 [ -z "$unbound_conf" ] && exit 0
-[ -z "$RESOLVCONF" ] && eval "$(@PREFIX@/sbin/resolvconf -v)"
+[ -z "$RESOLVCONF" ] && eval "$(@SBINDIR@/resolvconf -v)"
 NL="
 "
 
@@ -41,6 +43,11 @@
 for d in $DOMAINS; do
 	dn="${d%%:*}"
 	ns="${d#*:}"
+	case "$unbound_insecure" in
+	[Yy][Ee][Ss]|[Tt][Rr][Uu][Ee]|[Oo][Nn]|1)
+		newconf="$newconf${NL}domain-insecure: \"$dn\""
+		;;
+	esac
 	newconf="$newconf${NL}forward-zone:$NL	name: \"$dn\"$NL"
 	while [ -n "$ns" ]; do
 		newconf="$newconf	forward-addr: ${ns%%,*}$NL"
@@ -56,6 +63,13 @@
 	done
 fi
 
+# Try to ensure that config dirs exist
+if type config_mkdirs >/dev/null 2>&1; then
+	config_mkdirs "$unbound_conf"
+else
+	@SBINDIR@/resolvconf -D "$unbound_conf"
+fi
+
 if [ ! -f "$unbound_conf" ] || \
 	[ "$(cat "$unbound_conf")" != "$(printf %s "$newconf")" ]
 then



More information about the Midnightbsd-cvs mailing list