#!/bin/sh -efu

dhcp_generalconf_file="/etc/alterator/dhcp/general"
dhcp6_generalconf_file="/etc/alterator/dhcp6/general"
dhcp_lease_file="/var/lib/dhcp/dhcpd/state/dhcpd.leases"
dhcp6_lease_file="/var/lib/dhcp/dhcpd6/state/dhcpd6.leases"
_radvd="/usr/sbin/radvd"

. alterator-service-functions
. shell-config
. shell-quote

### daemon

dhcp_daemon_status()
{
	local ipv="${1-}"
    local IFS=' '

	[ "$ipv" = 6 ] || ipv=

	service_control "dhcpd$ipv" is-enabled || return 1
    service_control "dhcpd$ipv" is-active || return 1
	if [ "$ipv" = 6 ]; then
		service_control radvd is-enabled || return 1
		service_control radvd is-active || return 1
	fi

	return 0
}

dhcp_daemon_on()
{
	local ipv="${1-}"

	if [ "$ipv" = 6 ]; then
		[ -x "$_radvd" ] || return 1
	else
		ipv=
	fi

    dhcp_daemon_status "$ipv" && return 0

    service_control "dhcpd$ipv" enable &&
    service_control "dhcpd$ipv" start ||:

	# Enable radvd too
	if [ "$ipv" = 6 ]; then
		service_control radvd on &&
	    service_control radvd start ||:
	fi
}

dhcp_daemon_off()
{
	local ipv="${1-}"

	[ "$ipv" = 6 ] || ipv=

    service_control "dhcpd$ipv" condstop ||:
    service_control "dhcpd$ipv" disable ||:
	# Disable radvd too
	if [ "$ipv" = 6 ]; then
		service_control radvd condstop ||:
		service_control radvd disable ||:
	fi
}

dhcp_daemon_condreload()
{
	local ipv="${1-}"

	[ "$ipv" = 6 ] || ipv=

    service_control "dhcpd$ipv" condreload
	# Reload radvd too
	if [ "$ipv" = 6 ]; then
		service_control radvd condreload
	fi
}

### config file

dhcp_config_get()
{
	local var="$1"; shift
	local ipv="${1-}"
	local conf_file=

	[ "$ipv" = 6 ] || ipv=

	eval "conf_file=\$dhcp${ipv}_generalconf_file"
    shell_config_get "$conf_file" "$var"
}

dhcp_config_set()
{
	local var="$1"; shift
	local value="$1"; shift
	local ipv="${1-}"
	local conf_file=

	[ "$ipv" = 6 ] || ipv=

	eval "conf_file=\$dhcp${ipv}_generalconf_file"
    shell_config_set "$conf_file" "$var" "$value"
}

dhcp_update_config()
{
	local ipv="${1-}"
    alterator-dhcp-reset "$ipv" && dhcp_daemon_condreload "$ipv" || :
}

#### leases

dhcp_lease_list()
{
	local ipv="${1-}"
	local lease_file=

	[ "$ipv" = 6 ] || ipv=
	eval "lease_file=\$dhcp${ipv}_lease_file"

    /bin/awk \
	'BEGIN { OFS = "_"}

	match($0,/^[[:space:]]*lease[[:space:]]+([^[:space:]]+)[[:space:]]+\{[[:space:]]*$/,re) { r["ip"]=re[1]; }
	match($0,/^[[:space:]]*binding state[[:space:]]+([^[:space:]]+)[[:space:]]*;[[:space:]]*$/,re) { r["state"] = re[1]; }
	match($0,/^[[:space:]]*hardware ethernet[[:space:]]+([^[:space:]]+)[[:space:]]*;[[:space:]]*$/,re) { r["hw"] = re[1]; }
	match($0,/^[[:space:]]*ends[[:space:]]+[^[:space:]]+[[:space:]]+([^;]+);[[:space:]]*$/,re) { r["expired"]=re[1]; }
	match($0,/^[[:space:]]*client-hostname[[:space:]]+"([^;"]+)"[[:space:]]*;[[:space:]]*$/,re) { r["hostname"]=re[1]; }

	/^[[:space:]]*}[[:space:]]*$/	{ if (r["state"] == "active") print r["ip"],r["hw"],r["expired"],r["hostname"]; for (i in r) delete r[i]; } ' \
	"$lease_file"
}

dhcp_lease_remove()
{
    local ip="$1";shift
	local ipv="${1-}"
	local lease_file=

	[ "$ipv" = 6 ] || ipv=
	eval "lease_file=\$dhcp${ipv}_lease_file"

    dhcp_daemon_status "$ipv"
    local running="$?"
    service_control "dhcpd$ipv" condstop

    sed "/^[[:space:]]*lease[[:space:]]\+$(quote_sed_regexp "$ip")[[:space:]]\+{/,/^[[:space:]]*}[[:space:]]*$/ d" \
	-i "$lease_file"

    [ "$running" = "0" ] && service_control "dhcpd$ipv" start
}
