#!/bin/sh

################### shell file helpers

run_ifup()
{
    env -i PATH="$PATH" HOME="$HOME" TMPDIR="$TMPDIR" /sbin/ifup "$1"
}

run_ifdown()
{
    env -i PATH="$PATH" HOME="$HOME" TMPDIR="$TMPDIR" /sbin/ifdown "$1"
}

ifdumptool="/etc/net/scripts/contrib/ifdump"
ifup="run_ifup"
ifdown="run_ifdown"


. /etc/net/scripts/functions


shell_add_or_subst()
{
	local name="$1" && shift
	local value="$1" && shift
	local file="$1" && shift

	[ -f "$file" ] || touch "$file"
	if grep -qs "^$name" "$file"; then
		/bin/sed -r -i "s,^$name.*,$name$value," -- "$file"
		return 0
	fi
	printf %s\\n "$name$value" >> "$file"
}

shell_get()
{
	local name="$1" && shift
	local file="$1" && shift

	[ -f "$file" ] &&
	grep -qs "^$name=" "$file" &&
	grep "^$name=" "$file"|sed "s,^$name=,,"
}

################### interface modificators
update_iftab()
{
    local IFTAB_CONFIG="/etc/iftab"
    /sbin/ip -o a l|
	sed -nre 's|^[0-9]+: ([^:]+): [^/]* link/ether ([a-f0-9:]+).*|\1 \2|p'|
	while read name mac;do
	    if grep -qs "^$name[[:space:]]" "$IFTAB_CONFIG";then
		sed -r -e "s,^($name[[:space:]]+mac[[:space:]]+).*,\1$mac," -i "$IFTAB_CONFIG"
	    else
		printf "%s\tmac %s\n" "$name" "$mac" >>"$IFTAB_CONFIG"
	    fi
	done
}

list_mask()
{
    echo '('
    for i in `seq 32 -1 0`; do 
        printf '("%s" label "/%s (%s)")' "$i" "$i" "$(maskname "$i")"
    done
    echo ')'
}

list_iface()
{
    echo '('
    /sbin/ip -o a l|
        sed -ne 's|^[0-9]\+: \([^:]\+\): [^/]* link/ether .*|\1|p'|
        while read iface; do
            printf '("%s" label "%s (%s)")' "$iface" "$iface" "$(ifaceinfo "$iface")"
        done
    echo ')'
}

restart_iface()
{
    "$ifdown" "$1" && "$ifup" "$1"
}

restart_all_ifaces() {
    /sbin/ip -o a l|
        sed -ne 's|^[0-9]\+: \([^:]\+\): [^/]* link/ether .*|\1|p'|
        while read iface; do
		restart_iface "$iface"
        done >&2
}

read_iface()
{
	local name="$1" && shift
	if [ -z "$name" -o ! -d "/etc/net/ifaces/$name" ]; then
		printf '(wireless #f dhcp #f state #f)\n'
		return
	fi
	local addr= ip= mask=
	local BOOTPROTO= DISABLED=
	echo "("
	[ ! -s "/etc/net/ifaces/$name/ipv4address" ] ||
		addr=$(grep '^[0-9]' "/etc/net/ifaces/$name/ipv4address" | head -n1 || echo "")

	if [ -n "$addr" ]; then
		ip="${addr%%/*}"
		mask="${addr#$ip}"; mask="${mask#/}"
	fi

	printf 'ip "%s" mask "%s"\n' "$ip" "${mask:-32}"

	printf 'wireless %s' "$([ -d "/sys/class/net/$name/wireless" ] && echo "#t" || echo "#f")"

	[ ! -s "/etc/net/ifaces/$name/ipv4route" ] ||
		printf 'default "%s"\n' \
			$(grep '^default' "/etc/net/ifaces/$name/ipv4route" | sed -r 's,default[[:space:]]+via[[:space:]],,' || echo "")

	(eval $("$ifdumptool" "$name")
		[ "$BOOTPROTO" = "dhcp" ] && echo "dhcp #t" || echo "dhcp #f"
		is_yes "$DISABLED" && echo "state #f" || echo "state #t")

	echo ")"
}

write_iface()
{
	local name="$1" && shift
	[ -d "/etc/net/ifaces/$name" ] || mkdir "/etc/net/ifaces/$name"
	[ -n "$in_mask" ] && [ -n "$in_ip" ] && \
		printf '%s/%s\n' "$in_ip" "$in_mask" >"/etc/net/ifaces/$name/ipv4address"
	[ -n "$in_default" ] &&
		printf 'default via %s\n' "$in_default" >"/etc/net/ifaces/$name/ipv4route"
	local tmpfile=$(mktemp "/etc/net/ifaces/$name/options.XXXXXX")
	[ ! -s "/etc/net/ifaces/$name/options" ] ||
		cat "/etc/net/ifaces/$name/options" >"$tmpfile"
	[ -n "$in_dhcp" ] &&
		shell_add_or_subst "BOOTPROTO=" \
			$([ "$in_dhcp" = "#t" ] && echo "dhcp" || echo "static")\
			"$tmpfile"
	[ -n "$in_state" ] &&
		shell_add_or_subst "DISABLED=" \
			$([ "$in_state" = "#t" ] && echo "no" || echo "yes") \
			"$tmpfile"
	if [ ! -s "$tmpfile" ]; then
		rm "$tmpfile"
		return
	fi
	mv -f "$tmpfile" "/etc/net/ifaces/$name/options"
}

_()
{
LANG=${in_language%%;*}.utf8 gettext "alterator-net-tcp" "$1"
}

. /usr/share/alterator/build/backend3.sh

#initial actions
run_ifup lo
update_iftab

on_message()
{
	case "$in_action" in
		constraints)
			echo '('
			printf 'state (exclude (#f ip) exclude (#f default) exclude (#f mask) exclude (#f dhcp) default #f label "%s")' \
				"`_ "Interface is enabled"`"
			printf 'dhcp (exclude (#t ip) exclude (#t default) exclude (#t mask) default #f label "%s")' \
				"`_ "Use DHCP"`"
			printf 'ip (required #t ipv4-address #t label "%s")' \
				"`_ "IP address"`"
			printf 'default (ipv4-address #t label "%s")' \
				"`_ "Default gateway"`"
			printf 'mask (label "%s")' \
				"`_ "NetMask"`"
			echo ')'
			;;
		list)
			if [ "$in__objects" == "/" ];then
				list_iface
			else
				list_mask
			fi
			;;
		read) 
			if [ "$in__objects" == "/" ];then
				echo '()'
			else
				read_iface "${in__objects}"
			fi
			;;
		write)
			write_iface "${in__objects}"
			[ "$in_restart" = "#f" ] || restart_iface "$in__objects"
			echo '()'
			;;
		restart)
			restart_all_ifaces
			echo '()'
			;;
		*)
			echo '#f'
			;;
	esac
}

message_loop
