#! /bin/sh
# Copyright (c) 1996 SuSE GmbH Nuernberg, Germany.  All rights reserved.
#
# Author: Florian La Roche <florian@suse.de>, 1996
#	  Werner Fink <werner@suse.de>, 1996-2001
#
# /etc/init.d/halt (and symlinked to reboot)
#

. /etc/rc.status
. /etc/rc.config

#
# Avoid being interrupted by child or keyboard
#
trap "echo" SIGINT SIGSEGV SIGQUIT SIGTERM
set +e

rc_splash "reboot"

case "$0" in
	*halt)
		message="The system will be halted immediately."
		case `/bin/uname -m` in
                    i?86)
                        command="halt"
                        if test -e /proc/apm -o -e /proc/sys/acpi ; then
                            command="halt -p"
                        else
                            read cmdline < /proc/cmdline
                            case "$cmdline" in
                                *apm=smp-power-off*|*apm=power-off*)  command="halt -p" ;;
                            esac
                        fi
                        ;;
                    *)
                        command="halt -p"
                        ;;
                esac
		;;
	*reboot)
		message="Please stand by while rebooting the system..."
		command="reboot"
		;;
	*)
		echo "$0: call me as \"halt\" or \"reboot\" please!"
		exit 1
		;;
esac

#
# helper shell function
#
reverse ()
{
    local _line
    while read -r _line ; do
        reverse
        echo "$_line"
        break
    done
}


#
# first do local stuff
#
rc_reset
test -e /etc/init.d/halt.local && {
    echo Running /etc/init.d/halt.local
    /bin/sh /etc/init.d/halt.local
    rc_status -v1 -r
}

# Write to wtmp file before unmounting /var
$command -w 

# Set a flag that we had success upto this point
> /success

# Stop blogd before umounting /var
killproc -QUIT /sbin/blogd

# Redirect our mesages to default console
test -n "$REDIRECT" && exec 0<> $REDIRECT 1>&0 2>&0

echo "Sending all processes the TERM signal..."
killall5 -15
echo -e "$rc_done_up"

sleep 1
test "$1" = "fast" -o -e /fastboot || sleep 4

echo "Sending all processes the KILL signal..."
killall5 -9
echo -e "$rc_done_up"

if test "$HOSTTYPE" = "s390" ; then
    HWCLOCK_ACCESS=no
fi
if test "$HWCLOCK_ACCESS" != "no" ; then
    echo -n "Set Hardware Clock to the current System Time:"
    if test "$GMT" != "YAST_ASK" -a "$START_XNTPD" = "yes" -a -n "$XNTPD_INITIAL_NTPDATE" ; then
        # write back to hardware clock and calculate adjtime
	/sbin/hwclock_wrapper --systohc $GMT
	rc_status
    fi
    rc_status -v -r
fi



echo "Turning off swap"
sync ; sync
rc_reset
swapoff -a &> /dev/null
rc_status -v1 -r
# Something forgotten?
if test -r /proc/swaps ; then
    # Use cat and a pipe because swapoff changes
    # /proc/swaps during direct read call
    cat /proc/swaps | \
    while read des rest ; do
	test "$des" = "Filename" && continue
	swapoff $des &> /dev/null
    done
fi

mounts=/etc/fstab
test -r /proc/mounts && mounts=/proc/mounts
reverse < $mounts | \
while read des fs type rest; do
    case "$des"  in
	""|\#*)	   continue ;;
	/dev/loop*)

### ppdd do not umount a loop root filesystem yet

		if [ "$fs" != "/" ];then
		   umount -v $fs
		   losetup $des &> /dev/null
		   test $? -eq 0 && losetup -d $des 
		fi
###
		;;
    esac
    case "$fs"   in
	/proc)     continue ;;
	/dev/pts)  continue ;;
	/dev)      continue ;;
	/dev/shm)  continue ;;
    esac
    case "$type" in
	proc)      umount -t proc     $fs ;;
	devpts)    umount -t devpts   $fs ;;
	devfs)     umount -t devfs    $fs ;;
	shm)       umount -t shm      $fs ;;
	usbdevfs)  umount -t usbdevfs $fs ;;
    esac
done

UMOUNT_FAILED=false
echo "Unmounting file systems"
umount -avt noproc,nonfs,nosmbfs || {
    rc_status
    UMOUNT_FAILED=true
}
rc_status -v1 -r

if test "$UMOUNT_FAILED" = true ; then
    echo "Oops: umount failed :-(  --  trying to remount readonly..."
    mounts=/etc/fstab
    test -r /proc/mounts && mounts=/proc/mounts
    # Use cat and a pipe because umount changes
    # /proc/mounts during direct read call
    cat $mounts | \
    while read des fs type rest; do
	case "$des" in ""|\#*) continue ;; esac
	case "$type" in
	    swap)     continue ;; # No umount on swap devices
	    proc)     continue ;; # Required
	    nfs)      continue ;; # Avoid hanging reboot/halt
	    smbfs)    continue ;; # Avoid hanging reboot/halt
	esac
        mount -v -n -o remount,ro $fs
    done

    echo "extra sync..."
    sync; sync
    echo "... hope now it's ok to reboot."
fi

if test -d /etc/lvmtab.d -a -x /sbin/vgchange ; then
    /sbin/vgchange -a n
fi

umount -anvt proc

# maybe we use Multiple devices
if test -f /etc/mdtab -a -x /sbin/mdstop ; then
    echo -n "Disable Multiple Devices"
    /sbin/mdstop -a
    rc_status -v1 -r
fi

### ppdd

if [ -f /etc/ppddtab ]; then
  if [ -x /initrd/ppdddown ]; then
    exec /initrd/ppdddown $command "$message"
  fi
fi

### end ppdd

# on umsdos fs this would lead to an error message, so direct errors to
# /dev/null
mount -no remount,ro / 2> /dev/null
sync

# Make reboot noise and wait a few seconds to give harddisks the chance
# to really flush their buffers before power goes down.
if test -n "$REDIRECT" ; then
    sleep 1
    case "$HALT_SOUND" in
    "yes"|"quint")
	echo -en "\033[10;393]\a\033[10;262]"
	sleep 1
	;;
    "octave")
	for tone in 524 491 440 393 349 328 295 ; do
	    echo -en "\033[10;${tone}]\a"
	    usleep 125000
	done
	echo -en "\033[10;262]"
	;;
    *)
    	echo -en "\033[10;440]\a"
	usleep 250000
	;;
    esac
else
    echo -en "\a"
    sleep 2
fi
echo $message
echo -en "\a"

# Set system console back to intial value
test -n "$REDIRECT" -a -n "$CONSOLE" && setconsole $REDIRECT < $CONSOLE

# Now talk to kernel
exec $command -d -f
