18382a10eSAaron LI#!/bin/sh 2*d19862cdSRoy Marples# Copyright (c) 2007-2023 Roy Marples 38382a10eSAaron LI# All rights reserved 48382a10eSAaron LI 58382a10eSAaron LI# dnsmasq subscriber for resolvconf 68382a10eSAaron LI 78382a10eSAaron LI# Redistribution and use in source and binary forms, with or without 88382a10eSAaron LI# modification, are permitted provided that the following conditions 98382a10eSAaron LI# are met: 108382a10eSAaron LI# * Redistributions of source code must retain the above copyright 118382a10eSAaron LI# notice, this list of conditions and the following disclaimer. 128382a10eSAaron LI# * Redistributions in binary form must reproduce the above 138382a10eSAaron LI# copyright notice, this list of conditions and the following 148382a10eSAaron LI# disclaimer in the documentation and/or other materials provided 158382a10eSAaron LI# with the distribution. 168382a10eSAaron LI# 178382a10eSAaron LI# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 188382a10eSAaron LI# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 198382a10eSAaron LI# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 208382a10eSAaron LI# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 218382a10eSAaron LI# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 228382a10eSAaron LI# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 238382a10eSAaron LI# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 248382a10eSAaron LI# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 258382a10eSAaron LI# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 268382a10eSAaron LI# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 278382a10eSAaron LI# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 288382a10eSAaron LI 298382a10eSAaron LI[ -f "@SYSCONFDIR@"/resolvconf.conf ] || exit 0 308382a10eSAaron LI. "@SYSCONFDIR@/resolvconf.conf" || exit 1 31a37440eeSRoy Marples[ -z "${dnsmasq_conf}${dnsmasq_resolv}" ] && exit 0 328382a10eSAaron LI[ -z "$RESOLVCONF" ] && eval "$(@SBINDIR@/resolvconf -v)" 338382a10eSAaron LINL=" 348382a10eSAaron LI" 358382a10eSAaron LI 368382a10eSAaron LI: ${dnsmasq_pid:=/var/run/dnsmasq.pid} 378382a10eSAaron LI[ -s "$dnsmasq_pid" ] || dnsmasq_pid=/var/run/dnsmasq/dnsmasq.pid 388382a10eSAaron LI[ -s "$dnsmasq_pid" ] || unset dnsmasq_pid 398382a10eSAaron LI: ${dnsmasq_service:=dnsmasq} 408382a10eSAaron LInewconf="# Generated by resolvconf$NL" 418382a10eSAaron LInewresolv="$newconf" 428382a10eSAaron LI 438382a10eSAaron LI# Using dbus means that we never have to restart the daemon 448382a10eSAaron LI# This is important as it means we should not drop DNS queries 458382a10eSAaron LI# whilst changing DNS options around. However, dbus support is optional 468382a10eSAaron LI# so we need to validate a few things first. 478382a10eSAaron LI# Check for DBus support in the binary 488382a10eSAaron LIdbus=false 498382a10eSAaron LIdbus_ex=false 508382a10eSAaron LIdbus_introspect=$(dbus-send --print-reply --system \ 518382a10eSAaron LI --dest=uk.org.thekelleys.dnsmasq \ 528382a10eSAaron LI /uk/org/thekelleys/dnsmasq \ 538382a10eSAaron LI org.freedesktop.DBus.Introspectable.Introspect \ 548382a10eSAaron LI 2>/dev/null) 558382a10eSAaron LIif [ $? = 0 ]; then 568382a10eSAaron LI dbus=true 578382a10eSAaron LI if printf %s "$dbus_introspect" | \ 588382a10eSAaron LI grep -q '<method name="SetDomainServers">' 598382a10eSAaron LI then 608382a10eSAaron LI dbus_ex=true 618382a10eSAaron LI fi 628382a10eSAaron LIfi 638382a10eSAaron LI 648382a10eSAaron LIfor n in $NAMESERVERS; do 658382a10eSAaron LI newresolv="${newresolv}nameserver $n$NL" 668382a10eSAaron LIdone 678382a10eSAaron LI 688382a10eSAaron LIdbusdest= 698382a10eSAaron LIdbusdest_ex= 708382a10eSAaron LIconf= 718382a10eSAaron LIfor d in $DOMAINS; do 728382a10eSAaron LI dn="${d%%:*}" 738382a10eSAaron LI ns="${d#*:}" 748382a10eSAaron LI while [ -n "$ns" ]; do 758382a10eSAaron LI n="${ns%%,*}" 768382a10eSAaron LI if $dbus && ! $dbus_ex; then 778382a10eSAaron LI case "$n" in 788382a10eSAaron LI *.*.*.*) 798382a10eSAaron LI SIFS=${IFS-y} OIFS=$IFS 808382a10eSAaron LI IFS=. 818382a10eSAaron LI set -- $n 828382a10eSAaron LI num="0x$(printf %02x $1 $2 $3 $4)" 838382a10eSAaron LI if [ "$SIFS" = y ]; then 848382a10eSAaron LI unset IFS 858382a10eSAaron LI else 868382a10eSAaron LI IFS=$OIFS 878382a10eSAaron LI fi 888382a10eSAaron LI dbusdest="$dbusdest uint32:$(printf %u $num)" 898382a10eSAaron LI dbusdest="$dbusdest string:$dn" 908382a10eSAaron LI ;; 918382a10eSAaron LI *:*%*) 928382a10eSAaron LI # This version of dnsmasq won't accept 938382a10eSAaron LI # scoped IPv6 addresses 948382a10eSAaron LI dbus=false 958382a10eSAaron LI ;; 968382a10eSAaron LI *:*) 978382a10eSAaron LI SIFS=${IFS-y} OIFS=$IFS bytes= front= back= 988382a10eSAaron LI empty=false i=0 998382a10eSAaron LI IFS=: 1008382a10eSAaron LI set -- $n 101a37440eeSRoy Marples while [ -n "$1" ] || [ -n "$2" ]; do 1028382a10eSAaron LI addr="$1" 1038382a10eSAaron LI shift 1048382a10eSAaron LI if [ -z "$addr" ]; then 1058382a10eSAaron LI empty=true 1068382a10eSAaron LI continue 1078382a10eSAaron LI fi 108*d19862cdSRoy Marples i=$((i + 1)) 1098382a10eSAaron LI while [ ${#addr} -lt 4 ]; do 1108382a10eSAaron LI addr="0${addr}" 1118382a10eSAaron LI done 1128382a10eSAaron LI byte1="$(printf %d 0x${addr%??})" 1138382a10eSAaron LI byte2="$(printf %d 0x${addr#??})" 1148382a10eSAaron LI if $empty; then 1158382a10eSAaron LI back="$back byte:$byte1 byte:$byte2" 1168382a10eSAaron LI else 1178382a10eSAaron LI front="$front byte:$byte1 byte:$byte2" 1188382a10eSAaron LI fi 1198382a10eSAaron LI done 1208382a10eSAaron LI while [ $i != 8 ]; do 121*d19862cdSRoy Marples i=$((i + 1)) 1228382a10eSAaron LI front="$front byte:0 byte:0" 1238382a10eSAaron LI done 1248382a10eSAaron LI front="${front}$back" 1258382a10eSAaron LI if [ "$SIFS" = y ]; then 1268382a10eSAaron LI unset IFS 1278382a10eSAaron LI else 1288382a10eSAaron LI IFS=$OIFS 1298382a10eSAaron LI fi 1308382a10eSAaron LI dbusdest="${dbusdest}$front string:$dn" 1318382a10eSAaron LI ;; 1328382a10eSAaron LI *) 1338382a10eSAaron LI if ! $dbus_ex; then 1348382a10eSAaron LI dbus=false 1358382a10eSAaron LI fi 1368382a10eSAaron LI ;; 1378382a10eSAaron LI esac 1388382a10eSAaron LI fi 1398382a10eSAaron LI dbusdest_ex="$dbusdest_ex${dbusdest_ex:+,}/$dn/$n" 1408382a10eSAaron LI conf="${conf}server=/$dn/$n$NL" 1418382a10eSAaron LI [ "$ns" = "${ns#*,}" ] && break 1428382a10eSAaron LI ns="${ns#*,}" 1438382a10eSAaron LI done 1448382a10eSAaron LIdone 1458382a10eSAaron LI 1468382a10eSAaron LIif $dbus; then 1478382a10eSAaron LI newconf="$newconf$NL# Domain specific servers will" 1488382a10eSAaron LI newconf="$newconf be sent over dbus${NL}" 1498382a10eSAaron LIelse 1508382a10eSAaron LI newconf="$newconf$conf" 1518382a10eSAaron LIfi 1528382a10eSAaron LI 1538382a10eSAaron LI# Try to ensure that config dirs exist 154*d19862cdSRoy Marplesif command -v config_mkdirs >/dev/null 2>&1; then 1558382a10eSAaron LI config_mkdirs "$dnsmasq_conf" "$dnsmasq_resolv" 1568382a10eSAaron LIelse 1578382a10eSAaron LI @SBINDIR@/resolvconf -D "$dnsmasq_conf" "$dnsmasq_resolv" 1588382a10eSAaron LIfi 1598382a10eSAaron LI 1608382a10eSAaron LIchanged=false 1618382a10eSAaron LIif [ -n "$dnsmasq_conf" ]; then 1628382a10eSAaron LI if [ ! -f "$dnsmasq_conf" ] || \ 1638382a10eSAaron LI [ "$(cat "$dnsmasq_conf")" != "$(printf %s "$newconf")" ] 1648382a10eSAaron LI then 1658382a10eSAaron LI changed=true 1668382a10eSAaron LI printf %s "$newconf" >"$dnsmasq_conf" 1678382a10eSAaron LI fi 1688382a10eSAaron LIfi 1698382a10eSAaron LIif [ -n "$dnsmasq_resolv" ]; then 1708382a10eSAaron LI # dnsmasq polls this file so no need to set changed=true 1718382a10eSAaron LI if [ -f "$dnsmasq_resolv" ]; then 1728382a10eSAaron LI if [ "$(cat "$dnsmasq_resolv")" != "$(printf %s "$newresolv")" ] 1738382a10eSAaron LI then 1748382a10eSAaron LI printf %s "$newresolv" >"$dnsmasq_resolv" 1758382a10eSAaron LI fi 1768382a10eSAaron LI else 1778382a10eSAaron LI printf %s "$newresolv" >"$dnsmasq_resolv" 1788382a10eSAaron LI fi 1798382a10eSAaron LIfi 1808382a10eSAaron LI 1818382a10eSAaron LIif $changed; then 1828382a10eSAaron LI # dnsmasq does not re-read the configuration file on SIGHUP 1838382a10eSAaron LI if [ -n "$dnsmasq_restart" ]; then 1848382a10eSAaron LI eval $dnsmasq_restart 1858382a10eSAaron LI elif [ -n "$RESTARTCMD" ]; then 1868382a10eSAaron LI set -- ${dnsmasq_service} 187a37440eeSRoy Marples eval "$RESTARTCMD" 1888382a10eSAaron LI else 1898382a10eSAaron LI @SBINDIR@/resolvconf -r ${dnsmasq_service} 1908382a10eSAaron LI fi 1918382a10eSAaron LIfi 1928382a10eSAaron LIif $dbus; then 1938382a10eSAaron LI if [ -s "$dnsmasq_pid" ]; then 1948382a10eSAaron LI $changed || kill -HUP $(cat "$dnsmasq_pid") 1958382a10eSAaron LI fi 1968382a10eSAaron LI # Send even if empty so old servers are cleared 1978382a10eSAaron LI if $dbus_ex; then 1988382a10eSAaron LI method=SetDomainServers 1998382a10eSAaron LI if [ -n "$dbusdest_ex" ]; then 2008382a10eSAaron LI dbusdest_ex="array:string:$dbusdest_ex" 2018382a10eSAaron LI fi 2028382a10eSAaron LI dbusdest="$dbusdest_ex" 2038382a10eSAaron LI else 2048382a10eSAaron LI method=SetServers 2058382a10eSAaron LI fi 2068382a10eSAaron LI dbus-send --system --dest=uk.org.thekelleys.dnsmasq \ 2078382a10eSAaron LI /uk/org/thekelleys/dnsmasq uk.org.thekelleys.$method \ 2088382a10eSAaron LI $dbusdest 209a37440eeSRoy Marples dbus-send --system --dest=uk.org.thekelleys.dnsmasq \ 210a37440eeSRoy Marples /uk/org/thekelleys/dnsmasq uk.org.thekelleys.ClearCache 2118382a10eSAaron LIfi 212