#!/bin/sh
#
# Copyright Rene Mayrhofer, 2005
# This script starts a complete system update by putting new files onto the
# (usually VFAT) boot media. It updates the kernel, the initrd image, backs up
# the old files to roll back the update and puts the new root filesystem image
# to the media for switching during the next reboot.
#
# It expects the update file in ZIP format on stdin.

# echo TODO: document this path and put it into common files!
BOOT_MEDIA=/initrd/mnt/media/

set -e

# when we don't exit cleanly, then at least remount the boot media ro
# this is safer
cleanup() {
  mount -o remount,ro $BOOT_MEDIA
}

# do a cleanup on unclean exits
trap 'cleanup' HUP INT QUIT TERM

if [ `ls $BOOT_MEDIA/*.old 2>/dev/null | wc -w` -ne 0 ]; then
  echo "Error: there are still files of the last version on the boot media."
  echo "Please remove them before attempting the next upgrade, since the media"
  echo "will not have enough space for more than two versions."
  exit 10
fi

echo "Starting system update."
oldpwd=`pwd`
cd $BOOT_MEDIA

if [ -e gibraltar.new ]; then
  echo "    Warning: overwriting a previous (seemingly incomplete) update."
  rm gibraltar.new
fi

echo -n "    Remounting boot media read/write ... "
mount -o remount,rw $BOOT_MEDIA
echo "done"

echo -n "    Receiving update files ... "
if [ ! -d new ]; then mkdir new; fi
if ! tar -C $BOOT_MEDIA/new -xz --no-same-owner --no-same-permissions; then
  echo "Failed to unpack update! Maybe it is corrupt?"
  exit 1
else
  echo "done"
fi
if [ ! -r new/gibraltar.bin -o \
     ! -r new/id.txt -o \
     ! -r new/linux -o \
     ! -r new/initrd.bin -o \
     ! -r new/md5sums.lst -o \
     ! -r new/syslinux.cfg ]; then
  echo "Error: some expected files are missing. Is this really a Gibraltar update?"
  cd $oldpwd
  rm -r $BOOT_MEDIA/new
  exit 2
fi

echo -n "    Verifying checksums ... "
cd new
if ! md5sum -c md5sums.lst; then
  echo "Error: Verfication failed! The update is either incomplete or corrupt. Please try again."
  cd $oldpwd
  rm -r $BOOT_MEDIA/new
  exit 3
else
  echo "done"
fi

echo -n "    Putting files in place for update on next reboot ... "
cd $BOOT_MEDIA
mv new/gibraltar.bin gibraltar.new

mv id.txt id.old
mv new/id.txt .

mv linux linux.old
mv new/linux .

mv initrd.bin initrd.old
mv new/initrd.bin .

mv new/md5sums.lst .

mv syslinux.cfg syslinux.old
# special handling here: keep the default boot option
defaultboot=`awk '/DEFAULT / { print $2; }' syslinux.old`
sed "s/DEFAULT .*/DEFAULT $defaultboot/" < new/syslinux.cfg > syslinux.cfg
rm new/syslinux.cfg

mv bootmsg.txt bootmsg.old
mv new/bootmsg.txt .

if [ `ls new/ | wc -w` -ne 0 ]; then
  echo "    Warning: unexpected files in update! Please look at them manually."
else
  rm -r $BOOT_MEDIA/new
fi
echo "done"

echo -n "    Remounting boot media read-only ... "
mount -o remount,ro $BOOT_MEDIA
echo "done"

cd $oldpwd
exit 0
