# kboot-mkconfig helper script.
# Copyright (C) 2011  Antonio Ospite <ospite@studenti.unina.it>
#
# Inspired by the 10_linux script from kboot
#
# This program 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.
#
# This progra, 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 this software.  If not, see <http://www.gnu.org/licenses/>.

prefix=/usr
exec_prefix=${prefix}
bindir=${exec_prefix}/bin
libdir=${exec_prefix}/lib

LINUX_ROOT_DEVICE="$(readlink -f $(mount | grep ' / ' | cut -d ' ' -f 1))"

if $(which gettext >/dev/null 2>/dev/null) ; then
  gettext="gettext"
else
  gettext="echo"
fi

# One layer of quotation is eaten by "", the second by sed, and the third by
# printf; so this turns ' into \'.  Note that you must use the output of
# this function in a printf format string.
gettext_quoted () {
  $gettext "$@" | sed "s/'/'\\\\\\\\''/g"
}

# Run the first argument through gettext_quoted, and then pass that and all
# remaining arguments to printf.  This is a useful abbreviation and tends to
# be easier to type.
gettext_printf () {
  local format="$1"
  shift
  printf "$(gettext_quoted "$format")" "$@"
}

kboot_file_is_not_garbage ()
{
  if test -f "$1" ; then
    case "$1" in
      *.dpkg-*) return 1 ;; # debian dpkg
      README*)  return 1 ;; # documentation
    esac
  else
    return 1
  fi
  return 0
}

version_test_gt ()
{
  local sedexp="s/[^-]*-//;s/[._-]\(pre\|rc\|test\|git\|old\|trunk\)/~\1/g"
  local a=`echo $1 | sed -e "$sedexp"`
  local b=`echo $2 | sed -e "$sedexp"`
  local cmp=gt
  if [ "x$b" = "x" ] ; then
    return 0
  fi
  case $a:$b in
    *.old:*.old) ;;
    *.old:*) a=`echo -n $a | sed -e s/\.old$//` ; cmp=gt ;;
    *:*.old) b=`echo -n $b | sed -e s/\.old$//` ; cmp=ge ;;
  esac
  dpkg --compare-versions "$a" $cmp "$b"
  return $?
}

version_find_latest ()
{
  local a=""
  for i in $@ ; do
    if version_test_gt "$i" "$a" ; then
      a="$i"
    fi
  done
  echo "$a"
}

linux_entry ()
{
  os="$1"
  version="$2"
  recovery="$3"
  args="$4"
  if ${recovery} ; then
    title="$(gettext_quoted "%s, with Linux %s (recovery mode)")"
  else
    title="$(gettext_quoted "%s, with Linux %s")"
  fi
  label="$(printf "${title}" "${os}" "${version}")"
  echo -n "'${label}'='${dirname}/${basename} "
  if test -n "${initrd}" ; then
	echo -n "initrd=${dirname}/${initrd}"
  fi
  echo " root=${linux_root_device_thisversion} ro ${args}'"
}

list_kernels ()
{
  list=`for i in /boot/vmlinuz-* /boot/vmlinux-* /vmlinuz-* /vmlinux-* ; do
          if kboot_file_is_not_garbage "$i" ; then echo -n "$i " ; fi
        done`
  prepare_boot_cache=

  while [ "x$list" != "x" ] ; do
    linux=`version_find_latest $list`
    echo "Found linux image: $linux" >&2
    basename=`basename $linux`
    dirname=`dirname $linux`
    
    # XXX: this relies on a binary shipped by GRUB, we just use ${dirname} for 
    # now, check the ${dirname} entries if we need something like that later
    #rel_dirname=`make_system_path_relative_to_its_root $dirname`
    
    version=`echo $basename | sed -e "s,^[^0-9]*-,,g"`
    alt_version=`echo $version | sed -e "s,\.old$,,g"`
    linux_root_device_thisversion="${LINUX_ROOT_DEVICE}"

    initrd=
    for i in "initrd.img-${version}" "initrd-${version}.img" \
             "initrd-${version}" "initramfs-${version}.img" \
             "initrd.img-${alt_version}" "initrd-${alt_version}.img" \
             "initrd-${alt_version}" "initramfs-${alt_version}.img"; do
      if test -e "${dirname}/${i}" ; then
        initrd="$i"
        break
      fi
    done

    initramfs=
    for i in "config-${version}" "config-${alt_version}"; do
      if test -e "${dirname}/${i}" ; then
        initramfs=`grep CONFIG_INITRAMFS_SOURCE= "${dirname}/${i}" | cut -f2 -d= | tr -d \"`
        break
      fi
    done

    if test -n "${initrd}" ; then
      echo "Found initrd image: ${dirname}/${initrd}" >&2
    elif test -z "${initramfs}" ; then
      # "UUID=" magic is parsed by initrd or initramfs.  Since there's
      # no initrd or builtin initramfs, it can't work here.
      linux_root_device_thisversion=${KBOOT_DEVICE}
    fi

    linux_entry "${OS}" "${version}" false \
        "${KBOOT_CMDLINE_LINUX} ${KBOOT_CMDLINE_LINUX_DEFAULT}"
    if [ "x${KBOOT_DISABLE_RECOVERY}" != "xtrue" ]; then
      linux_entry "${OS}" "${version}" true \
          "single ${KBOOT_CMDLINE_LINUX}"
    fi

    list=`echo $list | tr ' ' '\n' | grep -vx $linux | tr '\n' ' '`
  done
}