#!/bin/bash

if [ -z "${__net_cmdline_sh_functions-}" ]; then
__net_cmdline_sh_functions=1

. shell-error

__valid_hex()
{
	while [ "$#" -gt 0 ]; do
		[ "${#1}" -eq 2 ] && [ -z "${1#[0-9a-fA-F][0-9a-fA-F]}" ] ||
			return 1
		shift
	done
}

__cmdline_parse_macaddr()
{
	case "$#" in
		6|20)
			__valid_hex "$@" ||
				fatal "syntax error: value does not look like a MAC address"
			;;
		*)
			fatal "syntax error: MAC address must contain 6 or 20 components, but got $#"
			;;
	esac
	case "$#" in
		6)  macaddr="$1:$2:$3:$4:$5:$6" ;;
		20) macaddr="$1:$2:$3:$4:$5:$6:$7:$8:$9:${10}:${11}:${12}:${13}:${14}:${15}:${16}:${17}:${18}:${19}:${20}" ;;
	esac
}

ip_to_var()
{
	local i v="$1:"
	set --

	while [ -n "$v" ]; do
		if [ -z "${v##\[*:*:*\]:*}" ]; then
			# handle IPv6 address
			i="${v%%\]:*}"
			i="${i##\[}"

			set -- "$@" "$i"
			v=${v#\[$i\]:}
		else
			set -- "$@" "${v%%:*}"
			v=${v#*:}
		fi
	done

	ipaddr='' srv='' gw='' netmask='' hostname='' interface='' autoconf='' macaddr='' mtu='' dns1='' dns2=''

	if [ $# -eq 0 ] || [ -z "$1" ]; then
		autoconf="error"
		return 0
	fi

	# format: ip=<autoconf>

	if [ $# -eq 1 ]; then
		autoconf="$1"
		return 0
	fi

	# format: ip=<interface>:<autoconf>[:[<mtu>][:<macaddr>]]

	case "${2-}" in
		on|any|dhcp|auto|dhcp4|auto4|dhcp6|auto6)
			interface="$1"
			autoconf="$2"
			shift 2
			[ $# -eq 0 ] ||
				{ mtu="$1"; shift; }
			[ $# -eq 0 ] ||
				__cmdline_parse_macaddr "$@"
			[ -n "$interface" ] ||
				fatal "interface name must be non-empty"
			return 0
			;;
	esac

	# format: ip=<ipaddr>:[<peer>]:<gw>:<netmask>:<hostname>:<interface>:<autoconf>[:[<mtu>][:<macaddr>]]

	ipaddr="$1" srv="$2" gw="$3" netmask="$4" hostname="$5" interface="$6" autoconf="$7"
	shift 7

	[ -n "$interface" ] ||
		fatal "interface name must be non-empty"

	[ $# -gt 0 ] ||
		return 0

	if [ -z "$1" ] || [ -n "${1##*[!0-9]*}" ]; then
		mtu="$1"; shift
		[ $# -eq 0 ] ||
			__cmdline_parse_macaddr "$@"
		return 0
	fi

	# format: ip=<ipaddr>:[<peer>]:<gw>:<netmask>:<hostname>:<interface>:<autoconf>[:[<dns1>][:<dns2>]]

	dns1="$1"; shift
	[ $# -eq 0 ] || dns2="$1"
}

route_to_var()
{
	local i v="$1:"
	set --
	while [ -n "$v" ]; do
		if [ "${v#\[*:*:*\]:}" != "$v" ]; then
			# handle IPv6 address
			i="${v%%\]:*}"
			i="${i##\[}"
			set -- "$@" "$i"
			v=${v#\[$i\]:}
		else
			set -- "$@" "${v%%:*}"
			v=${v#*:}
		fi
	done

	# format: route=<net>/<netmask>:<gateway>:<interface>

	route_mask='' route_gw='' interface=''

	case "$#" in
		3)
			route_mask="$1"
			route_gw="$2"
			interface="$3"
			;;
		*)
			fatal "syntax error: route must contain 3 components"
			;;
	esac
}

ifname_to_var()
{
	local IFS=:

	# format: ifname=<interface>:<macaddr>
	set :$1

	interface='' macaddr=''

	[ "$#" -gt 1 ] ||
		fatal "syntax error: ifname must contain 7 or 21 components"

	interface="${1#:}"; shift
	__cmdline_parse_macaddr "$@"
}

fi #__net_cmdline_sh_functions
