| #!/bin/sh |
| # |
| # Script to update the resolver list for dnsmasq |
| # |
| # N.B. Resolvconf may run us even if dnsmasq is not (yet) running. |
| # If dnsmasq is installed then we go ahead and update the resolver list |
| # in case dnsmasq is started later. |
| # |
| # Assumption: On entry, PWD contains the resolv.conf-type files. |
| # |
| # This file is part of the dnsmasq package. |
| # |
| |
| set -e |
| |
| RUN_DIR="/run/dnsmasq" |
| RSLVRLIST_FILE="${RUN_DIR}/resolv.conf" |
| TMP_FILE="${RSLVRLIST_FILE}_new.$$" |
| MY_NAME_FOR_RESOLVCONF="dnsmasq" |
| |
| [ -x /usr/sbin/dnsmasq ] || exit 0 |
| [ -x /lib/resolvconf/list-records ] || exit 1 |
| |
| PATH=/bin:/sbin |
| |
| report_err() { echo "$0: Error: $*" >&2 ; } |
| |
| # Stores arguments (minus duplicates) in RSLT, separated by spaces |
| # Doesn't work properly if an argument itself contains whitespace |
| uniquify() |
| { |
| RSLT="" |
| while [ "$1" ] ; do |
| for E in $RSLT ; do |
| [ "$1" = "$E" ] && { shift ; continue 2 ; } |
| done |
| RSLT="${RSLT:+$RSLT }$1" |
| shift |
| done |
| } |
| |
| if [ ! -d "$RUN_DIR" ] && ! mkdir --parents --mode=0755 "$RUN_DIR" ; then |
| report_err "Failed trying to create directory $RUN_DIR" |
| exit 1 |
| fi |
| |
| RSLVCNFFILES="" |
| for F in $(/lib/resolvconf/list-records --after "lo.$MY_NAME_FOR_RESOLVCONF") ; do |
| case "$F" in |
| "lo.$MY_NAME_FOR_RESOLVCONF") |
| # Omit own record |
| ;; |
| lo.*) |
| # Include no more records after one for a local nameserver |
| RSLVCNFFILES="${RSLVCNFFILES:+$RSLVCNFFILES }$F" |
| break |
| ;; |
| *) |
| RSLVCNFFILES="${RSLVCNFFILES:+$RSLVCNFFILES }$F" |
| ;; |
| esac |
| done |
| |
| NMSRVRS="" |
| if [ "$RSLVCNFFILES" ] ; then |
| uniquify $(sed -n -e 's/^[[:space:]]*nameserver[[:space:]]\+//p' $RSLVCNFFILES) |
| NMSRVRS="$RSLT" |
| fi |
| |
| # Dnsmasq uses the mtime of $RSLVRLIST_FILE, with a resolution of one second, |
| # to detect changes in the file. This means that if a resolvconf update occurs |
| # within one second of the previous one then dnsmasq may fail to notice the |
| # more recent change. To work around this problem we sleep one second here |
| # if necessary in order to ensure that the new mtime is different. |
| if [ -f "$RSLVRLIST_FILE" ] && [ "$(ls -go --time-style='+%s' "$RSLVRLIST_FILE" | { read p h s t n ; echo "$t" ; })" = "$(date +%s)" ] ; then |
| sleep 1 |
| fi |
| |
| clean_up() { rm -f "$TMP_FILE" ; } |
| trap clean_up EXIT |
| : >| "$TMP_FILE" |
| for N in $NMSRVRS ; do echo "nameserver $N" >> "$TMP_FILE" ; done |
| mv -f "$TMP_FILE" "$RSLVRLIST_FILE" |
| |