#!/bin/dash

#
# Note: linuxrc-based tools are in /lbin.
#

PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/X11/bin:/lbin

# tmpfs has mode 1777, sshd doesnt like that
chmod 755 /

# gdb can't be symlink
#if [ -L /usr/bin/gdb ] ; then
#  i=`readlink /usr/bin/gdb`
#  rm -f /usr/bin/gdb
#  touch /usr/bin/gdb
#  mount --bind $i /usr/bin/gdb
#fi

# see bug 61535
[ -e /proc/sys/vm/local-oom-kill ] && echo 1 > /proc/sys/vm/local-oom-kill

if [ -f /.timestamp ] ; then
  read -r build_time < /.timestamp
  now_time=$(TZ='' LANG='' LC_ALL='' date +%Y%m%d)
  if [ "$now_time" -lt "$build_time" ] ; then
       echo
       echo "your system time is not correct:"
       TZ='' date
       echo "setting system time to:"
       TZ='' LANG='' LC_ALL='' date "${build_time#????*}1234${build_time%*????}.56"
       echo
       /sbin/hwclock --systohc -u &
       sleep 3
  fi
fi

if [ -d /dev/pts ] ; then
  grep -q devpts /proc/mounts || mount -t devpts devpts /dev/pts
fi

# no old hotplug stuff
echo  > /proc/sys/kernel/hotplug

yast="$1"
shift
echo "$yast" > /tmp/linuxrc_installer_name
export YAST2_SSH=false
unset SSH_FAILED
stty sane 2>/dev/null

# get hostname & hostips
hostip_from_wicked /tmp/host_ips /tmp/host_name
host_name=$([ -f /tmp/host_name ] && cat /tmp/host_name)

#
# a few files should be restored when installation has completed if we
# return to linuxrc.
FILES_TO_RESTORE="/etc/ld.so.cache"
for file in $FILES_TO_RESTORE ; do
  test -e $file && mv $file $file.initrd
done
#

ldconfig

# driver update: rebuild yast update tree
[ -L /y2update ] && rm -f /y2update
[ -d /update/y2update ] && mv /update/y2update /update/y2update.bak
for i in /update/[0-9]*/y2update ; do
  [ -d "$i" ] && cp -a "$i" /update
done
if [ -d /update/y2update ] ; then
  rm -rf /update/y2update.bak
else
  [ -d /update/y2update.bak ] && mv /update/y2update.bak /update/y2update
fi

# driver update: add files to inst-sys
for i in /update/[0-9]*/inst-sys ; do
  [ -d "$i" ] && adddir "$i" /
done

# driver update: run update.pre scripts
for i in /update/[0-9]*/install/update.pre ; do
  [ -x "$i" ] && "$i"
done

# start rsyslogd
if [ -x /usr/sbin/rsyslogd ] ; then
  checkproc /usr/sbin/rsyslogd || {
    echo -n "starting rsyslogd (logging to /dev/tty4)..."
    sh -c '/usr/sbin/rsyslogd >&1' 2>/dev/null
    echo " ok"
  }
fi

# start klog
if [ -x /sbin/klogd ] ; then
  checkproc /sbin/klogd || {
    echo -n "starting klogd..."
    if /sbin/klogd -c 1 ; then
      echo " ok"
    else
      echo " failed"
    fi
  }
fi

# start nscd (bnc #530440, bnc #878904)
if [ -x /usr/sbin/nscd ] ; then
  checkproc /usr/sbin/nscd || {
    echo -n "starting nscd..."
    if /usr/sbin/nscd ; then
      echo " ok"
    else
      echo " failed"
    fi
  }
fi

# Update module config.
#
# Note: modules are all from initrd, but new ones might have come in via
# driver updates.
#
depmod -a 2>/dev/null

test -x /usr/lib/hyper-v/bin/inst_sys.sh && /usr/lib/hyper-v/bin/inst_sys.sh

# ensure everything below those dirs is writable
for i in /root /etc/ssh /etc/sysconfig ; do
  cp -aL $i ${i}_tmp
  rm -rf $i
  mv ${i}_tmp $i
done

# boot with usessh=1 or use linuxrc to enable ssh 
# vnc=1 will override the install mode
if grep -q "^SSHD:.*1" /etc/install.inf ; then
  # shellcheck source=data/root/etc/inst_setup_ssh
  test -x /sbin/inst_setup_ssh && . /sbin/inst_setup_ssh
fi

# for yast debugging.
if grep -iwq y2debug < /proc/cmdline ; then
  export Y2DEBUG=1
fi

export XCURSOR_THEME=DMZ
export LIBGL_ALWAYS_INDIRECT=1
export EGL_LOG_LEVEL=fatal

grep -qwi start_shell /proc/cmdline && START_SHELL=1
grep -qi "^StartShell:.*1" /etc/install.inf && START_SHELL=1
# leave a core file if yast crashes
# shellcheck disable=SC2169 # "ulimit in dash may behave differently"; fine here
ulimit -c unlimited

