diff options
Diffstat (limited to 'libc.in')
-rw-r--r-- | libc.in | 126 |
1 files changed, 101 insertions, 25 deletions
@@ -1,5 +1,5 @@ #!/bin/sh -# Copyright (c) 2007-2011 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; printf %s "$newconf" >"$resolv_conf") eval $libc_restart |