#!/bin/sh # Copyright 2007-2009 Roy Marples # All rights reserved # 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 # 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. # Load our variables from resolvconf eval "$(resolvconf -v)" RESOLVCONF=/etc/resolv.conf PREFIX=@PREFIX@ SYSCONFDIR=@SYSCONFDIR@ LIBEXECDIR=@LIBEXECDIR@ BASE="${SYSCONFDIR}/resolv.conf.base" uniqify() { local result= while [ -n "$1" ]; do case " ${result} " in *" $1 "*);; *) result="${result} $1";; esac shift done echo "${result# *}" } # 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 } 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 fi NEWSEARCH="$(uniqify ${NEWSEARCH} ${SEARCH})" NEWNS="$(uniqify ${NEWNS} ${NAMESERVERS})" # Hold our new resolv.conf in a variable to save on temporary files NEWCONF="" [ -e "${SYSCONFDIR}"/resolv.conf.head ] \ && NEWCONF="${NEWCONF}$(cat "${SYSCONFDIR}"/resolv.conf.head)\n" [ -n "${NEWSEARCH}" ] && NEWCONF="${NEWCONF}search ${NEWSEARCH}\n" for N in ${NEWNS}; do NEWCONF="${NEWCONF}nameserver ${N}\n" done # Now get any configured options OPTS= if [ -e "${BASE}" ]; then 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 [ -e "${SYSCONFDIR}"/resolv.conf.tail ] \ && NEWCONF="${NEWCONF}$(cat "${SYSCONFDIR}"/resolv.conf.tail)\n" # Check if the file has actually changed or not if [ -e "${RESOLVCONF}" ]; then [ "$(cat "${RESOLVCONF}")" = "$(printf "${NEWCONF}")" ] && exit 0 fi # Create our resolv.conf now (umask 022; printf "${NEWCONF}" > "${RESOLVCONF}") resolvconf -s nscd restart retval=$? # Notify users of the resolver for x in "${LIBEXECDIR}"/libc.d/*; do if [ -e "${x}" ]; then "${x}" "$@" retval=$((${retval} + $?)) fi done exit ${retval}