1#!/bin/sh 2# 3# Script to update the resolver list for dnsmasq 4# 5# N.B. Resolvconf may run us even if dnsmasq is not (yet) running. 6# If dnsmasq is installed then we go ahead and update the resolver list 7# in case dnsmasq is started later. 8# 9# Assumption: On entry, PWD contains the resolv.conf-type files. 10# 11# This file is part of the dnsmasq package. 12# 13 14set -e 15 16RUN_DIR="/run/dnsmasq" 17RSLVRLIST_FILE="${RUN_DIR}/resolv.conf" 18TMP_FILE="${RSLVRLIST_FILE}_new.$$" 19MY_NAME_FOR_RESOLVCONF="dnsmasq" 20 21[ -x /usr/bin/dnsmasq ] || exit 0 22[ -x /lib/resolvconf/list-records ] || exit 1 23 24PATH=/bin:/sbin 25 26report_err() { echo "$0: Error: $*" >&2 ; } 27 28# Stores arguments (minus duplicates) in RSLT, separated by spaces 29# Doesn't work properly if an argument itself contains whitespace 30uniquify() 31{ 32 RSLT="" 33 while [ "$1" ] ; do 34 for E in $RSLT ; do 35 [ "$1" = "$E" ] && { shift ; continue 2 ; } 36 done 37 RSLT="${RSLT:+$RSLT }$1" 38 shift 39 done 40} 41 42if [ ! -d "$RUN_DIR" ] && ! mkdir --parents --mode=0755 "$RUN_DIR" ; then 43 report_err "Failed trying to create directory $RUN_DIR" 44 exit 1 45fi 46 47RSLVCNFFILES="" 48for F in $(/lib/resolvconf/list-records --after "lo.$MY_NAME_FOR_RESOLVCONF") ; do 49 case "$F" in 50 "lo.$MY_NAME_FOR_RESOLVCONF") 51 # Omit own record 52 ;; 53 lo.*) 54 # Include no more records after one for a local nameserver 55 RSLVCNFFILES="${RSLVCNFFILES:+$RSLVCNFFILES }$F" 56 break 57 ;; 58 *) 59 RSLVCNFFILES="${RSLVCNFFILES:+$RSLVCNFFILES }$F" 60 ;; 61 esac 62done 63 64NMSRVRS="" 65if [ "$RSLVCNFFILES" ] ; then 66 uniquify $(sed -n -e 's/^[[:space:]]*nameserver[[:space:]]\+//p' $RSLVCNFFILES) 67 NMSRVRS="$RSLT" 68fi 69 70# Dnsmasq uses the mtime of $RSLVRLIST_FILE, with a resolution of one second, 71# to detect changes in the file. This means that if a resolvconf update occurs 72# within one second of the previous one then dnsmasq may fail to notice the 73# more recent change. To work around this problem we sleep one second here 74# if necessary in order to ensure that the new mtime is different. 75if [ -f "$RSLVRLIST_FILE" ] && [ "$(stat -c %X "$RSLVRLIST_FILE")" = "$(date +%s)" ] ; then 76 sleep 1 77fi 78 79clean_up() { rm -f "$TMP_FILE" ; } 80trap clean_up EXIT 81: >| "$TMP_FILE" 82for N in $NMSRVRS ; do echo "nameserver $N" >> "$TMP_FILE" ; done 83mv -f "$TMP_FILE" "$RSLVRLIST_FILE" 84 85