Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/external/bsd/openresolv/dist Import openresolv-3.7.0 with th...



details:   https://anonhg.NetBSD.org/src/rev/aaeb3bb4cd0f
branches:  trunk
changeset: 337860:aaeb3bb4cd0f
user:      roy <roy%NetBSD.org@localhost>
date:      Fri May 01 18:21:17 2015 +0000

description:
Import openresolv-3.7.0 with the following change:
  *  -x marks the resolv.conf as exclusive.
     Only the latest resolv.conf will be processed, if none then
     as normal.

diffstat:

 external/bsd/openresolv/dist/resolvconf.in |  216 +++++++++++++++++++---------
 1 files changed, 142 insertions(+), 74 deletions(-)

diffs (truncated from 354 to 300 lines):

diff -r feb37bc878ac -r aaeb3bb4cd0f external/bsd/openresolv/dist/resolvconf.in
--- a/external/bsd/openresolv/dist/resolvconf.in        Fri May 01 17:48:36 2015 +0000
+++ b/external/bsd/openresolv/dist/resolvconf.in        Fri May 01 18:21:17 2015 +0000
@@ -1,5 +1,5 @@
 #!/bin/sh
-# Copyright (c) 2007-2014 Roy Marples
+# Copyright (c) 2007-2015 Roy Marples
 # All rights reserved
 
 # Redistribution and use in source and binary forms, with or without
@@ -54,6 +54,7 @@
 IFACEDIR="$VARDIR/interfaces"
 METRICDIR="$VARDIR/metrics"
 PRIVATEDIR="$VARDIR/private"
+EXCLUSIVEDIR="$VARDIR/exclusive"
 LOCKDIR="$VARDIR/lock"
 
 warn()
@@ -79,6 +80,7 @@
                           (DNS supplied via stdin in resolv.conf format)
          -m metric        Give the added DNS information a metric
          -p               Mark the interface as private
+         -x               Mark the interface as exclusive
          -d \$INTERFACE    Delete DNS information from the specified interface
          -f               Ignore non existant interfaces
          -I               Init the state dir
@@ -101,7 +103,7 @@
 {
        local line= OIFS="$IFS"
 
-       [ -n "$1" -a -e "$IFACEDIR/$1" ] || return 1
+       [ -n "$1" -a -f "$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.
@@ -247,28 +249,46 @@
 {
        [ -d "$IFACEDIR" ] || return 0
 
-       local report=false list= retval=0 cmd="$1"
+       local report=false list= retval=0 cmd="$1" excl=
        shift
 
+       case "$IF_EXCLUSIVE" in
+       [Yy][Ee][Ss]|[Tt][Rr][Uu][Ee]|[Oo][Nn]|1)
+               if [ -d "$EXCLUSIVEDIR" ]; then
+                       cd "$EXCLUSIVEDIR"
+                       for i in *; do
+                               if [ -f "$i" ]; then
+                                       list="${i#* }"
+                                       break
+                               fi
+                       done
+               fi
+               excl=true
+               ;;
+       *)
+               excl=false
+               ;;
+       esac
+
        # If we have an interface ordering list, then use that.
        # It works by just using pathname expansion in the interface directory.
        if [ -n "$1" ]; then
                list="$*"
                $force || report=true
-       else
+       elif ! $excl; then
                cd "$IFACEDIR"
                for i in $interface_order; do
-                       [ -e "$i" ] && list="$list $i"
-                       for ii in "$i":*; do
-                               [ -e "$ii" ] && list="$list $ii"
+                       [ -f "$i" ] && list="$list $i"
+                       for ii in "$i":* "$i".*; do
+                               [ -f "$ii" ] && list="$list $ii"
                        done
                done
                for i in $dynamic_order; do
                        if [ -e "$i" -a ! -e "$METRICDIR/"*" $i" ]; then
                                list="$list $i"
                        fi
-                       for ii in "$i":*; do
-                               if [ -e "$ii" -a ! -e "$METRICDIR/"*" $ii" ]; then
+                       for ii in "$i":* "$i".*; do
+                               if [ -f "$ii" -a ! -e "$METRICDIR/"*" $ii" ]; then
                                        list="$list $ii"
                                fi
                        done
@@ -276,19 +296,20 @@
                if [ -d "$METRICDIR" ]; then
                        cd "$METRICDIR"
                        for i in *; do
-                               list="$list ${i#* }"
+                               [ -f "$i" ] && list="$list ${i#* }"
                        done
                fi
                list="$list *"
        fi
 
        cd "$IFACEDIR"
+       retval=1
        for i in $(uniqify $list); do
                # Only list interfaces which we really have
-               if ! [ -e "$i" ]; then
+               if ! [ -f "$i" ]; then
                        if $report; then
                                echo "No resolv.conf for interface $i" >&2
-                               retval=$(($retval + 1))
+                               retval=2
                        fi
                        continue
                fi
@@ -298,6 +319,7 @@
                else
                        echo_resolv "$i"
                fi
+               [ $? = 0 -a "$retval" = 1 ] && retval=0
        done
        [ "$cmd" = i -o "$cmd" = "-i" ] && echo
        return $retval
@@ -405,11 +427,13 @@
        SEARCH=
        NAMESERVERS=
        LOCALNAMESERVERS=
-
+       
        if [ -n "$name_servers" -o -n "$search_domains" ]; then
                eval "$(echo_prepend | parse_resolv)"
        fi
        if [ -z "$VFLAG" ]; then
+               IF_EXCLUSIVE=1
+               list_resolv -i "$@" >/dev/null || IF_EXCLUSIVE=0
                eval "$(list_resolv -l "$@" | replace | parse_resolv)"
        fi
        if [ -n "$name_servers_append" -o -n "$search_domains_append" ]; then
@@ -459,7 +483,7 @@
 
 force=false
 VFLAG=
-while getopts a:Dd:fhIilm:puvV OPT; do
+while getopts a:Dd:fhIilm:puvVx OPT; do
        case "$OPT" in
        f) force=true;;
        h) usage;;
