summaryrefslogtreecommitdiffstats
path: root/contrib
diff options
context:
space:
mode:
authorgjb <gjb@FreeBSD.org>2015-05-11 01:33:34 +0000
committergjb <gjb@FreeBSD.org>2015-05-11 01:33:34 +0000
commit5e2ef62eeed97f6a86a3a35addc1447b975b55f9 (patch)
tree7b76f7b5d438e8bbfb15fe9670ae2a5386dfb71c /contrib
parent64ba14eeb3ccf05ac514cf82f0a3aceaefffa2dc (diff)
downloadFreeBSD-src-5e2ef62eeed97f6a86a3a35addc1447b975b55f9.zip
FreeBSD-src-5e2ef62eeed97f6a86a3a35addc1447b975b55f9.tar.gz
MFC r282434:
MFV r225523, r282431: r225523 (hrs): Import openresolv-3.4.4. r282431: Import openresolv-3.7.0. PR: 199854 Submitted by: yuri@rawbw.com Relnotes: yes Sponsored by: The FreeBSD Foundation
Diffstat (limited to 'contrib')
-rw-r--r--contrib/openresolv/GNUmakefile4
-rw-r--r--contrib/openresolv/Makefile55
-rw-r--r--contrib/openresolv/config-null.mk1
-rw-r--r--contrib/openresolv/configure135
-rw-r--r--contrib/openresolv/dnsmasq.in143
-rw-r--r--contrib/openresolv/libc.in128
-rw-r--r--contrib/openresolv/named.in14
-rw-r--r--contrib/openresolv/pdns_recursor.in72
-rw-r--r--contrib/openresolv/pdnsd.in44
-rw-r--r--contrib/openresolv/resolvconf.8.in108
-rw-r--r--contrib/openresolv/resolvconf.conf.5.in152
-rw-r--r--contrib/openresolv/resolvconf.in524
-rw-r--r--contrib/openresolv/unbound.in18
13 files changed, 1130 insertions, 268 deletions
diff --git a/contrib/openresolv/GNUmakefile b/contrib/openresolv/GNUmakefile
new file mode 100644
index 0000000..4bc845a
--- /dev/null
+++ b/contrib/openresolv/GNUmakefile
@@ -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
diff --git a/contrib/openresolv/Makefile b/contrib/openresolv/Makefile
index e4e3498..aca2cb5 100644
--- a/contrib/openresolv/Makefile
+++ b/contrib/openresolv/Makefile
@@ -1,8 +1,19 @@
-include config.mk
+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,31 +28,36 @@ TARGET= ${RESOLVCONF} ${SUBSCRIBERS}
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'
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 +65,21 @@ install: ${TARGET}
${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}
-
-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
+ rm -rf /tmp/${DISTPREFIX}
+ ${INSTALL} -d /tmp/${DISTPREFIX}
+ cp README ${SRCS} /tmp/${DISPREFIX}
+
+dist:
+ fossil tarball --name ${DISTPREFIX} ${FOSSILID} ${DISTFILEGZ}
+ gunzip -c ${DISTFILEGZ} | bzip2 >${DISTFILE}
+ rm ${DISTFILEGZ}
diff --git a/contrib/openresolv/config-null.mk b/contrib/openresolv/config-null.mk
new file mode 100644
index 0000000..6bf701d
--- /dev/null
+++ b/contrib/openresolv/config-null.mk
@@ -0,0 +1 @@
+# This space left intentionally blank
diff --git a/contrib/openresolv/configure b/contrib/openresolv/configure
index 39bdddb..190ee71 100644
--- a/contrib/openresolv/configure
+++ b/contrib/openresolv/configure
@@ -9,7 +9,7 @@ TARGET=
RESTARTCMD=
RCDIR=
-for x; do
+for x do
opt=${x%%=*}
var=${x#*=}
case "$opt" in
@@ -18,7 +18,7 @@ for x; do
--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,68 +41,76 @@ for x; do
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}
eval SYSCONFDIR="$SYSCONFDIR"
eval SBINDIR="$SBINDIR"
-eval LIBEXECDIR="$LIBEXECDIR/resolvconf"
+eval LIBEXECDIR="$LIBEXECDIR"
eval VARDIR="$RUNDIR/resolvconf"
eval MANDIR="$MANDIR"
CONFIG_MK=config.mk
if [ -z "$BUILD" ]; then
- BUILD=`uname -m`-`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
-
-# 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
+ # autoconf target triplet: cpu-vendor-os
+ BUILD=$(uname -m)-unknown-$(uname -s | tr '[:upper:]' '[:lower:]')
fi
+: ${HOST:=$BUILD}
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 @@ for x in SYSCONFDIR SBINDIR LIBEXECDIR VARDIR MANDIR; do
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 @@ if [ -z "$RESTARTCMD" ]; then
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,19 @@ if [ -z "$RESTARTCMD" ]; then
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"
+ 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"
@@ -159,7 +198,7 @@ if [ -z "$RESTARTCMD" ]; then
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 @@ if [ -z "$RESTARTCMD" ]; then
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
diff --git a/contrib/openresolv/dnsmasq.in b/contrib/openresolv/dnsmasq.in
index 178f4dd..1b6ad16 100644
--- a/contrib/openresolv/dnsmasq.in
+++ b/contrib/openresolv/dnsmasq.in
@@ -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 @@ newresolv="$newconf"
# 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 @@ for n in $NAMESERVERS; do
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 @@ if [ -n "$dnsmasq_conf" ]; then
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 @@ if $changed; then
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
diff --git a/contrib/openresolv/libc.in b/contrib/openresolv/libc.in
index cf0323e..d4f6cc9 100644
--- a/contrib/openresolv/libc.in
+++ b/contrib/openresolv/libc.in
@@ -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 @@ NL="
# 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 @@ key_get_value()
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 @@ elif [ -d "$SYSCONFDIR"/resolvconf ]; then
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 @@ fi
: ${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 @@ if [ "${resolv_conf_tail-x}" = x -a -f "$SYSCONFDIR"/resolv.conf.tail ]; then
resolv_conf_tail="$(cat "$SYSCONFDIR"/resolv.conf.tail)"
fi
+backup=true
+signature="# Generated by resolvconf"
+
uniqify()
{
local result=
@@ -104,6 +124,7 @@ uniqify()
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,31 +134,70 @@ case "${resolv_conf_passthrough:-NO}" in
[ -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 "$(@SBINDIR@/resolvconf -v)"
+ ;;
+esac
+case "${resolv_conf_passthrough:-NO}" in
+[Yy][Ee][Ss]|[Tt][Rr][Uu][Ee]|[Oo][Nn]|1) ;;
*)
- [ -z "$RESOLVCONF" ] && eval "$(@PREFIX@/sbin/resolvconf -v)"
- newsearch="$(uniqify $search_domains $SEARCH $search_domains_append)"
+ : ${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
@@ -151,6 +211,22 @@ if [ -e "$resolv_conf" ]; then
[ "$(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 @@ for script in "$LIBEXECDIR"/libc.d/*; do
if [ -x "$script" ]; then
"$script" "$@"
else
- (. "$script" "$@")
+ (. "$script")
fi
retval=$(($retval + $?))
fi
diff --git a/contrib/openresolv/named.in b/contrib/openresolv/named.in
index 47b10e0..43ceabb 100644
--- a/contrib/openresolv/named.in
+++ b/contrib/openresolv/named.in
@@ -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 @@ then
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 @@ for d in $DOMAINS; do
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
diff --git a/contrib/openresolv/pdns_recursor.in b/contrib/openresolv/pdns_recursor.in
new file mode 100644
index 0000000..2919e7d
--- /dev/null
+++ b/contrib/openresolv/pdns_recursor.in
@@ -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
diff --git a/contrib/openresolv/pdnsd.in b/contrib/openresolv/pdnsd.in
index 61dc5e1..59a4755 100644
--- a/contrib/openresolv/pdnsd.in
+++ b/contrib/openresolv/pdnsd.in
@@ -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 @@ remove_markers()
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 @@ change_file()
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 @@ if [ -n "$pdnsd_conf" ]; then
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 @@ if [ -n "$pdnsd_conf" ]; then
ns="${ns#*,}"
newconf="${newconf},"
done
- newconf="${newconf};\n}\n"
+ newconf="${newconf};$NL}$NL"
done
rm -f "$cf"
@@ -136,7 +146,7 @@ if [ -n "$pdnsd_conf" ]; then
fi
if change_file "$pdnsd_conf" "$cf"; then
changed=true
- fi
+ fi
fi
if [ -n "$pdnsd_resolv" ]; then
diff --git a/contrib/openresolv/resolvconf.8.in b/contrib/openresolv/resolvconf.8.in
index 4e6f59a..10dcf5d 100644
--- a/contrib/openresolv/resolvconf.8.in
+++ b/contrib/openresolv/resolvconf.8.in
@@ -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 @@ file to
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 @@ then
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 @@ for how to configure
.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 @@ is used to add interfaces.
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 @@ List the
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 @@ as private.
.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 @@ the operating systems lexical order.
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 @@ for the metric.
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 @@ This implementation of
.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@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 @@ will generate.
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@marples.name
-.Sh BUGS
-Please report them to http://roy.marples.name/projects/openresolv
diff --git a/contrib/openresolv/resolvconf.conf.5.in b/contrib/openresolv/resolvconf.conf.5.in
index 454aac5..d4f6543 100644
--- a/contrib/openresolv/resolvconf.conf.5.in
+++ b/contrib/openresolv/resolvconf.conf.5.in
@@ -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 @@ must contain valid shell commands.
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,16 +66,27 @@ If unset, defaults to the following:-
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
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 @@ Useful for VPN domains.
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 @@ A list of libc resolver options, as specified in
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 @@ and
.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 @@ Example resolvconf.conf for dnsmasq:
.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 @@ setup to read
.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 @@ Example pdnsd.conf:
.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 resolvconf.conf for unbound:
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@marples.name
+.An Roy Marples Aq Mt roy@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
diff --git a/contrib/openresolv/resolvconf.in b/contrib/openresolv/resolvconf.in
index 8a608d3..3b2b0f5 100644
--- a/contrib/openresolv/resolvconf.in
+++ b/contrib/openresolv/resolvconf.in
@@ -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 @@ RESOLVCONF="$0"
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 @@ elif [ -d "$SYSCONFDIR/resolvconf" ]; then
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 @@ usage()
(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 @@ usage()
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 @@ echo_resolv()
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,24 +142,34 @@ parse_resolv()
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#* }"
;;
*)
@@ -187,70 +210,243 @@ uniqify()
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 *"
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,34 +454,56 @@ make_vars()
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#*,}"
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 @@ if [ "$cmd" = I ]; then
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 @@ if [ "$cmd" = l -o "$cmd" = i ]; then
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 @@ elif [ "$cmd" != u ]; then
[ -n "$cmd" -a "$cmd" != h ] && usage "Unknown option $cmd"
usage
fi
+
if [ "$cmd" = a ]; then
for x in '/' \\ ' ' '*'; do
case "$iface" in
@@ -331,78 +556,198 @@ if [ "$cmd" = a ]; then
[ "$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
[ -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
@@ -410,10 +755,15 @@ export RESOLVCONF DOMAINS SEARCH NAMESERVERS LOCALNAMESERVERS
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
diff --git a/contrib/openresolv/unbound.in b/contrib/openresolv/unbound.in
index aa04a31..5752e6f 100644
--- a/contrib/openresolv/unbound.in
+++ b/contrib/openresolv/unbound.in
@@ -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 @@ newconf="# Generated by resolvconf$NL"
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 @@ if [ -n "$NAMESERVERS" ]; then
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
OpenPOWER on IntegriCloud