#!/bin/sh

# Author : Benoit PAPILLAULT <benoit.papillault@free.fr>
# Creation : 26/05/2003

# Create a bootable CD-ROM from several files:
# - work/initrd.fs : the initial ramdisk (uncompressed form)
# - work/initrd.gz : the initial ramdisk (compressed form)
# - work/iso_root  : pre-image of the CDROM's root content
# 
# Five steps:
# - copy bootloader files
# - copy bootloader configuration files
# - copy kernel to boot/linux
# - copy ramdisk to boot/initrd.gz
# - create an ISO

# read common configuration file
# you should set one of USE_SYSLINUX or USE_GRUB to "yes"

. config-auto

if [ "${ISOROOT_FS}" = "none" ]; then
  TARGET=work/iso-root
else
  TARGET=work/iso
fi

# usefull functions

# usage: cp_template src/iso_root/isolinux.cfg
# it copies the file (like cp), and replace some patterns (like configure)
#
# @RAMDISK_SIZE@ : uncompressed initrd size in KB (initrd.fs)
# @KERNEL_VERSION@ : kernel version
# @DATE@ : the current date, like 2005-03-17
# @ISO@ : iso filename

cp_template() {

  local src="$1" &&
  local dst="$2" &&
  local RAMDISK_SIZE=`ls -lk work/initrd.fs | awk '{print $5}'` &&
  local DATE=`date +%Y-%m-%d` &&

# if the destination is a directory, add the filename
  if [ -d "${dst}" ]; then
    local base=`basename "${src}"` &&
    dst="${dst}/${base}"
  fi &&

  sed -e "s/@RAMDISK_SIZE@/${RAMDISK_SIZE}/g" \
    -e "s/@KERNEL_VERSION@/${KERNEL_VERSION}/g" \
    -e "s/@ISO@/${ISO}/g" \
    -e "s/@DATE@/${DATE}/g" "${src}" > "${dst}"

}

# checking image directory
if [ ! -d "${IMAGE}" ]; then
    echo "${IMAGE} is missing"
    exit 1
fi

if [ ! -f "${IMAGE}/etc/sorcery/local/depends/glibc" ]; then
  echo "missing /etc/sorcery/local/depends/glibc"
  exit 1
fi

if grep -q 'NPTL=yes' "${IMAGE}/etc/sorcery/local/depends/glibc" ||
    grep -q 'GLIBC_NPTL="y"' "${IMAGE}/etc/sorcery/local/depends/glibc.p"; then
  NPTL=nptl
else
  NPTL=non-nptl
fi

# checking initrd
if [ ! -f work/initrd.gz ]; then
	echo "work/initrd.gz is missing"
	exit 1
fi

# checkinit iso-root.fs
if [ "${ISOROOT_FS}" != "none" ] && [ ! -f work/iso-root.fs ]; then
  echo "work/iso-root.fs is missing"
  exit 1
fi

# umount directories under $TARGET
if [ -d "${TARGET}" ]; then
  DIR=`cd "${TARGET}" && pwd`
  cat /proc/mounts | awk '{print $2}' | grep "^${DIR}" | sort -r |
  while read dir;
  do
    echo "umounting ${dir}..."
    umount "${dir}" || exit 1
  done || exit 1
fi

# erase existing directory if any (and if using iso-root.fs)

if [ "${ISOROOT_FS}" != "none" ]; then
  echo "deleting existing ${TARGET}"
  rm -rf "${TARGET}" || exit 1
fi &&

# create a new directory
mkdir -p "${TARGET}" &&

# copy bootloader files
case "${ARCH}" in
  i486|x86_64)
  # install isolinux

	if [ "${USE_SYSLINUX}" = "yes" ]; then
      FILE="syslinux-${SYSLINUX_VERSION}.tar.bz2"
  	  URL1="http://www.kernel.org/pub/linux/utils/boot/syslinux/${FILE}"
      URL2="http://www.kernel.org/pub/linux/utils/boot/syslinux/Old/${FILE}"

      if [ ! -f "${FILE}" ]; then
		wget -c "${URL1}" || wget -c "${URL2}"
	  fi

	  echo "unpacking ${FILE}"
	  if ! tar jxf "${FILE}"; then
		echo "file ${FILE} is corrupted or does not exist"
		echo "try to remove it and try again";
		rm -rf "syslinux-${SYSLINUX_VERSION}"
		exit 1;
	  fi

  	  mkdir -p "${TARGET}/isolinux" &&
	  cp "syslinux-${SYSLINUX_VERSION}/isolinux.bin" "${TARGET}/isolinux" &&
