1#!/bin/sh 2# Copyright (c) 2007-2009 Roy Marples 3# All rights reserved 4 5# libc subscriber for resolvconf 6 7# Redistribution and use in source and binary forms, with or without 8# modification, are permitted provided that the following conditions 9# are met: 10# * Redistributions of source code must retain the above copyright 11# notice, this list of conditions and the following disclaimer. 12# * Redistributions in binary form must reproduce the above 13# copyright notice, this list of conditions and the following 14# disclaimer in the documentation and/or other materials provided 15# with the distribution. 16# 17# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 18# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 19# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 20# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 21# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 22# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 23# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 29SYSCONFDIR=@SYSCONFDIR@ 30LIBEXECDIR=@LIBEXECDIR@ 31VARDIR=@VARDIR@ 32IFACEDIR="$VARDIR/interfaces" 33 34# sed may not be available, and this is faster on small files 35key_get_value() 36{ 37 local key="$1" value= x= line= 38 39 shift 40 if [ $# -eq 0 ]; then 41 while read line; do 42 case "$line" in 43 "$key"*) echo "${line##$key}";; 44 esac 45 done 46 else 47 for x; do 48 while read line; do 49 case "$line" in 50 "$key"*) echo "${line##$key}";; 51 esac 52 done < "$x" 53 done 54 fi 55} 56 57# Support original resolvconf configuration layout 58# as well as the openresolv config file 59if [ -f "$SYSCONFDIR"/resolvconf.conf ]; then 60 . "$SYSCONFDIR"/resolvconf.conf 61elif [ -d "$SYSCONFDIR"/resolvconf ]; then 62 SYSCONFDIR="$SYSCONFDIR/resolvconf/resolv.conf.d" 63 base="$SYSCONFDIR/resolv.conf.d/base" 64 if [ -f "$base" ]; then 65 name_servers="$(key_get_value "nameserver " "$base")" 66 search_domains="$(key_get_value "search " "$base")" 67 if [ -z "$search_domains" ]; then 68 search_domains="$(key_get_value "domain " "$base")" 69 fi 70 resolv_conf_options="$(key_get_value "options " "$base")" 71 fi 72 if [ -f "$SYSCONFDIR"/resolv.conf.d/head ]; then 73 resolv_conf_head="$(cat "${SYSCONFDIR}"/resolv.conf.d/head)" 74 fi 75 if [ -f "$SYSCONFDIR"/resolv.conf.d/tail ]; then 76 resolv_conf_tail="$(cat "$SYSCONFDIR"/resolv.conf.d/tail)" 77 fi 78fi 79: ${resolv_conf:=/etc/resolv.conf} 80: ${libc_service:=nscd} 81: ${libc_restart:=@RESTARTCMD ${libc_service}@} 82: ${list_resolv:=@PREFIX@/sbin/resolvconf -l} 83if [ "${resolv_conf_head-x}" = x -a -f "$SYSCONFDIR"/resolv.conf.head ]; then 84 resolv_conf_head="$(cat "${SYSCONFDIR}"/resolv.conf.head)" 85fi 86if [ "${resolv_conf_tail-x}" = x -a -f "$SYSCONFDIR"/resolv.conf.tail ]; then 87 resolv_conf_tail="$(cat "$SYSCONFDIR"/resolv.conf.tail)" 88fi 89 90uniqify() 91{ 92 local result= 93 while [ -n "$1" ]; do 94 case " $result " in 95 *" $1 "*);; 96 *) result="$result $1";; 97 esac 98 shift 99 done 100 echo "${result# *}" 101} 102 103case "${resolv_conf_passthrough:-NO}" in 104[Yy][Ee][Ss]|[Tt][Rr][Uu][Ee]|[Oo][Nn]|1) 105 newest= 106 for conf in "$IFACEDIR"/*; do 107 if [ -z "$newest" -o "$conf" -nt "$newest" ]; then 108 newest="$conf" 109 fi 110 done 111 [ -z "$newest" ] && exit 0 112 newconf="$(cat "$newest")\n" 113 ;; 114*) 115 [ -z "$RESOLVCONF" ] && eval "$(@PREFIX@/sbin/resolvconf -v)" 116 newsearch="$(uniqify $search_domains $SEARCH $search_domains_append)" 117 NS="$LOCALNAMESERVERS $NAMESERVERS" 118 newns="$(uniqify $name_servers $NS $name_servers_append)" 119 120 # Hold our new resolv.conf in a variable to save on temporary files 121 newconf="# Generated by resolvconf\n" 122 if [ -n "$resolv_conf_head" ]; then 123 newconf="$newconf$resolv_conf_head\n" 124 fi 125 [ -n "$newsearch" ] && newconf="${newconf}search $newsearch\n" 126 for n in $newns; do 127 newconf="${newconf}nameserver $n\n" 128 done 129 130 # Now get any configured options 131 opts="$resolv_conf_options${resolv_conf_options:+ }" 132 opts="$opts$($list_resolv | key_get_value "options ")" 133 if [ -n "$opts" ]; then 134 newconf="${newconf}options" 135 for opt in $(uniqify $opts); do 136 newconf="${newconf} $opt" 137 done 138 newconf="$newconf\n" 139 fi 140 141 if [ -n "$resolv_conf_tail" ]; then 142 newconf="$newconf$resolv_conf_tail\n" 143 fi 144 ;; 145esac 146 147# Check if the file has actually changed or not 148if [ -e "$resolv_conf" ]; then 149 [ "$(cat "$resolv_conf")" = "$(printf "$newconf")" ] && exit 0 150fi 151 152# Create our resolv.conf now 153(umask 022; printf "$newconf" >"$resolv_conf") 154eval $libc_restart 155 156retval=0 157# Notify users of the resolver 158for script in "$LIBEXECDIR"/libc.d/*; do 159 if [ -f "$script" ]; then 160 if [ -x "$script" ]; then 161 "$script" "$@" 162 else 163 (. "$script" "$@") 164 fi 165 retval=$(($retval + $?)) 166 fi 167done 168exit $retval 169