#!/bin/bash

## Copyright (C) 2006-2012 Daniel Baumann <daniel.baumann@progress-technologies.net>
## Copyright (C) 2016-2017 Riku Voipio    <riku.voipio@linaro.org>
##
## This program comes with ABSOLUTELY NO WARRANTY; for details see COPYING.
## This is free software, and you are welcome to redistribute it
## under certain conditions; see COPYING for details.

set -e

_U_BOOT_DIRECTORY="/boot/extlinux"

Update ()
{
	 # Upate target file using source content
	_TARGET="${1}"
	_SOURCE="${2}"

	_TMPFILE="${_TARGET}.tmp"
	rm -f "${_TMPFILE}"

	echo "${_SOURCE}" > "${_TMPFILE}"

	if [ -e "${_TARGET}" ] && cmp -s "${_TARGET}" "${_TMPFILE}"
	then
		rm -f "${_TMPFILE}"
	else
		# FIXME: should use fsync here
		echo "P: Updating ${_TARGET}..."
		mv -f "${_TMPFILE}" "${_TARGET}"
	fi
}

# FIXME: switch to check extlinux file can be written to
# User is unprivileged
if [ "$(id -u)" -ne 0 ]
then
	echo "E: need root privileges"
	exit 1
fi

# Redirect stdout to stderr due Debconf usage
exec 1>&2

# Reading the default file
if [ -e /etc/default/u-boot ]
then
	. /etc/default/u-boot
fi

# Reading the os-release file
if [ -e /etc/os-release ]
then
	. /etc/os-release
elif [ -e /usr/lib/os-release ]
then
	. /usr/lib/os-release
fi


U_BOOT_UPDATE="${U_BOOT_UPDATE:-true}"

if [ "${U_BOOT_UPDATE}" != "true" ]
then
	echo "P: u-boot-update is disabled in /etc/default/u-boot."

	exit 0
fi

# Checking extlinux directory
echo -n "P: Checking for EXTLINUX directory..."

# Creating extlinux directory
if [ ! -e "${_U_BOOT_DIRECTORY}" ]
then
	echo " not found."

	echo -n "P: Creating EXTLINUX directory..."
	mkdir -p "${_U_BOOT_DIRECTORY}"
	echo " done: ${_U_BOOT_DIRECTORY}"
else
	echo " found."
fi

# Setting defaults if /etc/default/u-boot is missing

U_BOOT_ALTERNATIVES="${U_BOOT_ALTERNATIVES:-default recovery}"
U_BOOT_DEFAULT="${U_BOOT_DEFAULT:-l0}"
U_BOOT_ENTRIES="${U_BOOT_ENTRIES:-all}"
U_BOOT_TIMEOUT="${U_BOOT_TIMEOUT:-50}"
U_BOOT_MENU_LABEL="${U_BOOT_MENU_LABEL:-${PRETTY_NAME:-Debian GNU/Linux kernel}}"
U_BOOT_PARAMETERS="${U_BOOT_PARAMETERS:-ro earlycon}"
U_BOOT_FDT_DIR="${U_BOOT_FDT_DIR:-/lib/firmware/}"

# Find parameter for root from fstab
if [ -z "${U_BOOT_ROOT}" ]
then
	# Find root partition
	while read _LINE
	do

read _FS_SPEC _FS_FILE _FS_VFSTYPE _FS_MNTOPS _FS_FREQ _FS_PASSNO << EOF
${_LINE}
EOF

		if [ "${_FS_FILE}" = "/" ]
		then
			case "${_FS_SPEC}" in
				"#"*) ;;
				*) U_BOOT_ROOT="root=${_FS_SPEC}"
				   break ;;
			esac
		fi
	done < /etc/fstab
fi

# if not in fstab, try from current kernel arguments
if [ -z "${U_BOOT_ROOT}" ]
then
	for param in `cat /proc/cmdline`
	do
		if [[ $param == root=* ]]
		then
			U_BOOT_ROOT="$param"
			break
		fi
	done
