#!/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