1219732Sume#!/bin/sh
2282434Sgjb# Copyright (c) 2010-2013 Roy Marples
3219732Sume# All rights reserved
4219732Sume
5219732Sume# pdnsd subscriber for resolvconf
6219732Sume
7219732Sume# Redistribution and use in source and binary forms, with or without
8219732Sume# modification, are permitted provided that the following conditions
9219732Sume# are met:
10219732Sume#     * Redistributions of source code must retain the above copyright
11219732Sume#       notice, this list of conditions and the following disclaimer.
12219732Sume#     * Redistributions in binary form must reproduce the above
13219732Sume#       copyright notice, this list of conditions and the following
14219732Sume#       disclaimer in the documentation and/or other materials provided
15219732Sume#       with the distribution.
16219732Sume#
17219732Sume# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18219732Sume# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19219732Sume# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20219732Sume# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
21219732Sume# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22219732Sume# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23219732Sume# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24219732Sume# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25219732Sume# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26219732Sume# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27219732Sume# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28219732Sume
29219732Sume[ -f "@SYSCONFDIR@"/resolvconf.conf ] || exit 0
30219732Sume. "@SYSCONFDIR@/resolvconf.conf" || exit 1
31219732Sume[ -z "$pdnsd_conf" -a -z "$pdnsd_resolv" ] && exit 0
32282434Sgjb[ -z "$RESOLVCONF" ] && eval "$(@SBINDIR@/resolvconf -v)"
33282434SgjbNL="
34282434Sgjb"
35219732Sume
36219732Sume: ${pdnsd_restart:=pdnsd-ctl config $pdnsd_conf}
37219732Sumesignature="# Generated by resolvconf"
38219732Sumesignature_end="# End of resolvconf"
39219732Sume
40219732Sume# We normally use sed to remove markers from a configuration file
41219732Sume# but sed may not always be available at the time.
42219732Sumeremove_markers()
43219732Sume{
44219732Sume	local m1="$1" m2="$2" x= line= in_marker=0
45219732Sume
46219732Sume	shift; shift
47219732Sume	if type sed >/dev/null 2>&1; then
48219732Sume		sed "/^$m1/,/^$m2/d" $@
49219732Sume	else
50219732Sume		for x; do
51282434Sgjb			while read -r line; do
52219732Sume				case "$line" in
53219732Sume				"$m1"*) in_marker=1;;
54219732Sume				"$m2"*) in_marker=0;;
55219732Sume				*) [ $in_marker = 0 ] && echo "$line";;
56219732Sume				esac
57219732Sume			done < "$x"
58219732Sume		done
59219732Sume	fi
60219732Sume}
61219732Sume
62219732Sume# Compare two files
63219732Sume# If different, replace first with second otherwise remove second
64219732Sumechange_file()
65219732Sume{
66219732Sume	if [ -e "$1" ]; then
67219732Sume		if type cmp >/dev/null 2>&1; then
68219732Sume			cmp -s "$1" "$2"
69219732Sume		elif type diff >/dev/null 2>&1; then
70219732Sume			diff -q "$1" "$2" >/dev/null
71219732Sume		else
72219732Sume			# Hopefully we're only working on small text files ...
73219732Sume			[ "$(cat "$1")" = "$(cat "$2")" ]
74219732Sume		fi
75219732Sume		if [ $? -eq 0 ]; then
76219732Sume			rm -f "$2"
77219732Sume			return 1
78219732Sume		fi
79219732Sume	fi
80219732Sume	cat "$2" > "$1"
81219732Sume	rm -f "$2"
82219732Sume	return 0
83219732Sume}
84219732Sume
85282434Sgjbnewresolv="# Generated by resolvconf$NL"
86219732Sumechanged=false
87219732Sume
88282434Sgjb# Try to ensure that config dirs exist
89282434Sgjbif type config_mkdirs >/dev/null 2>&1; then
90282434Sgjb	config_mkdirs "$pdnsd_resolv" "$pdnsd_conf"
91282434Sgjbelse
92282434Sgjb	@SBINDIR@/resolvconf -D "$pdnsd_resolv" "$pdnsd_conf"
93282434Sgjbfi
94282434Sgjb
95219732Sumeif [ -n "$pdnsd_resolv" ]; then
96219732Sume	for n in $NAMESERVERS; do
97282434Sgjb		newresolv="${newresolv}nameserver $n$NL"
98219732Sume	done
99219732Sumefi
100219732Sume
101282434Sgjb# Only modify the configuration if it exists and we can write to it
102282434Sgjbif [ -w "$pdnsd_conf" ]; then
103219732Sume	cf="$pdnsd_conf.new"
104219732Sume	newconf=
105219732Sume
106219732Sume	if [ -z "$pdnsd_resolv" ]; then
107282434Sgjb		newconf="${newconf}server {$NL"
108282434Sgjb		newconf="${newconf}	label=resolvconf;$NL"
109219732Sume		if [ -n "$NAMESERVERS" ]; then
110282434Sgjb			newconf="${newconf}	ip="
111219732Sume			first=true
112219732Sume			for n in $NAMESERVERS; do
113219732Sume				if $first; then
114219732Sume					first=false
115219732Sume				else
116219732Sume					newconf="${newconf},"
117219732Sume				fi
118219732Sume				newconf="$newconf$n"
119219732Sume			done
120282434Sgjb			newconf="${newconf};$NL"
121219732Sume		fi
122282434Sgjb		newconf="${newconf}}$NL"
123219732Sume	fi
124219732Sume
125219732Sume	for d in $DOMAINS; do
126282434Sgjb		newconf="${newconf}server {$NL"
127282434Sgjb		newconf="${newconf}	include=.${d%%:*}.;$NL"
128282434Sgjb		newconf="${newconf}	policy=excluded;$NL"
129282434Sgjb		newconf="${newconf}	ip="
130219732Sume		ns="${d#*:}"
131219732Sume		while [ -n "$ns" ]; do
132219732Sume			newconf="${newconf}${ns%%,*}"
133219732Sume			[ "$ns" = "${ns#*,}" ] && break
134219732Sume			ns="${ns#*,}"
135219732Sume			newconf="${newconf},"
136219732Sume		done
137282434Sgjb		newconf="${newconf};$NL}$NL"
138219732Sume	done
139219732Sume
140219732Sume	rm -f "$cf"
141219732Sume	remove_markers "$signature" "$signature_end" "$pdnsd_conf" > "$cf"
142219732Sume	if [ -n "$newconf" ]; then
143219732Sume		echo "$signature" >> "$cf"
144225524Shrs		printf %s "$newconf" >> "$cf"
145219732Sume		echo "$signature_end" >> "$cf"
146219732Sume	fi
147219732Sume	if change_file "$pdnsd_conf" "$cf"; then
148219732Sume		changed=true
149282434Sgjb	fi
150219732Sumefi
151219732Sume
152219732Sumeif [ -n "$pdnsd_resolv" ]; then
153219732Sume	if [ ! -f "$pdnsd_resolv" ] || \
154225524Shrs		[ "$(cat "$pdnsd_resolv")" != "$(printf %s "$newresolv")" ]
155219732Sume	then
156219732Sume		changed=true
157225524Shrs		printf %s "$newresolv" >"$pdnsd_resolv"
158219732Sume	fi
159219732Sumefi
160219732Sume
161219732Sumeif $changed; then
162219732Sume	eval $pdnsd_restart
163219732Sumefi
164