#!/bin/sh

############ common network helpers

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

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

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

ifrestart()
{
    echo "Restarting $i" >&2
    "$ifdown" "$1" 
    "$ifup" "$1"
}

condifup()
{
    ip -o link show dev "$i" 2>/dev/null |cut -d' ' -f3 |grep -qvs -- '[<,]UP[,>]' &&
    "$ifup" "$1" && echo "Up $i" >&2 ||:

}

network_dhcp_find()
{
	local i
	for i in /etc/net/ifaces/*;do
		i="${i##*/}"
		[ "$i" != "unknown" -a "$i" != "default" ] || continue
		(eval $("$ifdumptool" "$i"); [ "$DISABLED" != "yes" ] && [ -z "${BOOTPROTO%%dhcp*}" ] && [ "$DHCP_CLIENT" = "/sbin/dhcpcd" ]) &&
		"$1" "$i"
	done
}


############ main config files

netconfig="/etc/sysconfig/network"
resolv_conf="/etc/resolv.conf"
etc_hosts="/etc/hosts"
hostnameconfig="/etc/HOSTNAME"

############ helpers: shell config

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=,,"
}

############ hostname

local_hostname()
{
	shell_get "HOSTNAME" "$netconfig"
}

dhcp_hostname()
{
	f=$(grep -l "HOSTNAME=" /etc/dhcpc/*.info 2>/dev/null)
	[ -n "$f" ] && shell_get "HOSTNAME" "$f"|sed "s,',,g"
}

resolve_hostname()
{
    grep -qs "^nameserver" "$resolv_conf" &&
    for i in $(/sbin/ip addr show |
 	   	sed -ne 's,^[[:space:]]*inet[[:space:]]\+\([^/]\+\).*,\1,p'|
		grep -v '^127\.') ;do
	/usr/bin/resolve -t 2 -s "$i" && return 0
    done
    return 1
}

add_hosts()
{
	local host_name="$1" && shift
	grep -qs "^[^#]*\<$host_name\>" "$etc_hosts" && return 0
	if grep -qs "^127.0.0.1" "$etc_hosts"; then
		sed -r -e "s,^127\.0\.0\.1[[:space:]].*,127.0.0.1	$host_name ${host_name%%.*} localhost.localdomain localhost," -i "$etc_hosts"
		return 0
	fi
	printf '127.0.0.1\t%s %s\n' "$host_name" "${host_name%%.*} localhost.localdomain localhost" >> "$etc_hosts"
}

read_hostname()
{
	local_hostname || resolve_hostname || echo "localhost.localdomain"
}

write_hostname()
{
	local value="$1" && shift
	shell_add_or_subst "HOSTNAME=" "$value" "$netconfig"
	shell_add_or_subst "DOMAINNAME=" "${value#*.}" "$netconfig"
	printf %s\\n "$value" >"$hostnameconfig"
	hostname "$value"
	domainname "${value#*.}"
	add_hosts "$value"	
}

############ dns

read_dns()
{
	[ -f "$resolv_conf" ] &&
	grep "^nameserver " "$resolv_conf"|sed s,nameserver[[:space:]]*,,
}


write_dns()
{
	local values="$1" && shift
	[ -f "$resolv_conf" ] || touch "$resolv_conf"
	sed -i -r '/^nameserver/ d' "$resolv_conf"
	for i in $values ;
	do
		printf "nameserver %s\n" "$i" >>"$resolv_conf"
	done
}

############ search

read_search()
{
	[ -f "$resolv_conf" ] &&
	grep "^search " "$resolv_conf"|sed s,search[[:space:]]*,,|tr ' ' '\n'
}

write_search()
{
	local value="$(echo "$1"|grep -v '^$'|sed -r 's,^[[:space:]]*([^[:space:]]+)[[:space:]]*,\1,'|tr '\n' ' ')"
	shell_add_or_subst "search " "$value" "$resolv_conf"
}

############ dhcp args
read_dhcp()
{
	local f
	for f in /etc/net/ifaces/*; do
		f=${f##/etc/net/ifaces/}
		[ "$f" != "unknown" ] && [ "$f" != "default" ] || continue
		(eval $("$ifdumptool" "$f")
			[ "$DISABLED" != "yes" ] && 
			[ "$BOOTPROTO" != "${BOOTPROTO#dhcp*}" ] &&
			[ "$DHCP_CLIENT" = "/sbin/dhcpcd" ] &&
			echo "${DHCP_ARGS:+$DHCP_ARGS}"
		 ) && return 0
	done
	return 1
}


read_dhcp_arg()
{
	local arg="$1" && shift
	grep -wqs  -- "-$arg" 
}

write_dhcp_arg()
{
	local f
	local arg="$1" && shift
	local value="$1" && shift

	for f in /etc/net/ifaces/*; do
		mf=${f##/etc/net/ifaces/}
		[ "$mf" != "unknown" ] && [ "$mf" != "default" ] || continue
		(eval $("$ifdumptool" "$mf")
			[ "$DISABLED" != "yes" ] &&
			[ "$BOOTPROTO" != "${BOOTPROTO#dhcp*}" ] &&
			{ args="$(printf %s\\n "${DHCP_ARGS:+$DHCP_ARGS }" | sed -re "s,(^|.*[[:space:]])-$arg[[:space:]]([[:space:]]*.*|$),\1\2," | sed -re 's,^[[:space:]]*(.*)[[:space:]]+$,\1,')" #"
				sed -i '/^DHCP_ARGS=.*/d' "$f/options"
				if [ "$value" = "yes" ];then
					printf "DHCP_ARGS=\"%s -$arg\"\n" "$args" >> "$f/options"
				else
					[ -z "$args" ] || printf 'DHCP_ARGS="%s"\n' "$args" >> "$f/options"
				fi
			}
		 )
	done
}

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

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


