# Copyright (c) 2004-2005 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
# $Header: /var/cvsroot/gentoo-src/rc-scripts/net-scripts/net.modules.d/udhcpc,v 1.20.2.5 2005/03/21 16:06:04 uberlord Exp $

# Contributed by Roy Marples (uberlord@gentoo.org)

# Fix any potential localisation problems
# Note that LC_ALL trumps LC_anything_else according to locale(7)
udhcpc() {
	LC_ALL=C /sbin/udhcpc "$@"
}

# char* udhcpc_provides(void)
#
# Returns a string to change module definition for starting up
udhcpc_provides() {
	echo "dhcp"
}

# void udhcpc_depend(void)
#
# Sets up the dependancies for the module
udhcpc_depend() {
	after interface
}

# bool udhcpc_check_installed(void)
#
# Returns 1 if udhcpc is installed, otherwise 0
udhcpc_check_installed() {
	[[ -x /sbin/udhcpc ]] && return 0
	${1:-false} && eerror "For DHCP (udhcpc) support, emerge net-misc/udhcp"
	return 1
}

# char* udhcpc_get_script(void)
#
# Returns the filename of the script to run
udhcpc_get_script() {
	local module=$( interface_module )
	echo "${MODULES_DIR}/helpers.d/udhcpc-${module}"
}

# bool udhcpc_check_depends(void)
#
# Checks to see if we have the needed functions
udhcpc_check_depends() {
	local f

	for f in interface_variable interface_device interface_is_up interface_get_address interface_module; do
		[[ $( type -t ${f} ) == "function" ]] && continue
		eerror "udhcpc: missing required function ${f}\n"
		return 1
	done

	return 0
}

# char* udhcpc_get_vars(char *interface)
#
# Returns a string spaced with possible user set
# configuration variables
udhcpc_get_vars() {
	echo "udhcpc_$1 dhcp_$1 dns_$1"
}

# bool udhcpc_stop(char *iface)
#
# Stops udhcpc running on an interface
# Always returns 0
udhcpc_stop() {
	local iface=$1 count release pidfile="/var/run/udhcpc-${1}.pid" dhcp
	
	udhcpc_check_installed || return 0
	[[ ! -f ${pidfile} ]] && return 0

	ebegin "Stopping udhcpc on ${iface}"
	local pid=$( < ${pidfile} ) e=true

	# Release the lease if told to
	eval dhcp=\" \$\{dhcp_${ifvar}\} \"
	if [[ ${dhcp} == *' release '* ]]; then
		kill -s USR2 ${pid} &>/dev/null
		rm /var/cache/udhcpc-${iface}.cache
	fi

	kill -s TERM ${pid} &>/dev/null

	# udhcp-0.9.8-r3 and earlier do not process signals correctly
	# so we need to kill them off
	if ps -p ${pid} &>/dev/null ; then
		kill -s KILL ${pid} &>/dev/null
		ps -p ${pid} &>/dev/null && e=false
	fi

	${e}
	eend $?

	return 0
}

# bool udhcpc_start(char *iface)
#
# Start DHCP on an interface by calling udhcpc $iface $options
#
# Returns 0 (true) when a DHCP address is obtained, otherwise 1
udhcpc_start() {
	local iface=$1 opts hostname pidfile="/var/run/udhcpc-${1}.pid"
	local cachefile="/var/cache/udhcpc-${1}.cache" x dhcp

	interface_exists ${iface} true || return 1

	local ifvar=$( interface_variable ${iface} )
	local script=$( udhcpc_get_script ) opts hostname
	eval opts=\" \$\{udhcpc_${ifvar}\} \"
	eval dhcp=\" \$\{dhcp_${ifvar}\} \"

	if [[ ${dhcp} != *' nosendhost '* ]]; then
	    if [[ ! " ${opts}" =~ " -([hH] |-hostname=)" ]]; then
	    	hostname=$( hostname )
		[[ -n ${hostname} && ${hostname} != "(none)" \
		&& ${hostname} != "localhost" ]] \
		&& hostname="--hostname=${hostname}"
	    fi
	fi

	# Bring up DHCP for this interface (or alias)
	ebegin "Running udhcpc"

	if ! clean_pidfile ${pidfile} ; then
		ewarn "udhcpc is already running on ${iface}"
		eend 0
		return 0
	fi

	# Try and load the cache if it exists
	if [[ -f ${cachefile} && ${opts} != *'--request='* && ${opts} != *'-r '* ]]; then
		x=$( < ${cachefile} )
		[[ -n ${x} ]] && opts="${opts} --request=${x}"
	fi

	x=$( eval "udhcpc ${hostname} ${opts} --script=${script} --now --pidfile=${pidfile} --interface=${iface} 2>&1 | egrep -v '^info,'" )
	# We just check the last 5 letters
	[[ ${x:((${#x} - 5)):5} == bound ]]
	eend $? "${x}" || return 1

	# DHCP succeeded, show address retrieved
	local addr=$( interface_get_address ${iface} )
	einfo "${iface} received address ${addr}"

	# Store the address in a cache for future usage
	echo ${addr} > ${cachefile}
	chmod 600 ${cachefile}

	return 0
}
