xref: /freebsd/contrib/openresolv/resolvconf.in (revision 342af4d5efec74bb4bc11261fdd9991c53616f54)
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=
131
132	for n; do
133		printf "%s" "${n%.}"
134	done
135	printf "\n"
136}
137
138# Parse resolv.conf's and make variables
139# for domain name servers, search name servers and global nameservers
140parse_resolv()
141{
142	local line= ns= ds= search= d= n= newns=
143	local new=true iface= private=false p= domain= l= islocal=
144
145	newns=
146
147	while read -r line; do
148		case "$line" in
149		"# resolv.conf from "*)
150			if ${new}; then
151				iface="${line#\# resolv.conf from *}"
152				new=false
153				if [ -e "$PRIVATEDIR/$iface" ]; then
154					private=true
155				else
156					# Allow expansion
157					cd "$IFACEDIR"
158					private=false
159					for p in $private_interfaces; do
160						case "$iface" in
161						"$p"|"$p":*) private=true; break;;
162						esac
163					done
164				fi
165			fi
166			;;
167		"nameserver "*)
168			islocal=false
169			for l in $local_nameservers; do
170				case "${line#* }" in
171				$l)
172					islocal=true
173					echo "LOCALNAMESERVERS=\"\$LOCALNAMESERVERS ${line#* }\""
174					break
175					;;
176				esac
177			done
178			$islocal || ns="$ns${line#* } "
179			;;
180		"domain "*)
181			search="$(strip_trailing_dots ${line#* })"
182			if [ -z "$domain" ]; then
183				domain="$search"
184				echo "DOMAIN=\"$domain\""
185			fi
186			;;
187		"search "*)
188			search="$(strip_trailing_dots ${line#* })"
189			;;
190		*)
191			[ -n "$line" ] && continue
192			if [ -n "$ns" -a -n "$search" ]; then
193				newns=
194				for n in $ns; do
195					newns="$newns${newns:+,}$n"
196				done
197				ds=
198				for d in $search; do
199					ds="$ds${ds:+ }$d:$newns"
200				done
201				echo "DOMAINS=\"\$DOMAINS $ds\""
202			fi
203			echo "SEARCH=\"\$SEARCH $search\""
204			if ! $private; then
205				echo "NAMESERVERS=\"\$NAMESERVERS $ns\""
206			fi
207			ns=
208			search=
209			new=true
210			;;
211		esac
212	done
213}
214
215uniqify()
216{
217	local result=
218	while [ -n "$1" ]; do
219		case " $result " in
220		*" $1 "*);;
221		*) result="$result $1";;
222		esac
223		shift
224	done
225	echo "${result# *}"
226}
227
228dirname()
229{
230	local dir= OIFS="$IFS"
231	local IFS=/
232	set -- $@
233	IFS="$OIFS"
234	if [ -n "$1" ]; then
235		printf %s .
236	else
237		shift
238	fi
239	while [ -n "$2" ]; do
240		printf "/%s" "$1"
241		shift
242	done
243	printf "\n"
244}
245
246config_mkdirs()
247{
248	local e=0 f d
249	for f; do
250		[ -n "$f" ] || continue
251		d="$(dirname "$f")"
252		if [ ! -d "$d" ]; then
253			if type install >/dev/null 2>&1; then
254				install -d "$d" || e=$?
255			else
256				mkdir "$d" || e=$?
257			fi
258		fi
259	done
260	return $e
261}
262
263list_resolv()
264{
265	[ -d "$IFACEDIR" ] || return 0
266
267	local report=false list= retval=0 cmd="$1" excl=
268	shift
269
270	case "$IF_EXCLUSIVE" in
271	[Yy][Ee][Ss]|[Tt][Rr][Uu][Ee]|[Oo][Nn]|1)
272		if [ -d "$EXCLUSIVEDIR" ]; then
273			cd "$EXCLUSIVEDIR"
274			for i in *; do
275				if [ -f "$i" ]; then
276					list="${i#* }"
277					break
278				fi
279			done
280		fi
281		excl=true
282		;;
283	*)
284		excl=false
285		;;
286	esac
287
288	# If we have an interface ordering list, then use that.
289	# It works by just using pathname expansion in the interface directory.
290	if [ -n "$1" ]; then
291		list="$*"
292		$force || report=true
293	elif ! $excl; then
294		cd "$IFACEDIR"
295		for i in $interface_order; do
296			[ -f "$i" ] && list="$list $i"
297			for ii in "$i":* "$i".*; do
298				[ -f "$ii" ] && list="$list $ii"
299			done
300		done
301		for i in $dynamic_order; do
302			if [ -e "$i" -a ! -e "$METRICDIR/"*" $i" ]; then
303				list="$list $i"
304			fi
305			for ii in "$i":* "$i".*; do
306				if [ -f "$ii" -a ! -e "$METRICDIR/"*" $ii" ]; then
307					list="$list $ii"
308				fi
309			done
310		done
311		if [ -d "$METRICDIR" ]; then
312			cd "$METRICDIR"
313			for i in *; do
314				[ -f "$i" ] && list="$list ${i#* }"
315			done
316		fi
317		list="$list *"
318	fi
319
320	cd "$IFACEDIR"
321	retval=1
322	for i in $(uniqify $list); do
323		# Only list interfaces which we really have
324		if ! [ -f "$i" ]; then
325			if $report; then
326				echo "No resolv.conf for interface $i" >&2
327				retval=2
328			fi
329			continue
330		fi
331
332		if [ "$cmd" = i -o "$cmd" = "-i" ]; then
333			printf %s "$i "
334		else
335			echo_resolv "$i"
336		fi
337		[ $? = 0 -a "$retval" = 1 ] && retval=0
338	done
339	[ "$cmd" = i -o "$cmd" = "-i" ] && echo
340	return $retval
341}
342
343list_remove() {
344	local list= e= l= result= found= retval=0
345
346	[ -z "$2" ] && return 0
347	eval list=\"\$$1\"
348	shift
349
350	set -f
351	for e; do
352		found=false
353		for l in $list; do
354			case "$e" in
355			$l) found=true;;
356			esac
357			$found && break
358		done
359		if $found; then
360			retval=$(($retval + 1))
361		else
362			result="$result $e"
363		fi
364	done
365	set +f
366	echo "${result# *}"
367	return $retval
368}
369
370echo_prepend()
371{
372	echo "# Generated by resolvconf"
373	if [ -n "$search_domains" ]; then
374		echo "search $search_domains"
375	fi
376	for n in $name_servers; do
377		echo "nameserver $n"
378	done
379	echo
380}
381
382echo_append()
383{
384	echo "# Generated by resolvconf"
385	if [ -n "$search_domains_append" ]; then
386		echo "search $search_domains_append"
387	fi
388	for n in $name_servers_append; do
389		echo "nameserver $n"
390	done
391	echo
392}
393
394replace()
395{
396	local r= k= f= v= val= sub=
397
398	while read -r keyword value; do
399		for r in $replace; do
400			k="${r%%/*}"
401			r="${r#*/}"
402			f="${r%%/*}"
403			r="${r#*/}"
404			v="${r%%/*}"
405			case "$keyword" in
406			$k)
407				case "$value" in
408				$f) value="$v";;
409				esac
410				;;
411			esac
412		done
413		val=
414		for sub in $value; do
415			for r in $replace_sub; do
416				k="${r%%/*}"
417				r="${r#*/}"
418				f="${r%%/*}"
419				r="${r#*/}"
420				v="${r%%/*}"
421				case "$keyword" in
422				$k)
423					case "$sub" in
424					$f) sub="$v";;
425					esac
426					;;
427				esac
428			done
429			val="$val${val:+ }$sub"
430		done
431		printf "%s %s\n" "$keyword" "$val"
432	done
433}
434
435make_vars()
436{
437	local newdomains= d= dn= newns= ns=
438
439	# Clear variables
440	DOMAIN=
441	DOMAINS=
442	SEARCH=
443	NAMESERVERS=
444	LOCALNAMESERVERS=
445
446	if [ -n "$name_servers" -o -n "$search_domains" ]; then
447		eval "$(echo_prepend | parse_resolv)"
448	fi
449	if [ -z "$VFLAG" ]; then
450		IF_EXCLUSIVE=1
451		list_resolv -i "$@" >/dev/null || IF_EXCLUSIVE=0
452		eval "$(list_resolv -l "$@" | replace | parse_resolv)"
453	fi
454	if [ -n "$name_servers_append" -o -n "$search_domains_append" ]; then
455		eval "$(echo_append | parse_resolv)"
456	fi
457
458	# Ensure that we only list each domain once
459	for d in $DOMAINS; do
460		dn="${d%%:*}"
461		list_remove domain_blacklist "$dn" >/dev/null || continue
462		case " $newdomains" in
463		*" ${dn}:"*) continue;;
464		esac
465		newns=
466		for nd in $DOMAINS; do
467			if [ "$dn" = "${nd%%:*}" ]; then
468				ns="${nd#*:}"
469				while [ -n "$ns" ]; do
470					case ",$newns," in
471					*,${ns%%,*},*) ;;
472					*) list_remove name_server_blacklist \
473						"${ns%%,*}" >/dev/null \
474					&& newns="$newns${newns:+,}${ns%%,*}";;
475					esac
476					[ "$ns" = "${ns#*,}" ] && break
477					ns="${ns#*,}"
478				done
479			fi
480		done
481		if [ -n "$newns" ]; then
482			newdomains="$newdomains${newdomains:+ }$dn:$newns"
483		fi
484	done
485	DOMAIN="$(list_remove domain_blacklist $DOMAIN)"
486	SEARCH="$(uniqify $SEARCH)"
487	SEARCH="$(list_remove domain_blacklist $SEARCH)"
488	NAMESERVERS="$(uniqify $NAMESERVERS)"
489	NAMESERVERS="$(list_remove name_server_blacklist $NAMESERVERS)"
490	LOCALNAMESERVERS="$(uniqify $LOCALNAMESERVERS)"
491	LOCALNAMESERVERS="$(list_remove name_server_blacklist $LOCALNAMESERVERS)"
492	echo "DOMAIN='$DOMAIN'"
493	echo "SEARCH='$SEARCH'"
494	echo "NAMESERVERS='$NAMESERVERS'"
495	echo "LOCALNAMESERVERS='$LOCALNAMESERVERS'"
496	echo "DOMAINS='$newdomains'"
497}
498
499force=false
500VFLAG=
501while getopts a:Dd:fhIilm:puvVx OPT; do
502	case "$OPT" in
503	f) force=true;;
504	h) usage;;
505	m) IF_METRIC="$OPTARG";;
506	p) IF_PRIVATE=1;;
507	V)
508		VFLAG=1
509		if [ "$local_nameservers" = \
510		    "127.* 0.0.0.0 255.255.255.255 ::1" ]
511		then
512			local_nameservers=
513		fi
514		;;
515	x) IF_EXCLUSIVE=1;;
516	'?') ;;
517	*) cmd="$OPT"; iface="$OPTARG";;
518	esac
519done
520shift $(($OPTIND - 1))
521args="$iface${iface:+ }$*"
522
523# -I inits the state dir
524if [ "$cmd" = I ]; then
525	if [ -d "$VARDIR" ]; then
526		rm -rf "$VARDIR"/*
527	fi
528	exit $?
529fi
530
531# -D ensures that the listed config file base dirs exist
532if [ "$cmd" = D ]; then
533	config_mkdirs "$@"
534	exit $?
535fi
536
537# -l lists our resolv files, optionally for a specific interface
538if [ "$cmd" = l -o "$cmd" = i ]; then
539	list_resolv "$cmd" "$args"
540	exit $?
541fi
542
543# Not normally needed, but subscribers should be able to run independently
544if [ "$cmd" = v -o -n "$VFLAG" ]; then
545	make_vars "$iface"
546	exit $?
547fi
548
549# Test that we have valid options
550if [ "$cmd" = a -o "$cmd" = d ]; then
551	if [ -z "$iface" ]; then
552		usage "Interface not specified"
553	fi
554elif [ "$cmd" != u ]; then
555	[ -n "$cmd" -a "$cmd" != h ] && usage "Unknown option $cmd"
556	usage
557fi
558
559if [ "$cmd" = a ]; then
560	for x in '/' \\ ' ' '*'; do
561		case "$iface" in
562		*[$x]*) error_exit "$x not allowed in interface name";;
563		esac
564	done
565	for x in '.' '-' '~'; do
566		case "$iface" in
567		[$x]*) error_exit \
568			"$x not allowed at start of interface name";;
569		esac
570	done
571	[ "$cmd" = a -a -t 0 ] && error_exit "No file given via stdin"
572fi
573
574if [ ! -d "$VARDIR" ]; then
575	if [ -L "$VARDIR" ]; then
576		dir="$(readlink "$VARDIR")"
577		# link maybe relative
578		cd "${VARDIR%/*}"
579		if ! mkdir -m 0755 -p "$dir"; then
580			error_exit "Failed to create needed" \
581				"directory $dir"
582		fi
583	else
584		if ! mkdir -m 0755 -p "$VARDIR"; then
585			error_exit "Failed to create needed" \
586				"directory $VARDIR"
587		fi
588	fi
589fi
590
591if [ ! -d "$IFACEDIR" ]; then
592	mkdir -m 0755 -p "$IFACEDIR" || \
593		error_exit "Failed to create needed directory $IFACEDIR"
594	if [ "$cmd" = d ]; then
595		# Provide the same error messages as below
596		if ! ${force}; then
597			cd "$IFACEDIR"
598			for i in $args; do
599				warn "No resolv.conf for interface $i"
600			done
601		fi
602		${force}
603		exit $?
604	fi
605fi
606
607# An interface was added, changed, deleted or a general update was called.
608# Due to exclusivity we need to ensure that this is an atomic operation.
609# Our subscribers *may* need this as well if the init system is sub par.
610# As such we spinlock at this point as best we can.
611# We don't use flock(1) because it's not widely available and normally resides
612# in /usr which we do our very best to operate without.
613[ -w "$VARDIR" ] || error_exit "Cannot write to $LOCKDIR"
614: ${lock_timeout:=10}
615while true; do
616	if mkdir "$LOCKDIR" 2>/dev/null; then
617		trap 'rm -rf "$LOCKDIR";' EXIT
618		trap 'rm -rf "$LOCKDIR"; exit 1' INT QUIT ABRT SEGV ALRM TERM
619		echo $$ >"$LOCKDIR/pid"
620		break
621	fi
622	pid=$(cat "$LOCKDIR/pid")
623	if ! kill -0 "$pid"; then
624		warn "clearing stale lock pid $pid"
625		rm -rf "$LOCKDIR"
626		continue
627	fi
628	lock_timeout=$(($lock_timeout - 1))
629	if [ "$lock_timeout" -le 0 ]; then
630		error_exit "timed out waiting for lock from pid $pid"
631	fi
632	sleep 1
633done
634
635case "$cmd" in
636a)
637	# Read resolv.conf from stdin
638	resolv="$(cat)"
639	changed=false
640	changedfile=false
641	# If what we are given matches what we have, then do nothing
642	if [ -e "$IFACEDIR/$iface" ]; then
643		if [ "$(echo "$resolv")" != \
644			"$(cat "$IFACEDIR/$iface")" ]
645		then
646			changed=true
647			changedfile=true
648		fi
649	else
650		changed=true
651		changedfile=true
652	fi
653
654	# Set metric and private before creating the interface resolv.conf file
655	# to ensure that it will have the correct flags
656	[ ! -d "$METRICDIR" ] && mkdir "$METRICDIR"
657	oldmetric="$METRICDIR/"*" $iface"
658	newmetric=
659	if [ -n "$IF_METRIC" ]; then
660		# Pad metric to 6 characters, so 5 is less than 10
661		while [ ${#IF_METRIC} -le 6 ]; do
662			IF_METRIC="0$IF_METRIC"
663		done
664		newmetric="$METRICDIR/$IF_METRIC $iface"
665	fi
666	rm -f "$METRICDIR/"*" $iface"
667	[ "$oldmetric" != "$newmetric" -a \
668	    "$oldmetric" != "$METRICDIR/* $iface" ] &&
669		changed=true
670	[ -n "$newmetric" ] && echo " " >"$newmetric"
671
672	case "$IF_PRIVATE" in
673	[Yy][Ee][Ss]|[Tt][Rr][Uu][Ee]|[Oo][Nn]|1)
674		if [ ! -d "$PRIVATEDIR" ]; then
675			[ -e "$PRIVATEDIR" ] && rm "$PRIVATEDIR"
676			mkdir "$PRIVATEDIR"
677		fi
678		[ -e "$PRIVATEDIR/$iface" ] || changed=true
679		[ -d "$PRIVATEDIR" ] && echo " " >"$PRIVATEDIR/$iface"
680		;;
681	*)
682		if [ -e "$PRIVATEDIR/$iface" ]; then
683			rm -f "$PRIVATEDIR/$iface"
684			changed=true
685		fi
686		;;
687	esac
688
689	oldexcl=
690	for x in "$EXCLUSIVEDIR/"*" $iface"; do
691		if [ -f "$x" ]; then
692			oldexcl="$x"
693			break
694		fi
695	done
696	case "$IF_EXCLUSIVE" in
697	[Yy][Ee][Ss]|[Tt][Rr][Uu][Ee]|[Oo][Nn]|1)
698		if [ ! -d "$EXCLUSIVEDIR" ]; then
699			[ -e "$EXCLUSIVEDIR" ] && rm "$EXCLUSIVEDIR"
700			mkdir "$EXCLUSIVEDIR"
701		fi
702		cd "$EXCLUSIVEDIR"
703		for x in *; do
704			[ -f "$x" ] && break
705		done
706		if [ "${x#* }" != "$iface" ]; then
707			if [ "$x" = "${x% *}" ]; then
708				x=10000000
709			else
710				x="${x% *}"
711			fi
712			if [ "$x" = "0000000" ]; then
713				warn "exclusive underflow"
714			else
715				x=$(($x - 1))
716			fi
717			if [ -d "$EXCLUSIVEDIR" ]; then
718				echo " " >"$EXCLUSIVEDIR/$x $iface"
719			fi
720			changed=true
721		fi
722		;;
723	*)
724		if [ -f "$oldexcl" ]; then
725			rm -f "$oldexcl"
726			changed=true
727		fi
728		;;
729	esac
730
731	if $changedfile; then
732		printf "%s\n" "$resolv" >"$IFACEDIR/$iface" || exit $?
733	elif ! $changed; then
734		exit 0
735	fi
736	unset changed changedfile oldmetric newmetric x oldexcl
737	;;
738
739d)
740	# Delete any existing information about the interface
741	cd "$IFACEDIR"
742	changed=false
743	for i in $args; do
744		if [ -e "$i" ]; then
745			changed=true
746		elif ! ${force}; then
747			warn "No resolv.conf for interface $i"
748		fi
749		rm -f "$i" "$METRICDIR/"*" $i" \
750			"$PRIVATEDIR/$i" \
751			"$EXCLUSIVEDIR/"*" $i" || exit $?
752	done
753	if ! ${changed}; then
754		# Set the return code based on the forced flag
755		${force}
756		exit $?
757	fi
758	unset changed i
759	;;
760esac
761
762case "${resolvconf:-YES}" in
763[Yy][Ee][Ss]|[Tt][Rr][Uu][Ee]|[Oo][Nn]|1) ;;
764*) exit 0;;
765esac
766
767eval "$(make_vars)"
768export RESOLVCONF DOMAINS SEARCH NAMESERVERS LOCALNAMESERVERS
769: ${list_resolv:=list_resolv -l}
770retval=0
771
772# Run scripts in the same directory resolvconf is run from
773# in case any scripts accidently dump files in the wrong place.
774cd "$_PWD"
775for script in "$LIBEXECDIR"/*; do
776	if [ -f "$script" ]; then
777		eval script_enabled="\$${script##*/}"
778		case "${script_enabled:-YES}" in
779		[Yy][Ee][Ss]|[Tt][Rr][Uu][Ee]|[Oo][Nn]|1) ;;
780		*) continue;;
781		esac
782		if [ -x "$script" ]; then
783			"$script" "$cmd" "$iface"
784		else
785			(set -- "$cmd" "$iface"; . "$script")
786		fi
787		retval=$(($retval + $?))
788	fi
789done
790exit $retval
791