Import openresolv-3.4.5 with the following changes since the last version:

* More printf portabitiy fixes.
* Use read -r to avoid backslash problems.
* If we have a valid domain, put that in resolv.conf as well as search.
  This does not fix a technical problem, just stops me getting bug reports.
* Update metric and privacy even if resolv.conf didn't change.
* sortlist is now supported.
* Ensure subscriber config directories exist before writing the configs
* Don't create pdnsd.conf if it doesn't exist or is not writeable.
This commit is contained in:
roy 2011-11-24 00:36:05 +00:00
parent d4009eded7
commit 02c18234cd
6 changed files with 171 additions and 45 deletions

View File

@ -93,6 +93,13 @@ for d in $DOMAINS; do
done
done
# Try to ensure that config dirs exist
if type config_mkdirs >/dev/null 2>&1; then
config_mkdirs "$dnsmasq_conf" "$dnsmasq_resolv"
else
@PREFIX@/sbin/resolvconf -D "$dnsmasq_conf" "$dnsmasq_resolv"
fi
changed=false
if [ -n "$dnsmasq_conf" ]; then
if [ ! -f "$dnsmasq_conf" ] || \

View File

@ -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,22 @@ 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
}
# Support original resolvconf configuration layout
# as well as the openresolv config file
if [ -f "$SYSCONFDIR"/resolvconf.conf ]; then
@ -65,11 +81,10 @@ elif [ -d "$SYSCONFDIR"/resolvconf ]; then
base="$SYSCONFDIR/resolv.conf.d/base"
if [ -f "$base" ]; then
name_servers="$(key_get_value "nameserver " "$base")"
domain="$(key_get_value "domain " "$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")"
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)"
@ -78,6 +93,7 @@ elif [ -d "$SYSCONFDIR"/resolvconf ]; then
resolv_conf_tail="$(cat "$SYSCONFDIR"/resolv.conf.d/tail)"
fi
fi
: ${domain:=$DOMAIN}
: ${resolv_conf:=/etc/resolv.conf}
: ${libc_service:=nscd}
: ${libc_restart:=@RESTARTCMD ${libc_service}@}
@ -124,20 +140,27 @@ case "${resolv_conf_passthrough:-NO}" in
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
@ -152,7 +175,7 @@ if [ -e "$resolv_conf" ]; then
fi
# Create our resolv.conf now
(umask 022; echo "$newconf" >"$resolv_conf")
(umask 022; printf %s "$newconf" >"$resolv_conf")
eval $libc_restart
retval=0

View File

@ -71,6 +71,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
@PREFIX@/sbin/resolvconf -D "$named_options" "$named_zones"
fi
# No point in changing files or reloading bind if the end result has not
# changed
changed=false

View File

@ -30,6 +30,8 @@
. "@SYSCONFDIR@/resolvconf.conf" || exit 1
[ -z "$pdnsd_conf" -a -z "$pdnsd_resolv" ] && exit 0
[ -z "$RESOLVCONF" ] && eval "$(@PREFIX@/sbin/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;;
@ -83,21 +85,29 @@ change_file()
newresolv="# Generated by resolvconf\n"
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
@PREFIX@/sbin/resolvconf -D "$pdnsd_resolv" "$pdnsd_conf"
fi
if [ -n "$pdnsd_resolv" ]; then
for n in $NAMESERVERS; do
newresolv="${newresolv}nameserver $n\n"
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"

View File

@ -84,16 +84,23 @@ usage()
echo_resolv()
{
local line=
local line= OIFS="$IFS"
[ -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"
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,8 +108,9 @@ 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=
echo "DOMAIN="
echo "DOMAINS="
echo "SEARCH=\"$search_domains\""
# let our subscribers know about global nameservers
@ -116,7 +124,7 @@ parse_resolv()
echo "LOCALNAMESERVERS="
newns=
while read line; do
while read -r line; do
case "$line" in
"# resolv.conf from "*)
if ${new}; then
@ -146,7 +154,14 @@ parse_resolv()
esac
ns="$ns${line#* } "
;;
"domain "*|"search "*)
"domain "*)
if [ -z "$domain" ]; then
domain="${line#* }"
echo "DOMAIN=\"$domain\""
fi
search="${line#* }"
;;
"search "*)
search="${line#* }"
;;
*)
@ -187,6 +202,41 @@ 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
@ -230,7 +280,7 @@ list_resolv()
fi
if [ "$cmd" = i -o "$cmd" = "-i" ]; then
printf "$i "
printf %s "$i "
else
echo_resolv "$i"
fi
@ -267,14 +317,15 @@ make_vars()
done
newdomains="$newdomains$newns"
done
echo "DOMAINS='$newdomains'"
echo "DOMAIN='$DOMAIN'"
echo "SEARCH='$(uniqify $SEARCH)'"
echo "NAMESERVERS='$(uniqify $NAMESERVERS)'"
echo "LOCALNAMESERVERS='$(uniqify $LOCALNAMESERVERS)'"
echo "DOMAINS='$newdomains'"
}
force=false
while getopts a:d:fhIilm:puv OPT; do
while getopts a:Dd:fhIilm:puv OPT; do
case "$OPT" in
f) force=true;;
h) usage;;
@ -295,6 +346,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"
@ -369,39 +426,54 @@ fi
if [ "$cmd" = a ]; then
# Read resolv.conf from stdin
resolv="$(cat)"
changed=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
rm "$IFACEDIR/$iface"
changed=true
fi
rm "$IFACEDIR/$iface"
else
changed=true
fi
if $changed; then
echo "$resolv" >"$IFACEDIR/$iface" || exit $?
fi
echo "$resolv" >"$IFACEDIR/$iface" || exit $?
[ ! -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
$changed || exit 0
unset changed oldmetric newmetric
fi
eval "$(make_vars)"

View File

@ -56,6 +56,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
@PREFIX@/sbin/resolvconf -D "$unbound_conf"
fi
if [ ! -f "$unbound_conf" ] || \
[ "$(cat "$unbound_conf")" != "$(printf %s "$newconf")" ]
then