1#!/bin/sh 2# Copyright (c) 2007-2012 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" 33NL=" 34" 35 36# sed may not be available, and this is faster on small files 37key_get_value() 38{ 39 local key="$1" x= line= 40 41 shift 42 if [ $# -eq 0 ]; then 43 while read -r line; do 44 case "$line" in 45 "$key"*) echo "${line##$key}";; 46 esac 47 done 48 else 49 for x do 50 while read -r line; do 51 case "$line" in 52 "$key"*) echo "${line##$key}";; 53 esac 54 done < "$x" 55 done 56 fi 57} 58 59keys_remove() 60{ 61 local key x line found 62 63 while read -r line; do 64 found=false 65 for key do 66 case "$line" in 67 "$key"*|"#"*|" "*|" "*|"") found=true;; 68 esac 69 $found && break 70 done 71 $found || echo "$line" 72 done 73} 74 75# Support original resolvconf configuration layout 76# as well as the openresolv config file 77if [ -f "$SYSCONFDIR"/resolvconf.conf ]; then 78 . "$SYSCONFDIR"/resolvconf.conf 79elif [ -d "$SYSCONFDIR"/resolvconf ]; then 80 SYSCONFDIR="$SYSCONFDIR/resolvconf/resolv.conf.d" 81 base="$SYSCONFDIR/resolv.conf.d/base" 82 if [ -f "$base" ]; then 83 prepend_nameservers="$(key_get_value "nameserver " "$base")" 84 domain="$(key_get_value "domain " "$base")" 85 prepend_search="$(key_get_value "search " "$base")" 86 resolv_conf_options="$(key_get_value "options " "$base")" 87 resolv_conf_sortlist="$(key_get_value "sortlist " "$base")" 88 fi 89 if [ -f "$SYSCONFDIR"/resolv.conf.d/head ]; then 90 resolv_conf_head="$(cat "${SYSCONFDIR}"/resolv.conf.d/head)" 91 fi 92 if [ -f "$SYSCONFDIR"/resolv.conf.d/tail ]; then 93 resolv_conf_tail="$(cat "$SYSCONFDIR"/resolv.conf.d/tail)" 94 fi 95fi 96: ${domain:=$DOMAIN} 97: ${resolv_conf:=/etc/resolv.conf} 98: ${libc_service:=nscd} 99: ${libc_restart:=@RESTARTCMD ${libc_service}@} 100: ${list_resolv:=@SBINDIR@/resolvconf -l} 101if [ "${resolv_conf_head-x}" = x -a -f "$SYSCONFDIR"/resolv.conf.head ]; then 102 resolv_conf_head="$(cat "${SYSCONFDIR}"/resolv.conf.head)" 103fi 104if [ "${resolv_conf_tail-x}" = x -a -f "$SYSCONFDIR"/resolv.conf.tail ]; then 105 resolv_conf_tail="$(cat "$SYSCONFDIR"/resolv.conf.tail)" 106fi 107 108uniqify() 109{ 110 local result= 111 while [ -n "$1" ]; do 112 case " $result " in 113 *" $1 "*);; 114 *) result="$result $1";; 115 esac 116 shift 117 done 118 echo "${result# *}" 119} 120 121case "${resolv_conf_passthrough:-NO}" in 122[Yy][Ee][Ss]|[Tt][Rr][Uu][Ee]|[Oo][Nn]|1) 123 newest= 124 for conf in "$IFACEDIR"/*; do 125 if [ -z "$newest" -o "$conf" -nt "$newest" ]; then 126 newest="$conf" 127 fi 128 done 129 [ -z "$newest" ] && exit 0 130 newconf="$(cat "$newest")$NL" 131 ;; 132*) 133 [ -z "$RESOLVCONF" ] && eval "$(@SBINDIR@/resolvconf -v)" 134 newsearch="$(uniqify $prepend_search $SEARCH)" 135 NS="$LOCALNAMESERVERS $NAMESERVERS" 136 newns= 137 gotlocal=false 138 for n in $(uniqify $prepend_nameservers $NS); do 139 add=true 140 case "$n" in 141 127.*|0.0.0.0|255.255.255.255|::1) gotlocal=true;; 142 *) 143 case "${resolv_conf_local_only:-YES}" in 144 [Yy][Ee][Ss]|[Tt][Rr][Uu][Ee]|[Oo][Nn]|1) 145 $gotlocal && add=false;; 146 esac 147 esac 148 $add && newns="$newns $n" 149 done 150 151 # Hold our new resolv.conf in a variable to save on temporary files 152 newconf="# Generated by resolvconf$NL" 153 if [ -n "$resolv_conf_head" ]; then 154 newconf="$newconf$resolv_conf_head$NL" 155 fi 156 157 [ -n "$domain" ] && newconf="${newconf}domain $domain$NL" 158 if [ -n "$newsearch" -a "$newsearch" != "$domain" ]; then 159 newconf="${newconf}search $newsearch$NL" 160 fi 161 for n in $newns; do 162 newconf="${newconf}nameserver $n$NL" 163 done 164 165 # Now add anything we don't care about such as sortlist and options 166 stuff="$($list_resolv | keys_remove nameserver domain search)" 167 if [ -n "$stuff" ]; then 168 newconf="$newconf$stuff$NL" 169 fi 170 171 # Append any user defined ones 172 if [ -n "$resolv_conf_options" ]; then 173 newconf="${newconf}options $resolv_conf_options$NL" 174 fi 175 if [ -n "$resolv_conf_sortlist" ]; then 176 newconf="${newconf}sortlist $resolv_conf_sortlist$NL" 177 fi 178 179 if [ -n "$resolv_conf_tail" ]; then 180 newconf="$newconf$resolv_conf_tail$NL" 181 fi 182 ;; 183esac 184 185# Check if the file has actually changed or not 186if [ -e "$resolv_conf" ]; then 187 [ "$(cat "$resolv_conf")" = "$(printf %s "$newconf")" ] && exit 0 188fi 189 190# Create our resolv.conf now 191(umask 022; printf %s "$newconf" >"$resolv_conf") 192eval $libc_restart 193 194retval=0 195# Notify users of the resolver 196for script in "$LIBEXECDIR"/libc.d/*; do 197 if [ -f "$script" ]; then 198 if [ -x "$script" ]; then 199 "$script" "$@" 200 else 201 (. "$script") 202 fi 203 retval=$(($retval + $?)) 204 fi 205done 206exit $retval 207