# Sample GRUB script to autodetect operating systems
#
# Copyright (C) 2010  Free Software Foundation, Inc.
#
# GRUB is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# GRUB is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with GRUB.  If not, see <http://www.gnu.org/licenses/>.

function pathname { regexp -s 2:"$2" '^(\(.*\))?(/.*)$' "$1"; }
function devname  { regexp -s "$2" '^(\(.*\)).*$' "$1"; }

function loopback_iso_entry {
    realdev="$1"
    isopath="$2"
    loopdev="$3"

    if test -f /boot/grub/loopback.cfg; then
	cfgpath=/boot/grub/loopback.cfg
    elif test -f /grub/loopback.cfg; then
	cfgpath=/grub/loopback.cfg
    else
	return 1;
    fi

    echo loopback.cfg $isopath: yes
    menuentry "Boot GRUB Loopback Config from ${realdev}${isopath}" "$realdev" "$isopath" "$cfgpath" {
	set device="$2"
	set iso_path="$3"
	set cfg_path="$4"

	export iso_path
	loopback loopdev_cfg "${device}${iso_path}"
	set root=(loopdev_cfg)
	configfile $cfg_path
	loopback -d loopdev_cfg
    }
    return 0
}

function grml_iso_entry {
    realdev="$1"
    isopath="$2"
    loopdev="$3"

    result=1
    for dir in /boot/grml /boot/grmlsmall /boot/grmlmedium; do
	if ! test -f ${dir}/linux26 -a -f ${dir}/initrd.gz; then continue; fi

	echo grml $isopath: yes
	result=0
	menuentry "GRML Linux from ${realdev}${isopath}" \
	    "$realdev" "$isopath" "$dir" {
	    set device="$2"
	    set isopath="$3"
	    set grmldir="$4"

	    loopback loopdev_grml "${device}${isopath}"
	    set root=(loopdev_grml)
	    linux $grmldir/linux26 findiso="$isopath" apm=power-off quiet \
		boot=live nomce
	    initrd $grmldir/initrd.gz
	    loopback -d loopdev_grml
	}
    done
    return $result
}

function pmagic_iso_entry {
    realdev="$1"
    isopath="$2"
    loopdev="$3"

    if ! test -f /pmagic/bzImage -a -f /pmagic/initramfs; then return 1; fi

    echo pmagic $isopath: yes
    menuentry "Parted Magic from ${realdev}${isopath}" "$realdev" "$isopath" {
	set device="$2"
	set isopath="$3"

	loopback loopdev_pmagic "${device}${isopath}"
	set root=(loopdev_pmagic)
	linux /pmagic/bzImage iso_filename="$isopath" edd=off noapic \
	    load_ramdisk=1 prompt_ramdisk=0 rw sleep=10 loglevel=0 \
	    keymap=$langcode
	initrd /pmagic/initramfs
	loopback -d loopdev_pmagic
    }
    return 0
}

function sidux_iso_entry {
    realdev="$1"
    isopath="$2"
    loopdev="$3"

    result=1
    for kernel in /boot/vmlinuz-*-sidux-*; do
	if ! test -f "$kernel"; then continue; fi
	regexp -s 1:v1 -s 2:v2 '/boot/vmlinuz-(.*)-sidux-(.*)' "$kernel"

	initrd="/boot/initrd.img-$v1-sidux-$v2"
	if ! test -f "$initrd"; then continue; fi

	result=0
	echo sidux $isopath: yes
	menuentry "Sidux vmlinux-$v1-sidux-$v2 from ${realdev}${isopath}" "$realdev" "$isopath" "$kernel" "$initrd" {
	    set device="$2"
	    set isopath="$3"
	    set kernel="$4"
	    set initrd="$5"

	    loopback loopdev_sidux "${device}${isopath}"
	    set root=(loopdev_sidux)
	    linux $kernel fromiso=$isopath boot=fll quiet
	    initrd $initrd
	    loopback -d loopdev_sidux
	}
    done
    return $result
}

function slax_iso_entry {
    realdev="$1"
    isopath="$2"
    loopdev="$3"

    if ! test -f /boot/vmlinuz -a -f /boot/initrd.gz; then return 1; fi

    echo slax $isopath: yes
    menuentry "Slax Linux from ${realdev}${isopath}" "$realdev" "$isopath" {
	set device="$2"
	set isopath="$3"

	loopback loopdev_slax "${device}${isopath}"
	set root=(loopdev_slax)
	linux /boot/vmlinuz from=$isopath ramdisk_size=6666 root=/dev/ram0 rw
	initrd /boot/initrd.gz
	loopback -d loopdev_slax
    }
    return 0
}

function tinycore_iso_entry {
    realpath="$1"
    isopath="$2"
    loopdev="$3"

    if ! test -f /boot/bzImage -a -f /boot/tinycore.gz; then return 1; fi

    echo tinycore $isopath: yes
    menuentry "Tinycore Linux from ${realdev}${isopath}" "$realdev" "$isopath" {
	set device="$2"
	set isopath="$3"

	loopback loopdev_tiny "${device}${isopath}"
	set root=(loopdev_tiny)
	linux /boot/bzImage
	initrd /boot/tinycore.gz
	loopback -d loopdev_tiny
    }
    return 0
}

function casper_iso_entry {
    realpath="$1"
    isopath="$2"
    loopdev="$3"

    if ! test -f /casper/vmlinuz; then return 1; fi
    initrd=
    for f in /casper/initrd.*z; do
	if ! test -f "$f"; then continue; fi
	pathname "$f" initrd
    done
    if test -z "$initrd"; then return 1; fi

    echo casper $isopath: yes
    menuentry "Casper based Linux from ${realdev}${isopath}" "$realdev" "$isopath" "$initrd" {
	set device="$2"
	set isopath="$3"
	set initrd="$4"

	loopback loopdev_casper "${device}${isopath}"
	set root=(loopdev_casper)
	linux /casper/vmlinuz boot=casper iso-scan/filename="$isopath" quiet splash noprompt keyb="$langcode" \
	    debian-installer/language="$langcode" console-setup/layoutcode?="$langcode" --
	initrd $initrd
	loopback -d loopdev_casper
    }
    return 0
}

function scan_isos {
    isodirs="$1"

    for dev in (*); do
	for dir in $isodirs; do
	    for file in ${dev}${dir}/*.iso ${dev}${dir}/*.ISO; do
		if ! test -f "$file"; then continue; fi

		pathname $file isopath
		if test -z "$dev" -o -z "$isopath"; then continue; fi

		if ! loopback loopdev_scan "$file"; then continue; fi
		saved_root=$root
		set root=(loopdev_scan)

		if   loopback_iso_entry $dev $isopath (loopdev_scan); then true;
		elif grml_iso_entry     $dev $isopath (loopdev_scan); then true;
		elif pmagic_iso_entry   $dev $isopath (loopdev_scan); then true;
		elif sidux_iso_entry    $dev $isopath (loopdev_scan); then true;
		elif slax_iso_entry     $dev $isopath (loopdev_scan); then true;
		elif tinycore_iso_entry $dev $isopath (loopdev_scan); then true;
		elif casper_iso_entry   $dev $isopath (loopdev_scan); then true;
		else true; fi

		set root=$saved_root
		loopback -d loopdev_scan
	    done
	done
    done
    return 0
}

# XXX Remove later
insmod serial
serial
terminal_output --append serial
# terminal_input --append serial

langcode="$lang"

insmod regexp
scan_isos /iso /boot/iso

