diff --git a/external/bsd/openresolv/dist/dnsmasq.in b/external/bsd/openresolv/dist/dnsmasq.in index a120189ba994..9c7fdeef9670 100644 --- a/external/bsd/openresolv/dist/dnsmasq.in +++ b/external/bsd/openresolv/dist/dnsmasq.in @@ -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" ] || \ diff --git a/external/bsd/openresolv/dist/libc.in b/external/bsd/openresolv/dist/libc.in index 9c73f0fffad0..5aea64174b59 100644 --- a/external/bsd/openresolv/dist/libc.in +++ b/external/bsd/openresolv/dist/libc.in @@ -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 diff --git a/external/bsd/openresolv/dist/named.in b/external/bsd/openresolv/dist/named.in index c960866b9985..a89deb2693bc 100644 --- a/external/bsd/openresolv/dist/named.in +++ b/external/bsd/openresolv/dist/named.in @@ -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 diff --git a/external/bsd/openresolv/dist/pdnsd.in b/external/bsd/openresolv/dist/pdnsd.in index 237939ca9b5d..0a0241a7c7b3 100644 --- a/external/bsd/openresolv/dist/pdnsd.in +++ b/external/bsd/openresolv/dist/pdnsd.in @@ -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" diff --git a/external/bsd/openresolv/dist/resolvconf.in b/external/bsd/openresolv/dist/resolvconf.in index 2b292dd341bd..567e7986c20c 100644 --- a/external/bsd/openresolv/dist/resolvconf.in +++ b/external/bsd/openresolv/dist/resolvconf.in @@ -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)" diff --git a/external/bsd/openresolv/dist/unbound.in b/external/bsd/openresolv/dist/unbound.in index 839a85944059..4ee0da720263 100644 --- a/external/bsd/openresolv/dist/unbound.in +++ b/external/bsd/openresolv/dist/unbound.in @@ -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