When an interface is marked private, we just discard the nameservers from the
[openresolv] / libc.in
diff --git a/libc.in b/libc.in
old mode 100755 (executable)
new mode 100644 (file)
index 83d2519..a01d431
--- a/libc.in
+++ b/libc.in
@@ -1,9 +1,10 @@
 #!/bin/sh
-# Copyright 2006 Gentoo Foundation
-# Copyright 2007 Roy Marples
+# Copyright 2007-2008 Roy Marples
 # All rights reserved
 
-# libc subscriber for resolvconf 
+# libc subscriber for resolvconf
+# You could symlink /etc/resolv.conf to resolvconf/run/resolv.conf
+# for a read only etc, if resolvconf/run is linked to /var/run/resolvconf.
 
 # Redistribution and use in source and binary forms, with or without
 # modification, are permitted provided that the following conditions
 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
-PREFIX=
-RESOLVCONF="${PREFIX}"/etc/resolvconf
-RESOLVCONFS="$(resolvconf -l)"
-BASE="${RESOLVCONF}/resolv.conf.d/base"
+# Load our variables from resolvconf
+eval "$(resolvconf -v)"
 
-uniqify() {
+RESOLVCONF=/etc/resolv.conf
+PREFIX=@PREFIX@
+SYSCONFDIR=@SYSCONFDIR@
+BASE="${SYSCONFDIR}/resolv.conf.d/base"
+
+uniqify()
+{
     local result=
     while [ -n "$1" ]; do
                case " ${result} " in
-                       *" $1 "*) ;;
-                       *) result="${result} $1" ;;
+               *" $1 "*);;
+               *) result="${result} $1";;
                esac
                shift
        done
     echo "${result# *}"
 }
 
-OUR_NS=
-if [ -e "${BASE}" ]; then
-       OUR_NS="$(sed -n -e 's/^[[:space:]]*nameserver[[:space:]]*//p' "${BASE}")"
-fi
-OUR_NS="$(uniqify \
-       ${OUR_NS} \
-       $(echo "${RESOLVCONFS}" \
-       | sed -n -e 's/^[[:space:]]*nameserver[[:space:]]*//p') \
-)"
-
-# libc only allows for 3 nameservers
-# truncate after 127 as well
-i=0
-NS=
-LOCALH=false
-for N in ${OUR_NS}; do
-       i=$((${i} + 1))
-       NS="${NS} ${N}"
-       [ "${i}" = "3" ] && break
-       case "${N}" in
-               127.*) LOCALH=true; break ;;
-       esac
-done
-
-# This is nasty!
-# If we have a local nameserver then assume they are intelligent enough
-# to be forwarding domain requests to the correct nameserver and not search
-# ones. This means we prefer search then domain, otherwise, we use them in
-# the order given to us.
-OUR_SEARCH=
-if ${LOCALH} ; then
-       if [ -e "${BASE}" ]; then
-               OUR_SEARCH="$(sed -n -e 's/^[[:space:]]*search[[:space:]]*//p' "${BASE}")"
+# 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
-       OUR_SEARCH="${OUR_SEARCH} $(echo "${RESOLVCONFS}" \
-               | sed -n 's/^[[:space:]]*search[[:space:]]*//p')"
-       if [ -e "${BASE}" ]; then
-               OUR_SEARCH="${OUR_SEARCH} $(sed -n -e 's/^[[:space:]]*domain[[:space:]]*//p' "${BASE}")"
-       fi
-       OUR_SEARCH="${OUR_SEARCH} $( echo "${RESOLVCONFS}" \
-               | sed -n -e 's/^[[:space:]]*domain[[:space:]]*//p')"
-else
-       if [ -e "${BASE}" ]; then
-               OUR_SEARCH="$(sed -n -e 's/^[[:space:]]*search[[:space:]]*//p' \
-                       -e 's/^[[:space:]]*domain[[:space:]]*//p' "${BASE}")"
+}
+
+NEWNS=
+NEWSEARCH=
+if [ -e "${BASE}" ]; then
+       NEWNS="$(key_get_value "nameserver " "${BASE}")"
+       NEWSEARCH="$(key_get_value "search " "${BASE}")"
+       if [ -z "${NEWSEARCH}" ]; then
+               NEWSEARCH="$(key_get_value "domain " "${BASE}")"
        fi