#initial actions
run_ifup lo
network_dhcp_find "condifup"

on_message()
{
	case "$in_action" in
		constraints)
			echo '('
			echo 'dhcp (exclude (#f hostname_auto) exclude (#f dns_auto))'
			printf 'hostname_auto (exclude (#t hostname) default #f label "%s")\n' \
				"`_ "Get hostname from DHCP"`"
			printf 'dns_auto (exclude (#t dns) exclude (#t search) default #f label "%s")\n' \
				"`_ "Get resolver configuration from DHCP"`"
			printf 'hostname (required #t hostname #t label "%s" default "localhost.localdomain")\n' \
				"`_ "Hostname"`"
			printf 'search (hostname #t label "%s")\n' \
				"`_ "Search Domains"`"
			printf 'dns (ipv4-address #t label "%s")' \
				"`_ "Domain Name Servers (DNS)"`"
			echo ')'
			;;
		read) 
			local dns_dhcp=
			local hostname_dhcp=
			local dhcp=
			if args="$(read_dhcp)"; then
				dhcp="yes"
				echo "$args"|read_dhcp_arg "H" && hostname_dhcp="yes"
				echo "$args"|read_dhcp_arg "R" || dns_dhcp="yes"
			fi
			local hname=
			[ "$hostname_dhcp" = "yes" ] && hname="$(dhcp_hostname)"
			[ -z "$hname" ] && hname="$(read_hostname)"

			echo "("
			printf "hostname \"%s\"\n" "$hname"
			printf "dns \"%s\"\n" "$(read_dns)"
			printf "search \"%s\"\n" "$(read_search)"
	
			printf "dhcp %s\n"  $([ "$dhcp" = "yes" ] && echo "#t" || echo "#f")
			printf "dns_auto %s\n"  $([ "$dns_dhcp" = "yes" ] && echo "#t" || echo "#f")
			printf "hostname_auto %s\n" $([ "$hostname_dhcp" = "yes" ] && echo "#t" || echo "#f")
			echo ")"
		;;
		write)
			[ -n "$in_dns_auto" ] && 
				write_dhcp_arg "R" $([ "$in_dns_auto" = "#t" ] && echo "no" || echo "yes")
			[ -n "$in_hostname_auto" ] && 
				( write_dhcp_arg "H" $([ "$in_hostname_auto" = "#t" ] && echo "yes" || echo "no")
				  write_dhcp_arg "D" $([ "$in_hostname_auto" = "#t" ] && echo "yes" || echo "no")
				)
			[ -n "$in_hostname" ] &&
				if args="$(read_dhcp)"; then
					echo "$args"|read_dhcp_arg "H" || write_hostname "$in_hostname"
				else
					write_hostname "$in_hostname"
				fi
			[ -n "$in_dns" ] &&
				if args="$(read_dhcp)"; then
					echo "$args"|read_dhcp_arg "R" && write_dns "$in_dns"
				else
					write_dns "$in_dns"
				fi
			[ -n "$in_search" ] &&
				if args="$(read_dhcp)"; then
					echo "$args"|read_dhcp_arg "R" && write_search "$in_search"
				else
					write_search "$in_search"
				fi
			[ "$in_restart" = "#f" ] || network_dhcp_find "ifrestart"
			/sbin/update_chrooted conf >&2 || :
		    echo '()'
		    ;;
		*)
		    echo '#f'
		    ;;
	esac
}

message_loop

