1219732Sume#!/bin/sh 2304515Spfg# Copyright (c) 2007-2016 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{ 39282434Sgjb local key="$1" x= line= 40219732Sume 41219732Sume shift 42219732Sume if [ $# -eq 0 ]; then 43282434Sgjb while read -r line; do 44219732Sume case "$line" in 45219732Sume "$key"*) echo "${line##$key}";; 46219732Sume esac 47219732Sume done 48219732Sume else 49282434Sgjb for x do 50282434Sgjb 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 59282434Sgjbkeys_remove() 60282434Sgjb{ 61282434Sgjb local key x line found 62282434Sgjb 63282434Sgjb while read -r line; do 64282434Sgjb found=false 65282434Sgjb for key do 66282434Sgjb case "$line" in 67282434Sgjb "$key"*|"#"*|" "*|" "*|"") found=true;; 68282434Sgjb esac 69282434Sgjb $found && break 70282434Sgjb done 71282434Sgjb $found || echo "$line" 72282434Sgjb done 73282434Sgjb} 74282434Sgjb 75282434Sgjblocal_nameservers="127.* 0.0.0.0 255.255.255.255 ::1" 76282434Sgjb 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 85282434Sgjb prepend_nameservers="$(key_get_value "nameserver " "$base")" 86282434Sgjb domain="$(key_get_value "domain " "$base")" 87282434Sgjb prepend_search="$(key_get_value "search " "$base")" 88219732Sume resolv_conf_options="$(key_get_value "options " "$base")" 89282434Sgjb 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} 100282434Sgjb: ${list_resolv:=@SBINDIR@/resolvconf -l} 101219732Sumeif [ "${resolv_conf_head-x}" = x -a -f "$SYSCONFDIR"/resolv.conf.head ]; then 102219732Sume resolv_conf_head="$(cat "${SYSCONFDIR}"/resolv.conf.head)" 103219732Sumefi 104219732Sumeif [ "${resolv_conf_tail-x}" = x -a -f "$SYSCONFDIR"/resolv.conf.tail ]; then 105219732Sume resolv_conf_tail="$(cat "$SYSCONFDIR"/resolv.conf.tail)" 106219732Sumefi 107219732Sume 108282434Sgjbbackup=true 109282434Sgjbsignature="# Generated by resolvconf" 110282434Sgjb 111219732Sumeuniqify() 112219732Sume{ 113219732Sume local result= 114219732Sume while [ -n "$1" ]; do 115219732Sume case " $result " in 116219732Sume *" $1 "*);; 117219732Sume *) result="$result $1";; 118219732Sume esac 119219732Sume shift 120219732Sume done 121219732Sume echo "${result# *}" 122219732Sume} 123219732Sume 124219732Sumecase "${resolv_conf_passthrough:-NO}" in 125219732Sume[Yy][Ee][Ss]|[Tt][Rr][Uu][Ee]|[Oo][Nn]|1) 126282434Sgjb backup=false 127219732Sume newest= 128219732Sume for conf in "$IFACEDIR"/*; do 129219732Sume if [ -z "$newest" -o "$conf" -nt "$newest" ]; then 130219732Sume newest="$conf" 131219732Sume fi 132219732Sume done 133219732Sume [ -z "$newest" ] && exit 0 134225524Shrs newconf="$(cat "$newest")$NL" 135219732Sume ;; 136282434Sgjb/dev/null|[Nn][Uu][Ll][Ll]) 137282434Sgjb : ${resolv_conf_local_only:=NO} 138282434Sgjb if [ "$local_nameservers" = "127.* 0.0.0.0 255.255.255.255 ::1" ]; then 139282434Sgjb local_nameservers= 140282434Sgjb fi 141282434Sgjb # Need to overwrite our variables. 142282434Sgjb eval "$(@SBINDIR@/resolvconf -V)" 143282434Sgjb ;; 144282434Sgjb 145219732Sume*) 146282434Sgjb [ -z "$RESOLVCONF" ] && eval "$(@SBINDIR@/resolvconf -v)" 147282434Sgjb ;; 148282434Sgjbesac 149282434Sgjbcase "${resolv_conf_passthrough:-NO}" in 150282434Sgjb[Yy][Ee][Ss]|[Tt][Rr][Uu][Ee]|[Oo][Nn]|1) ;; 151282434Sgjb*) 152282434Sgjb : ${domain:=$DOMAIN} 153282434Sgjb newsearch="$(uniqify $prepend_search $SEARCH $append_search)" 154219732Sume NS="$LOCALNAMESERVERS $NAMESERVERS" 155282434Sgjb newns= 156282434Sgjb gotlocal=false 157282434Sgjb for n in $(uniqify $prepend_nameservers $NS $append_nameservers); do 158282434Sgjb add=true 159282434Sgjb islocal=false 160282434Sgjb for l in $local_nameservers; do 161282434Sgjb case "$n" in 162282434Sgjb $l) islocal=true; gotlocal=true; break;; 163282434Sgjb esac 164282434Sgjb done 165282434Sgjb if ! $islocal; then 166282434Sgjb case "${resolv_conf_local_only:-YES}" in 167282434Sgjb [Yy][Ee][Ss]|[Tt][Rr][Uu][Ee]|[Oo][Nn]|1) 168282434Sgjb $gotlocal && add=false;; 169282434Sgjb esac 170282434Sgjb fi 171282434Sgjb $add && newns="$newns $n" 172282434Sgjb done 173219732Sume 174219732Sume # Hold our new resolv.conf in a variable to save on temporary files 175282434Sgjb newconf="$signature$NL" 176219732Sume if [ -n "$resolv_conf_head" ]; then 177225524Shrs newconf="$newconf$resolv_conf_head$NL" 178219732Sume fi 179282434Sgjb 180282434Sgjb [ -n "$domain" ] && newconf="${newconf}domain $domain$NL" 181282434Sgjb if [ -n "$newsearch" -a "$newsearch" != "$domain" ]; then 182282434Sgjb newconf="${newconf}search $newsearch$NL" 183282434Sgjb fi 184219732Sume for n in $newns; do 185225524Shrs newconf="${newconf}nameserver $n$NL" 186219732Sume done 187219732Sume 188282434Sgjb # Now add anything we don't care about such as sortlist and options 189282434Sgjb stuff="$($list_resolv | keys_remove nameserver domain search)" 190282434Sgjb if [ -n "$stuff" ]; then 191282434Sgjb newconf="$newconf$stuff$NL" 192219732Sume fi 193219732Sume 194282434Sgjb # Append any user defined ones 195282434Sgjb if [ -n "$resolv_conf_options" ]; then 196282434Sgjb newconf="${newconf}options $resolv_conf_options$NL" 197282434Sgjb fi 198282434Sgjb if [ -n "$resolv_conf_sortlist" ]; then 199282434Sgjb newconf="${newconf}sortlist $resolv_conf_sortlist$NL" 200282434Sgjb fi 201282434Sgjb 202219732Sume if [ -n "$resolv_conf_tail" ]; then 203225524Shrs newconf="$newconf$resolv_conf_tail$NL" 204219732Sume fi 205219732Sume ;; 206219732Sumeesac 207219732Sume 208219732Sume# Check if the file has actually changed or not 209219732Sumeif [ -e "$resolv_conf" ]; then 210225524Shrs [ "$(cat "$resolv_conf")" = "$(printf %s "$newconf")" ] && exit 0 211219732Sumefi 212219732Sume 213282434Sgjb# Change is good. 214282434Sgjb# If the old file does not have our signature, back it up. 215282434Sgjb# If the new file just has our signature, restore the backup. 216282434Sgjbif $backup; then 217282434Sgjb if [ "$newconf" = "$signature$NL" ]; then 218282434Sgjb if [ -e "$resolv_conf.bak" ]; then 219313980Spfg newconf="$(cat "$resolv_conf.bak")$NL" 220282434Sgjb fi 221282434Sgjb elif [ -e "$resolv_conf" ]; then 222282434Sgjb read line <"$resolv_conf" 223282434Sgjb if [ "$line" != "$signature" ]; then 224282434Sgjb cp "$resolv_conf" "$resolv_conf.bak" 225282434Sgjb fi 226282434Sgjb fi 227282434Sgjbfi 228282434Sgjb 229219732Sume# Create our resolv.conf now 230225524Shrs(umask 022; echo "$newconf" >"$resolv_conf") 231304515Spfgif [ -n "$libc_restart" ]; then 232304515Spfg eval $libc_restart 233304515Spfgelif [ -n "$RESTARTCMD" ]; then 234304515Spfg set -- ${libc_service} 235304515Spfg eval $RESTARTCMD 236304515Spfgelse 237304515Spfg @SBINDIR@/resolvconf -r ${libc_service} 238304515Spfgfi 239219732Sume 240219732Sumeretval=0 241219732Sume# Notify users of the resolver 242219732Sumefor script in "$LIBEXECDIR"/libc.d/*; do 243219732Sume if [ -f "$script" ]; then 244219732Sume if [ -x "$script" ]; then 245219732Sume "$script" "$@" 246219732Sume else 247282434Sgjb (. "$script") 248219732Sume fi 249219732Sume retval=$(($retval + $?)) 250219732Sume fi 251219732Sumedone 252219732Sumeexit $retval 253