#!/bin/sh
#
# linbo_update
# thomas@linuxmuster.net
# 20250423
#

usage(){
  local RC="$1"
  echo
  echo "Updates LINBO and grub files in cache."
  echo
  echo "Usage: linbo_update [force] | [help]"
  echo
  echo "Per default this is done on boot. \"force\" forces the whole process"
  echo "although it was already done before."
  echo
  exit "$RC"
}

# print help
[ "$1" = "help" ] && usage 0

# get environment
source /usr/share/linbo/shell_functions
echo "### $timestamp $(basename "$0") $@ ###"

# do not execute in localmode
if localmode; then
  echo "Local mode detected!"
  exit 0
fi

# cmdline
if [ -z "$1" ] || validip "$1"; then shift ;fi
[ -z "$1" -o -b "$1" ] && shift
[ "$1" = "force" ] && FORCE="yes"

doneflag="/tmp/.update.done"

if [ -e "$doneflag" -a -z "$FORCE" ]; then
  echo "linbo_update has been already done."
  sendlog
  exit 0
else
  rm -f "$doneflag"
fi

rebootflag="/tmp/.linbo.reboot"

RC=0

grubdir="/cache/boot/grub"
if ! linbo_mountcache &> /dev/null; then
  sendlog
  exit 1
fi
mkdir -p "$grubdir"

cd /cache

# restore of start.conf in cache (necessary if cache partition was formatted before)
[ -s start.conf ] || cp /start.conf .

# check for linbo/linbofs updates on server
# download newer linbo/linbofs if applicable and check download
echo "Looking for LINBO updates."
# first check md5sum of linbofs
[ -e linbofs64 ] && md5_before="$(md5sum linbofs64 | awk '{ print $1 }')"
[ -e linbofs64.md5 ] && mv linbofs64.md5 linbofs64.md5.bak
linbo_download linbofs64.md5 &> /dev/null
md5_after="$(cat linbofs64.md5 2> /dev/null)"
if [ -z "$md5_after" ]; then
  echo "Failed to download linbofs64.md5!"
  [ -e linbofs64.md5.bak ] && mv linbofs64.md5.bak linbofs64.md5
  sendlog
  exit 1
fi
rm -f linbofs64.md5.bak
# if the linbofs checksum differs, download recent versions of linbofs and linbo
if [ "$md5_before" != "$md5_after" ]; then
  # first linbofs
  linbo_download linbofs64 &> /dev/null
  # verify download
  md5_current="$(md5sum linbofs64 | awk '{ print $1 }')"
  if [ "$md5_current" != "$md5_after" ]; then
    echo "Checksums differ, failed to download linbofs64!"
    sendlog
    exit 1
  fi
  # second linbo
  linbo_download linbo64 &> /dev/null
  md5_current="$(md5sum linbo64 | awk '{ print $1 }')"
  rm -f linbo64.md5
  linbo_download linbo64.md5 &> /dev/null
  # verify download
  md5_after="$(cat linbo64.md5 2> /dev/null)"
  if [ "$md5_current" != "$md5_after" ]; then
    echo "Checksums differ, failed to download linbo64!"
    sendlog
    exit 1
  fi
  # flag a reboot if linbo was not booted over network
  grep -q localboot /proc/cmdline && reboot="yes"
else
  echo "LINBO is up-to-date."
fi

# also look for other needed files
for i in "torrent-client.conf" "multicast.list"; do
  echo "Downloading $i."
   rsync --skip-compress="$RSYNC_SKIP_COMPRESS" -L "$LINBOSERVER::linbo/$i" "/$i" &> /dev/null
done

# update wallpaper
echo "Downloading linbo wallpaper."
[ -d icons ] || rm -rf icons ; mkdir -p icons
 rsync --skip-compress="$RSYNC_SKIP_COMPRESS" -L "$server::linbo/icons/linbo_wallpaper.png" icons &> /dev/null
