Rejig our Makefile to better support NetBSD. We now talk to /var/run/resolvconf direc...
[openresolv] / resolvconf.in
index 111c27ed78cabfe938afba2d81b887a68a4ea643..dc6f335e2f025da5a08689523fc62edb6ebd41c3 100755 (executable)
@@ -1,5 +1,5 @@
 #!/bin/sh
-# Copyright 2007 Roy Marples
+# Copyright 2007-2008 Roy Marples
 # All rights reserved
 
 # Redistribution and use in source and binary forms, with or without
 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
-argv0="$0"
+ARGV0="$0"
 
-PREFIX=
-RESOLVCONF="${PREFIX}"/etc/resolvconf
-UPDATED="${RESOLVCONF}"/update.d
-VARDIR="${RESOLVCONF}"/run
+SYSCONFDIR=@SYSCONFDIR@
+VARDIR=@VARBASE@/run/resolvconf
 IFACEDIR="${VARDIR}/interfaces"
 
 error_exit() {
@@ -39,7 +37,7 @@ error_exit() {
 
 usage() {
        cat <<-EOF
-       Usage: ${argv0##*/} [options]
+       Usage: ${ARGV0##*/} [options]
 
        Inform the system about any DNS updates.
 
@@ -47,6 +45,7 @@ usage() {
          -a \$INTERFACE    Add DNS information to the specified interface
                           (DNS supplied via stdin in resolv.conf format)
          -d \$INTERFACE    Delete DNS information from the specified interface
+         -f               Ignore non existant interfaces
          -u               Run updates from our current DNS information
          -l [\$PATTERN]    Show DNS information, optionally from interfaces
                           that match the specified pattern
@@ -82,19 +81,22 @@ uniqify() {
     echo "${result# *}"
 }
 
-if [ -n "$1" ]; then
-       CMD="$1"
-       shift
-fi
+FORCE=false
+while getopts a:d:fhils:uv OPT; do
+       case "${OPT}" in
+               f) FORCE=true;;
+               h) usage;;
+               s) CMD=s; SERVICE="${OPTARG}";;
+               '?') exit 1;;
+               *) CMD="${OPT}"; IFACE="${OPTARG}";;
+       esac
+done
+shift $((${OPTIND} - 1))
+ARGS="${IFACE}${IFACE:+ }$@"
 
 # We do our service restarting here so that our subscribers don't have to know
 # about the OS's init system.
-if [ "x${CMD}" = "x-s" ]; then
-       if [ -n "$1" ]; then
-               SERVICE="$1"
-               shift
-       fi
-       [ -z "${SERVICE}" ] && usage "Service not specified"
+if [ "${CMD}" = "s" ]; then
        if [ -n "$1" ]; then
                ACTION="$1"
                shift
@@ -102,23 +104,23 @@ if [ "x${CMD}" = "x-s" ]; then
        [ -z "${ACTION}" ] && usage "Action not specified"
 
        # If restarting check if service is running or not if we can
-       if [ "x${ACTION}" = "xrestart" ]; then
+       if [ "${ACTION}" = "restart" ]; then
                if [ -s /var/run/"${SERVICE}".pid ]; then
-                       kill -0 $(cat /var/run/"${SERVICE}".pid)
+                       kill -0 $(cat /var/run/"${SERVICE}".pid) 2>/dev/null
                elif [ -s /var/run/"${SERVICE}"/"${SERVICE}".pid ]; then
-                       kill -0 $(cat /var/run/"${SERVICE}".pid)
+                       kill -0 $(cat /var/run/"${SERVICE}".pid) 2>/dev/null
                elif [ -s /var/run/"${SERVICE}"/pid ]; then
-                       kill -0 $(cat /var/run/"${SERVICE}"/pid)
+                       kill -0 $(cat /var/run/"${SERVICE}"/pid) 2>/dev/null
                else
                        false
                fi
                # Service not running, so don't restart
-               [ $? != 0 ] && exit 1
+               [ $? != 0 ] && exit 0
        fi      
        if [ -x /sbin/service ]; then
                service "${SERVICE}" "${ACTION}" "$@" 
        elif [ -x /etc/init.d/"${SERVICE}" -a -x /sbin/runscript ]; then
-               if [ "x${ACTION}" = "xrestart" ]; then
+               if [ "${ACTION}" = "restart" ]; then
                        /etc/init.d/"${SERVICE}" --quiet --nodeps conditionalrestart "$@"
                else
                        /etc/init.d/"${SERVICE}" --quiet --nodeps "${ACTION}" "$@"
@@ -135,21 +137,18 @@ if [ "x${CMD}" = "x-s" ]; then
        exit $?
 fi
 
-if [ -n "$1" ]; then
-       IFACE="$1"
-       shift
-fi
-
 # -l lists our resolv files, optionally for a specific interface
-if [ "x${CMD}" = "x-l" -o "x${CMD}" = "x-i" ]; then
+if [ "${CMD}" = "l" -o "${CMD}" = "i" ]; then
        [ -d "${IFACEDIR}" ] || exit 0
-       
+
+       REPORT=false
        # If we have an interface ordering list, then use that.
        # It works by just using pathname expansion in the interface directory.
-       if [ -n "${IFACE}" ]; then
-               LIST="${IFACE} $@"
-       elif [ -r "${RESOLVCONF}"/interface-order ]; then
-               LIST="$(cat "${RESOLVCONF}"/interface-order)"
+       if [ -n "${ARGS}" ]; then
+               LIST="${ARGS}"
+               ${FORCE} || REPORT=true
+       elif [ -r "${SYSCONFDIR}"/interface-order ]; then
+               LIST="$(cat "${SYSCONFDIR}"/interface-order)"
        fi
 
        # If we don't have a list then prefer lo, tunnels, ppp
@@ -158,29 +157,37 @@ if [ "x${CMD}" = "x-l" -o "x${CMD}" = "x-i" ]; then
                LIST="lo lo[0-9]* tap[0-9]* tun[0-9]* vpn vpn[0-9]* ppp[0-9]* ippp[0-9]* *"
        fi
 
+       RETVAL=0
        cd "${IFACEDIR}"
        for IFACE in $(uniqify ${LIST}); do
                # Only list interfaces which we really have
-               [ -e "${IFACE}" ] || continue
+               if ! [ -e "${IFACE}" ]; then
+                       if ${REPORT}; then
+                               echo "No resolv.conf for interface ${IFACE}" >&2
+                               RETVAL=$((${RETVAL} + 1))
+                       fi
+                       continue
+               fi
                
-               if [ "x${CMD}" = "x-i" ]; then
+               if [ "${CMD}" = "i" ]; then
                        printf "${IFACE} "
                else
                        echo_resolv "${IFACE}"
                fi
        done
-       [ "x${CMD}" = "x-i" ] && echo
-       exit 0
+       [ "${CMD}" = "i" ] && echo
+       exit ${RETVAL} 
 fi
 
-if [ "x${CMD}" = "x-v" ]; then
+if [ "${CMD}" = "v" ]; then
        NS=
        DOMAIN=
        SEARCH=
        NEWSEARCH=
        NEWNS=
        NEWDOMAIN=
-       LINES="$("${argv0}" -l "${IFACE}" | sed -e "s/'/'\\\\''/g" -e "s/^/'/g" -e "s/$/'/g")"
+       LINES="$("${ARGV0}" -l "${IFACE}" |
+               sed -e "s/'/'\\\\''/g" -e "s/^/'/g" -e "s/$/'/g")"
        eval set -- ${LINES}
        for LINE in "$@"; do
                case "${LINE}" in
