1219732Sume#!/bin/sh 2282746Sgjb# Copyright (c) 2007-2014 Roy Marples 3219732Sume# All rights reserved 4219732Sume 5219732Sume# libc subscriber for resolvconf 6219732Sume 7219732Sume# Redistribution and use in source and binary forms, with or without 8219732Sume# modification, are permitted provided that the following conditions 9219732Sume# are met: 10219732Sume# * Redistributions of source code must retain the above copyright 11219732Sume# notice, this list of conditions and the following disclaimer. 12219732Sume# * Redistributions in binary form must reproduce the above 13219732Sume# copyright notice, this list of conditions and the following 14219732Sume# disclaimer in the documentation and/or other materials provided 15219732Sume# with the distribution. 16219732Sume# 17219732Sume# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 18219732Sume# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 19219732Sume# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 20219732Sume# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 21219732Sume# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 22219732Sume# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 23219732Sume# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24219732Sume# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25219732Sume# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26219732Sume# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27219732Sume# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28219732Sume 29219732SumeSYSCONFDIR=@SYSCONFDIR@ 30219732SumeLIBEXECDIR=@LIBEXECDIR@ 31219732SumeVARDIR=@VARDIR@ 32219732SumeIFACEDIR="$VARDIR/interfaces" 33225524ShrsNL=" 34225524Shrs" 35219732Sume 36219732Sume# sed may not be available, and this is faster on small files 37219732Sumekey_get_value() 38219732Sume{ 39282746Sgjb local key="$1" x= line= 40219732Sume 41219732Sume shift 42219732Sume if [ $# -eq 0 ]; then 43282746Sgjb while read -r line; do 44219732Sume case "$line" in 45219732Sume "$key"*) echo "${line##$key}";; 46219732Sume esac 47219732Sume done 48219732Sume else 49282746Sgjb for x do 50282746Sgjb while read -r line; do 51219732Sume case "$line" in 52219732Sume "$key"*) echo "${line##$key}";; 53219732Sume esac 54219732Sume done < "$x" 55219732Sume done 56219732Sume fi 57219732Sume} 58219732Sume 59282746Sgjbkeys_remove() 60282746Sgjb{ 61282746Sgjb local key x line found 62282746Sgjb 63282746Sgjb while read -r line; do 64282746Sgjb found=false 65282746Sgjb for key do 66282746Sgjb case "$line" in 67282746Sgjb "$key"*|"#"*|" "*|" "*|"") found=true;; 68282746Sgjb esac 69282746Sgjb $found && break 70282746Sgjb done 71282746Sgjb $found || echo "$line" 72282746Sgjb done 73282746Sgjb} 74282746Sgjb 75282746Sgjblocal_nameservers="127.* 0.0.0.0 255.255.255.255 ::1" 76282746Sgjb 77219732Sume# Support original resolvconf configuration layout 78219732Sume# as well as the openresolv config file 79219732Sumeif [ -f "$SYSCONFDIR"/resolvconf.conf ]; then 80219732Sume . "$SYSCONFDIR"/resolvconf.conf 81219732Sumeelif [ -d "$SYSCONFDIR"/resolvconf ]; then 82219732Sume SYSCONFDIR="$SYSCONFDIR/resolvconf/resolv.conf.d" 83219732Sume base="$SYSCONFDIR/resolv.conf.d/base" 84219732Sume if [ -f "$base" ]; then 85282746Sgjb prepend_nameservers="$(key_get_value "nameserver " "$base")" 86282746Sgjb domain="$(key_get_value "domain " "$base")" 87282746Sgjb prepend_search="$(key_get_value "search " "$base")" 88219732Sume resolv_conf_options="$(key_get_value "options " "$base")" 89282746Sgjb resolv_conf_sortlist="$(key_get_value "sortlist " "$base")" 90219732Sume fi 91219732Sume if [ -f "$SYSCONFDIR"/resolv.conf.d/head ]; then 92219732Sume resolv_conf_head="$(cat "${SYSCONFDIR}"/resolv.conf.d/head)" 93219732Sume fi 94219732Sume if [ -f "$SYSCONFDIR"/resolv.conf.d/tail ]; then 95219732Sume resolv_conf_tail="$(cat "$SYSCONFDIR"/resolv.conf.d/tail)" 96219732Sume fi 97219732Sumefi 98219732Sume: ${resolv_conf:=/etc/resolv.conf} 99219732Sume: ${libc_service:=nscd} 100219732Sume: ${libc_restart:=@RESTARTCMD ${libc_service}@} 101282746Sgjb: ${list_resolv:=@SBINDIR@/resolvconf -l} 102219732Sumeif [ "${resolv_conf_head-x}" = x -a -f "$SYSCONFDIR"/resolv.conf.head ]; then 103219732Sume resolv_conf_head="$(cat "${SYSCONFDIR}"/resolv.conf.head)" 104219732Sumefi 105219732Sumeif [ "${resolv_conf_tail-x}" = x -a -f "$SYSCONFDIR"/resolv.conf.tail ]; then 106219732Sume resolv_conf_tail="$(cat "$SYSCONFDIR"/resolv.conf.tail)" 107219732Sumefi 108219732Sume 109282746Sgjbbackup=true 110282746Sgjbsignature="# Generated by resolvconf" 111282746Sgjb 112219732Sumeuniqify() 113219732Sume{ 114219732Sume local result= 115219732Sume while [ -n "$1" ]; do 116219732Sume case " $result " in 117219732Sume *" $1 "*);; 118219732Sume *) result="$result $1";; 119219732Sume esac 120219732Sume shift 121219732Sume done 122219732Sume echo "${result# *}" 123219732Sume} 124219732Sume 125219732Sumecase "${resolv_conf_passthrough:-NO}" in 126219732Sume[Yy][Ee][Ss]|[Tt][Rr][Uu][Ee]|[Oo][Nn]|1) 127282746Sgjb backup=false 128219732Sume newest= 129219732Sume for conf in "$IFACEDIR"/*; do 130219732Sume if [ -z "$newest" -o "$conf" -nt "$newest" ]; then 131219732Sume newest="$conf" 132219732Sume fi 133219732Sume done 134219732Sume [ -z "$newest" ] && exit 0 135225524Shrs newconf="$(cat "$newest")$NL" 136219732Sume ;; 137282746Sgjb/dev/null|[Nn][Uu][Ll][Ll]) 138282746Sgjb : ${resolv_conf_local_only:=NO} 139282746Sgjb if [ "$local_nameservers" = "127.* 0.0.0.0 255.255.255.255 ::1" ]; then 140282746Sgjb local_nameservers= 141282746Sgjb fi 142282746Sgjb # Need to overwrite our variables. 143282746Sgjb eval "$(@SBINDIR@/resolvconf -V)" 144282746Sgjb ;; 145282746Sgjb 146219732Sume*) 147282746Sgjb [ -z "$RESOLVCONF" ] && eval "$(@SBINDIR@/resolvconf -v)" 148282746Sgjb ;; 149282746Sgjbesac 150282746Sgjbcase "${resolv_conf_passthrough:-NO}" in 151282746Sgjb[Yy][Ee][Ss]|[Tt][Rr][Uu][Ee]|[Oo][Nn]|1) ;; 152282746Sgjb*) 153282746Sgjb : ${domain:=$DOMAIN} 154282746Sgjb newsearch="$(uniqify $prepend_search $SEARCH $append_search)" 155219732Sume NS="$LOCALNAMESERVERS $NAMESERVERS" 156282746Sgjb newns= 157282746Sgjb gotlocal=false 158282746Sgjb for n in $(uniqify $prepend_nameservers $NS $append_nameservers); do 159282746Sgjb add=true 160282746Sgjb islocal=false 161282746Sgjb for l in $local_nameservers; do 162282746Sgjb case "$n" in 163282746Sgjb $l) islocal=true; gotlocal=true; break;; 164282746Sgjb esac 165282746Sgjb done 166282746Sgjb if ! $islocal; then 167282746Sgjb case "${resolv_conf_local_only:-YES}" in 168282746Sgjb [Yy][Ee][Ss]|[Tt][Rr][Uu][Ee]|[Oo][Nn]|1) 169282746Sgjb $gotlocal && add=false;; 170282746Sgjb esac 171282746Sgjb fi 172282746Sgjb $add && newns="$newns $n" 173282746Sgjb done 174219732Sume 175219732Sume # Hold our new resolv.conf in a variable to save on temporary files 176282746Sgjb newconf="$signature$NL" 177219732Sume if [ -n "$resolv_conf_head" ]; then 178225524Shrs newconf="$newconf$resolv_conf_head$NL" 179219732Sume fi 180282746Sgjb 181282746Sgjb [ -n "$domain" ] && newconf="${newconf}domain $domain$NL" 182282746Sgjb if [ -n "$newsearch" -a "$newsearch" != "$domain" ]; then 183282746Sgjb newconf="${newconf}search $newsearch$NL" 184282746Sgjb fi 185219732Sume for n in $newns; do 186225524Shrs newconf="${newconf}nameserver $n$NL" 187219732Sume done 188219732Sume 189282746Sgjb # Now add anything we don't care about such as sortlist and options 190282746Sgjb stuff="$($list_resolv | keys_remove nameserver domain search)" 191282746Sgjb if [ -n "$stuff" ]; then 192282746Sgjb newconf="$newconf$stuff$NL" 193219732Sume fi 194219732Sume 195282746Sgjb # Append any user defined ones 196282746Sgjb if [ -n "$resolv_conf_options" ]; then 197282746Sgjb newconf="${newconf}options $resolv_conf_options$NL" 198282746Sgjb fi 199282746Sgjb if [ -n "$resolv_conf_sortlist" ]; then 200282746Sgjb newconf="${newconf}sortlist $resolv_conf_sortlist$NL" 201282746Sgjb fi 202282746Sgjb 203219732Sume if [ -n "$resolv_conf_tail" ]; then 204225524Shrs newconf="$newconf$resolv_conf_tail$NL" 205219732Sume fi 206219732Sume ;; 207219732Sumeesac 208219732Sume 209219732Sume# Check if the file has actually changed or not 210219732Sumeif [ -e "$resolv_conf" ]; then 211225524Shrs [ "$(cat "$resolv_conf")" = "$(printf %s "$newconf")" ] && exit 0 212219732Sumefi 213219732Sume 214282746Sgjb# Change is good. 215282746Sgjb# If the old file does not have our signature, back it up. 216282746Sgjb# If the new file just has our signature, restore the backup. 217282746Sgjbif $backup; then 218282746Sgjb if [ "$newconf" = "$signature$NL" ]; then 219282746Sgjb if [ -e "$resolv_conf.bak" ]; then 220282746Sgjb newconf="$(cat "$resolv_conf.bak")" 221282746Sgjb fi 222282746Sgjb elif [ -e "$resolv_conf" ]; then 223282746Sgjb read line <"$resolv_conf" 224282746Sgjb if [ "$line" != "$signature" ]; then 225282746Sgjb cp "$resolv_conf" "$resolv_conf.bak" 226282746Sgjb fi 227282746Sgjb fi 228282746Sgjbfi 229282746Sgjb 230219732Sume# Create our resolv.conf now 231225524Shrs(umask 022; echo "$newconf" >"$resolv_conf") 232219732Sumeeval $libc_restart 233219732Sume 234219732Sumeretval=0 235219732Sume# Notify users of the resolver 236219732Sumefor script in "$LIBEXECDIR"/libc.d/*; do 237219732Sume if [ -f "$script" ]; then 238219732Sume if [ -x "$script" ]; then 239219732Sume "$script" "$@" 240219732Sume else 241282746Sgjb (. "$script") 242219732Sume fi 243219732Sume retval=$(($retval + $?)) 244219732Sume fi 245219732Sumedone 246219732Sumeexit $retval 247