2 # Copyright 2006 Gentoo Foundation
3 # Copyright 2007 Roy Marples
6 # Redistribution and use in source and binary forms, with or without
7 # modification, are permitted provided that the following conditions
9 # * Redistributions of source code must retain the above copyright
10 # notice, this list of conditions and the following disclaimer.
11 # * Redistributions in binary form must reproduce the above
12 # copyright notice, this list of conditions and the following
13 # disclaimer in the documentation and/or other materials provided
14 # with the distribution.
16 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 RESOLVCONF="${PREFIX}"/etc/resolvconf
32 UPDATED="${RESOLVCONF}"/update.d
33 VARDIR="${RESOLVCONF}"/run
34 IFACEDIR="${VARDIR}/interfaces"
43 Usage: ${argv0##*/} [options]
45 Inform the system about any DNS updates.
48 -a \$INTERFACE Add DNS information to the specified interface
49 (DNS supplied via stdin in resolv.conf format)
50 -d \$INTERFACE Delete DNS information from the specified interface
51 -u Run updates from our current DNS information
52 -l [\$PATTERN] Show DNS information, optionally from interfaces
53 that match the specified pattern
54 -i [\$PATTERN] Show interfaces that have supplied DNS information
55 optionally from interfaces that match the specified
57 -v [\$PATTERN] echo NEWDOMAIN, NEWSEARCH and NEWNS variables to
59 -s \$SVC \$CMD Do \$CMD for the system service \$SVC
60 -h Show this help cruft
68 [ -n "$1" -a -e "${IFACEDIR}/$1" ] || return 1
69 echo "# resolv.conf for interface $1"
70 grep "." "${IFACEDIR}/$1"
79 *) result="${result} $1" ;;
91 # We do our service restarting here so that our subscribers don't have to know
92 # about the OS's init system.
93 if [ "x${CMD}" = "x-s" ]; then
98 [ -z "${SERVICE}" ] && usage "Service not specified"
103 [ -z "${ACTION}" ] && usage "Action not specified"
105 # If restarting check if service is running or not if we can
106 if [ "x${ACTION}" = "xrestart" ]; then
107 if [ -s /var/run/"${SERVICE}".pid ]; then
108 kill -0 $(cat /var/run/"${SERVICE}".pid)
109 elif [ -s /var/run/"${SERVICE}"/"${SERVICE}".pid ]; then
110 kill -0 $(cat /var/run/"${SERVICE}".pid)
111 elif [ -s /var/run/"${SERVICE}"/pid ]; then
112 kill -0 $(cat /var/run/"${SERVICE}"/pid)
116 # Service not running, so don't restart
117 [ $? != 0 ] && exit 1
119 if [ -x /sbin/service ]; then
120 service "${SERVICE}" "${ACTION}" "$@"
121 elif [ -x /etc/init.d/"${SERVICE}" -a -x /sbin/runscript ]; then
122 if [ "x${ACTION}" = "xrestart" ]; then
123 /etc/init.d/"${SERVICE}" --quiet --nodeps conditionalrestart "$@"
125 /etc/init.d/"${SERVICE}" --quiet --nodeps "${ACTION}" "$@"
127 elif [ -x /etc/init.d/"${SERVICE}" ]; then
128 /etc/init.d/"${SERVICE}" "${ACTION}" "$@"
129 elif [ -x /etc/rc.d/"${SERVICE}" ]; then
130 /etc/rc.d/"${SERVICE}" "${ACTION}" "$@"
131 elif [ -x /etc/rc.d/rc."${SERVICE}" ]; then
132 /etc/rc.d/rc."${SERVICE}" "${ACTION}" "$@"
134 error_exit "Don't know how to interact with services on this platform"
144 # -l is a Gentoo option that lists our resolv files
145 # optionally for a specific interface
146 if [ "x${CMD}" = "x-l" -o "x${CMD}" = "x-i" ]; then
147 [ -d "${IFACEDIR}" ] || exit 0
149 # If we have an interface ordering list, then use that.
150 # It works by just using pathname expansion in the interface directory.
151 if [ -n "${IFACE}" ]; then
153 elif [ -r "${RESOLVCONF}"/interface-order ]; then
154 LIST="$(cat "${RESOLVCONF}"/interface-order)"
157 # If we don't have a list then prefer lo, tunnels, ppp
158 # and then anything else.
159 if [ -z "${LIST}" ]; then
160 LIST="lo lo[0-9]* tap[0-9]* tun[0-9]* vpn vpn[0-9]* ppp[0-9]* ippp[0-9]* *"
164 for IFACE in $(uniqify ${LIST}); do
165 # Only list interfaces which we really have
166 [ -e "${IFACE}" ] || continue
168 if [ "x${CMD}" = "x-i" ]; then
171 echo_resolv "${IFACE}"
174 [ "x${CMD}" = "x-i" ] && echo
178 if [ "x${CMD}" = "x-v" ]; then
185 LINES="$("${argv0}" -l "${IFACE}" | sed -e "s/'/'\\\\''/g" -e "s/^/'/g" -e "s/$/'/g")"
193 NS="${NS}${LINE#* } "
196 [ -z "${SEARCH}" ] && DOMAIN="${LINE#* }"
203 if [ -z "${LINE}" ]; then
205 if [ -n "${DOMAIN}" ]; then
206 NEWDOMAIN="${NEWDOMAIN} ${DOMAIN},${N}"
207 elif [ -n "${SEARCH}" ]; then
208 for S in ${SEARCH}; do
209 NEWSEARCH="${NEWSEARCH} ${S},${N}"
212 NEWNS="${NEWNS} ${N}"
223 # Prefer DOMAIN nameservers over SEARCH nameservers
224 # if we are supplied both.
225 NEWDOMAIN="$(uniqify ${NEWDOMAIN})"
226 NEWSEARCH="$(uniqify ${NEWSEARCH})"
227 NEWNS="$(uniqify ${NEWNS})"
228 for S in ${NEWSEARCH}; do
229 for DN in ${NEWDOMAIN}; do
230 if [ "${S%,*}" = "${DN%,*}" ]; then
231 NEWSEARCH="$(echo "${NEWSEARCH}" | sed -e "s/${S}/${DN}/g")"
232 NEWDOMAIN="$(echo "${NEWDOMAIN}" | sed -e "s/${DN}//g")"
238 echo "NEWDOMAIN='${NEWDOMAIN}'"
239 echo "NEWSEARCH='${NEWSEARCH}'"
240 echo "NEWNS='${NEWNS}'"
244 # Test that we have valid options
245 if [ "x${CMD}" = "x-a" -o "x${CMD}" = "x-d" ]; then
246 if [ -z "${IFACE}" ]; then
247 usage "Interface not specified"
249 elif [ "x${CMD}" != "x-u" ]; then
250 [ -n "x${CMD}" -a "x${CMD}" != "x-h" ] && usage "Unknown option ${CMD}"
253 if [ "x${CMD}" = "x-a" ]; then
254 for x in '/' \\ ' ' '*'; do
256 *[${x}]*) error_exit "${x} not allowed in interface name" ;;
259 for x in '.' '-' '~'; do
261 [${x}]*) error_exit "${x} not allowed at start of interface name" ;;
264 [ "x${CMD}" = "x-a" -a -t 0 ] && error_exit "No file given via stdin"
265 IFACERESOLV="${IFACEDIR}/${IFACE}"
268 # Ensure that libdir exists
269 if [ ! -d "${IFACEDIR}" ]; then
270 if [ ! -d "${VARDIR}" ]; then
271 if [ -L "${VARDIR}" ]; then
272 DIR="$(readlink "${VARDIR}")"
273 # Change to /etc as link maybe relative
275 if ! mkdir -m 0755 -p "${DIR}"; then
276 error_exit "Failed to create needed directory ${DIR}"
279 if ! mkdir -m 0755 -p "${VARDIR}"; then
280 error_exit "Failed to create needed directory ${VARDIR}"
284 mkdir -m 0755 -p "${IFACEDIR}" || \
285 error_exit "Failed to create needed directory ${IFACEDIR}"
287 # Delete any existing information about the interface
288 if [ "x${CMD}" = "x-a" -o "x${CMD}" = "x-d" ]; then
290 for iface in ${IFACE}; do
291 rm -f "${iface}" || exit $?
296 if [ "x${CMD}" = "x-a" ]; then
297 # Create our resolv.conf file
298 cat >"${IFACEDIR}"/"${IFACE}" || exit $?
302 for x in "${UPDATED}"/*; do
303 if [ -e "${x}" ]; then
304 "${x}" "${CMD}" "${IFACE}"
305 retval=$((${retval} + $?))