[ -d /icons ] || rm -rf /icons ; mkdir -p /icons
 rsync --skip-compress="$RSYNC_SKIP_COMPRESS" icons/linbo_wallpaper.png /icons &> /dev/null

# get ipxe files from server
echo "Updating ipxe file."
# efi or bios?
if [ -d /sys/firmware/efi/efivars ]; then
  linbo_download boot/grub/ipxe.efi &> /dev/null
else
  linbo_download boot/grub/ipxe.lkrn &> /dev/null
fi

# get grub configs from server
echo "Updating common grub configuration."
cfgfile="$HOSTNAME.$HOSTGROUP.grub.cfg"
if linbo_download "boot/grub/spool/$cfgfile" &> /dev/null; then
  # initiate reboot if grub configuration has changed
  if ! diff -q "$cfgfile" "$grubdir/grub.cfg" &> /dev/null; then
    echo "grub.cfg was updated."
    reboot="yes"
  fi
  # move downloaded cfgfile in place
  mv "$cfgfile" "$grubdir/grub.cfg"
fi

# get host or group specific grub config from server
echo "Updating host and group specific grub configuration."
for i in "boot/grub/hostcfg/$HOSTNAME.cfg" "boot/grub/$HOSTGROUP.cfg"; do
  if linbo_download "$i" &> /dev/null; then
    cfgfile="$(basename "$i")"
    # initiate reboot if grub configuration has changed
    if ! diff -q "$cfgfile" "$grubdir/custom.cfg" &> /dev/null; then
      echo "custom.cfg was updated."
      reboot="yes"
    fi
    # move downloaded cfgfile in place
    mv "$cfgfile" "$grubdir/custom.cfg"
    break
  fi
done

# keep grub themes also updated
echo -n "Updating grub themes ... "
themesdir="/boot/grub/themes"
mkdir -p "/cache$themesdir"
 rsync --skip-compress="$RSYNC_SKIP_COMPRESS" -a --delete "${LINBOSERVER}::linbo${themesdir}/" "/cache${themesdir}/" || RC=1
if [ "$RC" = "1" ]; then
  echo "Failed!"
  sendlog
  exit 1
else
  echo "OK!"
fi

# fetch also current linuxmuster-win scripts
echo -n "Updating linuxmuster-win ... "
[ -d /cache/linuxmuster-win ] || mkdir -p /cache/linuxmuster-win
 rsync --skip-compress="$RSYNC_SKIP_COMPRESS" -a --exclude=*.ex --delete --delete-excluded "$LINBOSERVER::linbo/linuxmuster-win/" /cache/linuxmuster-win/ || RC=1
if [ "$RC" = "1" ]; then
  echo "Failed!"
  sendlog
  exit 1
else
  echo "OK!"
fi

# unix2dos and sambadomain fix
sambadomain="$(echo "$DOMAIN" | awk -F\. '{print $1}' | tr a-z A-Z)"
for item in /cache/linuxmuster-win/*.reg /cache/*.reg; do
  [ -e "$item" ] || continue
  unix2dos "$item"
  if [ -n "$sambadomain" ]; then
    sed -i "s|SAMBADOMAIN|$sambadomain|g" "$item"
    sed -i 's|^"NV Domain"=.*|"NV Domain"='\"$sambadomain\"'|' "$item"
    sed -i 's|^"Domain"=.*|"Domain"='\"$sambadomain\"'|' "$item"
  fi
done

# finally update/install grub stuff
if mk_boot; then
  # set efi bootorder to local,network
  [ -d /sys/firmware/efi ] && set_efibootorder
else
  RC="1"
fi

if [ "$RC" = "0" ]; then
  echo "Linbo & grub update successfully finished."
  touch "$doneflag"
  # initiate warmstart|reboot only if linbo has been booted locally from cache
  [ -n "$reboot" -a -n "$LOCALBOOT" ] && touch "$rebootflag"
else
  echo "Linbo & grub update failed!"
fi

sendlog

exit "$RC"
