# 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