-       OUR_SEARCH="${OUR_SEARCH} $(echo "${RESOLVCONFS}" \
-               | sed -n -e 's/^[[:space:]]*search[[:space:]]*//p' \
-                       -e 's/^[[:space:]]*domain[[:space:]]*//p')"
 fi
-
-# libc only allows for 6 search domains 
-i=0
-SEARCH=
-for S in $(uniqify ${OUR_SEARCH}); do
-       i=$((${i} + 1))
-       SEARCH="${SEARCH} ${S}"
-       [ "${i}" = "6" ] && break
-done
-[ -n "${SEARCH}" ] && SEARCH="search${SEARCH}"
+NEWSEARCH="$(uniqify ${NEWSEARCH} ${SEARCH})"
+NEWNS="$(uniqify ${NEWNS} ${NAMESERVERS})"
 
 # Hold our new resolv.conf in a variable to save on temporary files
-NEWCONF="# Generated by resolvconf\n"
-[ -e "${RESOLVCONF}"/resolv.conf.d/head ] \
-       && NEWCONF="${NEWCONF}$(cat "${RESOLVCONF}"/resolv.conf.d/head)\n"
-[ -n "${SEARCH}" ] && NEWCONF="${NEWCONF}${SEARCH}\n"
-for N in ${NS}; do
+NEWCONF=""
+[ -e "${SYSCONFDIR}"/resolv.conf.d/head ] \
+       && NEWCONF="${NEWCONF}$(cat "${SYSCONFDIR}"/resolv.conf.d/head)\n"
+[ -n "${NEWSEARCH}" ] && NEWCONF="${NEWCONF}search ${NEWSEARCH}\n"
+for N in ${NEWNS}; do
        NEWCONF="${NEWCONF}nameserver ${N}\n"
 done
 
-# Now dump everything else from our resolvs
+# Now get any configured options
+OPTS=
 if [ -e "${BASE}" ]; then
-       NEWCONF="${NEWCONF}$(sed -e '/^[[:space:]]*$/d' \
-               -e '/^[[:space:]]*nameserver[[:space:]]*.*/d' \
-               -e '/^[[:space:]]*search[[:space:]]*.*/d' \
-               -e '/^[[:space:]]*domain[[:space:]]*.*/d' \
-               "${BASE}")" 
+       OPTS="$(key_get_value "options " "${BASE}")"
+fi
+OPTS="${OPTS}${OPTS:+ }$(resolvconf -l | 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
 
-# We don't know we're using GNU sed, so we do it like this
-NEWCONF="${NEWCONF}$(echo "${RESOLVCONFS}" | sed -e '/^[[:space:]]*$/d' \
-       -e '/^[[:space:]]*#/d' \
-       -e '/^[[:space:]]*nameserver[[:space:]]*.*/d' \
-       -e '/^[[:space:]]*search[[:space:]]*.*/d' \
-       -e '/^[[:space:]]*domain[[:space:]]*.*/d' \
-       )"
-[ -e "${RESOLVCONF}"/resolv.conf.d/tail ] \
-       && NEWCONF="${NEWCONF}$(cat "${RESOLVCONF}"/resolv.conf.d/tail)"
+[ -e "${SYSCONFDIR}"/resolv.conf.d/tail ] \
+       && NEWCONF="${NEWCONF}$(cat "${SYSCONFDIR}"/resolv.conf.d/tail)\n"
 
 # Check if the file has actually changed or not
-if [ -e "${RESOLVCONF}"/run/resolv.conf ]; then
-       [ "$(cat "${RESOLVCONF}"/run/resolv.conf)" = "$(printf "${NEWCONF}")" ] && exit 0
+if [ -e "${RESOLVCONF}" ]; then
+       [ "$(cat "${RESOLVCONF}")" = "$(printf "${NEWCONF}")" ] && exit 0
 fi
 
 # Create our resolv.conf now
-(umask 022; printf "${NEWCONF}" > "${RESOLVCONF}"/run/resolv.conf)
+(umask 022; printf "${NEWCONF}" > "${RESOLVCONF}")
 
 resolvconf -s nscd restart
+retval=$?
 
 # Notify users of the resolver
-for x in "${REVOLVCONF}"/update-libc.d/*; do
-       [ -e "${x}" ] && "${x}" "$@"
+for x in "${SYSCONFDIR}"/update-libc.d/*; do
+       if [ -e "${x}" ]; then
+               "${x}" "$@"
+               retval=$((${retval} + $?))
+       fi
 done
-
-# vim: ts=4 :
+exit ${retval}