fi


# Create extlinux.conf
_CONFIG="\
## ${_U_BOOT_DIRECTORY}/extlinux.conf
##
## IMPORTANT WARNING
##
## The configuration of this file is generated automatically.
## Do not edit this file manually, use: u-boot-update

default ${U_BOOT_DEFAULT}
menu title U-Boot menu
prompt 0
timeout ${U_BOOT_TIMEOUT}
"

# Find linux versions
_KERNELS=$(linux-version list --paths | linux-version sort --reverse | sed -e 's,.*/boot/,,g')

# Find boot directory as seen in u-boot, and path prefix while in linux
if [ "$(stat --printf %d /)" = "$(stat --printf %d /boot)" ]
then
	# / and /boot are on the same filesystem
	_BOOT_DIRECTORY="/boot"
	_BOOT_PATH=""
else
	# / and /boot are not on the same filesystem
	_BOOT_DIRECTORY=""
	_BOOT_PATH="/boot"
fi


for _KERNEL in ${_KERNELS}
do
	# Strip kernel prefix to derive version.
	_VERSION=${_KERNEL#*-}
	echo "P: Writing config for ${_KERNEL}..."

	_NUMBER="${_NUMBER:-0}"
	_ENTRY="${_ENTRY:-1}"

	if [ -e /boot/initrd.img-${_VERSION} ]
	then
		_INITRD="initrd ${_BOOT_DIRECTORY}/initrd.img-${_VERSION}"
	else
		_INITRD=""
	fi
	if [ -e ${_BOOT_PATH}${U_BOOT_FDT_DIR}${_VERSION}/${U_BOOT_FDT} ] && [ -n "${U_BOOT_FDT}" ]
	then
		_FDT="fdt ${U_BOOT_FDT_DIR}${_VERSION}/${U_BOOT_FDT}"
	elif [ -d ${_BOOT_PATH}${U_BOOT_FDT_DIR}${_VERSION}/device-tree ]
	then
		_FDT="fdtdir ${U_BOOT_FDT_DIR}${_VERSION}/device-tree/"
	elif [ -d ${_BOOT_PATH}${U_BOOT_FDT_DIR}${_VERSION}/ ]
	then
		_FDT="fdtdir ${U_BOOT_FDT_DIR}${_VERSION}/"
	elif [ -f "${_BOOT_PATH}/${U_BOOT_FDT:-dtb-${_VERSION}}" ] && [ /usr/lib/linux-image- = "${U_BOOT_FDT_DIR}" ]
	then
		_FDT="fdt /${U_BOOT_FDT:-dtb-${_VERSION}}"
	else
		_FDT=""
	fi

	if echo ${U_BOOT_ALTERNATIVES} | grep -q default
	then

	# Writing default entry
	_CONFIG="${_CONFIG}

label l${_NUMBER}
	menu label ${U_BOOT_MENU_LABEL} ${_VERSION}
	linux ${_BOOT_DIRECTORY}/${_KERNEL}
	${_INITRD}
	${_FDT}
	append ${U_BOOT_ROOT} ${U_BOOT_PARAMETERS}"

	fi

	if echo ${U_BOOT_ALTERNATIVES} | grep -q recovery
	then

	# Writing recovery entry
	_CONFIG="${_CONFIG}

label l${_NUMBER}r
	menu label ${U_BOOT_MENU_LABEL} ${_VERSION} (rescue target)
	linux ${_BOOT_DIRECTORY}/${_KERNEL}
	${_INITRD}
	${_FDT}
	append ${U_BOOT_ROOT} $(echo ${U_BOOT_PARAMETERS} | sed -e 's| quiet||') single
	"

	fi

	_NUMBER="$((${_NUMBER} + 1))"

	if [ "${U_BOOT_ENTRIES}" = "${_ENTRY}" ]
	then
		break
	fi
done

_NUMBER=""

Update "${_U_BOOT_DIRECTORY}/extlinux.conf" "${_CONFIG}"