# turn off plymouth splash screen
plymouth_off() {
  [ -x /usr/bin/plymouth ] && plymouth quit
}

# start shell, useful on iSeries or via serial console
start_shell() {
  plymouth_off
  echo -n \\033c
  echo 
  echo "ATTENTION: Starting shell... (use 'exit' to proceed with installation)"
  bash -l
}

zram_swap_on() {
  zram_swap=`awk '/^zram_swap:/ { print $2 }' /etc/install.inf`
  if [ -n "$zram_swap" ] ; then
    modprobe zram
    zram_dev_index=`cat /sys/class/zram-control/hot_add`
    zram_swap_dev=/dev/zram$zram_dev_index
    if [ -b "$zram_swap_dev" ] ; then
      echo zstd > /sys/block/zram$zram_dev_index/comp_algorithm
      echo "$zram_swap" > /sys/block/zram$zram_dev_index/disksize
      mkswap $zram_swap_dev >/dev/null
      swapon $zram_swap_dev
      create_zram_swap_disable_hook
    fi
  fi
}

zram_swap_off() {
  if [ -b "$zram_swap_dev" ] ; then
    swapoff $zram_swap_dev
    echo $zram_dev_index > /sys/class/zram-control/hot_remove
  fi
}

create_zram_swap_disable_hook() {
  tmp_dir=$(mktemp -d)
  hook_dir=/var/lib/YaST2/hooks/installation
  script=before_instsys_cleanup_10_zram_swap

  # make $hook_dir writable
  mkdir -p $tmp_dir/$hook_dir
  adddir $tmp_dir /

  cat > $hook_dir/$script <<XXX
#! /bin/sh -x

# at least 2 swap devices
if [ "\$(wc -l < /proc/swaps)" != 2 ] ; then
  swapoff $zram_swap_dev
  sync
  sleep 1
  echo $zram_dev_index > /sys/class/zram-control/hot_remove
fi
XXX
  chmod +x $hook_dir/$script
}

zram_swap_on

[ -f /tmp/host_ips ] && cat /tmp/host_ips

[ "$START_SHELL" ] && start_shell

# anounce VNC via slpd
if grep -qi "^VNC:.*1" /etc/install.inf ; then
  echo starting slpd to announce VNC...
  test -x /usr/sbin/slpd  &&  /usr/sbin/slpd ; ec=$?
  if test "$ec" = "0" ; then
    (
    sleep 3
    /usr/bin/slptool register "service:YaST.installation.suse:vnc://${host_name}:5901"
    ) >/tmp/slptool_register.txt 2>&1 &
  else
    echo "slpd returned with exit code $ec, VNC will not be announced"
  fi
  # vnc=1 usessh=1 should start sshd, but the result is a vnc installation
  YAST2_SSH=false
fi

plymouth_off

ec=
if [ "$YAST2_SSH" = "true" ] ; then
  cat <<EOF

***  login using 'ssh -X root@${host_name}'  ***
***  run '${yast}.ssh' to start the installation  ***

EOF
  cp /etc/issue /etc/motd
  { echo "Run yast.ssh to start the installation."; echo; } >>/etc/motd

  # print more detailed list of ifaces using a function from yast2-installation
  if [ -e /usr/lib/YaST2/startup/common/network.sh ] ; then
    echo "Active interfaces:"

    # shellcheck disable=SC1091 # file in a different repo
    . /usr/lib/YaST2/startup/common/network.sh
    list_ifaces | head -n 20
  fi

  while true ; do
    sleep 3
    # this file is created from YaST2.firstboot after installation
    test ! -f /tmp/YaST2_ssh_installation_finished && continue
    # you can touch this file to keep the ssh shell
    # useful for debugging the installer
    test -f /tmp/YaST2_keep_sshd_running && continue
    break
  done

  ec=$(cat /tmp/YaST2_ssh_installation_finished)
  rm -f /tmp/YaST2_ssh_installation_finished
elif [ "$yast" = yast ] ; then
  # now, run yast
  echo "starting yast..."
  /usr/sbin/yast2 "$@" ; ec=$?
elif [ "$yast" ] ; then
  # now, run yast
  echo "starting $yast..."
  "$yast" "$@" ; ec=$?
fi

# start shell, useful on iSeries or via serial console
[ "$START_SHELL" ] && start_shell

nscd --shutdown

# stop various daemons
# killall dbus-daemon >/dev/null 2>&1
killall slpd >/dev/null 2>&1
killall Xvnc >/dev/null 2>&1
killall sshd >/dev/null 2>&1

umount /usr/bin/gdb 2>/dev/null
umount devpts 2>/dev/null

for file in $FILES_TO_RESTORE ; do
  test -e $file.initrd && mv $file.initrd $file
done

rm -f /etc/modules.conf

# clean up after yast
# shellcheck disable=SC2016 # the ${} is for sed, not a shell expansion mistake
sed -n '1{h;n};x;H;${x;p}' /proc/mounts | awk '{ if($2 ~ /^\/var/) system("umount " $2) }'

zram_swap_off

exit $ec