@@ -226,8 +233,10 @@ if [ "x${CMD}" = "x-v" ]; then
        for S in ${NEWSEARCH}; do
                for DN in ${NEWDOMAIN}; do
                        if [ "${S%,*}" = "${DN%,*}" ]; then
-                               NEWSEARCH="$(echo "${NEWSEARCH}" | sed -e "s/${S}/${DN}/g")"
-                               NEWDOMAIN="$(echo "${NEWDOMAIN}" | sed -e "s/${DN}//g")"
+                               NEWSEARCH="$(echo "${NEWSEARCH}" |
+                                       sed -e "s/${S}/${DN}/g")"
+                               NEWDOMAIN="$(echo "${NEWDOMAIN}" |
+                                       sed -e "s/${DN}//g")"
                                break
                        fi
                done
@@ -240,15 +249,15 @@ if [ "x${CMD}" = "x-v" ]; then
 fi
 
 # Test that we have valid options
-if [ "x${CMD}" = "x-a" -o "x${CMD}" = "x-d" ]; then
+if [ "${CMD}" = "a" -o "${CMD}" = "d" ]; then
        if [ -z "${IFACE}" ]; then
                usage "Interface not specified"
        fi
-elif [ "x${CMD}" != "x-u" ]; then
-       [ -n "x${CMD}" -a "x${CMD}" != "x-h" ] && usage "Unknown option ${CMD}"
+elif [ "${CMD}" != "u" ]; then
+       [ -n "${CMD}" -a "${CMD}" != "h" ] && usage "Unknown option ${CMD}"
        usage
 fi
