#!/bin/bash
#
# rc.halt       This file is executed by init when it goes into runlevel
#               0 (halt) or runlevel 6 (reboot). It kills all processes,
#               unmounts file systems and then either halts or reboots.
#
# Author:       Miquel van Smoorenburg, <miquels@drinkel.nl.mugnet.org>
#               Modified for RHS Linux by Damien Neil
#
# securlevel: -

# Set the path.
PATH=/sbin:/bin:/usr/bin:/usr/sbin

. /etc/init.d/functions

runcmd() {
   echo -n "$1 "
   shift
   if [ "$BOOTUP" = "color" ]; then
      $* && echo_success || echo_failure
   else
      $*
   fi
   echo
}

halt_get_remaining() {
    awk '$2 ~ /^\/$|^\/proc|^\/sys|^\/dev/{next}
	 $3 == "tmpfs" || $3 == "proc" {print $2 ; next}
	 /(^#|loopfs|autofs|devfs|^none|^\/dev\/ram|^\/dev\/root)/ {next}
	 {print $2}' /proc/mounts
}

# See how we were called.
case "$0" in
  *halt)
	message="The system is halted"
	command="/sbin/halt"
	;;
  *reboot)
	message="Please stand by while rebooting the system..."
	command="/sbin/reboot"
	if [ ! -z "$FASTREBOOT" ] && [ -x /sbin/kexec ]; then
	    /sbin/kexec -l /boot/vmlinuz-$(uname -r) \
			--initrd=/boot/initrd-$(uname -r) \
			--append="$(cat /proc/cmdline)"
	else
	    FASTREBOOT=
	fi
	;;
  *)
	echo "$0: call me as \"rc.halt\" or \"rc.reboot\" please!"
	exit 1
	;;
esac

# Update GRUB password
grubconf=/boot/grub/grub.conf
if test -r $grubconf && grep -q "^password.*md5.*" $grubconf
then
  grubpass=""
  grubpass=`sed -n -e 's@^password.*\(\$1\$.*\)@\1@p' $grubconf | \
   head -n 1`
  realpass=""
  pfiles="/etc/passwd /etc/shadow"
  for pfile in $pfiles
  do
    if test -r $pfile && grep -q "^root:" $pfile
    then
      realpass=`grep "^root:" $pfile | cut -d":" -f 2 | \
       head -n 1`
      if test "$realpass" = "x"
      then
        realpass=""
      fi
    fi
  done
  #echo grubpass: $grubpass
  #echo realpass: $realpass
  if test -n "$grubpass" -a -n "$realpass" -a \
   "$grubpass" != "$realpass" -a \
   "`echo $realpass | sed -e 's/\(...\).*/\1/'`" = '$1$'
  then
    \cp $grubconf $grubconf.$$
    sed -e 's@^\(password.*\) \$1\$.*@\1 '$realpass'@' $grubconf.$$ \
     > $grubconf
    echo "$0: GRUB password updated."
  fi
fi

# Kill all processes.
[ "${BASH+bash}" = bash ] && enable kill

#runcmd "Sending all processes the TERM signal..." /sbin/killall5 -15
#sleep 5
#runcmd "Sending all processes the KILL signal.."  /sbin/killall5 -9

echo "Sending all processes the TERM signal..."
kill -15 -1
sleep 5
echo "Sending all processes the KILL signal.."
kill -9 -1

# Write to wtmp file before unmounting /var
halt -w

# Save mixer settings, here for lack of a better place.
grep -q "\(sparcaudio\|sound\)" /proc/devices
if [ $? = 0 -a -x /bin/aumix-minimal ]; then
   /bin/aumix-minimal -f /etc/.aumixrc -S >/dev/null 2>&1
fi

# Turn off swap, then unmount file systems.
SWAPS=`awk '! /^Filename/ { print $1 }' /proc/swaps`
[ -n "$SWAPS" ] && runcmd "Turning off swap" swapoff $SWAPS

[ -x /sbin/accton ] && runcmd "Turning off accounting" /sbin/accton

[ -x /sbin/quotaoff ] && runcmd "Turning off quotas" /sbin/quotaoff -a

