#!/bin/sh

cmdlinearg()
{
	grep -q $1= /proc/cmdline && sed "s/.*$1=\([^ ]*\).*/\1/" </proc/cmdline
}

get()
{
	grep -sq ^$1 $2 && sed "/^$1/!d;s/$1[ :=]*//" $2
}

list_entry()
{
	n=0
	while true ; do	
		n=$(($n+1))
		eval KEYWORD="\$KEYWORD_$n"
		eval ENTRY="\$ENTRY_$n"
		[ "$KEYWORD" ] || break
		echo -n "$KEYWORD \"$ENTRY\" "
	done
}

edit_menu()
{
while true; do

	eval KERNEL="\$KERNEL_$1"
	eval INITRD="\$INITRD_$1"
	eval CMDLINE="\$CMDLINE_$1"

	exec 3>&1
	value=$($DIALOG  --clear \
		--title "${edittitle:-Edit menu}" \
		--ok-label "Edit" \
		--cancel-label "Done" \
		--menu "" 20 72 14 \
		Kernel "$KERNEL" \
		Initramfs "$INITRD" \
		Cmdline "$CMDLINE" 2>&1 1>&3 )
	retval=$?
	exec 3>&-
	
	case $retval in
	1|255) return ;;
	esac

	exec 3>&1
	case $value in
	Kernel|Initramfs)
		data=$($DIALOG  --clear --title "Select $value" \
			 --fselect "$KEYWORD/" 10 72 2>&1 1>&3) ;;
	Cmdline)
		data=$($DIALOG  --clear --title "Edit $value" \
			 --inputbox "Cmdline" 20 72 2>&1 "$CMDLINE" 1>&3) ;;
	esac
	retval=$?
	exec 3>&-
	
	case $retval in
	1|255) continue ;;
	esac
	
	case $value in
	Kernel)		eval KERNEL_$1=\$data ;;
	Initramfs)	eval INITRD_$1=\$data ;;
	Cmdline)	eval CMDLINE_$1=\$data ;;
	esac
done
}

: ${DIALOG=dialog}

mount -t proc proc /proc
BOOTDEV=$(cmdlinearg bootdev)
mnt=/mnt
mount -t devtmpfs /dev /dev
[ -b /dev/mmcblk0p1 ] || mknod -m 660 /dev/mmcblk0p1 b 179 1
mount -r /dev/${BOOTDEV:-mmcblk0p1} $mnt
umount /dev

title=$(get title menu.txt)
subtitle="Select the OS to start"
grep -qs ^subtitle menu.txt && subtitle=$(get subtitle menu.txt)

editbutton='--extra-button --extra-label "Edit"'
grep -qs ^noedit menu.txt && editbutton=

edittitle=$(get edittitle menu.txt)

n=0
for i in $mnt/*/ ; do
	grep -qs ^kernel $i/config.txt || continue
	n=$(($n+1))
	eval KERNEL_$n="\$(get kernel \$i/config.txt)"
	eval INITRD_$n="\$(get initramfs \$i/config.txt)"
	eval CMDLINE_$n="\$(cat \$i/cmdline.txt)"
	eval KEYWORD_$n="\$(basename \$i)"
	eval ENTRY_$n="\$(get entry \$i/menu.txt)"
done

while true; do

	exec 3>&1
	value=$(sh 2>&1 1>&3 <<EOT
	$DIALOG  --clear \
		--title "${title:-Boot menu}" \
		$editbutton \
		--ok-label "Boot" \
		--cancel-label "Halt" \
		--menu "$subtitle" 20 72 14 \
		$(list_entry) \
		Default "Continue SliTaz boot sequence"
EOT
)
	retval=$?
	exec 3>&-
	
	n=0
	while true; do
		n=$(($n+1))
		eval KEYWORD="\$KEYWORD_$n"
		[ "$KEYWORD" ] || break
		[ "$KEYWORD" == "$value" ] && break
	done
	
	case $retval in
		0) break ;;
		1|255)
			umount /mnt
			umount /proc
			poweroff -f ;;
		3) edit_menu $n ;;
	esac
done

if [ "$value" == "Default" ]; then
	umount /mnt
	umount /proc
	exec /init
fi

eval KERNEL="\$KERNEL_$n"
eval INITRD="\$INITRD_$n"
cd $mnt/$value
cp $KERNEL $INITRD /root
[ "$INITRD" ] && INITRD="--initrd $(basename $INITRD)"
eval CMDLINE="\$CMDLINE_$n"
[ "$CMDLINE" ] && CMDLINE="--command-line \"$CMDLINE\""

cd /root
kexec -l $(basename $KERNEL) $INITRD $CMDLINE --atags
umount /mnt
umount /proc
kexec -e
