#!/bin/bash

. /.initrd/initenv

. shell-error
. uevent-sh-functions
. network-sh-functions

PROG="${QUEUE:--}: session=${SESSION:-0}: $PROG"
message_time=1

dhcp_packets_pause=5
dhcp_number_packets=3
piddir=/var/run

need_dhcp()
{
	local n
	for n in "ifaces/$NET_IF" "default"; do
		[ ! -e "$net_confdir/$n/ipv${ip_version}dhcp" ] ||
			return 0
	done
	return 1
}

run_dhcp()
{
	local pidfile="$piddir/udhcpc$ip_version.$NET_IF.pid"

	[ ! -f "$pidfile" ] && need_dhcp ||
		return 1

	[ "$ip_version" != 6 ] ||
		load_ipv6

	ipv${ip_version}_enabled ||
		return 1

	if ! is_link_up "$NET_IF"; then
		message "$NET_IF: trying to obtain configuration from dhcp ..."

		ip_cmd link set dev "$NET_IF" up ||:

		wait_for_link_up "$NET_IF" ||
			fatal "$NET_IF: could not bring interface up (timeout)"
	fi

	set -- "$1" -v -n \
		-i "$NET_IF" \
		-t "$dhcp_number_packets" \
		-T "$dhcp_packets_pause" \
		-s "/lib/network/udhcpc$ip_version.script" \
		-p "$pidfile"

	message "run: $*"

	"$@" >>"/var/log/udhcpc$ip_version.$NET_IF.log" 2>&1 &
}

handler()
{
	! is_loopback "$NET_IF" ||
		return 0

	case "$ev_action" in
		update)
			states=
			for ip_version in 4 6; do
				case "$ip_version" in
					4) cmd=udhcpc ;;
					6) cmd=udhcpc6 ;;
				esac
				! run_dhcp "$cmd" ||
					states="$states $ip_version"
			done

			[ -n "$states" ] ||
				return 0

			secs=$((1 + ($dhcp_number_packets * $dhcp_packets_pause) ))
			message "$NET_IF: waiting $secs seconds for configuration by dhcp ..."

			i=$(($secs * 10))
			while [ $i -ge 0 ]; do
				i=$(($i-1))
				sleep 0.1
				for v in $states; do
					[ -e "$net_statedir/dhcp/$NET_IF/ipv$v" ] ||
						continue 2
				done
				i=-1
			done

			message "$NET_IF: dhcp done"
			;;
		remove)
			for ip_version in 4 6; do
				pid=
				{ read -r pid < "$piddir/udhcpc$ip_version.$NET_IF.pid" ||:; } >/dev/null 2>&1

				[ -z "$pid" ] ||
					kill "$pid" 2>/dev/null ||:
			done
			;;
	esac
}

ev_type='config'
for e in "$1/network.$ev_type".*; do
	[ -e "$e" ] || break

	ev_action="${e##*/network.$ev_type.}"
	ev_action="${ev_action%%.*}"

	( . "$e"; handler; ) ||:
done