@@ -473,6 +497,7 @@
                        local_nameservers=
                fi
                ;;
+       x) IF_EXCLUSIVE=1;;
        '?') ;;
        *) cmd="$OPT"; iface="$OPTARG";;
        esac
@@ -562,29 +587,38 @@
                ${force}
                exit $?
        fi
-else
-       # Delete any existing information about the interface
-       if [ "$cmd" = d ]; then
-               cd "$IFACEDIR"
-               changed=false
-               for i in $args; do
-                       if [ -e "$i" ]; then
-                               changed=true
-                       elif ! ${force}; then
-                               warn "No resolv.conf for interface $i"
-                       fi
-                       rm -f "$i" "$METRICDIR/"*" $i" \
-                               "$PRIVATEDIR/$i" || exit $?
-               done
-               if ! ${changed}; then
-                       # Set the return code based on the forced flag
-                       ${force}
-                       exit $?
-               fi
-       fi
 fi
 
-if [ "$cmd" = a ]; then
+# An interface was added, changed, deleted or a general update was called.
+# Due to exclusivity we need to ensure that this is an atomic operation.
+# Our subscribers *may* need this as well if the init system is sub par.
+# As such we spinlock at this point as best we can.
+# We don't use flock(1) because it's not widely available and normally resides
+# in /usr which we do our very best to operate without.
+[ -w "$VARDIR" ] || error_exit "Cannot write to $LOCKDIR"
+: ${lock_timeout:=10}
+while true; do
+       if mkdir "$LOCKDIR" 2>/dev/null; then
+               trap 'rm -rf "$LOCKDIR";' EXIT
+               trap 'rm -rf "$LOCKDIR"; exit 1' INT QUIT ABRT SEGV ALRM TERM
+               echo $$ >"$LOCKDIR/pid"
+               break
+       fi
+       pid=$(cat "$LOCKDIR/pid")
+       if ! kill -0 "$pid"; then
+               warn "clearing stale lock pid $pid"
+               rm -rf "$LOCKDIR"
+               continue
+       fi
+       lock_timeout=$(($lock_timeout - 1))
+       if [ "$lock_timeout" -le 0 ]; then
+               error_exit "timed out waiting for lock from pid $pid"
+       fi
+       sleep 1
+done
+
+case "$cmd" in
+a)
        # Read resolv.conf from stdin
        resolv="$(cat)"
        changed=false
@@ -601,6 +635,7 @@
                changed=true
                changedfile=true
        fi
+
        # Set metric and private before creating the interface resolv.conf file
        # to ensure that it will have the correct flags
        [ ! -d "$METRICDIR" ] && mkdir "$METRICDIR"
@@ -618,6 +653,7 @@
            "$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
@@ -634,53 +670,85 @@
                fi
                ;;
        esac
-       if $changedfile; then
-               # Ensure that creating the file is an atomic operation
-               if [ ! -d "$TMPDIR" ]; then
-                       mkdir -m 0755 -p "$TMPDIR" || \
-                           error_exit \
-                               "Failed to create needed directory $TMPDIR"
+
+       oldexcl=
+       for x in "$EXCLUSIVEDIR/"*" $iface"; do
+               if [ -f "$x" ]; then
+                       oldexcl="$x"
+                       break
+               fi
+       done
+       case "$IF_EXCLUSIVE" in
+       [Yy][Ee][Ss]|[Tt][Rr][Uu][Ee]|[Oo][Nn]|1)
+               if [ ! -d "$EXCLUSIVEDIR" ]; then
+                       [ -e "$EXCLUSIVEDIR" ] && rm "$EXCLUSIVEDIR"
+                       mkdir "$EXCLUSIVEDIR"
+               fi
+               cd "$EXCLUSIVEDIR"
+               for x in *; do
+                       [ -f "$x" ] && break
+               done
+               if [ "${x#* }" != "$iface" ]; then
+                       if [ "$x" = "${x% *}" ]; then
+                               x=10000000
+                       else
+                               x="${x% *}"
+                       fi
+                       if [ "$x" = "0000000" ]; then
+                               warn "exclusive underflow"
+                       else
+                               x=$(($x - 1))
+                       fi
+                       if [ -d "$EXCLUSIVEDIR" ]; then
+                               echo " " >"$EXCLUSIVEDIR/$x $iface"
+                       fi
+                       changed=true
                fi
-               TMPFILE="$TMPDIR/$iface.$$"
-               cleanup() { [ -n "$TMPFILE" ] && rm -f "$TMPFILE"; }
-               trap cleanup EXIT
-               echo "$resolv" >"$TMPFILE" || exit $?
-               mv -f "$TMPFILE" "$IFACEDIR/$iface" || exit $?
-               TMPFILE=
+               ;;
+       *)
+               if [ -f "$oldexcl" ]; then
+                       rm -f "$oldexcl"
+                       changed=true
+               fi
+               ;;
+       esac
+
+       if $changedfile; then
+               printf "%s\n" "$resolv" >"$IFACEDIR/$iface" || exit $?
+       elif ! $changed; then
+               exit 0
        fi
-       $changed || exit 0
-       unset changed oldmetric newmetric
-fi
+       unset changed changedfile oldmetric newmetric x oldexcl
+       ;;
+
+d)



Home | Main Index | Thread Index | Old Index