#!/bin/sh
#
# Petitboot udhcpc user script.  Should be run by udhcpc when
# there is a change in the dhcp configuration.  For more info
# see the udhcpc man page and the Linux kernel source file
# Documentation/filesystems/nfsroot.txt.
#

PBOOT_USER_EVENT_SOCKET="/tmp/petitboot.ev"
log="/var/log/petitboot/pb-udhcpc.log"

resolve_url() {
	file="$1"

	# URL? use as-is.
	tmp=${file#://*}
	if [ "$tmp" != "$file" ]
	then
		echo "$file"
	fi

	# Otherwise, TFTP using an appropriate host. Start with the
	# DHCP 'tftp' option:
	host=${tftp}

	# next, try the DHCP next-server-address
	[ -z "$host" ] && host=${siaddr}

	# finally, use the DHCP server we got this lease from:
	[ -z "$host" ] && host=${serverid}

	echo "tftp://$host/$file"
}

do_pxe() {
	basedir=$1

	params="conf@/net/${interface} method=dhcp"

	# first, try by MAC
	mac=$(cat /sys/class/net/$interface/address)
	pb-event $params url=$basedir/$mac

	# try decreasing fragments of IP lease
	ip_hex=$(printf '%02X%02X%02X%02X' $(echo $ip | tr '.' ' '))
	for i in $(seq 8 -1 1)
	do
		frag=${hex_ip:0:$i}
		pb-event $params url=$basedir/$frag
	done

	# last, use default
	pb-event $params url=$basedir/default
}

pb_add () {

	# Look for an explicit config file location in the DHCP config-file
	# parameter
	if [ -n ${conffile} ]
	then
		url=$(resolve_url ${conffile})
		pb-event conf@/net/${interface} url=$url method=dhcp
		return
	fi

	# Otherwise, we'll need the boot-file parameter. Looks like udhcpc
	# will give us different names, depending if the parameter was in
	# the header, or specified by options
	[ -n "$bootfile" ] && bootfile=${boot_file}

	if [ -z "$bootfile" ]
	then
		return
	fi

	# PXE behaviour is to download the config file based on a file
	# structure relative to the pxelinux binary
	file=${bootfile}
	[ -z "$file" ] && file=${boot_file}
	if [ -n "$file" ]
	then
		basedir=${file%%/*}
		do_pxe $basedir
	fi

	# Finally, add an option for the boot_file parameter
	k_server_ip=${rootpath%%:*}
	k_root_dir=${rootpath#*:}

	args=
	if [ -n $rootpath ]
	then
		[ ${k_server_ip} != ${rootpath} ] || k_server_ip=${serverid}
		args="root=/dev/nfs ip=any nfsroot=${k_server_ip}:${k_root_dir}"
	fi

	pb-event add@/net/${interface} \
		name=netboot \
		image=tftp://${siaddr}/${boot_file} \
		args="$args"
}

pb_remove () {
	pb-event remove@/net/${interface} name=netboot
}

case "$1" in
bound | renew)
	pb_add
	;;
deconfig)
	pb_remove
	;;
*)
	;;
esac

printf "--- $1 ---\n" >> ${log}
set >> ${log}
printf "---------------\n" >> ${log}
