kill 2>/dev/null as we just interested in if we can signal it or not.
[openresolv] / dnsmasq.in
1 #!/bin/sh
2 # Copyright 2007 Roy Marples
3 # All rights reserved
4
5 # dnsmasq subscriber for resolvconf
6
7 # Redistribution and use in source and binary forms, with or without
8 # modification, are permitted provided that the following conditions
9 # are met:
10 #     * Redistributions of source code must retain the above copyright
11 #       notice, this list of conditions and the following disclaimer.
12 #     * Redistributions in binary form must reproduce the above
13 #       copyright notice, this list of conditions and the following
14 #       disclaimer in the documentation and/or other materials provided
15 #       with the distribution.
16 #
17 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18 # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19 # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20 # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
21 # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22 # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23 # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28
29 # This is very important!
30 # We assume that we are a local dns cache - after all, why would a server
31 # use resolvconf?
32 # Now that we have assumed this, we also assume that generic DHCP clients
33 # will enter their domains and search domains ONLY in the "search" field
34 # in their resolv.confs and VPN clients will put the domain they are for
35 # into the domain field only.
36 # This allows dnsmasq to forward domains for a specific VPN domain to the
37 # VPN nameserver and everything else to the standard name servers.
38
39 # A sample dnsmasq config that works as above is like so.
40 # NOTE: The loopback interface on some systems maybe lo0.
41 #domain-needed
42 #interface=lo
43 #resolv-file=/etc/dnsmasq-resolv.conf
44 #conf-file=/etc/dnsmasq-resolvconf.conf
45
46 # The last step is to configure dns configuration for /etc/resolv.conf
47 # for the lo interface. You can do this in resolvconf as well by adding
48 #nameserver 127.0.0.1
49 # to resolv.conf.d/base
50
51 # Load our variables from resolvconf
52 VARS="$(resolvconf -v)"
53 eval "${VARS}"
54
55 PREFIX=
56 DNSMASQRESOLV="${PREFIX}/etc/dnsmasq-resolv.conf"
57 DNSMASQCONF="${PREFIX}/etc/dnsmasq-resolvconf.conf"
58
59 NEWCONF="# Generated by resolvconf\n"
60 NEWRESOLV="${NEWCONF}"
61
62 # Using DBUS means that we never have to restart the daemon
63 # This is important as it means we should not drop DNS queries
64 # whilst changing DNS options around. However, DBUS support is optional
65 # so we need to validate a few things first.
66 # Check for DBus support in the binary
67 DBUS=no
68 dbuspid=/var/run/dbus/dbus.pid
69 [ -s "${dbuspid}" ] || dbuspid=/var/run/dbus.pid
70 if [ -s "${dbuspid}" -a -s /var/run/dnsmasq.pid ]; then
71         if dnsmasq --version 2>/dev/null | \
72                 grep -q "^Compile time options.*[[:space:]]DBus[[:space:]]" \
73                 ; then
74                 # Sanity - check that dnsmasq and dbus are running
75                 if kill -0 $(cat "${dbuspid}") 2>/dev/null \
76                         && kill -0 $(cat /var/run/dnsmasq.pid) 2>/dev/null; then
77                         DBUS=yes
78                         NEWCONF="${NEWCONF}\n# Domain specific servers will be sent over dbus\nenable-dbus\n"
79                 fi
80         fi
81 fi
82
83 uniqify() {
84     local result=
85     while [ -n "$1" ]; do
86                 case " ${result} " in
87                         *" $1 "*);;
88                         *) result="${result} $1";;
89                 esac
90                 shift
91         done
92     echo "${result# *}"
93 }
94
95 # If we only have domain information then put it in search too
96 [ -z "${NEWSEARCH}" -a -z "${NEWNS}" ] && NEWSEARCH="${NEWDOMAIN}"
97
98 for N in ${NEWSEARCH}; do
99         case " ${NEWSL} " in
100                 *" ${N%,*} "*);;
101                 *) NEWSL="${NEWSL} ${N%,*}";;
102         esac
103         case "\n${NEWRESOLV}\n" in
104                 *"\nnameserver ${N#*,}\n"*);;
105                 *) NEWRESOLV="${NEWRESOLV}nameserver ${N#*,}\n";;
106         esac
107 done
108 for N in ${NEWNS}; do
109         case "\n${NEWRESOLV}\n" in
110                 *"\nnameserver ${N}\n");;
111                 *) NEWRESOLV="${NEWRESOLV}nameserver ${N}\n";;
112         esac
113 done
114 [ -n "${NEWSL}" ] && NEWRESOLV="${NEWRESOLV}search${NEWSL}\n"
115
116 DBUSDEST=
117 for DN in $(uniqify ${NEWDOMAIN}); do
118         if [ "${DBUS}" = "yes" ]; then
119                 IP=${DN#*,}
120                 SIFS=${IFS-y} OIFS=$IFS
121                 IFS=.
122                 set -- ${IP}
123                 NUM="0x$(printf "%02x" $1 $2 $3 $4)"
124                 if [ "${SIFS}" = "y" ]; then
125                         unset IFS
126                 else
127                         IFS=$OIFS
128                 fi
129                 DBUSDEST="${DBUSDEST} uint32:$(printf "%d" ${NUM}) string:${DN%,*}"
130         else
131                 NEWCONF="${NEWCONF}server=/${DN%,*}/${DN#*,}\n"
132         fi
133 done
134
135 RELOAD="no"
136 if [ -e "${DNSMASQCONF}" ]; then
137         if [ "$(cat "${DNSMASQCONF}")" != "$(printf "${NEWCONF}")" ]; then
138                 RELOAD="yes"
139                 printf "${NEWCONF}" > "${DNSMASQCONF}"
140         fi
141 else
142         RELOAD="yes"
143         printf "${NEWCONF}" > "${DNSMASQCONF}"
144 fi
145 if [ -e "${DNSMASQRESOLV}" ]; then
146         if [ "$(cat "${DNSMASQRESOLV}")" != "$(printf "${NEWRESOLV}")" ]; then
147                 RELOAD="yes"
148                 printf "${NEWRESOLV}" > "${DNSMASQRESOLV}"
149         fi
150 else
151         # dnsmasq polls this file so no need to set RELOAD="yes"
152         printf "${NEWRESOLV}" > "${DNSMASQRESOLV}"
153 fi
154
155 [ "${RELOAD}" = "yes" ] && resolvconf -s dnsmasq restart
156 if [ "${DBUS}" = "yes" ]; then
157         [ "${RELOAD}" != "yes" ] && resolvconf -s dnsmasq reload
158         # Send even if emtpy so old servers are cleared
159         dbus-send --system --dest=uk.org.thekelleys.dnsmasq \
160                 /uk/org/thekelleys/dnsmasq uk.org.thekelleys.SetServers \
161                 ${DBUSDEST}
162 fi
163
164 # vim: ts=4 :