#!/bin/bash

# This file contains supplementary functions for config-ipv4
try_static()
{
	local REALFILE=`profiled_filename $MYIFACEDIR/ipv4address`
	if [ -s $REALFILE ]; then
		local ADDRESSLINE
		$DENOISE $REALFILE | while read ADDRESSLINE; do
			is_yes "$AUTO_BROADCAST" && [ "$ADDRESSLINE" = "${ADDRESSLINE/broadcast/}" ] && \
				ADDRESSLINE="$ADDRESSLINE broadcast +"
			$IP -4 address add dev $NAME $(eval_string $ADDRESSLINE) && print_progress
		done
	fi
	return 0
}

dhcp_cmdline()
{
	local H T
	case `basename $DHCP_CLIENT` in
		dhcpcd)
			if [ -n "$DHCP_HOSTNAME" ]; then
				case "$DHCP_HOSTNAME" in
					AUTO)
						H="-H"
					;;
					localhost)
						[ -n "$HOSTNAME" -a "$HOSTNAME" != "localhost" -a "$HOSTNAME" != "localhost.localdomain" ] && \
						H="-h $HOSTNAME"
					;;
					*)
						H="-h $DHCP_HOSTNAME"
					;;
				esac
			fi
			T=${DHCP_TIMEOUT:+-t $DHCP_TIMEOUT}
			echo "$H -d $T $NAME"
			;;
		dhclient)
			if [ -n "$DHCP_HOSTNAME" ]; then
				case "$DHCP_HOSTNAME" in
					localhost)
						[ -n "$HOSTNAME" -a "$HOSTNAME" != "localhost" -a "$HOSTNAME" != "localhost.localdomain" ] && \
						H="-F $HOSTNAME"
					;;
					*)
						H="-H $DHCP_HOSTNAME"
					;;
				esac
			fi
			T=${DHCP_TIMEOUT:+-T $DHCP_TIMEOUT}
			echo "$H -q $T -pf /var/run/dhclient-$NAME.pid $NAME"
			;;
		*)
			print_error "Can't pick command line for DHCP client '$DHCP_CLIENT'"
			;;
	esac
}

# This function uses check_eth_link(), but DHCP used to work for Ethernet
# mostly (if not only), so functions-eth should be already sourced in such
# case. This may break one day.

try_dhcp()
{
	[ -x "$DHCP_CLIENT" ] || {
		print_error "$DHCP_CLIENT does not exist or is not executable. Try installing dhcpcd/dhclient RPM."
		return 1
	}
	if need_detection; then
		if check_eth_link $NAME; then
			print_progress
		else
			print_nack
			return 1
		fi
	fi
	DHCP_CMDLINE=`dhcp_cmdline`
	$DHCP_CLIENT $DHCP_ARGS $DHCP_CMDLINE >/dev/null
	local RET=$?
	# dhcpcd sets iface down on failure, breaking dhcp-* BOOTPROTOs
	if [ "$RET" != "0" ]; then
		print_nack
		! is_yes $KEEP_DOWN && $IP link set dev $NAME up
	else
		print_progress
	fi
	return $RET
}

try_ipv4ll()
{
	[ -x "$ZCIP_CLIENT" ] || {
		print_error "$ZCIP_CLIENT does not exist or is not executable. Try installing avahi-autoipd RPM."
		return 1
	}
	if need_detection; then
		if check_eth_link $NAME; then
			print_progress
		else
			print_nack
			return 1
		fi
	fi
	$ZCIP_CLIENT --daemonize --wait $NAME
	local RET=$?
	if [ "$RET" != "0" ]; then
		print_nack
	else
		print_progress
	fi
	return $RET
}

process_ipv4rules()
{
	local OP=${1:?missing 1st arg to $FUNCNAME}
	local REVERSE
	[ "$OP" = "del" ] && REVERSE="|tac"
	SRCFILE=`profiled_filename $MYIFACEDIR/ipv4rule`
	[ -s "$SRCFILE" ] && eval "$DENOISE \"$SRCFILE\" $REVERSE" | \
	while read FIRST REST; do
		case "$FIRST" in
			add)
				[ $OP = "del" ] && FIRST=del
			;;
			del)
				# should we restore deleted rules on iface shutdown?
				 [ $OP = "del" ] && FIRST=add
			;;
			*)
				FIRST="$OP $FIRST"
			;;
		esac
		$IP -4 rule $(eval_string $FIRST $REST)
		print_progress
	done
}

config_ipv4_routes_rules()
{
	# setup routes
	local OP=${1:?missing 1st arg to $FUNCNAME}
	local SRCFILE=`profiled_filename $MYIFACEDIR/ipv4route`
	local SUFFIX
	IPV4ADDRESS=($(get_ipv4_addresses $NAME))
	[ "$OP" = "del" ] && REVERSE="|tac"
	[ -s "$SRCFILE" ] && eval "$DENOISE \"$SRCFILE\" $REVERSE" | \
	while read FIRST REST; do
		# If 'dev' is not specified, add current dev.
		SUFFIX=''
		echo "$FIRST $REST" | egrep -q '[[:space:]]dev[[:space:]]' || SUFFIX="dev $NAME"
		# If operation is not specified, use 'append'.
		case "$FIRST" in
			add|change|append|replace)
				[ $OP = "del" ] && FIRST=del
			;;
			del)
				# should we restore deleted rules on iface shutdown?
				[ $OP = "del" ] && FIRST=add
			;;
			*)
				[ "$OP" = "add" ] && FIRST="append $FIRST" || FIRST="$OP $FIRST"
			;;
		esac
		$IP -4 route $(eval_string $FIRST $REST $SUFFIX)
		print_progress
	done

	# Setup rules only after routes are Ok, so that route tables are
	# already populated when rule starts routing traffic to them.
	process_ipv4rules $OP
}

get_ipv4_addresses()
{
    local NAME=${1:?missing 1st argument to $FUNCNAME}
    # FIXME should we parse it by more complex regexp?
    printf "$($IP -4 addr show dev $NAME 2>/dev/null|grep -ose "\binet[[:space:]]\+[0-9.]\+"|cut -f2 -d" ")"
}

