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