head	1.1;
branch	1.1.1;
access;
symbols
	netbsd-11-0-RC6:1.1.1.4
	netbsd-11-0-RC5:1.1.1.4
	netbsd-11-0-RC4:1.1.1.4
	netbsd-11-0-RC3:1.1.1.4
	dhcpcd-10_3_1:1.1.1.4
	netbsd-11-0-RC2:1.1.1.4
	netbsd-11-0-RC1:1.1.1.4
	perseant-exfatfs-base-20250801:1.1.1.4
	netbsd-11:1.1.1.4.0.2
	netbsd-11-base:1.1.1.4
	dhcpcd-10_2_3:1.1.1.4
	dhcpcd-10_2_2:1.1.1.4
	dhcpcd-10_2_0a:1.1.1.4
	dhcpcd-10_2_0:1.1.1.3
	netbsd-10-1-RELEASE:1.1.1.1
	perseant-exfatfs-base-20240630:1.1.1.2
	perseant-exfatfs:1.1.1.2.0.2
	perseant-exfatfs-base:1.1.1.2
	dhcpcd-10_0_8:1.1.1.2
	dhcpcd-10_0_7:1.1.1.2
	netbsd-10-0-RELEASE:1.1.1.1
	netbsd-10-0-RC6:1.1.1.1
	netbsd-10-0-RC5:1.1.1.1
	netbsd-10-0-RC4:1.1.1.1
	netbsd-10-0-RC3:1.1.1.1
	netbsd-10-0-RC2:1.1.1.1
	dhcpcd-10_0_6a:1.1.1.2
	dhcpcd-10_0_6:1.1.1.2
	netbsd-10-0-RC1:1.1.1.1
	dhcpcd-10_0_4:1.1.1.2
	dhcpcd-10_0_3:1.1.1.2
	dhcpcd-10_0_2:1.1.1.2
	dhcpcd-10_0_1:1.1.1.2
	netbsd-10:1.1.1.1.0.2
	netbsd-10-base:1.1.1.1
	dhcpcd-9_4_1:1.1.1.1
	ROY:1.1.1;
locks; strict;
comment	@# @;


1.1
date	2021.10.22.13.21.59;	author roy;	state Exp;
branches
	1.1.1.1;
next	;
commitid	eOPIn2Vu4Z0idOdD;

1.1.1.1
date	2021.10.22.13.21.59;	author roy;	state Exp;
branches;
next	1.1.1.2;
commitid	eOPIn2Vu4Z0idOdD;

1.1.1.2
date	2023.04.21.16.52.46;	author roy;	state Exp;
branches;
next	1.1.1.3;
commitid	SzhZ9f5ppzfOOZlE;

1.1.1.3
date	2025.02.12.16.57.08;	author roy;	state Exp;
branches;
next	1.1.1.4;
commitid	hHC6B2p77DzGxcJF;

1.1.1.4
date	2025.02.12.18.57.11;	author roy;	state Exp;
branches;
next	;
commitid	bkeHrAZqaKIWcdJF;


desc
@@


1.1
log
@Initial revision
@
text
@#!/bin/sh
# dhcpcd client configuration script 

# Handy variables and functions for our hooks to use
ifname="$interface${protocol+.}$protocol"
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/hook-state
_detected_init=false

: ${if_up:=false}
: ${if_down:=false}
: ${syslog_debug:=false}

# Ensure that all arguments are unique
uniqify()
{
	result=
	for i do
		case " $result " in
			*" $i "*);;
			*) result="$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()
{
	ifaces=
	for i in $interface_order; do
		for x in "$1"/$i.*; do
			[ -f "$x" ] && ifaces="$ifaces${ifaces:+ }${x##*/}"
		done
	done
	for x in "$1"/*; do
		[ -f "$x" ] && ifaces="$ifaces${ifaces:+ }${x##*/}"
	done
	uniqify $ifaces
}