#	  cp "syslinux-${SYSLINUX_VERSION}/com32/modules/menu.c32" \
#		 "syslinux-${SYSLINUX_VERSION}/com32/modules/chain.c32" \
#        "${TARGET}/isolinux" &&
	  rm -rf "syslinux-${SYSLINUX_VERSION}" || exit 1
    fi

    if [ "${USE_GRUB}" = "yes" ]; then
      mkdir -p "${TARGET}/boot/grub" &&
	  cp "${IMAGE}/usr/share/grub/i386-pc/stage2_eltorito" \
	    "${TARGET}/boot/grub" || exit 1
    fi

    ;;

  ppc)
  # install yaboot (the directory containing yaboot should be marked
  # as blessed. it should be a top level directory only).
    mkdir -p "${TARGET}/yaboot" &&
    cp "${IMAGE}/usr/lib/yaboot/yaboot" "${TARGET}/yaboot/yaboot" || exit 1
    ;;

  sparc | sparc64)
  # install silo (if needed)
    if [ "${TARGET}" != "${IMAGE}" ]; then
      mkdir -p "${TARGET}/boot" &&
      cp "${IMAGE}/boot/second.b" "${TARGET}/boot"
    fi
    ;;
esac &&

# copy bootloader configuration files

# The name of the .iso file has changed, see:
# http://wiki.sourcemage.org/index.php?page=ISO+numbering+scheme

# get the version of the installed kernel
if [ ! -f "${SPELL_STATUS}" ]; then
  echo "${SPELL_STATUS} missing"
  exit 1
fi &&

KERNEL_VERSION=`grep "^linux:" "${SPELL_STATUS}"|cut -d: -f4` &&
if [ -z "${KERNEL_VERSION}" ]; then
  echo "linux is missing on image"
  exit 1
fi &&

echo "using ${KERNEL_VERSION} linux kernel" &&

ISO_BASE="smgl-${ISO_VERSION_MAJOR}-${ARCH}-${KERNEL_VERSION}-${NPTL}-${ISO_VERSION_MINOR}" &&

ISO="${ISO_BASE}.iso" &&
WIKI="iso/${ISO_BASE}.wiki" &&

case "${ARCH}" in
  i486|x86_64)
    if [ "${USE_SYSLINUX}" = "yes" ]; then
      mkdir -p "${TARGET}/isolinux" &&
      cp_template src/iso_root/isolinux.cfg "${TARGET}/isolinux" &&
	  cp src/iso_root/boot.lss "${TARGET}/isolinux" &&
	  cp_template src/iso_root/isolinux.msg "${TARGET}/isolinux" || exit 1
    fi

    if [ "${USE_GRUB}" = "yes" ]; then
      cp_template src/iso_root/menu.lst "${TARGET}/boot/grub" &&
	  cp "${IMAGE}/boot/grub/images/smgl-splash.xpm.gz" \
        "${TARGET}/boot/grub" || exit 1
    fi

	;;
  ppc)
    mkdir -p "${TARGET}/yaboot" &&
    cp src/iso_root/ofboot.b "${TARGET}/yaboot" &&
    cp_template src/iso_root/yaboot.conf "${TARGET}/yaboot" &&
    cp_template src/iso_root/yaboot.msg "${TARGET}/yaboot" || exit 1
    ;;

  sparc | sparc64)
    # copy /etc/silo.conf
    cp_template src/iso_root/silo.conf "${TARGET}/boot" &&
    cp_template src/iso_root/silo.msg "${TARGET}/boot"
    ;;

  *)
    echo "${ARCH} architecture is not supported"
    exit 1
    ;;
esac &&

# copy kernel to boot/linux

KERNEL_IMAGE="/boot/vmlinux-${KERNEL_VERSION}" &&
case "${ARCH}" in
  i486 | x86_64)
    KERNEL_IMAGE="/boot/vmlinubz-${KERNEL_VERSION}"
    ;;
  sparc | sparc64)
    KERNEL_IMAGE="/boot/vmlinuz-${KERNEL_VERSION}"
    ;;
esac &&
if [ ! -f "${IMAGE}/${KERNEL_IMAGE}" ]; then
	echo "kernel image ${KERNEL_IMAGE} is missing"
	exit 1
fi &&

echo "copying ${KERNEL_VERSION} linux kernel : ${KERNEL_IMAGE}" &&

mkdir -p "${TARGET}/boot" &&
cp "${IMAGE}/${KERNEL_IMAGE}" "${TARGET}/boot/linux" &&
cp "${IMAGE}/etc/sorcery/local/kernel.config" \
    "${TARGET}/boot/config-${KERNEL_VERSION}" || exit 1

# remove useless copies of linux kernel
#rm -f work/iso_root/boot/vmlinubz* &&
#rm -f work/iso_root/boot/vmlinux* &&

# copy ramdisk to boot/initrd.gz

mkdir -p "${TARGET}/boot" &&
cp work/initrd.gz "${TARGET}/boot" || exit 1

# copy iso-root.fs to / if needed

