Import openresolv-3.4.1.

This commit is contained in:
Hajimu UMEMOTO 2011-03-18 10:35:54 +00:00
commit 8e56b8ee7b
12 changed files with 1727 additions and 0 deletions

66
Makefile Normal file
View File

@ -0,0 +1,66 @@
include config.mk
NAME= openresolv
VERSION= 3.4.1
PKG= ${NAME}-${VERSION}
INSTALL?= install
SED?= sed
BINMODE?= 0755
DOCMODE?= 0644
MANMODE?= 0444
RESOLVCONF= resolvconf resolvconf.8 resolvconf.conf.5
SUBSCRIBERS= libc dnsmasq named pdnsd unbound
TARGET= ${RESOLVCONF} ${SUBSCRIBERS}
SRCS= ${TARGET:C,$,.in,} # pmake
SRCS:= ${TARGET:=.in} # gmake
SED_PREFIX= -e 's:@PREFIX@:${PREFIX}: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'
.SUFFIXES: .in
all: ${TARGET}
.in:
${SED} ${SED_PREFIX} ${SED_SYSCONFDIR} ${SED_LIBEXECDIR} \
${SED_VARDIR} ${SED_RCDIR} ${SED_RESTARTCMD} \
$< > $@
clean:
rm -f ${TARGET} openresolv-${VERSION}.tar.bz2
distclean: clean
rm -f config.mk
installdirs:
install: ${TARGET}
${INSTALL} -d ${DESTDIR}${SBINDIR}
${INSTALL} -m ${BINMODE} resolvconf ${DESTDIR}${SBINDIR}
${INSTALL} -d ${DESTDIR}${SYSCONFDIR}
test -e ${DESTDIR}${SYSCONFDIR}/resolvconf.conf || \
${INSTALL} -m ${DOCMODE} resolvconf.conf ${DESTDIR}${SYSCONFDIR}
${INSTALL} -d ${DESTDIR}${LIBEXECDIR}
${INSTALL} -m ${DOCMODE} ${SUBSCRIBERS} ${DESTDIR}${LIBEXECDIR}
${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
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

11
README Normal file
View File

@ -0,0 +1,11 @@
openresolv is a resolvconf implementation which manages resolv.conf
You can find the latest version at http://roy.marples.name/projects/openresolv
It is written and maintained by Roy Marples <roy@marples.name>
This resolvconf implementation, along with its subscribers, work with a
POSIX compliant shell and userland utilities. It is designed to work without
tools such as sed as it *has* to work without /usr being available.
On systems where resolvconf is expected to be used before /var/run is available
for writing, you can configure openresolv to write somewhere else, like say a
ramdisk.

186
configure vendored Normal file
View File

@ -0,0 +1,186 @@
#!/bin/sh
# Try and be like autotools configure, but without autotools
# Ensure that we do not inherit these from env
OS=
BUILD=
HOST=
TARGET=
RESTARTCMD=
RCDIR=
for x; do
opt=${x%%=*}
var=${x#*=}
case "$opt" in
--os|OS) OS=$var;;
--with-cc|CC) CC=$var;;
--debug) DEBUG=$var;;
--disable-debug) DEBUG=no;;
--enable-debug) DEBUG=yes;;
--prefix) prefix=$var;;
--sysconfdir) SYSCONFDIR=$var;;
--bindir|--sbindir) SBINDIR=$var;;
--libexecdir) LIBEXECDIR=$var;;
--statedir|--localstatedir) STATEDIR=$var;;
--dbdir) DBDIR=$var;;
--rundir) RUNDIR=$var;;
--mandir) MANDIR=$var;;
--with-ccopts|CFLAGS) CFLAGS=$var;;
CPPFLAGS) CPPFLAGS=$var;;
--build) BUILD=$var;;
--host) HOST=$var;;
--target) TARGET=$var;;
--libdir) LIBDIR=$var;;
--restartcmd) RESTARTCMD=$var;;
--includedir) eval INCLUDEDIR="$INCLUDEDIR${INCLUDEDIR:+ }$var";;
--datadir|--infodir) ;; # ignore autotools
--disable-maintainer-mode|--disable-dependency-tracking) ;;
--help) echo "See the README file for available options"; exit 0;;
*) echo "$0: WARNING: unknown option $opt" >&2;;
esac
done
: ${SED:=sed}
: ${PREFIX:=$prefix}
: ${SYSCONFDIR:=$PREFIX/etc}
: ${SBINDIR:=$PREFIX/sbin}
: ${LIBEXECDIR:=$PREFIX/libexec}
: ${STATEDIR:=/var}
: ${RUNDIR:=$STATEDIR/run}
: ${MANDIR:=${PREFIX:-/usr}/share/man}
eval SYSCONFDIR="$SYSCONFDIR"
eval SBINDIR="$SBINDIR"
eval LIBEXECDIR="$LIBEXECDIR/resolvconf"
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
fi
if [ -z "$OS" ]; then
# Derive OS from cpu-manufacturer-os-kernel
CPU=${TARGET%%-*}
REST=${TARGET#*-}
if [ "$CPU" != "$REST" ]; then
MANU=${REST%%-*}
REST=${REST#*-}
if [ "$MANU" != "$REST" ]; then
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=
fi
fi
fi
echo "Configuring openresolv for ... $OS"
rm -rf $CONFIG_MK
echo "# $OS" >$CONFIG_MK
for x in SYSCONFDIR SBINDIR LIBEXECDIR VARDIR MANDIR; do
eval v=\$$x
# Make files look nice for import
l=$((10 - ${#x}))
unset t
[ $l -gt 3 ] && t=" "
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"
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"
echo "yes"
else
echo "no"
fi
fi
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"
echo "yes"
else
echo "no"
fi
fi
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"
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"
echo "yes"
break
else
echo "no"
fi
done
fi
if [ -z "$RESTARTCMD" ]; then
echo "WARNING! No means of interacting with system services detected!"
exit 1
fi
echo "RCDIR= $RCDIR" >>$CONFIG_MK
# Work around bug in the dash shell as "echo 'foo \1'" does bad things
printf "%s\n" "RESTARTCMD= $RESTARTCMD" >>$CONFIG_MK
echo
echo " SYSCONFDIR = $SYSCONFDIR"
echo " SBINDIR = $SBINDIR"
echo " LIBEXECDIR = $LIBEXECDIR"
echo " VARDIR = $RUNDIR"
echo " MANDIR = $MANDIR"
echo

125
dnsmasq.in Normal file
View File

@ -0,0 +1,125 @@
#!/bin/sh
# Copyright (c) 2007-2009 Roy Marples
# All rights reserved
# dnsmasq 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 "$dnsmasq_conf" -a -z "$dnsmasq_resolv" ] && exit 0
[ -z "$RESOLVCONF" ] && eval "$(@PREFIX@/sbin/resolvconf -v)"
: ${dnsmasq_pid:=/var/run/dnsmasq.pid}
[ -s "$dnsmasq_pid" ] || dnsmasq_pid=/var/run/dnsmasq/dnsmasq.pid
: ${dnsmasq_service:=dnsmasq}
: ${dnsmasq_restart:=@RESTARTCMD ${dnsmasq_service}@}
newconf="# Generated by resolvconf\n"
newresolv="$newconf"
# Using dbus means that we never have to restart the daemon
# This is important as it means we should not drop DNS queries
# whilst changing DNS options around. However, dbus support is optional
# 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:]]"
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\n# Domain specific servers will"
newconf="$newconf be sent over dbus\nenable-dbus\n"
fi
fi
fi
for n in $NAMESERVERS; do
newresolv="${newresolv}nameserver $n\n"
done
dbusdest=
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%%,*}\n"
fi
[ "$ns" = "${ns#*,}" ] && break
ns="${ns#*,}"
done
done
changed=false
if [ -n "$dnsmasq_conf" ]; then
if [ ! -f "$dnsmasq_conf" ] || \
[ "$(cat "$dnsmasq_conf")" != "$(printf "$newconf")" ]
then
changed=true
printf "$newconf" >"$dnsmasq_conf"
fi
fi
if [ -n "$dnsmasq_resolv" ]; then
if [ -f "$dnsmasq_resolv" ]; then
if [ "$(cat "$dnsmasq_resolv")" != "$(printf "$newresolv")" ]
then
changed=true
printf "$newresolv" >"$dnsmasq_resolv"
fi
else
# dnsmasq polls this file so no need to set changed=true
printf "$newresolv" >"$dnsmasq_resolv"
fi
fi
if $changed; then
eval $dnsmasq_restart
fi
if $dbus; then
$changed || kill -HUP $(cat "$dnsmasq_pid")
# Send even if empty so old servers are cleared
dbus-send --system --dest=uk.org.thekelleys.dnsmasq \
/uk/org/thekelleys/dnsmasq uk.org.thekelleys.SetServers \
$dbusdest
fi

168
libc.in Normal file
View File

@ -0,0 +1,168 @@
#!/bin/sh
# Copyright (c) 2007-2009 Roy Marples
# All rights reserved
# libc 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.
SYSCONFDIR=@SYSCONFDIR@
LIBEXECDIR=@LIBEXECDIR@
VARDIR=@VARDIR@
IFACEDIR="$VARDIR/interfaces"
# sed may not be available, and this is faster on small files
key_get_value()
{
local key="$1" value= x= line=
shift
if [ $# -eq 0 ]; then
while read line; do
case "$line" in
"$key"*) echo "${line##$key}";;
esac
done
else
for x; do
while read line; do
case "$line" in
"$key"*) echo "${line##$key}";;
esac
done < "$x"
done
fi
}
# Support original resolvconf configuration layout
# as well as the openresolv config file
if [ -f "$SYSCONFDIR"/resolvconf.conf ]; then
. "$SYSCONFDIR"/resolvconf.conf
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
resolv_conf_options="$(key_get_value "options " "$base")"
fi
if [ -f "$SYSCONFDIR"/resolv.conf.d/head ]; then
resolv_conf_head="$(cat "${SYSCONFDIR}"/resolv.conf.d/head)"
fi
if [ -f "$SYSCONFDIR"/resolv.conf.d/tail ]; then
resolv_conf_tail="$(cat "$SYSCONFDIR"/resolv.conf.d/tail)"
fi
fi
: ${resolv_conf:=/etc/resolv.conf}
: ${libc_service:=nscd}
: ${libc_restart:=@RESTARTCMD ${libc_service}@}
: ${list_resolv:=@PREFIX@/sbin/resolvconf -l}
if [ "${resolv_conf_head-x}" = x -a -f "$SYSCONFDIR"/resolv.conf.head ]; then
resolv_conf_head="$(cat "${SYSCONFDIR}"/resolv.conf.head)"
fi
if [ "${resolv_conf_tail-x}" = x -a -f "$SYSCONFDIR"/resolv.conf.tail ]; then
resolv_conf_tail="$(cat "$SYSCONFDIR"/resolv.conf.tail)"
fi
uniqify()
{
local result=
while [ -n "$1" ]; do
case " $result " in
*" $1 "*);;
*) result="$result $1";;
esac
shift
done
echo "${result# *}"
}
case "${resolv_conf_passthrough:-NO}" in
[Yy][Ee][Ss]|[Tt][Rr][Uu][Ee]|[Oo][Nn]|1)
newest=
for conf in "$IFACEDIR"/*; do
if [ -z "$newest" -o "$conf" -nt "$newest" ]; then
newest="$conf"
fi
done
[ -z "$newest" ] && exit 0
newconf="$(cat "$newest")\n"
;;
*)
[ -z "$RESOLVCONF" ] && eval "$(@PREFIX@/sbin/resolvconf -v)"
newsearch="$(uniqify $search_domains $SEARCH $search_domains_append)"
NS="$LOCALNAMESERVERS $NAMESERVERS"
newns="$(uniqify $name_servers $NS $name_servers_append)"
# Hold our new resolv.conf in a variable to save on temporary files
newconf="# Generated by resolvconf\n"
if [ -n "$resolv_conf_head" ]; then
newconf="$newconf$resolv_conf_head\n"
fi
[ -n "$newsearch" ] && newconf="${newconf}search $newsearch\n"
for n in $newns; do
newconf="${newconf}nameserver $n\n"
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\n"
fi
if [ -n "$resolv_conf_tail" ]; then
newconf="$newconf$resolv_conf_tail\n"
fi
;;
esac
# Check if the file has actually changed or not
if [ -e "$resolv_conf" ]; then
[ "$(cat "$resolv_conf")" = "$(printf "$newconf")" ] && exit 0
fi
# Create our resolv.conf now
(umask 022; printf "$newconf" >"$resolv_conf")
eval $libc_restart
retval=0
# Notify users of the resolver
for script in "$LIBEXECDIR"/libc.d/*; do
if [ -f "$script" ]; then
if [ -x "$script" ]; then
"$script" "$@"
else
(. "$script" "$@")
fi
retval=$(($retval + $?))
fi
done
exit $retval

94
named.in Normal file
View File

@ -0,0 +1,94 @@
#!/bin/sh
# Copyright (c) 2007-2009 Roy Marples
# All rights reserved
# named 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 "$named_zones" -a -z "$named_options" ] && exit 0
[ -z "$RESOLVCONF" ] && eval "$(@PREFIX@/sbin/resolvconf -v)"
# Platform specific kludges
if [ -z "$named_service" -a -z "$named_restart" -a \
-d "@RCDIR@" -a ! -x "@RCDIR@"/named ]
then
if [ -x "@RCDIR@"/bind9 ]; then
# Debian and derivatives
named_service=bind9
fi
fi
: ${named_service:=named}
: ${named_restart:=@RESTARTCMD ${named_service}@}
newoptions="# Generated by resolvconf\n"
newzones="$newoptions"
forward=
for n in $NAMESERVERS; do
case "$forward" in
*"\n\t$n;"*);;
*) forward="$forward\n\t$n;";;
esac
done
if [ -n "$forward" ]; then
newoptions="${newoptions}forward first;\nforwarders {$forward\n};\n"
fi
for d in $DOMAINS; do
newzones="${newzones}zone \"${d%%:*}\" {\n"
newzones="$newzones\ttype forward;\n"
newzones="$newzones\tforward first;\n\tforwarders {\n"
ns="${d#*:}"
while [ -n "$ns" ]; do
newzones="$newzones\t\t${ns%%,*};\n"
[ "$ns" = "${ns#*,}" ] && break
ns="${ns#*,}"
done
newzones="$newzones\t};\n};\n"
done
# No point in changing files or reloading bind if the end result has not
# changed
changed=false
if [ -n "$named_options" ]; then
if [ ! -f "$named_options" ] || \
[ "$(cat "$named_options")" != "$(printf "$newoptions")" ]
then
printf "$newoptions" >"$named_options"
changed=true
fi
fi
if [ -n "$named_zones" ]; then
if [ ! -f "$named_zones" ] || \
[ "$(cat "$named_zones")" != "$(printf "$newzones")" ]
then
printf "$newzones" >"$named_zones"
changed=true
fi
fi
if $changed; then
eval $named_restart
fi

153
pdnsd.in Normal file
View File

@ -0,0 +1,153 @@
#!/bin/sh
# Copyright (c) 2010 Roy Marples
# All rights reserved
# pdnsd 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 "$pdnsd_conf" -a -z "$pdnsd_resolv" ] && exit 0
[ -z "$RESOLVCONF" ] && eval "$(@PREFIX@/sbin/resolvconf -v)"
: ${pdnsd_restart:=pdnsd-ctl config $pdnsd_conf}
signature="# Generated by resolvconf"
signature_end="# End of resolvconf"
# We normally use sed to remove markers from a configuration file
# but sed may not always be available at the time.
remove_markers()
{
local m1="$1" m2="$2" x= line= in_marker=0
shift; shift
if type sed >/dev/null 2>&1; then
sed "/^$m1/,/^$m2/d" $@
else
for x; do
while read line; do
case "$line" in
"$m1"*) in_marker=1;;
"$m2"*) in_marker=0;;
*) [ $in_marker = 0 ] && echo "$line";;
esac
done < "$x"
done
fi
}
# Compare two files
# If different, replace first with second otherwise remove second
change_file()
{
if [ -e "$1" ]; then
if type cmp >/dev/null 2>&1; then
cmp -s "$1" "$2"
elif type diff >/dev/null 2>&1; then
diff -q "$1" "$2" >/dev/null
else
# Hopefully we're only working on small text files ...
[ "$(cat "$1")" = "$(cat "$2")" ]
fi
if [ $? -eq 0 ]; then
rm -f "$2"
return 1
fi
fi
cat "$2" > "$1"
rm -f "$2"
return 0
}
newresolv="# Generated by resolvconf\n"
changed=false
if [ -n "$pdnsd_resolv" ]; then
for n in $NAMESERVERS; do
newresolv="${newresolv}nameserver $n\n"
done
fi
if [ -n "$pdnsd_conf" ]; then
cf="$pdnsd_conf.new"
newconf=
if [ -z "$pdnsd_resolv" ]; then
newconf="${newconf}server {\n"
newconf="${newconf}\tlabel=resolvconf;\n"
if [ -n "$NAMESERVERS" ]; then
newconf="${newconf}\tip="
first=true
for n in $NAMESERVERS; do
if $first; then
first=false
else
newconf="${newconf},"
fi
newconf="$newconf$n"
done
newconf="${newconf};\n"
fi
newconf="${newconf}}\n"
fi
for d in $DOMAINS; do
newconf="${newconf}server {\n"
newconf="${newconf}\tinclude=.${d%%:*}.;\n"
newconf="${newconf}\tpolicy=excluded;\n"
newconf="${newconf}\tip="
ns="${d#*:}"
while [ -n "$ns" ]; do
newconf="${newconf}${ns%%,*}"
[ "$ns" = "${ns#*,}" ] && break
ns="${ns#*,}"
newconf="${newconf},"
done
newconf="${newconf};\n}\n"
done
rm -f "$cf"
remove_markers "$signature" "$signature_end" "$pdnsd_conf" > "$cf"
if [ -n "$newconf" ]; then
echo "$signature" >> "$cf"
printf "$newconf" >> "$cf"
echo "$signature_end" >> "$cf"
fi
if change_file "$pdnsd_conf" "$cf"; then
changed=true
fi
fi
if [ -n "$pdnsd_resolv" ]; then
if [ ! -f "$pdnsd_resolv" ] || \
[ "$(cat "$pdnsd_resolv")" != "$(printf "$newresolv")" ]
then
changed=true
printf "$newresolv" >"$pdnsd_resolv"
fi
fi
if $changed; then
eval $pdnsd_restart
fi

240
resolvconf.8.in Normal file
View File

@ -0,0 +1,240 @@
.\" Copyright (c) 2007-2009 Roy Marples
.\" All rights reserved
.\"
.\" Redistribution and use in source and binary forms, with or without
.\" modification, are permitted provided that the following conditions
.\" are met:
.\" 1. Redistributions of source code must retain the above copyright
.\" notice, this list of conditions and the following disclaimer.
.\" 2. 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 AUTHOR 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 AUTHOR 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.
.\"
.Dd December 3, 2009
.Dt RESOLVCONF 8 SMM
.Os
.Sh NAME
.Nm resolvconf
.Nd a framework for managing multiple DNS configurations
.Sh SYNOPSIS
.Nm
.Fl I
.Nm
.Op Fl m Ar metric
.Op Fl p
.Fl a Ar interface No < Ns Pa file
.Nm
.Op Fl f
.Fl d Ar interface
.Nm
.Fl il Ar pattern
.Nm
.Fl u
.Sh DESCRIPTION
.Nm
manages
.Xr resolv.conf 5
files from multiple sources, such as DHCP and VPN clients.
Traditionally, the host runs just one client and that updates
.Pa /etc/resolv.conf .
More modern systems frequently have wired and wireless interfaces and there is
no guarantee both are on the same network.
With the advent of VPN and other
types of networking daemons, many things now contend for the contents of
.Pa /etc/resolv.conf .
.Pp
.Nm
solves this by letting the daemon send their
.Xr resolv.conf 5
file to
.Nm
via
.Xr stdin 3
with the argument
.Fl a Ar interface
instead of the filesystem.
.Nm
then updates
.Pa /etc/resolv.conf
as it thinks best.
When a local resolver other than libc is installed, such as
.Xr dnsmasq 8
or
.Xr named 8 ,
then
.Nm
will supply files that the resolver should be configured to include.
.Pp
.Nm
can mark an interfaces
.Pa resolv.conf
as private.
This means that the name servers listed in that
.Pa resolv.conf
are only used for queries against the domain/search listed in the same file.
This only works when a local resolver other than libc is installed.
See
.Xr resolvconf.conf 5
for how to configure
.Nm
to use a local name server.
.Pp
When an interface goes down, it should then call
.Nm
with
.Fl d Ar interface
arguments to delete the
.Pa resolv.conf
file for the
.Ar interface .
.Pp
Here are some more options that
.Nm
has:-
.Bl -tag -width indent
.It Fl I
Initialise the state directory
.Pa @VARDIR@ .
This only needs to be called if the initial system boot sequence does not
automatically clean it out; for example the state directory is moved
somewhere other than
.Pa /var/run .
If used, it should only be called once as early in the system boot sequence
as possible and before
.Nm
is used to add interfaces.
.It Fl f
Ignore non existant interfaces.
Only really useful for deleting interfaces.
.It Fl i Ar pattern
List the interfaces, optionally matching
.Ar pattern ,
we have
.Pa resolv.conf
files for.
.It Fl l Ar pattern
List the
.Pa resolv.conf
files we have.
If
.Ar pattern
is specified then we list the files for the interfaces that match it.
.It Fl m Ar metric
Set the metric of the interface when adding it, default of 0.
Lower metrics take precedence.
This affects the default order of interfaces when listed.
.It Fl p
Marks the interface
.Pa resolv.conf
as private.
.It Fl u
Force
.Nm
to update all it's subscribers.
.Nm
does not update the subscribers when adding a resolv.conf that matches
what it already has for that interface.
.El
.Pp
.Nm
also has some options designed to be used by it's subscribers:-
.Bl -tag -width indent
.It Fl v
Echo variables DOMAINS, SEARCH and NAMESERVERS so that the subscriber can
configure the resolver easily.
.El
.Sh INTERFACE ORDERING
For
.Nm
to work effectively, it has to process the resolv.confs for the interfaces
in the correct order.
.Nm
first processes interfaces from the
.Sy interface_order
list, then interfaces without a metic and that match the
.Sy dynamic_order
list, then interfaces with a metric in order and finally the rest in
the operating systems lexical order.
See
.Xr resolvconf.conf 5
for details on these lists.
.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
subshell.
This is done so that subscribers can remain fast, but are also not limited
to the shell language.
.Pp
Portable subscribers should not use anything outside of
.Pa /bin
and
.Pa /sbin
because
.Pa /usr
and others may not be available when booting.
Also, it would be unwise to assume any shell specific features.
.Sh ENVIRONMENT
.Bl -ohang
.It Va IF_METRIC
If the
.Fl m
option is not present then we use
.Va IF_METRIC
for the metric.
.It Va IF_PRIVATE
Marks the interface
.Pa resolv.conf
as private.
.El
.Sh FILES
.Bl -ohang
.It Pa @SYSCONFDIR@/resolvconf.conf
Configuration file for
.Nm .
.It Pa @LIBEXECDIR@
Directory of subscribers which are run every time
.Nm
adds, deletes or updates.
.It Pa @LIBEXECDIR@/libc.d
Directory of subscribers which are run after the libc subscriber is run.
.It Pa @VARDIR@
State directory for
.Nm .
.El
.Sh HISTORY
This implementation of
.Nm
is called openresolv and is fully command line compatible with Debian's
resolvconf, as written by Thomas Hood.
.Sh BUGS
.Nm
does not validate any of the files given to it.
.Pp
When running a local resolver other than libc, you will need to configure it
to include files that
.Nm
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

7
resolvconf.conf Normal file
View File

@ -0,0 +1,7 @@
# Configuration for resolvconf(8)
# See resolvconf.conf(5) for details
resolv_conf=/etc/resolv.conf
# If you run a local name server, you should uncomment the below line and
# configure your subscribers configuration files below.
#name_servers=127.0.0.1

187
resolvconf.conf.5.in Normal file
View File

@ -0,0 +1,187 @@
.\" Copyright (c) 2009-2010 Roy Marples
.\" All rights reserved
.\"
.\" Redistribution and use in source and binary forms, with or without
.\" modification, are permitted provided that the following conditions
.\" are met:
.\" 1. Redistributions of source code must retain the above copyright
.\" notice, this list of conditions and the following disclaimer.
.\" 2. 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 AUTHOR 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 AUTHOR 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.
.\"
.Dd October 29, 2010
.Dt RESOLVCONF.CONF 5 SMM
.Os
.Sh NAME
.Nm resolvconf.conf
.Nd resolvconf configuration file
.Sh DESCRIPTION
.Nm
is the configuration file for
.Xr resolvconf 8 .
The
.Nm
file is a shell script that is sourced by
.Xr resolvconf 8 ,
meaning that
.Nm
must contain valid shell commands.
Listed below are the standard
.Nm
variables that may be set.
.Pp
After updaing this file, you may wish to run
.Nm resolvconf -u
to apply the new configuration.
.Sh RESOLVCONF OPTIONS
.Bl -tag -width indent
.It Sy interface_order
These interfaces will always be processed first.
If unset, defaults to the following:-
.D1 lo lo[0-9]*
.It Sy dynamic_order
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 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 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 private_interfaces
These interfaces name servers will only be queried for the domains listed
in their resolv.conf.
Useful for VPN domains.
This is equivalent to the
.Nm resolvconf -p
option.
.It Sy state_dir
Override the default state directory of
.Pa @VARDIR@ .
This should not be changed once
.Nm resolvconf
is in use unless the old directory is copied to the new one.
.El
.Sh LIBC OPTIONS
The following variables affect
.Xr resolv.conf 5
directly:-
.Bl -tag -width indent
.It Sy resolv_conf
Defaults to
.Pa /etc/resolv.conf
if not set.
.It Sy resolv_conf_options
A list of libc resolver options, as specified in
.Xr resolv.conf 5 .
.It Sy resolv_conf_passthrough
When set to YES the latest resolv.conf is written to
.Sy resolv_conf
without any alteration.
.El
.Sh SUBSCRIBER OPTIONS
openresolv ships with subscribers for the name servers
.Xr dnsmasq 8 ,
.Xr named 8 ,
.Xr pdnsd 8
and
.Xr unbound 8 .
Each subscriber can create configuration files which should be included in
in the subscribers main configuration file.
.Bl -tag -width indent
.It Sy dnsmasq_conf
This file tells dnsmasq which nameservers to use for specific domains.
.It Sy dnsmasq_resolv
This file tells dnsmasq which nameservers to use for global lookups.
.Pp
Example resolvconf.conf for dnsmasq:
.D1 nameservers=127.0.0.1
.D1 dnsmasq_conf=/etc/dnsmasq-conf.conf
.D1 dnsmasq_resolv=/etc/dnsmasq-resolv.conf
.Pp
Example dnsmasq.conf:
.D1 listen-address=127.0.0.1
.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.
.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.
.Pp
Example resolvconf.conf for named:
.D1 nameservers=127.0.0.1
.D1 named_options=/etc/named-options.conf
.D1 named_zones=/etc/named-zones.conf
.Pp
Example named.conf:
.D1 options {
.D1 listen-on { 127.0.0.1; };
.D1 include "/etc/named-options.conf";
.D1 };
.D1 include "/etc/named-zones.conf";
.It Sy pdnsd_conf
This is the main pdnsd configuration file which we modify to add our
forward domains to.
If this variable is not set then we rely on the pdnsd configuration file
setup to read
.Pa pdnsd_resolv
as documented below.
.It Sy pdnsd_resolv
This file tells pdnsd about global nameservers.
If this variable is not set then it's written to
.Pa pdnsd_conf .
.Pp
Example resolvconf.conf for pdnsd:
.D1 nameservers=127.0.0.1
.D1 pdnsd_conf=/etc/pdnsd.conf
.D1 # pdnsd_resolv=/etc/pdnsd-resolv.conf
.Pp
Example pdnsd.conf:
.D1 global {
.D1 server_ip = 127.0.0.1;
.D1 status_ctl = on;
.D1 }
.D1 server {
.D1 # A server definition is required, even if emtpy.
.D1 label="empty";
.D1 proxy_only=on;
.D1 # file="/etc/pdnsd-resolv.conf";
.D1 }
.It Sy unbound_conf
This file tells unbound about specific and global nameservers.
.Pp
Example resolvconf.conf for unbound:
.D1 nameservers=127.0.0.1
.D1 unbound_conf=/etc/unbound-resolvconf.conf
.Pp
Example unbound.conf:
.D1 include: /etc/unbound-resolvconf.conf
.El
.Sh SEE ALSO
.Xr resolv.conf 5
and
.Xr resolvconf 8 .
.Sh AUTHORS
.An Roy Marples Aq roy@marples.name
.Sh BUGS
Please report them to http://roy.marples.name/projects/openresolv

421
resolvconf.in Normal file
View File

@ -0,0 +1,421 @@
#!/bin/sh
# Copyright (c) 2007-2009 Roy Marples
# All rights reserved
# 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.
RESOLVCONF="$0"
SYSCONFDIR=@SYSCONFDIR@
LIBEXECDIR=@LIBEXECDIR@
VARDIR=@VARDIR@
# Support original resolvconf configuration layout
# as well as the openresolv config file
if [ -f "$SYSCONFDIR"/resolvconf.conf ]; then
. "$SYSCONFDIR"/resolvconf.conf
[ -n "$state_dir" ] && VARDIR="$state_dir"
elif [ -d "$SYSCONFDIR/resolvconf" ]; then
SYSCONFDIR="$SYSCONFDIR/resolvconf"
if [ -f "$SYSCONFDIR"/interface-order ]; then
interface_order="$(cat "$SYSCONFDIR"/interface-order)"
fi
fi
IFACEDIR="$VARDIR/interfaces"
METRICDIR="$VARDIR/metrics"
PRIVATEDIR="$VARDIR/private"
: ${dynamic_order:=tap[0-9]* tun[0-9]* vpn vpn[0-9]* ppp[0-9]* ippp[0-9]*}
: ${interface_order:=lo lo[0-9]*}
error_exit()
{
echo "$*" >&2
exit 1
}
usage()
{
cat <<-EOF
Usage: ${RESOLVCONF##*/} [options]
Inform the system about any DNS updates.
Options:
-a \$INTERFACE Add DNS information to the specified interface
(DNS supplied via stdin in resolv.conf format)
-m metric Give the added DNS information a metric
-p Mark the interface as private
-d \$INTERFACE Delete DNS information from the specified interface
-f Ignore non existant interfaces
-I Init the state dir
-u Run updates from our current DNS information
-l [\$PATTERN] Show DNS information, optionally from interfaces
that match the specified pattern
-i [\$PATTERN] Show interfaces that have supplied DNS information
optionally from interfaces that match the specified
pattern
-v [\$PATTERN] echo NEWDOMAIN, NEWSEARCH and NEWNS variables to
the console
-h Show this help cruft
EOF
[ -z "$1" ] && exit 0
echo
error_exit "$*"
}
echo_resolv()
{
local line=
[ -n "$1" -a -e "$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"
done < "$IFACEDIR/$1"
echo
}
# Parse resolv.conf's and make variables
# for domain name servers, search name servers and global nameservers
parse_resolv()
{
local line= ns= ds= search= d= n= newns=
local new=true iface= private=false p=
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
case "$line" in
"# resolv.conf from "*)
if ${new}; then
iface="${line#\# resolv.conf from *}"
new=false
if [ -e "$PRIVATEDIR/$iface" ]; then
private=true
else
# Allow expansion
cd "$IFACEDIR"
private=false
for p in $private_interfaces; do
if [ "$p" = "$iface" ]; then
private=true
break
fi
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#* } "
;;
"domain "*|"search "*)
search="${line#* }"
;;
*)
[ -n "$line" ] && continue
if [ -n "$ns" -a -n "$search" ]; then
newns=
for n in $ns; do
newns="$newns${newns:+,}$n"
done
ds=
for d in $search; do
ds="$ds${ds:+ }$d:$newns"
done
echo "DOMAINS=\"\$DOMAINS $ds\""
fi
echo "SEARCH=\"\$SEARCH $search\""
if ! $private; then
echo "NAMESERVERS=\"\$NAMESERVERS $ns\""
fi
ns=
search=
new=true
;;
esac
done
}
uniqify()
{
local result=
while [ -n "$1" ]; do
case " $result " in
*" $1 "*);;
*) result="$result $1";;
esac
shift
done
echo "${result# *}"
}
list_resolv()
{
[ -d "$IFACEDIR" ] || return 0
local report=false list= retval=0 cmd="$1"
shift
# 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="$@"
$force || report=true
else
cd "$IFACEDIR"
for i in $interface_order; do
[ -e "$i" ] && list="$list $i"
done
for i in $dynamic_order; do
if [ -e "$i" -a ! -e "$METRICDIR/"*" $i" ]; then
list="$list $i"
fi
done
if [ -d "$METRICDIR" ]; then
cd "$METRICDIR"
for i in *; do
list="$list ${i#* }"
done
fi
list="$list *"
fi
cd "$IFACEDIR"
for i in $(uniqify $list); do
# Only list interfaces which we really have
if ! [ -e "$i" ]; then
if $report; then
echo "No resolv.conf for interface $i" >&2
retval=$(($retval + 1))
fi
continue
fi
if [ "$cmd" = i -o "$cmd" = "-i" ]; then
printf "$i "
else
echo_resolv "$i"
fi
done
[ "$cmd" = i -o "$cmd" = "-i" ] && echo
return $retval
}
make_vars()
{
eval "$(list_resolv -l "$@" | parse_resolv)"
# Ensure that we only list each domain once
newdomains=
for d in $DOMAINS; do
dn="${d%%:*}"
case " $newdomains" in
*" ${dn}:"*) continue;;
esac
newdomains="$newdomains${newdomains:+ }$dn:"
newns=
for nd in $DOMAINS; do
if [ "$dn" = "${nd%%:*}" ]; then
ns="${nd#*:}"
while [ -n "$ns" ]; do
case ",$newns," in
*,${ns%%,*},*) ;;
*) newns="$newns${newns:+,}${ns%%,*}";;
esac
[ "$ns" = "${ns#*,}" ] && break
ns="${ns#*,}"
done
fi
done
newdomains="$newdomains$newns"
done
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
case "$OPT" in
f) force=true;;
h) usage;;
m) IF_METRIC="$OPTARG";;
p) IF_PRIVATE=1;;
'?') ;;
*) cmd="$OPT"; iface="$OPTARG";;
esac
done
shift $(($OPTIND - 1))
args="$iface${iface:+ }$@"
# -I inits the state dir
if [ "$cmd" = I ]; then
if [ -d "$VARDIR" ]; then
rm -rf "$VARDIR"/*
fi
exit $?
fi
# -l lists our resolv files, optionally for a specific interface
if [ "$cmd" = l -o "$cmd" = i ]; then
list_resolv "$cmd" "$args"
exit $?
fi
# Not normally needed, but subscribers should be able to run independently
if [ "$cmd" = v ]; then
make_vars "$iface"
exit $?
fi
# Test that we have valid options
if [ "$cmd" = a -o "$cmd" = d ]; then
if [ -z "$iface" ]; then
usage "Interface not specified"
fi
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
*[$x]*) error_exit "$x not allowed in interface name";;
esac
done
for x in '.' '-' '~'; do
case "$iface" in
[$x]*) error_exit \
"$x not allowed at start of interface name";;
esac
done
[ "$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
fi
fi
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
fi
fi
if [ "$cmd" = a ]; then
# Read resolv.conf from stdin
resolv="$(cat)\n"
# If what we are given matches what we have, then do nothing
if [ -e "$IFACEDIR/$iface" ]; then
if [ "$(printf "$resolv")" = \
"$(cat "$IFACEDIR/$iface")" ]
then
exit 0
fi
rm "$IFACEDIR/$iface"
fi
printf "$resolv" >"$IFACEDIR/$iface" || exit $?
[ ! -d "$METRICDIR" ] && mkdir "$METRICDIR"
rm -f "$METRICDIR/"*" $iface"
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"
fi
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
[ -d "$PRIVATEDIR" ] && echo " " >"$PRIVATEDIR/$iface"
;;
*)
if [ -e "$PRIVATEDIR/$iface" ]; then
rm -f "$PRIVATEDIR/$iface"
fi
;;
esac
fi
eval "$(make_vars)"
export RESOLVCONF DOMAINS SEARCH NAMESERVERS LOCALNAMESERVERS
: ${list_resolv:=list_resolv -l}
retval=0
for script in "$LIBEXECDIR"/*; do
if [ -f "$script" ]; then
if [ -x "$script" ]; then
"$script" "$cmd" "$iface"
else
(. "$script" "$cmd" "$iface")
fi
retval=$(($retval + $?))
fi
done
exit $retval

69
unbound.in Normal file
View File

@ -0,0 +1,69 @@
#!/bin/sh
# Copyright (c) 2009 Roy Marples
# All rights reserved
# unbound 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 "$unbound_conf" ] && exit 0
[ -z "$RESOLVCONF" ] && eval "$(@PREFIX@/sbin/resolvconf -v)"
: ${unbound_pid:=/var/run/unbound.pid}
: ${unbound_service:=unbound}
: ${unbound_restart:=@RESTARTCMD ${unbound_service}@}
newconf="# Generated by resolvconf\n"
for d in $DOMAINS; do
dn="${d%%:*}"
ns="${d#*:}"
newconf="${newconf}\nforward-zone:\n\tname: \"$dn\"\n"
while [ -n "$ns" ]; do
newconf="${newconf}\tforward-addr: ${ns%%,*}\n"
[ "$ns" = "${ns#*,}" ] && break
ns="${ns#*,}"
done
done
if [ -n "$NAMESERVERS" ]; then
newconf="${newconf}\nforward-zone:\n\tname: \".\"\n"
for n in $NAMESERVERS; do
newconf="${newconf}\tforward-addr: $n\n"
done
fi
if [ ! -f "$unbound_conf" ] || \
[ "$(cat "$unbound_conf")" != "$(printf "$newconf")" ]
then
printf "$newconf" >"$unbound_conf"
# If we can't sent a HUP then force a restart
if [ -s "$unbound_pid" ]; then
if ! kill -HUP $(cat "$unbound_pid") 2>/dev/null; then
eval $unbound_restart
fi
else
eval $unbound_restart
fi
fi