-if [ "x${CMD}" = "x-a" ]; then
+if [ "${CMD}" = "a" ]; then
        for x in '/' \\ ' ' '*'; do
                case "${IFACE}" in
                        *[${x}]*) error_exit "${x} not allowed in interface name";;
@@ -259,7 +268,7 @@ if [ "x${CMD}" = "x-a" ]; then
                        [${x}]*) error_exit "${x} not allowed at start of interface name";;
                esac
        done
-       [ "x${CMD}" = "x-a" -a -t 0 ] && error_exit "No file given via stdin"
+       [ "${CMD}" = "a" -a -t 0 ] && error_exit "No file given via stdin"
        IFACERESOLV="${IFACEDIR}/${IFACE}"
 fi
 
@@ -283,27 +292,29 @@ if [ ! -d "${IFACEDIR}" ]; then
                error_exit "Failed to create needed directory ${IFACEDIR}"
 else
        # Delete any existing information about the interface
-       if [ "x${CMD}" = "x-a" -o "x${CMD}" = "x-d" ]; then
+       if [ "${CMD}" = "a" -o "${CMD}" = "d" ]; then
                cd "${IFACEDIR}"
-               for iface in ${IFACE}; do
-                       rm -f "${iface}" || exit $?
+               for ARG in ${ARGS}; do
+                       if [ "${CMD}" = "d" -a ! -e "${ARG}" ]; then
+                               ${FORCE} && continue
+                               error_exit "No resolv.conf for interface ${ARG}"
+                       fi
+                       rm -f "${ARG}" || exit $?
                done
        fi
 fi
 
-if [ "x${CMD}" = "x-a" ]; then
+if [ "${CMD}" = "a" ]; then
        # Create our resolv.conf file
        cat >"${IFACEDIR}"/"${IFACE}" || exit $?
 fi
 
-retval=0
-for x in "${UPDATED}"/*; do
-       if [ -e "${x}" ]; then
-               "${x}" "${CMD}" "${IFACE}"
-               retval=$((${retval} + $?))
+RETVAL=0
+for SCRIPT in "${SYSCONFDIR}"/update.d/*; do
+       if [ -e "${SCRIPT}" ]; then
+               "${SCRIPT}" "${CMD}" "${IFACE}"
+               RETVAL=$((${RETVAL} + $?))
        fi
 done
 
-exit ${retval}
-
-# vim: set ts=4 :
+exit ${RETVAL}