#!/bin/sh
############
# CHANGELOG
#===========
# 2012/07/31   CRMS00386301 Jerry ZHOU
#              fix 'eval' error when there is "()" in reboot reason

# 2011/02/16    CRMS00262654    Michel SULYAN
#               log reset with facility local6
#
# 2010/06/24    CRMS00240826    Thanh lam NGUYEN
#               Add reboot in entering a step.
#
# 2010/05/22	add the reason	TCREMEL
#		add a reason of reboot in the popup 
#
# 2010/05/22	displaypopup	TCREMEL
#		add a popup informing there is a reboot
#
# 2010/03/31	CRMS00219063	TCREMEL
#		add defence log
#
# 2010/03/30    CRMS00220154	TCREMEL
#               add warm/cold reboot (option soft and hard)
#
# 2010/03/25    CRMS00221778    Thanh lam NGUYEN
#               Add reboot in entering a step.
#
# 2010/03/05    CRMS00212892    TCREMEL
#               increased the delay before armagedon !
#
################

# read config
#------------
. /etc/init.d/rc.config

# script variables
#-----------------
# CRMS00221778
# Max time to wait before forcing the reboot
MAXWAITTIME=60
debugflag=.debug.reboot
delayfile=/tmp/reboot.delay
debug=0
cr=$'\n'

[[ -f /${debugflag} ]] && debug=1
[[ -f /tmp/${debugflag#.} ]] && debug=1
[[ -f /home/admin/${debugflag#.} ]] && debug=1
[[ $debug -eq 1 ]] && busybox=display
cur_stdout="$(readlink /proc/$$/fd/1)"
[[ "$cur_stdout" != "/dev/console" ]] && [[ "$cur_stdout" != "/dev/ttyAMA0" ]] && tostdout="tee /dev/console" || tostdout="cat"

# functions
#----------
securityReboot()
#---------------
{
    local timeout=$1
    ( trap "" HUP; sleep $timeout; display "SECURITY REBOOT" > /dev/console; [[ $debug -eq 0 ]] && kill -9 -1 ) &
    echo $! > /tmp/securityReboot.pid
}

getCallStack()
#-------------
{
    local -
    set +x
    # find the calling stack
    sep=$cr
    stack=""
    pid=0
    ppid=$$
    while [[ $ppid -ne $pid ]] && [[ $ppid -ne 0 ]]; do
        pid=$ppid
#CRMS00386301 jerryzh+
        eval "$(awk 'BEGIN{file=1}file==1{proc=$2; ppid=$4; gsub( /[()]/, "", proc ); file=2; nextfile}file==2{call=call" "$0}END{sub( /^[[:blank:]]*/, "", call ); sub ( /[[:blank:]]*$/, "", call ); gsub( /[()]/, "", call ); print "ppid=\""ppid"\""; print "proc=\""proc"\""; print "call=\""call"\""}' /proc/$pid/stat /proc/$pid/cmdline)"
#CRMS00386301 jerryzh-
        stack="$pid [$proc] [$call]$sep$stack"
    done
    stack="${stack%$sep}"
    [[ $debug -eq 1 ]] && { echo "reboot stack: "$'\n'"----------------"$'\n'"$stack"$'\n'"----------------" | $tostdout; }
}
# CRMS00221778 END


#======#
# MAIN #
#======#
[[ $debug -eq 1 ]] && { ps -w 2>&1 | $tostdout; }
getCallStack
cd /
delay=0
step=0
# CRMS00219063
reason="unknown"
owner="unknown"
# CRMS00219063 END

# process command line
#---------------------
# CRMS00220154
# default is warm reset
echo "1" > /proc/sys/reboot/warm
# CRMS00220154 END
while [[ $# -gt 0 ]]; do
    case "$1" in
        --waitSettings) : "Wait for the setting manager to exit"
            waitfile=$lockFile
        ;;
# CRMS00221778
        --step) : "Reboot at the beginning of step $2"
            step=$2
            shift
        ;;
        --delay|--wait ) : "Reboot delay of $2s"
            delay=$2
            stime="$(udate)"
            shift
        ;;
# CRMS00221778 END
# CRMS00220154
        --soft) : "Reboot at the beginning of step $2"
	    echo "1" > /proc/sys/reboot/warm
        ;;
        --hard) : "Reboot at the beginning of step $2"
	    echo "0" > /proc/sys/reboot/warm
        ;;
# CRMS00220154 END
# CRMS00219063
        --reason) :
            reason=$2
            shift
        ;;
        --owner) :
            owner=$2
            shift
        ;;
# CRMS00219063 END
        *)
        ;;
    esac
    shift
done

# CRMS00240826
# get current step
#-----------------
if [ -n "$stepFile" ]; then
    currentstep=$(cat $stepFile)
fi

# manage the step request
#------------------------
if [[ $step -ne 0 ]]; then
    [[ $debug ]] && { display "[$(udate)] Request reboot at the start of step $step.\nCall stack: \n$stack" | $tostdout; }
    echo "$stack" > /tmp/reboot.$step
    echo "stime=$stime" > $delayfile.$step
    echo "delay=$delay" >> $delayfile.$step
    # add the reason START
    # keep the reason for further call of reboot
    echo "owner=\"$owner\"" > /tmp/rebootinfo.$step
    echo "reason=\"$reason\"" >> /tmp/rebootinfo.$step
    # add the reason END
    # delay the reboot if the requested step is greater than the current one
    [[ $step -gt $currentstep ]] && exit 0
fi
# CRMS00240826 END

# add the reason START
if [ -f /tmp/rebootinfo.$currentstep -a "$reason" = "unknown" -a "$owner" = "unknown" ]; then
    source /tmp/rebootinfo.$currentstep
fi
# add the reason END

# CRMS00219063
echo $owner : $reason > $REBOOT_FLAG
# CRMS00262654
logger -t reset__ -p local6.emerg "$owner : $reason"
# CRMS00262654 END
# CRMS00219063 END

# add the reason START
if [ -f /usr/sbin/displaypopup ]
    then
    /usr/sbin/displaypopup Reboot in progress:" $reason"
    sleep 5
fi
# add the reason END

if [[ -n "${waitfile:-}" ]]; then
    while [[ -f "$waitfile" ]]; do sleep 1; done
fi

if [[ -f /tmp/reboot.[0-9] ]]; then
    stack="$(cat /tmp/reboot.[0-9])"
fi

if [[ -f $delayfile.[0-9] ]]; then
    source $delayfile.[0-9]
    elapse=$(udate $stime) elapse=${elapse#* } elapse=${elapse%.*}
    [[ $elapse -lt $delay ]] && sleep $((delay-elapse))
fi

securityReboot $MAXWAITTIME
display "[$(udate)] REBOOTING by \n$stack" | $tostdout
displaymsg "Rebooting ..."
$busybox reboot

while [ 0 ];do
    gotoInfiniteLoop
    sleep 50000
done