# Unmount file systems, killing processes if we have to.
# Unmount loopback stuff first
remaining=`awk '!/^#/ && $1 ~ /^\/dev\/loop/ && $2 != "/" {print $2}' /proc/mounts`
devremaining=`awk '!/^#/ && $1 ~ /^\/dev\/loop/ && $2 != "/" {print $1}' /proc/mounts`
[ -n "$remaining" ] && {
    sig=
    retry=3
    while [ -n "$remaining" -a "$retry" -gt 0 ]; do
	if [ "$retry" -lt 3 ]; then
	    runcmd $"Unmounting loopback filesystems (retry):" umount $remaining
	else
	    runcmd $"Unmounting loopback filesystems: " umount $remaining
	fi
	for dev in $devremaining ; do
	    losetup $dev > /dev/null 2>&1 && \
		runcmd $"Detaching loopback device $dev: " losetup -d $dev
	done
	remaining=`awk '!/^#/ && $1 ~ /^\/dev\/loop/ && $2 != "/" {print $2}' /proc/mounts`
	devremaining=`awk '!/^#/ && $1 ~ /^\/dev\/loop/ && $2 != "/" {print $1}' /proc/mounts`
	[ -z "$remaining" ] && break
	/sbin/fuser -k -m $sig $remaining >/dev/null
	sleep 5
	retry=$(($retry -1))
	sig=-9
    done
}

# Unmount RPC pipe file systems
sig=
retry=3
remaining=`awk '!/^#/ && $3 ~ /^rpc_pipefs$/ || $3 ~ /^rpc_svc_gss_pipefs$/ {print $2}' /proc/mounts`

while [ -n "$remaining" -a "$retry" -gt 0 ]; do
    if [ "$retry" -lt 3 ]; then
	runcmd $"Unmounting pipe file systems (retry): "  umount -f $remaining
    else
	runcmd $"Unmounting pipe file systems: "  umount -f $remaining
    fi
    sleep 2
    remaining=`awk '!/^#/ && $3 ~ /^rpc_pipefs$/ || $3 ~ /^rpc_svc_gss_pipefs$/ {print $2}' /proc/mounts`
    [ -z "$remaining" ] && break
    /sbin/fuser -k -m $sig $remaining >/dev/null
    sleep 5
    retry=$(($retry-1))
    sig=-9
done

sig=
retry=3
remaining=`halt_get_remaining | sort -r`

while [ -n "$remaining" -a "$retry" -gt 0 ]; do
    if [ "$retry" -lt 3 ]; then
	runcmd "Unmounting file systems (retry): "  umount -f $remaining
    else
	runcmd $"Unmounting file systems: "  umount -f $remaining
   fi
    sleep 2
    remaining=`halt_get_remaining | sort -r`
    [ -z "$remaining" ] && break
    /sbin/fuser -k -m $sig $remaining >/dev/null
    sleep 5
    retry=$(($retry-1))
    sig=-9
done

[ -f /proc/bus/usb/devices ] && umount /proc/bus/usb

# remove the crash indicator flag
rm -f /.autofsck

# Try all file systems other than root and RAM disks, one last time.
mount |  awk '!/( \/ |^\/dev\/root|^\/dev\/ram| \/proc )/ { print $3 }' | \
  while read line; do
    umount -f $line > /dev/null 2>&1
done

# Remount read only anything that's left mounted.
# echo $"Remounting remaining filesystems readonly"
mount | awk '{ print $3 }' | while read line; do
    mount -n -o ro,remount $line
done

# Check raid
if [ -f /proc/mdstat -a -f /etc/raidtab ]; then
  needraidstop=1
fi

raidstop()
{
  if [ "$needraidstop" = "1" ]; then
    for i in `grep "^raiddev" /etc/raidtab | awk '{print $2}'`;do
       /sbin/raidstop --readonly $i
    done
  fi
}

runcmd "Unmounting proc file system" umount /proc

# Now halt or reboot.
echo "$message"
if [ -f /fastboot ]; then
 echo "On the next boot fsck will be skipped."
elif [ -f /forcefsck ]; then
 echo "On the next boot fsck will be forced."
fi

if [ "$command" = /sbin/halt -a -r /etc/ups/upsmon.conf -a -f /etc/killpower -a -f /etc/sysconfig/ups ] ; then
  . /etc/sysconfig/ups
  if [ "$SERVER" = "yes" -a "$MODEL" = "upsdrvctl" ] ; then
    raidstop
    /sbin/upsdrvctl shutdown
  elif [ "$SERVER" = "yes" -a "$MODEL" != "NONE" -a -n "$MODEL" -a -n "$DEVICE" ] ; then
    raidstop
    $MODEL $OPTIONS_HALT -k $DEVICE
  fi
fi

if [ -x /sbin/halt.local ]; then
   /sbin/halt.local
fi

if [ -x /sbin/upspoweroff ]; then
  /bin/sleep 2
  raidstop
  /bin/sleep 3
  /sbin/upspoweroff
fi

HALTARGS="-i -d"
if [ -f /poweroff -o ! -f /halt ]; then
 HALTARGS="$HALTARGS -p"
fi

if [ ! -z "$FASTREBOOT" ] && [ -x /sbin/kexec ]; then
    /sbin/kexec -e
fi
eval $command $HALTARGS