if [ "${ISOROOT_FS}" != "none" ]; then
  cp work/iso-root.fs "${TARGET}" || exit 1
fi &&

# isolinux will try to boot /boot/linux. We cannot tell isolinux to
# boot /boot/bzImage-2.4.21 since isolinux only support 8.3 filename
# format and no symlinks. Thus, we create a symlink
# "/boot/bzImage-2.4.21 -> /boot/linux" to have the filenames we are
# used to. This is now done in mk-iso-root shell script.

# removing the rr_moved directory
rm -rf "${TARGET}/rr_moved" &&

VOLUME_ID="SourceMage ${ISO_VERSION_MAJOR}-${ISO_VERSION_MINOR} ${ARCH} CD"

# here is missing an explanation about all mkisofs options used here!
# -b boot/isolinux/isolinux.bin : specify the boot image
# -c boot/isolinux/boot.cat     : specify the boot catalog (it is created)
# -no-emul-boot                 : specify the "no-emulation" boot mode
# -R                            : generate SUSP/RR records for file permissions
# -hfs                          : generate a iso9660/hfs hybrid CD (for apple)
# -part                         : generate a hfs partition table
# -hfs-bless ./yaboot           : 'yaboot' directory is "blessed"

mkdir -p iso &&

case "${ARCH}" in
  i486|x86_64)
    if [ "${USE_SYSLINUX}" = "yes" ]; then
      (cd "${TARGET}" && mkisofs \
		  -b isolinux/isolinux.bin -c isolinux/boot.cat \
		  -no-emul-boot -boot-load-size 4 -boot-info-table \
		  -R -o "../../iso/${ISO}" .) 2>&1 | tee iso.log
	fi &&

	if [ "${USE_GRUB}" = "yes" ]; then
      (cd "${TARGET}" && mkisofs \
		  -b boot/grub/stage2_eltorito -c boot/grub/boot.cat \
		  -no-emul-boot -boot-load-size 4 -boot-info-table \
		  -R -o "../../iso/${ISO}" .) 2>&1 | tee iso.log
    fi || exit 1
	;;

  ppc)
    mkdir -p work/iso_root/yaboot &&
	(cd "${TARGET}" && mkisofs \
		-hfs -part -map ../../src/iso_root/map.hfs -hfs-bless ./yaboot \
		-hfs-volid "${VOLUME_ID}" -V "${VOLUME_ID}" -no-desktop \
		-R -o "../../iso/${ISO}" .) 2>&1 | tee iso.log || exit 1
	;;

  sparc | sparc64)
    mkisofs -G "${IMAGE}/boot/isofs.b" -B ... --sparc-label "${VOLUME_ID}" -R -o "iso/${ISO}" "${TARGET}"
    ;;

  *)
    echo "${ARCH} is not supported yet, making a generic ISO" &&
    mkisofs -R -o "iso/${ISO}" "${TARGET}"
    ;;
esac &&

# compute the md5
(cd iso ; md5sum "${ISO}" | tee "${ISO}.md5") &&
MD5=`awk '{print $1}' "iso/${ISO}.md5"` &&
SIZE=`du -h "iso/${ISO}" | awk '{print $1}'`&&

# fill in the wiki template
(
cat <<EOF &&
== Direct download link ==
* {{${MD5}}}  [http://download.sourcemage.org/iso/testing/${ISO} ${ISO}], ${SIZE}
== What's new in this release? ==
To be completed
== Software available on the ISO ==
EOF

awk -F: '{print "|| "$1" || "$4" ||"}' "${SPELL_STATUS}" &&

cat <<EOF &&
== Software available on the installed system ==
Some of them are optionals.
EOF

ls work/iso-root/install/ | awk -F_ '{print "|| "$1" || "$2" ||"}' &&

cat <<EOF
== Corrected bugs ==
To be completed
== Know bugs ==
To be completed
== Feedback is welcome ==
To help ensure that better ISO are produced, please report your installation success or failure to [mailto:sm-discuss@lists.ibiblio.org sm-discuss] and please post relevant bugs to [http://bugs.sourcemage.org bugzilla].

`date --utc +%Y-%m-%d` Benoit PAPILLAULT [mailto:benoit.papillault@sourcemage.org benoit.papillault@sourcemage.org]
EOF
) > "${WIKI}" &&
file "iso/${ISO}" &&
ls -lah "iso/${ISO}"

# if a burn proff CD burner is blocked burning :
# cdrecord -msinfo will force the CD to be ejected!!!

# to burn without using ide-scsi (it seems to be deprecated):
# cdrecord -dev=/dev/hdc blank=fast
# cdrecord -dev=/dev/hdc -driveropts=burnfree -dao -data my.iso

# the default device can be set in /etc/default/cdrecord
# CDR_DEVICE=/dev/hdc
