1587392a5SHajimu UMEMOTO#!/bin/sh 2*9af6c78cSPedro F. Giffuni# Copyright (c) 2007-2019 Roy Marples 3587392a5SHajimu UMEMOTO# All rights reserved 4587392a5SHajimu UMEMOTO 5587392a5SHajimu UMEMOTO# Redistribution and use in source and binary forms, with or without 6587392a5SHajimu UMEMOTO# modification, are permitted provided that the following conditions 7587392a5SHajimu UMEMOTO# are met: 8587392a5SHajimu UMEMOTO# * Redistributions of source code must retain the above copyright 9587392a5SHajimu UMEMOTO# notice, this list of conditions and the following disclaimer. 10587392a5SHajimu UMEMOTO# * Redistributions in binary form must reproduce the above 11587392a5SHajimu UMEMOTO# copyright notice, this list of conditions and the following 12587392a5SHajimu UMEMOTO# disclaimer in the documentation and/or other materials provided 13587392a5SHajimu UMEMOTO# with the distribution. 14587392a5SHajimu UMEMOTO# 15587392a5SHajimu UMEMOTO# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 16587392a5SHajimu UMEMOTO# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 17587392a5SHajimu UMEMOTO# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 18587392a5SHajimu UMEMOTO# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 19587392a5SHajimu UMEMOTO# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 20587392a5SHajimu UMEMOTO# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 21587392a5SHajimu UMEMOTO# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 22587392a5SHajimu UMEMOTO# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 23587392a5SHajimu UMEMOTO# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24587392a5SHajimu UMEMOTO# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 25587392a5SHajimu UMEMOTO# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26587392a5SHajimu UMEMOTO 27587392a5SHajimu UMEMOTORESOLVCONF="$0" 28*9af6c78cSPedro F. GiffuniOPENRESOLV_VERSION="3.9.2" 29587392a5SHajimu UMEMOTOSYSCONFDIR=@SYSCONFDIR@ 30587392a5SHajimu UMEMOTOLIBEXECDIR=@LIBEXECDIR@ 31587392a5SHajimu UMEMOTOVARDIR=@VARDIR@ 323f2a60a1SPedro F. GiffuniRCDIR=@RCDIR@ 333f2a60a1SPedro F. GiffuniRESTARTCMD=@RESTARTCMD@ 34d7149f4eSGlen Barber 3587b2cfceSPedro F. Giffuniif [ "$1" = "--version" ]; then 3687b2cfceSPedro F. Giffuni echo "openresolv $OPENRESOLV_VERSION" 3787b2cfceSPedro F. Giffuni echo "Copyright (c) 2007-2016 Roy Marples" 3887b2cfceSPedro F. Giffuni exit 0 3987b2cfceSPedro F. Giffunifi 4087b2cfceSPedro F. Giffuni 41d7149f4eSGlen Barber# Disregard dhcpcd setting 42d7149f4eSGlen Barberunset interface_order state_dir 43d7149f4eSGlen Barber 44d7149f4eSGlen Barber# If you change this, change the test in VFLAG and libc.in as well 45d7149f4eSGlen Barberlocal_nameservers="127.* 0.0.0.0 255.255.255.255 ::1" 46d7149f4eSGlen Barber 47d7149f4eSGlen Barberdynamic_order="tap[0-9]* tun[0-9]* vpn vpn[0-9]* ppp[0-9]* ippp[0-9]*" 48d7149f4eSGlen Barberinterface_order="lo lo[0-9]*" 49d7149f4eSGlen Barbername_server_blacklist="0.0.0.0" 50d7149f4eSGlen Barber 51587392a5SHajimu UMEMOTO# Support original resolvconf configuration layout 52587392a5SHajimu UMEMOTO# as well as the openresolv config file 53587392a5SHajimu UMEMOTOif [ -f "$SYSCONFDIR"/resolvconf.conf ]; then 54587392a5SHajimu UMEMOTO . "$SYSCONFDIR"/resolvconf.conf 55587392a5SHajimu UMEMOTO [ -n "$state_dir" ] && VARDIR="$state_dir" 56587392a5SHajimu UMEMOTOelif [ -d "$SYSCONFDIR/resolvconf" ]; then 57587392a5SHajimu UMEMOTO SYSCONFDIR="$SYSCONFDIR/resolvconf" 58587392a5SHajimu UMEMOTO if [ -f "$SYSCONFDIR"/interface-order ]; then 59587392a5SHajimu UMEMOTO interface_order="$(cat "$SYSCONFDIR"/interface-order)" 60587392a5SHajimu UMEMOTO fi 61587392a5SHajimu UMEMOTOfi 62587392a5SHajimu UMEMOTOIFACEDIR="$VARDIR/interfaces" 63587392a5SHajimu UMEMOTOMETRICDIR="$VARDIR/metrics" 64587392a5SHajimu UMEMOTOPRIVATEDIR="$VARDIR/private" 65d7149f4eSGlen BarberEXCLUSIVEDIR="$VARDIR/exclusive" 66d7149f4eSGlen BarberLOCKDIR="$VARDIR/lock" 67c364f334SPedro F. Giffuni_PWD="$PWD" 68587392a5SHajimu UMEMOTO 69d7149f4eSGlen Barberwarn() 70d7149f4eSGlen Barber{ 71d7149f4eSGlen Barber echo "$*" >&2 72d7149f4eSGlen Barber} 73587392a5SHajimu UMEMOTO 74587392a5SHajimu UMEMOTOerror_exit() 75587392a5SHajimu UMEMOTO{ 76587392a5SHajimu UMEMOTO echo "$*" >&2 77587392a5SHajimu UMEMOTO exit 1 78587392a5SHajimu UMEMOTO} 79587392a5SHajimu UMEMOTO 80587392a5SHajimu UMEMOTOusage() 81587392a5SHajimu UMEMOTO{ 82587392a5SHajimu UMEMOTO cat <<-EOF 833f2a60a1SPedro F. Giffuni Usage: ${RESOLVCONF##*/} [options] command [argument] 84587392a5SHajimu UMEMOTO 85587392a5SHajimu UMEMOTO Inform the system about any DNS updates. 86587392a5SHajimu UMEMOTO 873f2a60a1SPedro F. Giffuni Commands: 88587392a5SHajimu UMEMOTO -a \$INTERFACE Add DNS information to the specified interface 89587392a5SHajimu UMEMOTO (DNS supplied via stdin in resolv.conf format) 90587392a5SHajimu UMEMOTO -d \$INTERFACE Delete DNS information from the specified interface 913f2a60a1SPedro F. Giffuni -h Show this help cruft 92587392a5SHajimu UMEMOTO -i [\$PATTERN] Show interfaces that have supplied DNS information 93587392a5SHajimu UMEMOTO optionally from interfaces that match the specified 94587392a5SHajimu UMEMOTO pattern 953f2a60a1SPedro F. Giffuni -l [\$PATTERN] Show DNS information, optionally from interfaces 963f2a60a1SPedro F. Giffuni that match the specified pattern 973f2a60a1SPedro F. Giffuni 983f2a60a1SPedro F. Giffuni -u Run updates from our current DNS information 9987b2cfceSPedro F. Giffuni --version Echo the ${RESOLVCONF##*/} version 1003f2a60a1SPedro F. Giffuni 1013f2a60a1SPedro F. Giffuni Options: 1023f2a60a1SPedro F. Giffuni -f Ignore non existent interfaces 1033f2a60a1SPedro F. Giffuni -m metric Give the added DNS information a metric 1043f2a60a1SPedro F. Giffuni -p Mark the interface as private 1053f2a60a1SPedro F. Giffuni -x Mark the interface as exclusive 1063f2a60a1SPedro F. Giffuni 1073f2a60a1SPedro F. Giffuni Subscriber and System Init Commands: 1083f2a60a1SPedro F. Giffuni -I Init the state dir 1093f2a60a1SPedro F. Giffuni -r \$SERVICE Restart the system service 1103f2a60a1SPedro F. Giffuni (restarting a non-existent or non-running service 1113f2a60a1SPedro F. Giffuni should have no output and return 0) 1123f2a60a1SPedro F. Giffuni -R Show the system service restart command 113587392a5SHajimu UMEMOTO -v [\$PATTERN] echo NEWDOMAIN, NEWSEARCH and NEWNS variables to 114587392a5SHajimu UMEMOTO the console 1153f2a60a1SPedro F. Giffuni -V [\$PATTERN] Same as -v, but only uses configuration in 1163f2a60a1SPedro F. Giffuni $SYSCONFDIR/resolvconf.conf 117587392a5SHajimu UMEMOTO EOF 118587392a5SHajimu UMEMOTO [ -z "$1" ] && exit 0 119587392a5SHajimu UMEMOTO echo 120587392a5SHajimu UMEMOTO error_exit "$*" 121587392a5SHajimu UMEMOTO} 122587392a5SHajimu UMEMOTO 123c364f334SPedro F. Giffuni# Strip any trailing dot from each name as a FQDN does not belong 124c364f334SPedro F. Giffuni# in resolv.conf(5) 125c364f334SPedro F. Giffuni# If you think otherwise, capture a DNS trace and you'll see libc 126c364f334SPedro F. Giffuni# will strip it regardless. 127c364f334SPedro F. Giffuni# This also solves setting up duplicate zones in our subscribers. 128*9af6c78cSPedro F. Giffuni# Also strip any comments denoted by #. 129*9af6c78cSPedro F. Giffuniresolv_strip() 130c364f334SPedro F. Giffuni{ 131*9af6c78cSPedro F. Giffuni space= 132*9af6c78cSPedro F. Giffuni for word; do 133*9af6c78cSPedro F. Giffuni case "$word" in 134*9af6c78cSPedro F. Giffuni \#*) break;; 135*9af6c78cSPedro F. Giffuni esac 136*9af6c78cSPedro F. Giffuni printf "%s%s" "$space${word%.}" 137*9af6c78cSPedro F. Giffuni space=" " 138c364f334SPedro F. Giffuni done 139c364f334SPedro F. Giffuni printf "\n" 140c364f334SPedro F. Giffuni} 141c364f334SPedro F. Giffuni 14287b2cfceSPedro F. Giffuniprivate_iface() 14387b2cfceSPedro F. Giffuni{ 14487b2cfceSPedro F. Giffuni # Allow expansion 14587b2cfceSPedro F. Giffuni cd "$IFACEDIR" 14687b2cfceSPedro F. Giffuni 14787b2cfceSPedro F. Giffuni # Public interfaces override private ones. 14887b2cfceSPedro F. Giffuni for p in $public_interfaces; do 14987b2cfceSPedro F. Giffuni case "$iface" in 15087b2cfceSPedro F. Giffuni "$p"|"$p":*) return 1;; 15187b2cfceSPedro F. Giffuni esac 15287b2cfceSPedro F. Giffuni done 15387b2cfceSPedro F. Giffuni 15487b2cfceSPedro F. Giffuni if [ -e "$PRIVATEDIR/$iface" ]; then 15587b2cfceSPedro F. Giffuni return 0 15687b2cfceSPedro F. Giffuni fi 15787b2cfceSPedro F. Giffuni 15887b2cfceSPedro F. Giffuni for p in $private_interfaces; do 15987b2cfceSPedro F. Giffuni case "$iface" in 16087b2cfceSPedro F. Giffuni "$p"|"$p":*) return 0;; 16187b2cfceSPedro F. Giffuni esac 16287b2cfceSPedro F. Giffuni done 16387b2cfceSPedro F. Giffuni 16487b2cfceSPedro F. Giffuni # Not a private interface 16587b2cfceSPedro F. Giffuni return 1 16687b2cfceSPedro F. Giffuni} 16787b2cfceSPedro F. Giffuni 168587392a5SHajimu UMEMOTO# Parse resolv.conf's and make variables 169587392a5SHajimu UMEMOTO# for domain name servers, search name servers and global nameservers 170587392a5SHajimu UMEMOTOparse_resolv() 171587392a5SHajimu UMEMOTO{ 172*9af6c78cSPedro F. Giffuni domain= 173*9af6c78cSPedro F. Giffuni new=true 174587392a5SHajimu UMEMOTO newns= 175*9af6c78cSPedro F. Giffuni ns= 176*9af6c78cSPedro F. Giffuni private=false 177*9af6c78cSPedro F. Giffuni search= 178587392a5SHajimu UMEMOTO 179d7149f4eSGlen Barber while read -r line; do 180*9af6c78cSPedro F. Giffuni stripped_line="$(resolv_strip ${line#* })" 181587392a5SHajimu UMEMOTO case "$line" in 182587392a5SHajimu UMEMOTO "# resolv.conf from "*) 183587392a5SHajimu UMEMOTO if ${new}; then 184587392a5SHajimu UMEMOTO iface="${line#\# resolv.conf from *}" 185587392a5SHajimu UMEMOTO new=false 18687b2cfceSPedro F. Giffuni if private_iface "$iface"; then 187587392a5SHajimu UMEMOTO private=true 188587392a5SHajimu UMEMOTO else 189587392a5SHajimu UMEMOTO private=false 190587392a5SHajimu UMEMOTO fi 191587392a5SHajimu UMEMOTO fi 192587392a5SHajimu UMEMOTO ;; 193587392a5SHajimu UMEMOTO "nameserver "*) 194d7149f4eSGlen Barber islocal=false 195d7149f4eSGlen Barber for l in $local_nameservers; do 196*9af6c78cSPedro F. Giffuni case "$stripped_line" in 197d7149f4eSGlen Barber $l) 198d7149f4eSGlen Barber islocal=true 199d7149f4eSGlen Barber break 200587392a5SHajimu UMEMOTO ;; 201587392a5SHajimu UMEMOTO esac 202d7149f4eSGlen Barber done 203*9af6c78cSPedro F. Giffuni if $islocal; then 204*9af6c78cSPedro F. Giffuni echo "LOCALNAMESERVERS=\"\$LOCALNAMESERVERS $stripped_line\"" 205*9af6c78cSPedro F. Giffuni else 206*9af6c78cSPedro F. Giffuni ns="$ns$stripped_line " 207*9af6c78cSPedro F. Giffuni fi 208587392a5SHajimu UMEMOTO ;; 209d7149f4eSGlen Barber "domain "*) 210*9af6c78cSPedro F. Giffuni search="$stripped_line" 211d7149f4eSGlen Barber if [ -z "$domain" ]; then 212c364f334SPedro F. Giffuni domain="$search" 213d7149f4eSGlen Barber echo "DOMAIN=\"$domain\"" 214d7149f4eSGlen Barber fi 215d7149f4eSGlen Barber ;; 216d7149f4eSGlen Barber "search "*) 217*9af6c78cSPedro F. Giffuni search="$stripped_line" 218587392a5SHajimu UMEMOTO ;; 219587392a5SHajimu UMEMOTO *) 220587392a5SHajimu UMEMOTO [ -n "$line" ] && continue 221*9af6c78cSPedro F. Giffuni if [ -n "$ns" ] && [ -n "$search" ]; then 222587392a5SHajimu UMEMOTO newns= 223587392a5SHajimu UMEMOTO for n in $ns; do 224587392a5SHajimu UMEMOTO newns="$newns${newns:+,}$n" 225587392a5SHajimu UMEMOTO done 226587392a5SHajimu UMEMOTO ds= 227587392a5SHajimu UMEMOTO for d in $search; do 228587392a5SHajimu UMEMOTO ds="$ds${ds:+ }$d:$newns" 229587392a5SHajimu UMEMOTO done 230587392a5SHajimu UMEMOTO echo "DOMAINS=\"\$DOMAINS $ds\"" 231587392a5SHajimu UMEMOTO fi 232587392a5SHajimu UMEMOTO echo "SEARCH=\"\$SEARCH $search\"" 233587392a5SHajimu UMEMOTO if ! $private; then 234587392a5SHajimu UMEMOTO echo "NAMESERVERS=\"\$NAMESERVERS $ns\"" 235587392a5SHajimu UMEMOTO fi 236587392a5SHajimu UMEMOTO ns= 237587392a5SHajimu UMEMOTO search= 238587392a5SHajimu UMEMOTO new=true 239587392a5SHajimu UMEMOTO ;; 240587392a5SHajimu UMEMOTO esac 241587392a5SHajimu UMEMOTO done 242587392a5SHajimu UMEMOTO} 243587392a5SHajimu UMEMOTO 244587392a5SHajimu UMEMOTOuniqify() 245587392a5SHajimu UMEMOTO{ 246*9af6c78cSPedro F. Giffuni result= 247587392a5SHajimu UMEMOTO while [ -n "$1" ]; do 248587392a5SHajimu UMEMOTO case " $result " in 249587392a5SHajimu UMEMOTO *" $1 "*);; 250587392a5SHajimu UMEMOTO *) result="$result $1";; 251587392a5SHajimu UMEMOTO esac 252587392a5SHajimu UMEMOTO shift 253587392a5SHajimu UMEMOTO done 254587392a5SHajimu UMEMOTO echo "${result# *}" 255587392a5SHajimu UMEMOTO} 256587392a5SHajimu UMEMOTO 257d7149f4eSGlen Barberdirname() 258d7149f4eSGlen Barber{ 259*9af6c78cSPedro F. Giffuni OIFS="$IFS" 260*9af6c78cSPedro F. Giffuni IFS=/ 261d7149f4eSGlen Barber set -- $@ 262d7149f4eSGlen Barber IFS="$OIFS" 263d7149f4eSGlen Barber if [ -n "$1" ]; then 264d7149f4eSGlen Barber printf %s . 265d7149f4eSGlen Barber else 266d7149f4eSGlen Barber shift 267d7149f4eSGlen Barber fi 268d7149f4eSGlen Barber while [ -n "$2" ]; do 269d7149f4eSGlen Barber printf "/%s" "$1" 270d7149f4eSGlen Barber shift 271d7149f4eSGlen Barber done 272d7149f4eSGlen Barber printf "\n" 273d7149f4eSGlen Barber} 274d7149f4eSGlen Barber 275d7149f4eSGlen Barberconfig_mkdirs() 276d7149f4eSGlen Barber{ 277*9af6c78cSPedro F. Giffuni e=0 278d7149f4eSGlen Barber for f; do 279d7149f4eSGlen Barber [ -n "$f" ] || continue 280d7149f4eSGlen Barber d="$(dirname "$f")" 281d7149f4eSGlen Barber if [ ! -d "$d" ]; then 282d7149f4eSGlen Barber if type install >/dev/null 2>&1; then 283d7149f4eSGlen Barber install -d "$d" || e=$? 284d7149f4eSGlen Barber else 285d7149f4eSGlen Barber mkdir "$d" || e=$? 286d7149f4eSGlen Barber fi 287d7149f4eSGlen Barber fi 288d7149f4eSGlen Barber done 289d7149f4eSGlen Barber return $e 290d7149f4eSGlen Barber} 291d7149f4eSGlen Barber 2923f2a60a1SPedro F. Giffuni# With the advent of alternative init systems, it's possible to have 2933f2a60a1SPedro F. Giffuni# more than one installed. So we need to try and guess what one we're 2943f2a60a1SPedro F. Giffuni# using unless overriden by configure. 2953f2a60a1SPedro F. Giffuni# Note that restarting a service is a last resort - the subscribers 2963f2a60a1SPedro F. Giffuni# should make a reasonable attempt to reconfigre the service via some 2973f2a60a1SPedro F. Giffuni# method, normally SIGHUP. 2983f2a60a1SPedro F. Giffunidetect_init() 2993f2a60a1SPedro F. Giffuni{ 3003f2a60a1SPedro F. Giffuni [ -n "$RESTARTCMD" ] && return 0 3013f2a60a1SPedro F. Giffuni 3023f2a60a1SPedro F. Giffuni # Detect the running init system. 3033f2a60a1SPedro F. Giffuni # As systemd and OpenRC can be installed on top of legacy init 3043f2a60a1SPedro F. Giffuni # systems we try to detect them first. 305*9af6c78cSPedro F. Giffuni status="@STATUSARG@" 3063f2a60a1SPedro F. Giffuni : ${status:=status} 307*9af6c78cSPedro F. Giffuni if [ -x /bin/systemctl ] && [ -S /run/systemd/private ]; then 308*9af6c78cSPedro F. Giffuni RESTARTCMD=' 309*9af6c78cSPedro F. Giffuni if /bin/systemctl --quiet is-active $1.service 3103f2a60a1SPedro F. Giffuni then 311*9af6c78cSPedro F. Giffuni /bin/systemctl restart $1.service 312*9af6c78cSPedro F. Giffuni fi' 313*9af6c78cSPedro F. Giffuni elif [ -x /usr/bin/systemctl ] && [ -S /run/systemd/private ]; then 314*9af6c78cSPedro F. Giffuni RESTARTCMD=' 315*9af6c78cSPedro F. Giffuni if /usr/bin/systemctl --quiet is-active $1.service 316*9af6c78cSPedro F. Giffuni then 317*9af6c78cSPedro F. Giffuni /usr/bin/systemctl restart $1.service 318*9af6c78cSPedro F. Giffuni fi' 319*9af6c78cSPedro F. Giffuni elif [ -x /sbin/rc-service ] && 320*9af6c78cSPedro F. Giffuni { [ -s /libexec/rc/init.d/softlevel ] || 321*9af6c78cSPedro F. Giffuni [ -s /run/openrc/softlevel ]; } 322*9af6c78cSPedro F. Giffuni then 323*9af6c78cSPedro F. Giffuni RESTARTCMD='/sbin/rc-service -i $1 -- -Ds restart' 3243f2a60a1SPedro F. Giffuni elif [ -x /usr/sbin/invoke-rc.d ]; then 3253f2a60a1SPedro F. Giffuni RCDIR=/etc/init.d 326*9af6c78cSPedro F. Giffuni RESTARTCMD=' 327*9af6c78cSPedro F. Giffuni if /usr/sbin/invoke-rc.d --quiet $1 status >/dev/null 2>&1 328*9af6c78cSPedro F. Giffuni then 329*9af6c78cSPedro F. Giffuni /usr/sbin/invoke-rc.d $1 restart 330*9af6c78cSPedro F. Giffuni fi' 3313f2a60a1SPedro F. Giffuni elif [ -x /sbin/service ]; then 3323f2a60a1SPedro F. Giffuni # Old RedHat 3333f2a60a1SPedro F. Giffuni RCDIR=/etc/init.d 334*9af6c78cSPedro F. Giffuni RESTARTCMD=' 335*9af6c78cSPedro F. Giffuni if /sbin/service $1; then 336*9af6c78cSPedro F. Giffuni /sbin/service $1 restart 337*9af6c78cSPedro F. Giffuni fi' 3383f2a60a1SPedro F. Giffuni elif [ -x /usr/sbin/service ]; then 3393f2a60a1SPedro F. Giffuni # Could be FreeBSD 340*9af6c78cSPedro F. Giffuni RESTARTCMD=" 341*9af6c78cSPedro F. Giffuni if /usr/sbin/service \$1 $status >/dev/null 2>&1 342*9af6c78cSPedro F. Giffuni then 343*9af6c78cSPedro F. Giffuni /usr/sbin/service \$1 restart 3443f2a60a1SPedro F. Giffuni fi" 3453f2a60a1SPedro F. Giffuni elif [ -x /bin/sv ]; then 346*9af6c78cSPedro F. Giffuni RESTARTCMD='/bin/sv status $1 >/dev/null 2>&1 && 347*9af6c78cSPedro F. Giffuni /bin/sv try-restart $1' 3483f2a60a1SPedro F. Giffuni elif [ -x /usr/bin/sv ]; then 349*9af6c78cSPedro F. Giffuni RESTARTCMD='/usr/bin/sv status $1 >/dev/null 2>&1 && 350*9af6c78cSPedro F. Giffuni /usr/bin/sv try-restart $1' 351*9af6c78cSPedro F. Giffuni elif [ -e /etc/arch-release ] && [ -d /etc/rc.d ]; then 3523f2a60a1SPedro F. Giffuni RCDIR=/etc/rc.d 353*9af6c78cSPedro F. Giffuni RESTARTCMD=' 354*9af6c78cSPedro F. Giffuni if [ -e /var/run/daemons/$1 ] 355*9af6c78cSPedro F. Giffuni then 356*9af6c78cSPedro F. Giffuni /etc/rc.d/$1 restart 357*9af6c78cSPedro F. Giffuni fi' 358*9af6c78cSPedro F. Giffuni elif [ -e /etc/slackware-version ] && [ -d /etc/rc.d ]; then 359*9af6c78cSPedro F. Giffuni RESTARTCMD=' 360*9af6c78cSPedro F. Giffuni if /etc/rc.d/rc.$1 status >/dev/null 2>&1 361*9af6c78cSPedro F. Giffuni then 362*9af6c78cSPedro F. Giffuni /etc/rc.d/rc.$1 restart 363*9af6c78cSPedro F. Giffuni fi' 364*9af6c78cSPedro F. Giffuni elif [ -e /etc/rc.d/rc.subr ] && [ -d /etc/rc.d ]; then 3653f2a60a1SPedro F. Giffuni # OpenBSD 366*9af6c78cSPedro F. Giffuni RESTARTCMD=' 367*9af6c78cSPedro F. Giffuni if /etc/rc.d/$1 check >/dev/null 2>&1 368*9af6c78cSPedro F. Giffuni then 369*9af6c78cSPedro F. Giffuni /etc/rc.d/$1 restart 370*9af6c78cSPedro F. Giffuni fi' 3713f2a60a1SPedro F. Giffuni else 3723f2a60a1SPedro F. Giffuni for x in /etc/init.d/rc.d /etc/rc.d /etc/init.d; do 3733f2a60a1SPedro F. Giffuni [ -d $x ] || continue 374*9af6c78cSPedro F. Giffuni RESTARTCMD=" 375*9af6c78cSPedro F. Giffuni if $x/\$1 $status >/dev/null 2>&1 376*9af6c78cSPedro F. Giffuni then 377*9af6c78cSPedro F. Giffuni $x/\$1 restart 3783f2a60a1SPedro F. Giffuni fi" 3793f2a60a1SPedro F. Giffuni break 3803f2a60a1SPedro F. Giffuni done 3813f2a60a1SPedro F. Giffuni fi 3823f2a60a1SPedro F. Giffuni 3833f2a60a1SPedro F. Giffuni if [ -z "$RESTARTCMD" ]; then 384*9af6c78cSPedro F. Giffuni if [ "$_NOINIT_WARNED" != true ]; then 3853f2a60a1SPedro F. Giffuni warn "could not detect a useable init system" 3863f2a60a1SPedro F. Giffuni _NOINIT_WARNED=true 3873f2a60a1SPedro F. Giffuni fi 3883f2a60a1SPedro F. Giffuni return 1 3893f2a60a1SPedro F. Giffuni fi 3903f2a60a1SPedro F. Giffuni _NOINIT_WARNED= 3913f2a60a1SPedro F. Giffuni return 0 3923f2a60a1SPedro F. Giffuni} 3933f2a60a1SPedro F. Giffuni 3943f2a60a1SPedro F. Giffuniecho_resolv() 3953f2a60a1SPedro F. Giffuni{ 396*9af6c78cSPedro F. Giffuni OIFS="$IFS" 3973f2a60a1SPedro F. Giffuni 398*9af6c78cSPedro F. Giffuni [ -n "$1" ] && [ -f "$IFACEDIR/$1" ] || return 1 3993f2a60a1SPedro F. Giffuni echo "# resolv.conf from $1" 4003f2a60a1SPedro F. Giffuni # Our variable maker works of the fact each resolv.conf per interface 4013f2a60a1SPedro F. Giffuni # is separated by blank lines. 4023f2a60a1SPedro F. Giffuni # So we remove them when echoing them. 4033f2a60a1SPedro F. Giffuni while read -r line; do 4043f2a60a1SPedro F. Giffuni IFS="$OIFS" 4053f2a60a1SPedro F. Giffuni if [ -n "$line" ]; then 4063f2a60a1SPedro F. Giffuni # We need to set IFS here to preserve any whitespace 4073f2a60a1SPedro F. Giffuni IFS='' 4083f2a60a1SPedro F. Giffuni printf "%s\n" "$line" 4093f2a60a1SPedro F. Giffuni fi 4103f2a60a1SPedro F. Giffuni done < "$IFACEDIR/$1" 4113f2a60a1SPedro F. Giffuni IFS="$OIFS" 4123f2a60a1SPedro F. Giffuni} 4133f2a60a1SPedro F. Giffuni 414587392a5SHajimu UMEMOTOlist_resolv() 415587392a5SHajimu UMEMOTO{ 416587392a5SHajimu UMEMOTO [ -d "$IFACEDIR" ] || return 0 417587392a5SHajimu UMEMOTO 418*9af6c78cSPedro F. Giffuni cmd="$1" 419587392a5SHajimu UMEMOTO shift 420*9af6c78cSPedro F. Giffuni excl=false 421*9af6c78cSPedro F. Giffuni list= 422*9af6c78cSPedro F. Giffuni report=false 423*9af6c78cSPedro F. Giffuni retval=0 424587392a5SHajimu UMEMOTO 425d7149f4eSGlen Barber case "$IF_EXCLUSIVE" in 426d7149f4eSGlen Barber [Yy][Ee][Ss]|[Tt][Rr][Uu][Ee]|[Oo][Nn]|1) 427*9af6c78cSPedro F. Giffuni excl=true 428d7149f4eSGlen Barber if [ -d "$EXCLUSIVEDIR" ]; then 429d7149f4eSGlen Barber cd "$EXCLUSIVEDIR" 430d7149f4eSGlen Barber for i in *; do 431d7149f4eSGlen Barber if [ -f "$i" ]; then 432d7149f4eSGlen Barber list="${i#* }" 433d7149f4eSGlen Barber break 434d7149f4eSGlen Barber fi 435d7149f4eSGlen Barber done 436d7149f4eSGlen Barber fi 43787b2cfceSPedro F. Giffuni cd "$IFACEDIR" 43887b2cfceSPedro F. Giffuni for i in $inclusive_interfaces; do 439*9af6c78cSPedro F. Giffuni if [ -f "$i" ] && [ "$list" = "$i" ]; then 44087b2cfceSPedro F. Giffuni list= 44187b2cfceSPedro F. Giffuni excl=false 44287b2cfceSPedro F. Giffuni break 44387b2cfceSPedro F. Giffuni fi 44487b2cfceSPedro F. Giffuni done 445d7149f4eSGlen Barber ;; 446d7149f4eSGlen Barber esac 447d7149f4eSGlen Barber 448587392a5SHajimu UMEMOTO # If we have an interface ordering list, then use that. 449587392a5SHajimu UMEMOTO # It works by just using pathname expansion in the interface directory. 450587392a5SHajimu UMEMOTO if [ -n "$1" ]; then 451d7149f4eSGlen Barber list="$*" 452587392a5SHajimu UMEMOTO $force || report=true 453d7149f4eSGlen Barber elif ! $excl; then 454587392a5SHajimu UMEMOTO cd "$IFACEDIR" 455587392a5SHajimu UMEMOTO for i in $interface_order; do 456d7149f4eSGlen Barber [ -f "$i" ] && list="$list $i" 457d7149f4eSGlen Barber for ii in "$i":* "$i".*; do 458d7149f4eSGlen Barber [ -f "$ii" ] && list="$list $ii" 459d7149f4eSGlen Barber done 460587392a5SHajimu UMEMOTO done 461587392a5SHajimu UMEMOTO for i in $dynamic_order; do 462*9af6c78cSPedro F. Giffuni if [ -e "$i" ] && ! [ -e "$METRICDIR/"*" $i" ]; then 463587392a5SHajimu UMEMOTO list="$list $i" 464587392a5SHajimu UMEMOTO fi 465d7149f4eSGlen Barber for ii in "$i":* "$i".*; do 466*9af6c78cSPedro F. Giffuni if [ -f "$ii" ] && ! [ -e "$METRICDIR/"*" $ii" ] 467*9af6c78cSPedro F. Giffuni then 468d7149f4eSGlen Barber list="$list $ii" 469d7149f4eSGlen Barber fi 470d7149f4eSGlen Barber done 471587392a5SHajimu UMEMOTO done 472*9af6c78cSPedro F. Giffuni # Interfaces have an implicit metric of 0 if not specified. 473*9af6c78cSPedro F. Giffuni for i in *; do 474*9af6c78cSPedro F. Giffuni if [ -f "$i" ] && ! [ -e "$METRICDIR/"*" $i" ]; then 475*9af6c78cSPedro F. Giffuni list="$list $i" 476*9af6c78cSPedro F. Giffuni fi 477*9af6c78cSPedro F. Giffuni done 478587392a5SHajimu UMEMOTO if [ -d "$METRICDIR" ]; then 479587392a5SHajimu UMEMOTO cd "$METRICDIR" 480587392a5SHajimu UMEMOTO for i in *; do 481d7149f4eSGlen Barber [ -f "$i" ] && list="$list ${i#* }" 482587392a5SHajimu UMEMOTO done 483587392a5SHajimu UMEMOTO fi 484587392a5SHajimu UMEMOTO fi 485587392a5SHajimu UMEMOTO 486587392a5SHajimu UMEMOTO cd "$IFACEDIR" 487d7149f4eSGlen Barber retval=1 488587392a5SHajimu UMEMOTO for i in $(uniqify $list); do 489587392a5SHajimu UMEMOTO # Only list interfaces which we really have 490d7149f4eSGlen Barber if ! [ -f "$i" ]; then 491587392a5SHajimu UMEMOTO if $report; then 492587392a5SHajimu UMEMOTO echo "No resolv.conf for interface $i" >&2 493d7149f4eSGlen Barber retval=2 494587392a5SHajimu UMEMOTO fi 495587392a5SHajimu UMEMOTO continue 496587392a5SHajimu UMEMOTO fi 497587392a5SHajimu UMEMOTO 498*9af6c78cSPedro F. Giffuni if [ "$cmd" = i ] || [ "$cmd" = "-i" ]; then 499d7149f4eSGlen Barber printf %s "$i " 500587392a5SHajimu UMEMOTO else 50187b2cfceSPedro F. Giffuni echo_resolv "$i" && echo 502587392a5SHajimu UMEMOTO fi 503*9af6c78cSPedro F. Giffuni [ $? = 0 ] && [ "$retval" = 1 ] && retval=0 504587392a5SHajimu UMEMOTO done 505*9af6c78cSPedro F. Giffuni [ "$cmd" = i ] || [ "$cmd" = "-i" ] && echo 506587392a5SHajimu UMEMOTO return $retval 507587392a5SHajimu UMEMOTO} 508587392a5SHajimu UMEMOTO 509*9af6c78cSPedro F. Giffunilist_remove() 510*9af6c78cSPedro F. Giffuni{ 511d7149f4eSGlen Barber [ -z "$2" ] && return 0 512d7149f4eSGlen Barber eval list=\"\$$1\" 513d7149f4eSGlen Barber shift 514*9af6c78cSPedro F. Giffuni result= 515*9af6c78cSPedro F. Giffuni retval=0 516d7149f4eSGlen Barber 517d7149f4eSGlen Barber set -f 518d7149f4eSGlen Barber for e; do 519d7149f4eSGlen Barber found=false 520d7149f4eSGlen Barber for l in $list; do 521d7149f4eSGlen Barber case "$e" in 522d7149f4eSGlen Barber $l) found=true;; 523d7149f4eSGlen Barber esac 524d7149f4eSGlen Barber $found && break 525d7149f4eSGlen Barber done 526d7149f4eSGlen Barber if $found; then 527d7149f4eSGlen Barber retval=$(($retval + 1)) 528d7149f4eSGlen Barber else 529d7149f4eSGlen Barber result="$result $e" 530d7149f4eSGlen Barber fi 531d7149f4eSGlen Barber done 532d7149f4eSGlen Barber set +f 533d7149f4eSGlen Barber echo "${result# *}" 534d7149f4eSGlen Barber return $retval 535d7149f4eSGlen Barber} 536d7149f4eSGlen Barber 537d7149f4eSGlen Barberecho_prepend() 538d7149f4eSGlen Barber{ 539d7149f4eSGlen Barber echo "# Generated by resolvconf" 540d7149f4eSGlen Barber if [ -n "$search_domains" ]; then 541d7149f4eSGlen Barber echo "search $search_domains" 542d7149f4eSGlen Barber fi 543d7149f4eSGlen Barber for n in $name_servers; do 544d7149f4eSGlen Barber echo "nameserver $n" 545d7149f4eSGlen Barber done 546d7149f4eSGlen Barber echo 547d7149f4eSGlen Barber} 548d7149f4eSGlen Barber 549d7149f4eSGlen Barberecho_append() 550d7149f4eSGlen Barber{ 551d7149f4eSGlen Barber echo "# Generated by resolvconf" 552d7149f4eSGlen Barber if [ -n "$search_domains_append" ]; then 553d7149f4eSGlen Barber echo "search $search_domains_append" 554d7149f4eSGlen Barber fi 555d7149f4eSGlen Barber for n in $name_servers_append; do 556d7149f4eSGlen Barber echo "nameserver $n" 557d7149f4eSGlen Barber done 558d7149f4eSGlen Barber echo 559d7149f4eSGlen Barber} 560d7149f4eSGlen Barber 561d7149f4eSGlen Barberreplace() 562d7149f4eSGlen Barber{ 563d7149f4eSGlen Barber while read -r keyword value; do 564d7149f4eSGlen Barber for r in $replace; do 565d7149f4eSGlen Barber k="${r%%/*}" 566d7149f4eSGlen Barber r="${r#*/}" 567d7149f4eSGlen Barber f="${r%%/*}" 568d7149f4eSGlen Barber r="${r#*/}" 569d7149f4eSGlen Barber v="${r%%/*}" 570d7149f4eSGlen Barber case "$keyword" in 571d7149f4eSGlen Barber $k) 572d7149f4eSGlen Barber case "$value" in 573d7149f4eSGlen Barber $f) value="$v";; 574d7149f4eSGlen Barber esac 575d7149f4eSGlen Barber ;; 576d7149f4eSGlen Barber esac 577d7149f4eSGlen Barber done 578d7149f4eSGlen Barber val= 579d7149f4eSGlen Barber for sub in $value; do 580d7149f4eSGlen Barber for r in $replace_sub; do 581d7149f4eSGlen Barber k="${r%%/*}" 582d7149f4eSGlen Barber r="${r#*/}" 583d7149f4eSGlen Barber f="${r%%/*}" 584d7149f4eSGlen Barber r="${r#*/}" 585d7149f4eSGlen Barber v="${r%%/*}" 586d7149f4eSGlen Barber case "$keyword" in 587d7149f4eSGlen Barber $k) 588d7149f4eSGlen Barber case "$sub" in 589d7149f4eSGlen Barber $f) sub="$v";; 590d7149f4eSGlen Barber esac 591d7149f4eSGlen Barber ;; 592d7149f4eSGlen Barber esac 593d7149f4eSGlen Barber done 594d7149f4eSGlen Barber val="$val${val:+ }$sub" 595d7149f4eSGlen Barber done 596d7149f4eSGlen Barber printf "%s %s\n" "$keyword" "$val" 597d7149f4eSGlen Barber done 598d7149f4eSGlen Barber} 599d7149f4eSGlen Barber 600587392a5SHajimu UMEMOTOmake_vars() 601587392a5SHajimu UMEMOTO{ 602d7149f4eSGlen Barber # Clear variables 603d7149f4eSGlen Barber DOMAIN= 604d7149f4eSGlen Barber DOMAINS= 605d7149f4eSGlen Barber SEARCH= 606d7149f4eSGlen Barber NAMESERVERS= 607d7149f4eSGlen Barber LOCALNAMESERVERS= 608d7149f4eSGlen Barber 609*9af6c78cSPedro F. Giffuni if [ -n "${name_servers}${search_domains}" ]; then 610d7149f4eSGlen Barber eval "$(echo_prepend | parse_resolv)" 611d7149f4eSGlen Barber fi 612d7149f4eSGlen Barber if [ -z "$VFLAG" ]; then 613d7149f4eSGlen Barber IF_EXCLUSIVE=1 614d7149f4eSGlen Barber list_resolv -i "$@" >/dev/null || IF_EXCLUSIVE=0 615d7149f4eSGlen Barber eval "$(list_resolv -l "$@" | replace | parse_resolv)" 616d7149f4eSGlen Barber fi 617*9af6c78cSPedro F. Giffuni if [ -n "${name_servers_append}${search_domains_append}" ]; then 618d7149f4eSGlen Barber eval "$(echo_append | parse_resolv)" 619d7149f4eSGlen Barber fi 620587392a5SHajimu UMEMOTO 621587392a5SHajimu UMEMOTO # Ensure that we only list each domain once 622*9af6c78cSPedro F. Giffuni newdomains= 623587392a5SHajimu UMEMOTO for d in $DOMAINS; do 624587392a5SHajimu UMEMOTO dn="${d%%:*}" 625d7149f4eSGlen Barber list_remove domain_blacklist "$dn" >/dev/null || continue 626587392a5SHajimu UMEMOTO case " $newdomains" in 627587392a5SHajimu UMEMOTO *" ${dn}:"*) continue;; 628587392a5SHajimu UMEMOTO esac 629587392a5SHajimu UMEMOTO newns= 630587392a5SHajimu UMEMOTO for nd in $DOMAINS; do 631587392a5SHajimu UMEMOTO if [ "$dn" = "${nd%%:*}" ]; then 632587392a5SHajimu UMEMOTO ns="${nd#*:}" 633587392a5SHajimu UMEMOTO while [ -n "$ns" ]; do 634587392a5SHajimu UMEMOTO case ",$newns," in 635587392a5SHajimu UMEMOTO *,${ns%%,*},*) ;; 636d7149f4eSGlen Barber *) list_remove name_server_blacklist \ 637d7149f4eSGlen Barber "${ns%%,*}" >/dev/null \ 638d7149f4eSGlen Barber && newns="$newns${newns:+,}${ns%%,*}";; 639587392a5SHajimu UMEMOTO esac 640587392a5SHajimu UMEMOTO [ "$ns" = "${ns#*,}" ] && break 641587392a5SHajimu UMEMOTO ns="${ns#*,}" 642587392a5SHajimu UMEMOTO done 643587392a5SHajimu UMEMOTO fi 644587392a5SHajimu UMEMOTO done 645d7149f4eSGlen Barber if [ -n "$newns" ]; then 646d7149f4eSGlen Barber newdomains="$newdomains${newdomains:+ }$dn:$newns" 647d7149f4eSGlen Barber fi 648587392a5SHajimu UMEMOTO done 649d7149f4eSGlen Barber DOMAIN="$(list_remove domain_blacklist $DOMAIN)" 650d7149f4eSGlen Barber SEARCH="$(uniqify $SEARCH)" 651d7149f4eSGlen Barber SEARCH="$(list_remove domain_blacklist $SEARCH)" 652d7149f4eSGlen Barber NAMESERVERS="$(uniqify $NAMESERVERS)" 653d7149f4eSGlen Barber NAMESERVERS="$(list_remove name_server_blacklist $NAMESERVERS)" 654d7149f4eSGlen Barber LOCALNAMESERVERS="$(uniqify $LOCALNAMESERVERS)" 655d7149f4eSGlen Barber LOCALNAMESERVERS="$(list_remove name_server_blacklist $LOCALNAMESERVERS)" 656d7149f4eSGlen Barber echo "DOMAIN='$DOMAIN'" 657d7149f4eSGlen Barber echo "SEARCH='$SEARCH'" 658d7149f4eSGlen Barber echo "NAMESERVERS='$NAMESERVERS'" 659d7149f4eSGlen Barber echo "LOCALNAMESERVERS='$LOCALNAMESERVERS'" 660587392a5SHajimu UMEMOTO echo "DOMAINS='$newdomains'" 661587392a5SHajimu UMEMOTO} 662587392a5SHajimu UMEMOTO 663587392a5SHajimu UMEMOTOforce=false 664d7149f4eSGlen BarberVFLAG= 6653f2a60a1SPedro F. Giffuniwhile getopts a:Dd:fhIilm:pRruvVx OPT; do 666587392a5SHajimu UMEMOTO case "$OPT" in 667587392a5SHajimu UMEMOTO f) force=true;; 668587392a5SHajimu UMEMOTO h) usage;; 669587392a5SHajimu UMEMOTO m) IF_METRIC="$OPTARG";; 670587392a5SHajimu UMEMOTO p) IF_PRIVATE=1;; 671d7149f4eSGlen Barber V) 672d7149f4eSGlen Barber VFLAG=1 673d7149f4eSGlen Barber if [ "$local_nameservers" = \ 674d7149f4eSGlen Barber "127.* 0.0.0.0 255.255.255.255 ::1" ] 675d7149f4eSGlen Barber then 676d7149f4eSGlen Barber local_nameservers= 677d7149f4eSGlen Barber fi 678d7149f4eSGlen Barber ;; 679d7149f4eSGlen Barber x) IF_EXCLUSIVE=1;; 680587392a5SHajimu UMEMOTO '?') ;; 681587392a5SHajimu UMEMOTO *) cmd="$OPT"; iface="$OPTARG";; 682587392a5SHajimu UMEMOTO esac 683587392a5SHajimu UMEMOTOdone 684587392a5SHajimu UMEMOTOshift $(($OPTIND - 1)) 685d7149f4eSGlen Barberargs="$iface${iface:+ }$*" 686587392a5SHajimu UMEMOTO 687587392a5SHajimu UMEMOTO# -I inits the state dir 688587392a5SHajimu UMEMOTOif [ "$cmd" = I ]; then 689587392a5SHajimu UMEMOTO if [ -d "$VARDIR" ]; then 690587392a5SHajimu UMEMOTO rm -rf "$VARDIR"/* 691587392a5SHajimu UMEMOTO fi 692587392a5SHajimu UMEMOTO exit $? 693587392a5SHajimu UMEMOTOfi 694587392a5SHajimu UMEMOTO 695d7149f4eSGlen Barber# -D ensures that the listed config file base dirs exist 696d7149f4eSGlen Barberif [ "$cmd" = D ]; then 697d7149f4eSGlen Barber config_mkdirs "$@" 698d7149f4eSGlen Barber exit $? 699d7149f4eSGlen Barberfi 700d7149f4eSGlen Barber 701587392a5SHajimu UMEMOTO# -l lists our resolv files, optionally for a specific interface 702*9af6c78cSPedro F. Giffuniif [ "$cmd" = l ] || [ "$cmd" = i ]; then 703587392a5SHajimu UMEMOTO list_resolv "$cmd" "$args" 704587392a5SHajimu UMEMOTO exit $? 705587392a5SHajimu UMEMOTOfi 706587392a5SHajimu UMEMOTO 7073f2a60a1SPedro F. Giffuni# Restart a service or echo the command to restart a service 708*9af6c78cSPedro F. Giffuniif [ "$cmd" = r ] || [ "$cmd" = R ]; then 7093f2a60a1SPedro F. Giffuni detect_init || exit 1 7103f2a60a1SPedro F. Giffuni if [ "$cmd" = r ]; then 7113f2a60a1SPedro F. Giffuni set -- $args 712*9af6c78cSPedro F. Giffuni eval "$RESTARTCMD" 7133f2a60a1SPedro F. Giffuni else 714*9af6c78cSPedro F. Giffuni echo "$RESTARTCMD" | 715*9af6c78cSPedro F. Giffuni sed -e '/^$/d' -e 's/^ //g' 7163f2a60a1SPedro F. Giffuni fi 7173f2a60a1SPedro F. Giffuni exit $? 7183f2a60a1SPedro F. Giffunifi 7193f2a60a1SPedro F. Giffuni 720587392a5SHajimu UMEMOTO# Not normally needed, but subscribers should be able to run independently 721*9af6c78cSPedro F. Giffuniif [ "$cmd" = v ] || [ -n "$VFLAG" ]; then 722587392a5SHajimu UMEMOTO make_vars "$iface" 723587392a5SHajimu UMEMOTO exit $? 724587392a5SHajimu UMEMOTOfi 725587392a5SHajimu UMEMOTO 726587392a5SHajimu UMEMOTO# Test that we have valid options 727*9af6c78cSPedro F. Giffuniif [ "$cmd" = a ] || [ "$cmd" = d ]; then 728587392a5SHajimu UMEMOTO if [ -z "$iface" ]; then 729587392a5SHajimu UMEMOTO usage "Interface not specified" 730587392a5SHajimu UMEMOTO fi 731587392a5SHajimu UMEMOTOelif [ "$cmd" != u ]; then 732*9af6c78cSPedro F. Giffuni [ -n "$cmd" ] && [ "$cmd" != h ] && usage "Unknown option $cmd" 733587392a5SHajimu UMEMOTO usage 734587392a5SHajimu UMEMOTOfi 735d7149f4eSGlen Barber 736587392a5SHajimu UMEMOTOif [ "$cmd" = a ]; then 737587392a5SHajimu UMEMOTO for x in '/' \\ ' ' '*'; do 738587392a5SHajimu UMEMOTO case "$iface" in 739587392a5SHajimu UMEMOTO *[$x]*) error_exit "$x not allowed in interface name";; 740587392a5SHajimu UMEMOTO esac 741587392a5SHajimu UMEMOTO done 742587392a5SHajimu UMEMOTO for x in '.' '-' '~'; do 743587392a5SHajimu UMEMOTO case "$iface" in 744587392a5SHajimu UMEMOTO [$x]*) error_exit \ 745587392a5SHajimu UMEMOTO "$x not allowed at start of interface name";; 746587392a5SHajimu UMEMOTO esac 747587392a5SHajimu UMEMOTO done 748*9af6c78cSPedro F. Giffuni [ "$cmd" = a ] && [ -t 0 ] && error_exit "No file given via stdin" 749587392a5SHajimu UMEMOTOfi 750587392a5SHajimu UMEMOTO 751587392a5SHajimu UMEMOTOif [ ! -d "$VARDIR" ]; then 752587392a5SHajimu UMEMOTO if [ -L "$VARDIR" ]; then 753587392a5SHajimu UMEMOTO dir="$(readlink "$VARDIR")" 754587392a5SHajimu UMEMOTO # link maybe relative 755587392a5SHajimu UMEMOTO cd "${VARDIR%/*}" 756587392a5SHajimu UMEMOTO if ! mkdir -m 0755 -p "$dir"; then 757587392a5SHajimu UMEMOTO error_exit "Failed to create needed" \ 758587392a5SHajimu UMEMOTO "directory $dir" 759587392a5SHajimu UMEMOTO fi 760587392a5SHajimu UMEMOTO else 761587392a5SHajimu UMEMOTO if ! mkdir -m 0755 -p "$VARDIR"; then 762587392a5SHajimu UMEMOTO error_exit "Failed to create needed" \ 763587392a5SHajimu UMEMOTO "directory $VARDIR" 764587392a5SHajimu UMEMOTO fi 765587392a5SHajimu UMEMOTO fi 766587392a5SHajimu UMEMOTOfi 767d7149f4eSGlen Barber 768d7149f4eSGlen Barberif [ ! -d "$IFACEDIR" ]; then 769587392a5SHajimu UMEMOTO mkdir -m 0755 -p "$IFACEDIR" || \ 770587392a5SHajimu UMEMOTO error_exit "Failed to create needed directory $IFACEDIR" 771587392a5SHajimu UMEMOTO if [ "$cmd" = d ]; then 772d7149f4eSGlen Barber # Provide the same error messages as below 773d7149f4eSGlen Barber if ! ${force}; then 774587392a5SHajimu UMEMOTO cd "$IFACEDIR" 775587392a5SHajimu UMEMOTO for i in $args; do 776d7149f4eSGlen Barber warn "No resolv.conf for interface $i" 777587392a5SHajimu UMEMOTO done 778587392a5SHajimu UMEMOTO fi 779d7149f4eSGlen Barber ${force} 780d7149f4eSGlen Barber exit $? 781d7149f4eSGlen Barber fi 782587392a5SHajimu UMEMOTOfi 783587392a5SHajimu UMEMOTO 784d7149f4eSGlen Barber# An interface was added, changed, deleted or a general update was called. 785d7149f4eSGlen Barber# Due to exclusivity we need to ensure that this is an atomic operation. 786d7149f4eSGlen Barber# Our subscribers *may* need this as well if the init system is sub par. 787d7149f4eSGlen Barber# As such we spinlock at this point as best we can. 788d7149f4eSGlen Barber# We don't use flock(1) because it's not widely available and normally resides 789d7149f4eSGlen Barber# in /usr which we do our very best to operate without. 790d7149f4eSGlen Barber[ -w "$VARDIR" ] || error_exit "Cannot write to $LOCKDIR" 791d7149f4eSGlen Barber: ${lock_timeout:=10} 792d7149f4eSGlen Barberwhile true; do 793d7149f4eSGlen Barber if mkdir "$LOCKDIR" 2>/dev/null; then 794d7149f4eSGlen Barber trap 'rm -rf "$LOCKDIR";' EXIT 795d7149f4eSGlen Barber trap 'rm -rf "$LOCKDIR"; exit 1' INT QUIT ABRT SEGV ALRM TERM 796d7149f4eSGlen Barber echo $$ >"$LOCKDIR/pid" 797d7149f4eSGlen Barber break 798d7149f4eSGlen Barber fi 799d7149f4eSGlen Barber pid=$(cat "$LOCKDIR/pid") 800d7149f4eSGlen Barber if ! kill -0 "$pid"; then 801d7149f4eSGlen Barber warn "clearing stale lock pid $pid" 802d7149f4eSGlen Barber rm -rf "$LOCKDIR" 803d7149f4eSGlen Barber continue 804d7149f4eSGlen Barber fi 805d7149f4eSGlen Barber lock_timeout=$(($lock_timeout - 1)) 806d7149f4eSGlen Barber if [ "$lock_timeout" -le 0 ]; then 807d7149f4eSGlen Barber error_exit "timed out waiting for lock from pid $pid" 808d7149f4eSGlen Barber fi 809d7149f4eSGlen Barber sleep 1 810d7149f4eSGlen Barberdone 811d7149f4eSGlen Barber 812d7149f4eSGlen Barbercase "$cmd" in 813d7149f4eSGlen Barbera) 814587392a5SHajimu UMEMOTO # Read resolv.conf from stdin 815a02aba5fSHiroki Sato resolv="$(cat)" 816d7149f4eSGlen Barber changed=false 817d7149f4eSGlen Barber changedfile=false 818587392a5SHajimu UMEMOTO # If what we are given matches what we have, then do nothing 819587392a5SHajimu UMEMOTO if [ -e "$IFACEDIR/$iface" ]; then 820d7149f4eSGlen Barber if [ "$(echo "$resolv")" != \ 821587392a5SHajimu UMEMOTO "$(cat "$IFACEDIR/$iface")" ] 822587392a5SHajimu UMEMOTO then 823d7149f4eSGlen Barber changed=true 824d7149f4eSGlen Barber changedfile=true 825587392a5SHajimu UMEMOTO fi 826d7149f4eSGlen Barber else 827d7149f4eSGlen Barber changed=true 828d7149f4eSGlen Barber changedfile=true 829587392a5SHajimu UMEMOTO fi 830d7149f4eSGlen Barber 831d7149f4eSGlen Barber # Set metric and private before creating the interface resolv.conf file 832d7149f4eSGlen Barber # to ensure that it will have the correct flags 833587392a5SHajimu UMEMOTO [ ! -d "$METRICDIR" ] && mkdir "$METRICDIR" 834d7149f4eSGlen Barber oldmetric="$METRICDIR/"*" $iface" 835d7149f4eSGlen Barber newmetric= 836587392a5SHajimu UMEMOTO if [ -n "$IF_METRIC" ]; then 837587392a5SHajimu UMEMOTO # Pad metric to 6 characters, so 5 is less than 10 838587392a5SHajimu UMEMOTO while [ ${#IF_METRIC} -le 6 ]; do 839587392a5SHajimu UMEMOTO IF_METRIC="0$IF_METRIC" 840587392a5SHajimu UMEMOTO done 841d7149f4eSGlen Barber newmetric="$METRICDIR/$IF_METRIC $iface" 842587392a5SHajimu UMEMOTO fi 843d7149f4eSGlen Barber rm -f "$METRICDIR/"*" $iface" 844*9af6c78cSPedro F. Giffuni [ "$oldmetric" != "$newmetric" ] && 845*9af6c78cSPedro F. Giffuni [ "$oldmetric" != "$METRICDIR/* $iface" ] && 846d7149f4eSGlen Barber changed=true 847d7149f4eSGlen Barber [ -n "$newmetric" ] && echo " " >"$newmetric" 848d7149f4eSGlen Barber 849587392a5SHajimu UMEMOTO case "$IF_PRIVATE" in 850587392a5SHajimu UMEMOTO [Yy][Ee][Ss]|[Tt][Rr][Uu][Ee]|[Oo][Nn]|1) 851587392a5SHajimu UMEMOTO if [ ! -d "$PRIVATEDIR" ]; then 852587392a5SHajimu UMEMOTO [ -e "$PRIVATEDIR" ] && rm "$PRIVATEDIR" 853587392a5SHajimu UMEMOTO mkdir "$PRIVATEDIR" 854587392a5SHajimu UMEMOTO fi 855d7149f4eSGlen Barber [ -e "$PRIVATEDIR/$iface" ] || changed=true 856587392a5SHajimu UMEMOTO [ -d "$PRIVATEDIR" ] && echo " " >"$PRIVATEDIR/$iface" 857587392a5SHajimu UMEMOTO ;; 858587392a5SHajimu UMEMOTO *) 859587392a5SHajimu UMEMOTO if [ -e "$PRIVATEDIR/$iface" ]; then 860587392a5SHajimu UMEMOTO rm -f "$PRIVATEDIR/$iface" 861d7149f4eSGlen Barber changed=true 862587392a5SHajimu UMEMOTO fi 863587392a5SHajimu UMEMOTO ;; 864587392a5SHajimu UMEMOTO esac 865d7149f4eSGlen Barber 866d7149f4eSGlen Barber oldexcl= 867d7149f4eSGlen Barber for x in "$EXCLUSIVEDIR/"*" $iface"; do 868d7149f4eSGlen Barber if [ -f "$x" ]; then 869d7149f4eSGlen Barber oldexcl="$x" 870d7149f4eSGlen Barber break 871587392a5SHajimu UMEMOTO fi 872d7149f4eSGlen Barber done 873d7149f4eSGlen Barber case "$IF_EXCLUSIVE" in 874d7149f4eSGlen Barber [Yy][Ee][Ss]|[Tt][Rr][Uu][Ee]|[Oo][Nn]|1) 875d7149f4eSGlen Barber if [ ! -d "$EXCLUSIVEDIR" ]; then 876d7149f4eSGlen Barber [ -e "$EXCLUSIVEDIR" ] && rm "$EXCLUSIVEDIR" 877d7149f4eSGlen Barber mkdir "$EXCLUSIVEDIR" 878d7149f4eSGlen Barber fi 879d7149f4eSGlen Barber cd "$EXCLUSIVEDIR" 880d7149f4eSGlen Barber for x in *; do 881d7149f4eSGlen Barber [ -f "$x" ] && break 882d7149f4eSGlen Barber done 883d7149f4eSGlen Barber if [ "${x#* }" != "$iface" ]; then 884d7149f4eSGlen Barber if [ "$x" = "${x% *}" ]; then 885d7149f4eSGlen Barber x=10000000 886d7149f4eSGlen Barber else 887d7149f4eSGlen Barber x="${x% *}" 888d7149f4eSGlen Barber fi 889d7149f4eSGlen Barber if [ "$x" = "0000000" ]; then 890d7149f4eSGlen Barber warn "exclusive underflow" 891d7149f4eSGlen Barber else 892d7149f4eSGlen Barber x=$(($x - 1)) 893d7149f4eSGlen Barber fi 894d7149f4eSGlen Barber if [ -d "$EXCLUSIVEDIR" ]; then 895d7149f4eSGlen Barber echo " " >"$EXCLUSIVEDIR/$x $iface" 896d7149f4eSGlen Barber fi 897d7149f4eSGlen Barber changed=true 898d7149f4eSGlen Barber fi 899d7149f4eSGlen Barber ;; 900d7149f4eSGlen Barber *) 901d7149f4eSGlen Barber if [ -f "$oldexcl" ]; then 902d7149f4eSGlen Barber rm -f "$oldexcl" 903d7149f4eSGlen Barber changed=true 904d7149f4eSGlen Barber fi 905d7149f4eSGlen Barber ;; 906d7149f4eSGlen Barber esac 907d7149f4eSGlen Barber 908d7149f4eSGlen Barber if $changedfile; then 909d7149f4eSGlen Barber printf "%s\n" "$resolv" >"$IFACEDIR/$iface" || exit $? 910d7149f4eSGlen Barber elif ! $changed; then 911d7149f4eSGlen Barber exit 0 912d7149f4eSGlen Barber fi 913d7149f4eSGlen Barber unset changed changedfile oldmetric newmetric x oldexcl 914d7149f4eSGlen Barber ;; 915d7149f4eSGlen Barber 916d7149f4eSGlen Barberd) 917d7149f4eSGlen Barber # Delete any existing information about the interface 918d7149f4eSGlen Barber cd "$IFACEDIR" 919d7149f4eSGlen Barber changed=false 920d7149f4eSGlen Barber for i in $args; do 921d7149f4eSGlen Barber if [ -e "$i" ]; then 922d7149f4eSGlen Barber changed=true 923d7149f4eSGlen Barber elif ! ${force}; then 924d7149f4eSGlen Barber warn "No resolv.conf for interface $i" 925d7149f4eSGlen Barber fi 926d7149f4eSGlen Barber rm -f "$i" "$METRICDIR/"*" $i" \ 927d7149f4eSGlen Barber "$PRIVATEDIR/$i" \ 928d7149f4eSGlen Barber "$EXCLUSIVEDIR/"*" $i" || exit $? 929d7149f4eSGlen Barber done 930d7149f4eSGlen Barber if ! ${changed}; then 931d7149f4eSGlen Barber # Set the return code based on the forced flag 932d7149f4eSGlen Barber ${force} 933d7149f4eSGlen Barber exit $? 934d7149f4eSGlen Barber fi 935d7149f4eSGlen Barber unset changed i 936d7149f4eSGlen Barber ;; 937d7149f4eSGlen Barberesac 938d7149f4eSGlen Barber 939d7149f4eSGlen Barbercase "${resolvconf:-YES}" in 940d7149f4eSGlen Barber[Yy][Ee][Ss]|[Tt][Rr][Uu][Ee]|[Oo][Nn]|1) ;; 941d7149f4eSGlen Barber*) exit 0;; 942d7149f4eSGlen Barberesac 943587392a5SHajimu UMEMOTO 9443f2a60a1SPedro F. Giffuni# Try and detect a suitable init system for our scripts 9453f2a60a1SPedro F. Giffunidetect_init 9463f2a60a1SPedro F. Giffuniexport RESTARTCMD RCDIR _NOINIT_WARNED 9473f2a60a1SPedro F. Giffuni 948587392a5SHajimu UMEMOTOeval "$(make_vars)" 949587392a5SHajimu UMEMOTOexport RESOLVCONF DOMAINS SEARCH NAMESERVERS LOCALNAMESERVERS 950587392a5SHajimu UMEMOTO: ${list_resolv:=list_resolv -l} 951587392a5SHajimu UMEMOTOretval=0 952c364f334SPedro F. Giffuni 953c364f334SPedro F. Giffuni# Run scripts in the same directory resolvconf is run from 9543f2a60a1SPedro F. Giffuni# in case any scripts accidentally dump files in the wrong place. 955c364f334SPedro F. Giffunicd "$_PWD" 956587392a5SHajimu UMEMOTOfor script in "$LIBEXECDIR"/*; do 957587392a5SHajimu UMEMOTO if [ -f "$script" ]; then 958d7149f4eSGlen Barber eval script_enabled="\$${script##*/}" 959d7149f4eSGlen Barber case "${script_enabled:-YES}" in 960d7149f4eSGlen Barber [Yy][Ee][Ss]|[Tt][Rr][Uu][Ee]|[Oo][Nn]|1) ;; 961d7149f4eSGlen Barber *) continue;; 962d7149f4eSGlen Barber esac 963587392a5SHajimu UMEMOTO if [ -x "$script" ]; then 964587392a5SHajimu UMEMOTO "$script" "$cmd" "$iface" 965587392a5SHajimu UMEMOTO else 966d7149f4eSGlen Barber (set -- "$cmd" "$iface"; . "$script") 967587392a5SHajimu UMEMOTO fi 968587392a5SHajimu UMEMOTO retval=$(($retval + $?)) 969587392a5SHajimu UMEMOTO fi 970587392a5SHajimu UMEMOTOdone 971587392a5SHajimu UMEMOTOexit $retval 972