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