blob: 2125f9a2857e4a27e5e04e91c27aff59fcdfd280 [file] [log] [blame]
#!/bin/sh
# dhcpcd client configuration script
# Handy variables and functions for our hooks to use
if [ "$reason" = ROUTERADVERT ]; then
ifsuffix=":ra"
else
ifsuffix=
fi
ifname="$interface$ifsuffix"
from=from
signature_base="# Generated by dhcpcd"
signature="$signature_base $from $ifname"
signature_base_end="# End of dhcpcd"
signature_end="$signature_base_end $from $ifname"
state_dir=/var/run/dhcpcd
# Ensure that all arguments are unique
uniqify()
{
local result= i=
for i do
case " $result " in
*" $i "*);;
*) result="$result $i";;
esac
done
echo "${result# *}"
}
# List interface config files in a directory.
# If dhcpcd is running as a single instance then it will have a list of
# interfaces in the preferred order.
# Otherwise we just use what we have.
list_interfaces()
{
local i= x= ifaces=
for i in $interface_order; do
[ -e "$1/$i" ] && ifaces="$ifaces${ifaces:+ }$i"
done
for x in "$1"/*; do
[ -e "$x" ] || continue
for i in $interface_order; do
if [ $i = "${x##*/}" ]; then
unset x
break
fi
done
[ -n "$x" ] && ifaces="$ifaces${ifaces:+ }${x##*/}"
done
echo "$ifaces"
}
# We normally use sed to extract values using a key from a list of files
# but sed may not always be available at the time.
key_get_value()
{
local key="$1" value= x= line=
shift
if type sed >/dev/null 2>&1; then
sed -n "s/^$key//p" $@
else
for x do
while read line; do
case "$line" in
"$key"*) echo "${line##$key}";;
esac
done < "$x"
done
fi
}
# We normally use sed to remove markers from a configuration file
# but sed may not always be available at the time.
remove_markers()
{
local m1="$1" m2="$2" x= line= in_marker=0
shift; shift
if type sed >/dev/null 2>&1; then
sed "/^$m1/,/^$m2/d" $@
else
for x do
while read line; do
case "$line" in
"$m1"*) in_marker=1;;
"$m2"*) in_marker=0;;
*) [ $in_marker = 0 ] && echo "$line";;
esac
done < "$x"
done
fi
}
# Compare two files.
# If different, replace first with second otherwise remove second.
change_file()
{
if [ -e "$1" ]; then
if type cmp >/dev/null 2>&1; then
cmp -s "$1" "$2"
elif type diff >/dev/null 2>&1; then
diff -q "$1" "$2" >/dev/null
else
# Hopefully we're only working on small text files ...
[ "$(cat "$1")" = "$(cat "$2")" ]
fi
if [ $? -eq 0 ]; then
rm -f "$2"
return 1
fi
fi
cat "$2" > "$1"
rm -f "$2"
return 0
}
# Save a config file
save_conf()
{
if [ -f "$1" ]; then
rm -f "$1-pre.$interface"
cat "$1" > "$1-pre.$interface"
fi
}
# Restore a config file
restore_conf()
{
[ -f "$1-pre.$interface" ] || return 1
cat "$1-pre.$interface" > "$1"
rm -f "$1-pre.$interface"
}
# Write a syslog entry
syslog()
{
local lvl="$1"
[ -n "$lvl" ] && shift
if [ -n "$*" ]; then
if type logger >/dev/null 2>&1; then
logger -t dhcpcd -p daemon."$lvl" -is "$interface: $*"
fi
fi
}
# Check for a valid domain name as per RFC1123 with the exception of
# allowing - and _ as they seem to be widely used.
valid_domainname()
{
local name="$1" label
[ -z "$name" -o ${#name} -gt 255 ] && return 1
while [ -n "$name" ]; do
label="${name%%.*}"
[ -z "$label" -o ${#label} -gt 63 ] && return 1
case "$label" in
-*|_*|*-|*_) return 1;;
*[![:alnum:]-_]*) return 1;;
esac
[ "$name" = "${name#*.}" ] && break
name="${name#*.}"
done
return 0
}
valid_domainname_list()
{
local name
for name do
valid_domainname "$name" || return $?
done
return 0
}
# Check for a valid path
valid_path()
{
case "$@" in
*[![:alnum:]#%+-_:\.,@~\\/\[\]=\ ]*) return 1;;
esac
return 0
}
# Check a system service exists
service_exists()
{
@SERVICEEXISTS@
}
# Send a command to a system service
service_cmd()
{
@SERVICECMD@
}
# Send a command to a system service if it is running
service_status()
{
@SERVICESTATUS@
}
# Handy macros for our hooks
service_command()
{
service_exists $1 && service_cmd $1 $2
}
service_condcommand()
{
service_exists $1 && service_status $1 && service_cmd $1 $2
}
# We source each script into this one so that scripts run earlier can
# remove variables from the environment so later scripts don't see them.
# Thus, the user can create their dhcpcd.enter/exit-hook script to configure
# /etc/resolv.conf how they want and stop the system scripts ever updating it.
for hook in \
@SYSCONFDIR@/dhcpcd.enter-hook \
@HOOKDIR@/* \
@SYSCONFDIR@/dhcpcd.exit-hook
do
for skip in $skip_hooks; do
case "$hook" in
*/"$skip") continue 2;;
*/[0-9][0-9]"-$skip") continue 2;;
*/[0-9][0-9]"-$skip.sh") continue 2;;
esac
done
if [ -f "$hook" ]; then
. "$hook"
fi
done