# Trim function
trim()
{
	var="$*"
	var=${var#"${var%%[![:space:]]*}"}
	var=${var%"${var##*[![:space:]]}"}
	if [ -z "$var" ]; then
		# So it seems our shell doesn't support wctype(3) patterns
		# Fall back to sed
		var=$(echo "$*" | sed -e 's/^[[:space:]]*//;s/[[:space:]]*$//')
	fi
	printf %s "$var"
}

# 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()
{
	key="$1"
	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()
{
	m1="$1"
	m2="$2"
	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.
comp_file()
{
	[ -e "$1" ] && [ -e "$2" ] || return 1

	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
}

# Compare two files.
# If different, replace first with second otherwise remove second.
change_file()
{
	if [ -e "$1" ]; then
		if comp_file "$1" "$2"; then
			rm -f "$2"
			return 1
		fi
	fi
	cat "$2" > "$1"
	rm -f "$2"
	return 0
}

# Compare two files.
# If different, copy or link depending on target type
copy_file()
{
	if [ -h "$2" ]; then
		[ "$(readlink "$2")" = "$1" ] && return 1
		ln -sf "$1" "$2"
	else
		comp_file "$1" "$2" && return 1
		cat "$1" >"$2"
	fi
}

# 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()
{
	lvl="$1"

	if [ "$lvl" = debug ]; then
		${syslog_debug} || return 0
	fi
	[ -n "$lvl" ] && shift
	[ -n "$*" ] || return 0
	case "$lvl" in
	err|error)	echo "$interface: $*" >&2;;
	*)		echo "$interface: $*";;
	esac
	if type logger >/dev/null 2>&1; then
		logger -i -p daemon."$lvl" -t dhcpcd-run-hooks "$interface: $*"
	fi
}

# Check for a valid name as per RFC952 and RFC1123 section 2.1
valid_domainname()
{
	name="$1"
	[ -z "$name" ] || [ ${#name} -gt 255 ] && return 1
	
	while [ -n "$name" ]; do
		label="${name%%.*}"
		[ -z "$label" ] || [ ${#label} -gt 63 ] && return 1
		case "$label" in
		-*|_*|*-|*_)		return 1;;
		*[![:alnum:]_-]*)	return 1;;
		"$name")		return 0;;
		esac
		name="${name#*.}"
	done
	return 0
}

valid_domainname_list()
{
	for name do
		valid_domainname "$name" || return $?
	done
	return 0
}

# With the advent of alternative init systems, it's possible to have
# more than one installed. So we need to try to guess what one we're
# using unless overridden by configure.
detect_init()
{
	_service_exists=""
	_service_cmd=""
	_service_status=""

	[ -n "$_service_cmd" ] && return 0

	if $_detected_init; then
		[ -n "$_service_cmd" ]
		return $?
	fi

	# Detect the running init system.
	# As systemd and OpenRC can be installed on top of legacy init
	# systems we try to detect them first.
	status=""
	: ${status:=status}
	if [ -x /bin/systemctl ] && [ -S /run/systemd/private ]; then
		_service_exists="/bin/systemctl --quiet is-enabled \$1.service"
		_service_status="/bin/systemctl --quiet is-active \$1.service"
		_service_cmd="/bin/systemctl \$2 \$1.service"
	elif [ -x /usr/bin/systemctl ] && [ -S /run/systemd/private ]; then
		_service_exists="/usr/bin/systemctl --quiet is-enabled \$1.service"
		_service_status="/usr/bin/systemctl --quiet is-active \$1.service"
		_service_cmd="/usr/bin/systemctl \$2 \$1.service"
	elif [ -x /sbin/rc-service ] &&
	     { [ -s /libexec/rc/init.d/softlevel ] ||
	     [ -s /run/openrc/softlevel ]; }
	then
		_service_exists="/sbin/rc-service -e \$1"
		_service_cmd="/sbin/rc-service \$1 -- -D \$2"
	elif [ -x /usr/sbin/invoke-rc.d ]; then
		_service_exists="/usr/sbin/invoke-rc.d --query --quiet \$1 start >/dev/null 2>&1 || [ \$? = 104 ]"
		_service_cmd="/usr/sbin/invoke-rc.d \$1 \$2"
	elif [ -x /sbin/service ]; then
		_service_exists="/sbin/service \$1 >/dev/null 2>&1"
		_service_cmd="/sbin/service \$1 \$2"
	elif [ -x /usr/sbin/service ]; then
		_service_exists="/usr/sbin/service \$1 $status >/dev/null 2>&1"
		_service_cmd="/usr/sbin/service \$1 \$2"
	elif [ -x /bin/sv ]; then
		_service_exists="/bin/sv status \$1 >/dev/null 2>&1"
		_service_cmd="/bin/sv \$2 \$1"
	elif [ -x /usr/bin/sv ]; then
		_service_exists="/usr/bin/sv status \$1 >/dev/null 2>&1"
		_service_cmd="/usr/bin/sv \$2 \$1"
	elif [ -e /etc/slackware-version ] && [ -d /etc/rc.d ]; then
		_service_exists="[ -x /etc/rc.d/rc.\$1 ]"
		_service_cmd="/etc/rc.d/rc.\$1 \$2"
		_service_status="/etc/rc.d/rc.\$1 status >/dev/null 2>&1"
	else
		for x in /etc/init.d/rc.d /etc/rc.d /etc/init.d; do
			if [ -d $x ]; then
				_service_exists="[ -x $x/\$1 ]"
				_service_cmd="$x/\$1 \$2"
				_service_status="$x/\$1 $status >/dev/null 2>&1"
				break
			fi
		done
		if [ -e /etc/arch-release ]; then
			_service_status="[ -e /var/run/daemons/\$1 ]"
		elif [ "$x" = "/etc/rc.d" ] && [ -e /etc/rc.d/rc.subr ]; then
			_service_status="$x/\$1 check >/dev/null 2>&1"
		fi
	fi

	_detected_init=true
	if [ -z "$_service_cmd" ]; then
		syslog err "could not detect a useable init system"
		return 1
	fi
	return 0
}

# Check a system service exists 
service_exists()
{
	if [ -z "$_service_exists" ]; then
		detect_init || return 1
	fi
	eval $_service_exists
}

# Send a command to a system service
service_cmd()
{
	if [ -z "$_service_cmd" ]; then
		detect_init || return 1
	fi
	eval $_service_cmd
}

# Send a command to a system service if it is running
service_status()
{
	if [ -z "$_service_cmd" ]; then
		detect_init || return 1
	fi
	if [ -n "$_service_status" ]; then
		eval $_service_status
	else
		service_command $1 status >/dev/null 2>&1
	fi
}

# 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 \
	/etc/dhcpcd.enter-hook \
	/libexec/dhcpcd-hooks/* \
	/etc/dhcpcd.exit-hook
do
	for skip in $skip_hooks; do
		case "$hook" in
			*/*~)				continue 2;;
			*/"$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
@


1.1.1.1
log
@Update to dhcpcd-9.4.1 with the following changes:

 * BSD: Find the correct interface for tunnelled routes
 * OpenBSD: Fix uniqueness of routes for matching priorities
 * Linux: Support more platforms for seccomp (thanks to Fabrice Fontaine)
 * eloop: Process all waiting fd's as they come in
 * control: Unlink sockets when not in privsep
 * privsep: Renamed Master to Manager
 * privsep: Renamed Privilged Actioneer to Privileged Proxy
 * privsep: Fix getting interface VLANID on BSD
 * privsep: Enforce proper alignment of serialized struct cmsghdr
 * IPv4LL: Don't remove statically assigned addresses
 * routes: Fix route comparision for network prefixes with different masks
 * DHCP6: Only send FQDN for SOLICIT, REQUEST, RENEW, or REBIND messages
 * DHCP6: Don't spam the log when a RA repeatedly triggers an INFORM
 * DHCP: Fix infinite INFORM messages
@
text
@@


1.1.1.2
log
@Update to dhcpcd-10.0.1 with the following changes:

 * privsep: keep resources open rather than open/close
 * dhcp6: OPTION_NTP_SERVER is now preferred over OPTION_SNTP_SERVER
 * Misc bug fixes mainly around privsep for many platforms.
 * Fix for reading the some BSD routing table entries.
 * Fix reading authtokens from config.

Big new release, mainly around better privsep process management
which allows us to detect when they exit unexpectedly.
@
text
@d70 1
a70 1
	if command -v sed >/dev/null 2>&1; then
d92 1
a92 1
	if command -v sed >/dev/null 2>&1; then
d112 1
a112 1
	if command -v cmp >/dev/null 2>&1; then
d114 1
a114 1
	elif command -v diff >/dev/null 2>&1; then
d181 1
a181 1
	if command -v logger >/dev/null 2>&1; then
d237 1
a237 1
		_service_cmd="/bin/systemctl \$2 --no-block \$1.service"
d241 1
a241 1
		_service_cmd="/usr/bin/systemctl \$2 --no-block \$1.service"
a340 3
	case "$hook" in
		*/*~)	continue;;
	esac
d343 1
@


1.1.1.3
log
@Update to dhcpcd-10.2.0 with the following changes:

dhcp6: start request when advertise received after IRT
dhcpcd: stdout output sometimes empty when redirected to a file
Fix help text formatting
Apply lastlease behavior to DHCPv6
dhcpcd not ignoring source-based routes on linux
DHCP6: lastlease behavior after Confim non-response
Allow limited RLIMIT_FSIZE when dumping lease
IPv6: Avoid uninitialized ifp state when adding address
DHCPv6: Add support for sending Option 17 (VSIO)
Exit the timesyncd hook if not on systemd and not executable
Add route lifetime from Router Advertisement
Fix using multiple enterprise IDs with vendclass
Update route if acquired time changes
Always send req for InfoRefreshTime option on Inform-Req
Increase max IPv4 clientid
@
text
@d11 1
a11 1
state_dir=/hook-state
d337 3
a339 3
	/dhcpcd.enter-hook \
	/dhcpcd-hooks/* \
	/dhcpcd.exit-hook
@


1.1.1.4
log
@Reimport dhcpcd-10.2.0 without the compat entry to break stuff
@
text
@d11 1
a11 1
state_dir=/var/run/dhcpcd/hook-state
d337 3
a339 3
	/etc/dhcpcd.enter-hook \
	/libexec/dhcpcd-hooks/* \
	/etc/dhcpcd.exit-hook
@


