Permalink
Cannot retrieve contributors at this time
| #!/bin/sh | |
| # Copyright (c) 2007-2020 Roy Marples | |
| # All rights reserved | |
| # dnsmasq subscriber for 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. | |
| [ -f "@SYSCONFDIR@"/resolvconf.conf ] || exit 0 | |
| . "@SYSCONFDIR@/resolvconf.conf" || exit 1 | |
| [ -z "${dnsmasq_conf}${dnsmasq_resolv}" ] && exit 0 | |
| [ -z "$RESOLVCONF" ] && eval "$(@SBINDIR@/resolvconf -v)" | |
| NL=" | |
| " | |
| : ${dnsmasq_pid:=/var/run/dnsmasq.pid} | |
| [ -s "$dnsmasq_pid" ] || dnsmasq_pid=/var/run/dnsmasq/dnsmasq.pid | |
| [ -s "$dnsmasq_pid" ] || unset dnsmasq_pid | |
| : ${dnsmasq_service:=dnsmasq} | |
| newconf="# Generated by resolvconf$NL" | |
| newresolv="$newconf" | |
| # Using dbus means that we never have to restart the daemon | |
| # This is important as it means we should not drop DNS queries | |
| # whilst changing DNS options around. However, dbus support is optional | |
| # so we need to validate a few things first. | |
| # Check for DBus support in the binary | |
| dbus=false | |
| dbus_ex=false | |
| dbus_introspect=$(dbus-send --print-reply --system \ | |
| --dest=uk.org.thekelleys.dnsmasq \ | |
| /uk/org/thekelleys/dnsmasq \ | |
| org.freedesktop.DBus.Introspectable.Introspect \ | |
| 2>/dev/null) | |
| if [ $? = 0 ]; then | |
| dbus=true | |
| if printf %s "$dbus_introspect" | \ | |
| grep -q '<method name="SetDomainServers">' | |
| then | |
| dbus_ex=true | |
| fi | |
| fi | |
| for n in $NAMESERVERS; do | |
| newresolv="${newresolv}nameserver $n$NL" | |
| done | |
| dbusdest= | |
| dbusdest_ex= | |
| conf= | |
| for d in $DOMAINS; do | |
| dn="${d%%:*}" | |
| ns="${d#*:}" | |
| while [ -n "$ns" ]; do | |
| n="${ns%%,*}" | |
| if $dbus && ! $dbus_ex; then | |
| case "$n" in | |
| *.*.*.*) | |
| SIFS=${IFS-y} OIFS=$IFS | |
| IFS=. | |
| set -- $n | |
| num="0x$(printf %02x $1 $2 $3 $4)" | |
| if [ "$SIFS" = y ]; then | |
| unset IFS | |
| else | |
| IFS=$OIFS | |
| fi | |
| dbusdest="$dbusdest uint32:$(printf %u $num)" | |
| dbusdest="$dbusdest string:$dn" | |
| ;; | |
| *:*%*) | |
| # This version of dnsmasq won't accept | |
| # scoped IPv6 addresses | |
| dbus=false | |
| ;; | |
| *:*) | |
| SIFS=${IFS-y} OIFS=$IFS bytes= front= back= | |
| empty=false i=0 | |
| IFS=: | |
| set -- $n | |
| while [ -n "$1" ] || [ -n "$2" ]; do | |
| addr="$1" | |
| shift | |
| if [ -z "$addr" ]; then | |
| empty=true | |
| continue | |
| fi | |
| i=$(($i + 1)) | |
| while [ ${#addr} -lt 4 ]; do | |
| addr="0${addr}" | |
| done | |
| byte1="$(printf %d 0x${addr%??})" | |
| byte2="$(printf %d 0x${addr#??})" | |
| if $empty; then | |
| back="$back byte:$byte1 byte:$byte2" | |
| else | |
| front="$front byte:$byte1 byte:$byte2" | |
| fi | |
| done | |
| while [ $i != 8 ]; do | |
| i=$(($i + 1)) | |
| front="$front byte:0 byte:0" | |
| done | |
| front="${front}$back" | |
| if [ "$SIFS" = y ]; then | |
| unset IFS | |
| else | |
| IFS=$OIFS | |
| fi | |
| dbusdest="${dbusdest}$front string:$dn" | |
| ;; | |
| *) | |
| if ! $dbus_ex; then | |
| dbus=false | |
| fi | |
| ;; | |
| esac | |
| fi | |
| dbusdest_ex="$dbusdest_ex${dbusdest_ex:+,}/$dn/$n" | |
| conf="${conf}server=/$dn/$n$NL" | |
| [ "$ns" = "${ns#*,}" ] && break | |
| ns="${ns#*,}" | |
| done | |
| done | |
| if $dbus; then | |
| newconf="$newconf$NL# Domain specific servers will" | |
| newconf="$newconf be sent over dbus${NL}" | |
| else | |
| newconf="$newconf$conf" | |
| fi | |
| # Try to ensure that config dirs exist | |
| if type config_mkdirs >/dev/null 2>&1; then | |
| config_mkdirs "$dnsmasq_conf" "$dnsmasq_resolv" | |
| else | |
| @SBINDIR@/resolvconf -D "$dnsmasq_conf" "$dnsmasq_resolv" | |
| fi | |
| changed=false | |
| if [ -n "$dnsmasq_conf" ]; then | |
| if [ ! -f "$dnsmasq_conf" ] || \ | |
| [ "$(cat "$dnsmasq_conf")" != "$(printf %s "$newconf")" ] | |
| then | |
| changed=true | |
| printf %s "$newconf" >"$dnsmasq_conf" | |
| fi | |
| fi | |
| if [ -n "$dnsmasq_resolv" ]; then | |
| # dnsmasq polls this file so no need to set changed=true | |
| if [ -f "$dnsmasq_resolv" ]; then | |
| if [ "$(cat "$dnsmasq_resolv")" != "$(printf %s "$newresolv")" ] | |
| then | |
| printf %s "$newresolv" >"$dnsmasq_resolv" | |
| fi | |
| else | |
| printf %s "$newresolv" >"$dnsmasq_resolv" | |
| fi | |
| fi | |
| if $changed; then | |
| # dnsmasq does not re-read the configuration file on SIGHUP | |
| if [ -n "$dnsmasq_restart" ]; then | |
| eval $dnsmasq_restart | |
| elif [ -n "$RESTARTCMD" ]; then | |
| set -- ${dnsmasq_service} | |
| eval "$RESTARTCMD" | |
| else | |
| @SBINDIR@/resolvconf -r ${dnsmasq_service} | |
| fi | |
| fi | |
| if $dbus; then | |
| if [ -s "$dnsmasq_pid" ]; then | |
| $changed || kill -HUP $(cat "$dnsmasq_pid") | |
| fi | |
| # Send even if empty so old servers are cleared | |
| if $dbus_ex; then | |
| method=SetDomainServers | |
| if [ -n "$dbusdest_ex" ]; then | |
| dbusdest_ex="array:string:$dbusdest_ex" | |
| fi | |
| dbusdest="$dbusdest_ex" | |
| else | |
| method=SetServers | |
| fi | |
| dbus-send --system --dest=uk.org.thekelleys.dnsmasq \ | |
| /uk/org/thekelleys/dnsmasq uk.org.thekelleys.$method \ | |
| $dbusdest | |
| dbus-send --system --dest=uk.org.thekelleys.dnsmasq \ | |
| /uk/org/thekelleys/dnsmasq uk.org.thekelleys.ClearCache | |
| fi |