xref: /freebsd/contrib/openresolv/resolvconf.in (revision b1b73fc4c9924c4ca2f94b76155a0895373a0b5c)
1#!/bin/sh
2# Copyright (c) 2007-2016 Roy Marples
3# All rights reserved
4
5# Redistribution and use in source and binary forms, with or without
6# modification, are permitted provided that the following conditions
7# are met:
8#     * Redistributions of source code must retain the above copyright
9#       notice, this list of conditions and the following disclaimer.
10#     * Redistributions in binary form must reproduce the above
11#       copyright notice, this list of conditions and the following
12#       disclaimer in the documentation and/or other materials provided
13#       with the distribution.
14#
15# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
17# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
18# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
19# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
20# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
21# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
25# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26
27RESOLVCONF="$0"
28SYSCONFDIR=@SYSCONFDIR@
29LIBEXECDIR=@LIBEXECDIR@
30VARDIR=@VARDIR@
31
32# Disregard dhcpcd setting
33unset interface_order state_dir
34
35# If you change this, change the test in VFLAG and libc.in as well
36local_nameservers="127.* 0.0.0.0 255.255.255.255 ::1"
37
38dynamic_order="tap[0-9]* tun[0-9]* vpn vpn[0-9]* ppp[0-9]* ippp[0-9]*"
39interface_order="lo lo[0-9]*"
40name_server_blacklist="0.0.0.0"
41
42# Support original resolvconf configuration layout
43# as well as the openresolv config file
44if [ -f "$SYSCONFDIR"/resolvconf.conf ]; then
45	. "$SYSCONFDIR"/resolvconf.conf
46	[ -n "$state_dir" ] && VARDIR="$state_dir"
47elif [ -d "$SYSCONFDIR/resolvconf" ]; then
48	SYSCONFDIR="$SYSCONFDIR/resolvconf"
49	if [ -f "$SYSCONFDIR"/interface-order ]; then
50		interface_order="$(cat "$SYSCONFDIR"/interface-order)"
51	fi
52fi
53IFACEDIR="$VARDIR/interfaces"
54METRICDIR="$VARDIR/metrics"
55PRIVATEDIR="$VARDIR/private"
56EXCLUSIVEDIR="$VARDIR/exclusive"
57LOCKDIR="$VARDIR/lock"
58_PWD="$PWD"
59
60warn()
61{
62	echo "$*" >&2
63}
64
65error_exit()
66{
67	echo "$*" >&2
68	exit 1
69}
70
71usage()
72{
73	cat <<-EOF
74	Usage: ${RESOLVCONF##*/} [options]
75
76	Inform the system about any DNS updates.
77
78	Options:
79	  -a \$INTERFACE    Add DNS information to the specified interface
80	                   (DNS supplied via stdin in resolv.conf format)
81	  -m metric        Give the added DNS information a metric
82	  -p               Mark the interface as private
83	  -x               Mark the interface as exclusive
84	  -d \$INTERFACE    Delete DNS information from the specified interface
85	  -f               Ignore non existant interfaces
86	  -I               Init the state dir
87	  -u               Run updates from our current DNS information
88	  -l [\$PATTERN]    Show DNS information, optionally from interfaces
89	                   that match the specified pattern
90	  -i [\$PATTERN]    Show interfaces that have supplied DNS information
91                   optionally from interfaces that match the specified
92                   pattern
93	  -v [\$PATTERN]    echo NEWDOMAIN, NEWSEARCH and NEWNS variables to
94	  		   the console
95	  -h               Show this help cruft
96	EOF
97	[ -z "$1" ] && exit 0
98	echo
99	error_exit "$*"
100}
101
102echo_resolv()
103{
104	local line= OIFS="$IFS"
105
106	[ -n "$1" -a -f "$IFACEDIR/$1" ] || return 1
107	echo "# resolv.conf from $1"
108	# Our variable maker works of the fact each resolv.conf per interface
109	# is separated by blank lines.
110	# So we remove them when echoing them.
111	while read -r line; do
112		IFS="$OIFS"
113		if [ -n "$line" ]; then
114			# We need to set IFS here to preserve any whitespace
115			IFS=''
116			printf "%s\n" "$line"
117		fi
118	done < "$IFACEDIR/$1"
119	echo
120	IFS="$OIFS"
121}
122
123# Strip any trailing dot from each name as a FQDN does not belong
124# in resolv.conf(5)
125# If you think otherwise, capture a DNS trace and you'll see libc
126# will strip it regardless.
127# This also solves setting up duplicate zones in our subscribers.
128strip_trailing_dots()
129{
130	local n= d=
131
132	for n; do
133		printf "$d%s" "${n%.}"
134		d=" "
135	done
136	printf "\n"
137}
138
139# Parse resolv.conf's and make variables
140# for domain name servers, search name servers and global nameservers
141parse_resolv()
142{
143	local line= ns= ds= search= d= n= newns=
144	local new=true iface= private=false p= domain= l= islocal=
145
146	newns=
147
148	while read -r line; do
149		case "$line" in
150		"# resolv.conf from "*)
151			if ${new}; then
152				iface="${line#\# resolv.conf from *}"
153				new=false
154				if [ -e "$PRIVATEDIR/$iface" ]; then
155					private=true
156				else
157					# Allow expansion
158					cd "$IFACEDIR"
159					private=false
160					for p in $private_interfaces; do
161						case "$iface" in
162						"$p"|"$p":*) private=true; break;;
163						esac
164					done
165				fi
166			fi
167			;;
168		"nameserver "*)
169			islocal=false
170			for l in $local_nameservers; do
171				case "${line#* }" in
172				$l)
173					islocal=true
174					echo "LOCALNAMESERVERS=\"\$LOCALNAMESERVERS ${line#* }\""
175					break
176					;;
177				esac
178			done
179			$islocal || ns="$ns${line#* } "
180			;;
181		"domain "*)
182			search="$(strip_trailing_dots ${line#* })"
183			if [ -z "$domain" ]; then
184				domain="$search"
185				echo "DOMAIN=\"$domain\""
186			fi
187			;;
188		"search "*)
189			search="$(strip_trailing_dots ${line#* })"
190			;;
191		*)
192			[ -n "$line" ] && continue
193			if [ -n "$ns" -a -n "$search" ]; then
194				newns=
195				for n in $ns; do
196					newns="$newns${newns:+,}$n"
197				done
198				ds=
199				for d in $search; do
200					ds="$ds${ds:+ }$d:$newns"
201				done
202				echo "DOMAINS=\"\$DOMAINS $ds\""
203			fi
204			echo "SEARCH=\"\$SEARCH $search\""
205			if ! $private; then
206				echo "NAMESERVERS=\"\$NAMESERVERS $ns\""
207			fi
208			ns=
209			search=
210			new=true
211			;;
212		esac
213	done
214}
215
216uniqify()
217{
218	local result=
219	while [ -n "$1" ]; do
220		case " $result " in
221		*" $1 "*);;
222		*) result="$result $1";;
223		esac
224		shift
225	done
226	echo "${result# *}"
227}
228
229dirname()
230{
231	local dir= OIFS="$IFS"
232	local IFS=/
233	set -- $@
234	IFS="$OIFS"
235	if [ -n "$1" ]; then
236		printf %s .
237	else
238		shift
239	fi
240	while [ -n "$2" ]; do
241		printf "/%s" "$1"
242		shift
243	done
244	printf "\n"
245}
246
247config_mkdirs()
248{
249	local e=0 f d
250	for f; do
251		[ -n "$f" ] || continue
252		d="$(dirname "$f")"
253		if [ ! -d "$d" ]; then
254			if type install >/dev/null 2>&1; then
255				install -d "$d" || e=$?
256			else
257				mkdir "$d" || e=$?
258			fi
259		fi
260	done
261	return $e
262}
263
264list_resolv()
265{
266	[ -d "$IFACEDIR" ] || return 0
267
268	local report=false list= retval=0 cmd="$1" excl=
269	shift
270
271	case "$IF_EXCLUSIVE" in
272	[Yy][Ee][Ss]|[Tt][Rr][Uu][Ee]|[Oo][Nn]|1)
273		if [ -d "$EXCLUSIVEDIR" ]; then
274			cd "$EXCLUSIVEDIR"
275			for i in *; do
276				if [ -f "$i" ]; then
277					list="${i#* }"
278					break
279				fi
280			done
281		fi
282		excl=true
283		;;
284	*)
285		excl=false
286		;;
287	esac
288
289	# If we have an interface ordering list, then use that.
290	# It works by just using pathname expansion in the interface directory.
291	if [ -n "$1" ]; then
292		list="$*"
293		$force || report=true
294	elif ! $excl; then
295		cd "$IFACEDIR"
296		for i in $interface_order; do
297			[ -f "$i" ] && list="$list $i"
298			for ii in "$i":* "$i".*; do
299				[ -f "$ii" ] && list="$list $ii"
300			done
301		done
302		for i in $dynamic_order; do
303			if [ -e "$i" -a ! -e "$METRICDIR/"*" $i" ]; then
304				list="$list $i"
305			fi
306			for ii in "$i":* "$i".*; do
307				if [ -f "$ii" -a ! -e "$METRICDIR/"*" $ii" ]; then
308					list="$list $ii"
309				fi
310			done
311		done
312		if [ -d "$METRICDIR" ]; then
313			cd "$METRICDIR"
314			for i in *; do
315				[ -f "$i" ] && list="$list ${i#* }"
316			done
317		fi
318		list="$list *"
319	fi
320
321	cd "$IFACEDIR"
322	retval=1
323	for i in $(uniqify $list); do
324		# Only list interfaces which we really have
325		if ! [ -f "$i" ]; then
326			if $report; then
327				echo "No resolv.conf for interface $i" >&2
328				retval=2
329			fi
330			continue
331		fi
332
333		if [ "$cmd" = i -o "$cmd" = "-i" ]; then
334			printf %s "$i "
335		else
336			echo_resolv "$i"
337		fi
338		[ $? = 0 -a "$retval" = 1 ] && retval=0
339	done
340	[ "$cmd" = i -o "$cmd" = "-i" ] && echo
341	return $retval
342}
343
344list_remove() {
345	local list= e= l= result= found= retval=0
346
347	[ -z "$2" ] && return 0
348	eval list=\"\$$1\"
349	shift
350
351	set -f
352	for e; do
353		found=false
354		for l in $list; do
355			case "$e" in
356			$l) found=true;;
357			esac
358			$found && break
359		done
360		if $found; then
361			retval=$(($retval + 1))
362		else
363			result="$result $e"
364		fi
365	done
366	set +f
367	echo "${result# *}"
368	return $retval
369}
370
371echo_prepend()
372{
373	echo "# Generated by resolvconf"
374	if [ -n "$search_domains" ]; then
375		echo "search $search_domains"
376	fi
377	for n in $name_servers; do
378		echo "nameserver $n"
379	done
380	echo
381}
382
383echo_append()
384{
385	echo "# Generated by resolvconf"
386	if [ -n "$search_domains_append" ]; then
387		echo "search $search_domains_append"
388	fi
389	for n in $name_servers_append; do
390		echo "nameserver $n"
391	done
392	echo
393}
394
395replace()
396{
397	local r= k= f= v= val= sub=
398
399	while read -r keyword value; do
400		for r in $replace; do
401			k="${r%%/*}"
402			r="${r#*/}"
403			f="${r%%/*}"
404			r="${r#*/}"
405			v="${r%%/*}"
406			case "$keyword" in
407			$k)
408				case "$value" in
409				$f) value="$v";;
410				esac
411				;;
412			esac
413		done
414		val=
415		for sub in $value; do
416			for r in $replace_sub; do
417				k="${r%%/*}"
418				r="${r#*/}"
419				f="${r%%/*}"
420				r="${r#*/}"
421				v="${r%%/*}"
422				case "$keyword" in
423				$k)
424					case "$sub" in
425					$f) sub="$v";;
426					esac
427					;;
428				esac
429			done
430			val="$val${val:+ }$sub"
431		done
432		printf "%s %s\n" "$keyword" "$val"
433	done
434}
435
436make_vars()
437{
438	local newdomains= d= dn= newns= ns=
439
440	# Clear variables
441	DOMAIN=
442	DOMAINS=
443	SEARCH=
444	NAMESERVERS=
445	LOCALNAMESERVERS=
446
447	if [ -n "$name_servers" -o -n "$search_domains" ]; then
448		eval "$(echo_prepend | parse_resolv)"
449	fi
450	if [ -z "$VFLAG" ]; then
451		IF_EXCLUSIVE=1
452		list_resolv -i "$@" >/dev/null || IF_EXCLUSIVE=0
453		eval "$(list_resolv -l "$@" | replace | parse_resolv)"
454	fi
455	if [ -n "$name_servers_append" -o -n "$search_domains_append" ]; then
456		eval "$(echo_append | parse_resolv)"
457	fi
458
459	# Ensure that we only list each domain once
460	for d in $DOMAINS; do
461		dn="${d%%:*}"
462		list_remove domain_blacklist "$dn" >/dev/null || continue
463		case " $newdomains" in
464		*" ${dn}:"*) continue;;
465		esac
466		newns=
467		for nd in $DOMAINS; do
468			if [ "$dn" = "${nd%%:*}" ]; then
469				ns="${nd#*:}"
470				while [ -n "$ns" ]; do
471					case ",$newns," in
472					*,${ns%%,*},*) ;;
473					*) list_remove name_server_blacklist \
474						"${ns%%,*}" >/dev/null \
475					&& newns="$newns${newns:+,}${ns%%,*}";;
476					esac
477					[ "$ns" = "${ns#*,}" ] && break
478					ns="${ns#*,}"
479				done
480			fi
481		done
482		if [ -n "$newns" ]; then
483			newdomains="$newdomains${newdomains:+ }$dn:$newns"
484		fi
485	done
486	DOMAIN="$(list_remove domain_blacklist $DOMAIN)"
487	SEARCH="$(uniqify $SEARCH)"
488	SEARCH="$(list_remove domain_blacklist $SEARCH)"
489	NAMESERVERS="$(uniqify $NAMESERVERS)"
490	NAMESERVERS="$(list_remove name_server_blacklist $NAMESERVERS)"
491	LOCALNAMESERVERS="$(uniqify $LOCALNAMESERVERS)"
492	LOCALNAMESERVERS="$(list_remove name_server_blacklist $LOCALNAMESERVERS)"
493	echo "DOMAIN='$DOMAIN'"
494	echo "SEARCH='$SEARCH'"
495	echo "NAMESERVERS='$NAMESERVERS'"
496	echo "LOCALNAMESERVERS='$LOCALNAMESERVERS'"
497	echo "DOMAINS='$newdomains'"
498}
499
500force=false
501VFLAG=
502while getopts a:Dd:fhIilm:puvVx OPT; do
503	case "$OPT" in
504	f) force=true;;
505	h) usage;;
506	m) IF_METRIC="$OPTARG";;
507	p) IF_PRIVATE=1;;
508	V)
509		VFLAG=1
510		if [ "$local_nameservers" = \
511		    "127.* 0.0.0.0 255.255.255.255 ::1" ]
512		then
513			local_nameservers=
514		fi
515		;;
516	x) IF_EXCLUSIVE=1;;
517	'?') ;;
518	*) cmd="$OPT"; iface="$OPTARG";;
519	esac
520done
521shift $(($OPTIND - 1))
522args="$iface${iface:+ }$*"
523
524# -I inits the state dir
525if [ "$cmd" = I ]; then
526	if [ -d "$VARDIR" ]; then
527		rm -rf "$VARDIR"/*
528	fi
529	exit $?
530fi
531
532# -D ensures that the listed config file base dirs exist
533if [ "$cmd" = D ]; then
534	config_mkdirs "$@"
535	exit $?
536fi
537
538# -l lists our resolv files, optionally for a specific interface
539if [ "$cmd" = l -o "$cmd" = i ]; then
540	list_resolv "$cmd" "$args"
541	exit $?
542fi
543
544# Not normally needed, but subscribers should be able to run independently
545if [ "$cmd" = v -o -n "$VFLAG" ]; then
546	make_vars "$iface"
547	exit $?
548fi
549
550# Test that we have valid options
551if [ "$cmd" = a -o "$cmd" = d ]; then
552	if [ -z "$iface" ]; then
553		usage "Interface not specified"
554	fi
555elif [ "$cmd" != u ]; then
556	[ -n "$cmd" -a "$cmd" != h ] && usage "Unknown option $cmd"
557	usage
558fi
559
560if [ "$cmd" = a ]; then
561	for x in '/' \\ ' ' '*'; do
562		case "$iface" in
563		*[$x]*) error_exit "$x not allowed in interface name";;
564		esac
565	done
566	for x in '.' '-' '~'; do
567		case "$iface" in
568		[$x]*) error_exit \
569			"$x not allowed at start of interface name";;
570		esac
571	done
572	[ "$cmd" = a -a -t 0 ] && error_exit "No file given via stdin"
573fi
574
575if [ ! -d "$VARDIR" ]; then
576	if [ -L "$VARDIR" ]; then
577		dir="$(readlink "$VARDIR")"
578		# link maybe relative
579		cd "${VARDIR%/*}"
580		if ! mkdir -m 0755 -p "$dir"; then
581			error_exit "Failed to create needed" \
582				"directory $dir"
583		fi
584	else
585		if ! mkdir -m 0755 -p "$VARDIR"; then
586			error_exit "Failed to create needed" \
587				"directory $VARDIR"
588		fi
589	fi
590fi
591
592if [ ! -d "$IFACEDIR" ]; then
593	mkdir -m 0755 -p "$IFACEDIR" || \
594		error_exit "Failed to create needed directory $IFACEDIR"
595	if [ "$cmd" = d ]; then
596		# Provide the same error messages as below
597		if ! ${force}; then
598			cd "$IFACEDIR"
599			for i in $args; do
600				warn "No resolv.conf for interface $i"
601			done
602		fi
603		${force}
604		exit $?
605	fi
606fi
607
608# An interface was added, changed, deleted or a general update was called.
609# Due to exclusivity we need to ensure that this is an atomic operation.
610# Our subscribers *may* need this as well if the init system is sub par.
611# As such we spinlock at this point as best we can.
612# We don't use flock(1) because it's not widely available and normally resides
613# in /usr which we do our very best to operate without.
614[ -w "$VARDIR" ] || error_exit "Cannot write to $LOCKDIR"
615: ${lock_timeout:=10}
616while true; do
617	if mkdir "$LOCKDIR" 2>/dev/null; then
618		trap 'rm -rf "$LOCKDIR";' EXIT
619		trap 'rm -rf "$LOCKDIR"; exit 1' INT QUIT ABRT SEGV ALRM TERM
620		echo $$ >"$LOCKDIR/pid"
621		break
622	fi
623	pid=$(cat "$LOCKDIR/pid")
624	if ! kill -0 "$pid"; then
625		warn "clearing stale lock pid $pid"
626		rm -rf "$LOCKDIR"
627		continue
628	fi
629	lock_timeout=$(($lock_timeout - 1))
630	if [ "$lock_timeout" -le 0 ]; then
631		error_exit "timed out waiting for lock from pid $pid"
632	fi
633	sleep 1
634done
635
636case "$cmd" in
637a)
638	# Read resolv.conf from stdin
639	resolv="$(cat)"
640	changed=false
641	changedfile=false
642	# If what we are given matches what we have, then do nothing
643	if [ -e "$IFACEDIR/$iface" ]; then
644		if [ "$(echo "$resolv")" != \
645			"$(cat "$IFACEDIR/$iface")" ]
646		then
647			changed=true
648			changedfile=true
649		fi
650	else
651		changed=true
652		changedfile=true
653	fi
654
655	# Set metric and private before creating the interface resolv.conf file
656	# to ensure that it will have the correct flags
657	[ ! -d "$METRICDIR" ] && mkdir "$METRICDIR"
658	oldmetric="$METRICDIR/"*" $iface"
659	newmetric=
660	if [ -n "$IF_METRIC" ]; then
661		# Pad metric to 6 characters, so 5 is less than 10
662		while [ ${#IF_METRIC} -le 6 ]; do
663			IF_METRIC="0$IF_METRIC"
664		done
665		newmetric="$METRICDIR/$IF_METRIC $iface"
666	fi
667	rm -f "$METRICDIR/"*" $iface"
668	[ "$oldmetric" != "$newmetric" -a \
669	    "$oldmetric" != "$METRICDIR/* $iface" ] &&
670		changed=true
671	[ -n "$newmetric" ] && echo " " >"$newmetric"
672
673	case "$IF_PRIVATE" in
674	[Yy][Ee][Ss]|[Tt][Rr][Uu][Ee]|[Oo][Nn]|1)
675		if [ ! -d "$PRIVATEDIR" ]; then
676			[ -e "$PRIVATEDIR" ] && rm "$PRIVATEDIR"
677			mkdir "$PRIVATEDIR"
678		fi
679		[ -e "$PRIVATEDIR/$iface" ] || changed=true
680		[ -d "$PRIVATEDIR" ] && echo " " >"$PRIVATEDIR/$iface"
681		;;
682	*)
683		if [ -e "$PRIVATEDIR/$iface" ]; then
684			rm -f "$PRIVATEDIR/$iface"
685			changed=true
686		fi
687		;;
688	esac
689
690	oldexcl=
691	for x in "$EXCLUSIVEDIR/"*" $iface"; do
692		if [ -f "$x" ]; then
693			oldexcl="$x"
694			break
695		fi
696	done
697	case "$IF_EXCLUSIVE" in
698	[Yy][Ee][Ss]|[Tt][Rr][Uu][Ee]|[Oo][Nn]|1)
699		if [ ! -d "$EXCLUSIVEDIR" ]; then
700			[ -e "$EXCLUSIVEDIR" ] && rm "$EXCLUSIVEDIR"
701			mkdir "$EXCLUSIVEDIR"
702		fi
703		cd "$EXCLUSIVEDIR"
704		for x in *; do
705			[ -f "$x" ] && break
706		done
707		if [ "${x#* }" != "$iface" ]; then
708			if [ "$x" = "${x% *}" ]; then
709				x=10000000
710			else
711				x="${x% *}"
712			fi
713			if [ "$x" = "0000000" ]; then
714				warn "exclusive underflow"
715			else
716				x=$(($x - 1))
717			fi
718			if [ -d "$EXCLUSIVEDIR" ]; then
719				echo " " >"$EXCLUSIVEDIR/$x $iface"
720			fi
721			changed=true
722		fi
723		;;
724	*)
725		if [ -f "$oldexcl" ]; then
726			rm -f "$oldexcl"
727			changed=true
728		fi
729		;;
730	esac
731
732	if $changedfile; then
733		printf "%s\n" "$resolv" >"$IFACEDIR/$iface" || exit $?
734	elif ! $changed; then
735		exit 0
736	fi
737	unset changed changedfile oldmetric newmetric x oldexcl
738	;;
739
740d)
741	# Delete any existing information about the interface
742	cd "$IFACEDIR"
743	changed=false
744	for i in $args; do
745		if [ -e "$i" ]; then
746			changed=true
747		elif ! ${force}; then
748			warn "No resolv.conf for interface $i"
749		fi
750		rm -f "$i" "$METRICDIR/"*" $i" \
751			"$PRIVATEDIR/$i" \
752			"$EXCLUSIVEDIR/"*" $i" || exit $?
753	done
754	if ! ${changed}; then
755		# Set the return code based on the forced flag
756		${force}
757		exit $?
758	fi
759	unset changed i
760	;;
761esac
762
763case "${resolvconf:-YES}" in
764[Yy][Ee][Ss]|[Tt][Rr][Uu][Ee]|[Oo][Nn]|1) ;;
765*) exit 0;;
766esac
767
768eval "$(make_vars)"
769export RESOLVCONF DOMAINS SEARCH NAMESERVERS LOCALNAMESERVERS
770: ${list_resolv:=list_resolv -l}
771retval=0
772
773# Run scripts in the same directory resolvconf is run from
774# in case any scripts accidently dump files in the wrong place.
775cd "$_PWD"
776for script in "$LIBEXECDIR"/*; do
777	if [ -f "$script" ]; then
778		eval script_enabled="\$${script##*/}"
779		case "${script_enabled:-YES}" in
780		[Yy][Ee][Ss]|[Tt][Rr][Uu][Ee]|[Oo][Nn]|1) ;;
781		*) continue;;
782		esac
783		if [ -x "$script" ]; then
784			"$script" "$cmd" "$iface"
785		else
786			(set -- "$cmd" "$iface"; . "$script")
787		fi
788		retval=$(($retval + $?))
789	fi
790done
791exit $retval
792