#!/bin/bash

REMOTE_IFNAME=remote

# pick up some helper functions
source /ciena/scripts/utils.sh

###############################################################################
# FUNCTION:   flipBank
#
# Select the alternate application bank.  LEOS _cannot_ be running!
#
# ParamType_BootCookie is 282.  The poorly-documented -e option to
# hexdump takes a format string, which here calls for one 4-byte
# element printed as an unsigned integer.
#
###############################################################################
flipBank()
{
    BANK=`/mnt/apps/bin/saparam tofile 282 /proc/self/fd/1 | hexdump -n 4 -e '1/4 "%u"'`
    if [ $BANK = 0 ]; then	# bank = !bank;
	BANK=1
    else
	BANK=0
    fi
    /mnt/apps/bin/saparam write 282 $BANK
}

###############################################################################
# FUNCTION:   suckupKrn
#
# Process krn settings.
#
###############################################################################
suckupKrn()
{
    . /sbin/krn getenv

    ##########################################################
    #   Determine normal versus debug 'kernel' mode.
    #   In debug mode, timeouts are largely disabled.
    ##########################################################

    if [ "$KRN_MODE" = "debug" ]; then
	DEBUG=-D
    else
	DEBUG=
    fi
}

###############################################################################
# FUNCTION:   netWait
#
# Wait for network interface up; currently will wait forever.
#
# ARGS:
#       $1      interface name
#       $2      text to grep for in 'ifconfig' output
###############################################################################
netWait ()
{
        echo -n Waiting for $1 $2...
        while [ true ]; do
                IFCHK=`ifconfig $1 | grep $2`
                if [ -n "$IFCHK" ]; then
                        break
                else
                        echo -n .
                        sleep 1
                fi
        done
        echo
}

LOGFILE=/dev/console

. /etc/profile
suckupKrn

##########################################################
#   Determine which leos image to run,
#   download the images if necessary.
##########################################################
if [ "$KRN_LOC" = "tftp" ]; then
    LEOS_PATH=/tmp/bin/leos

    echo `date` Starting SAOS TFTP loader... >> $LOGFILE
    echo -n 1 > /tmp/fifo/mon/leos.loader
    /sbin/le0 start

    netWait $REMOTE_IFNAME inet

    # leos core files are huge, and could even prevent downloading a
    # new leos.  Wait for the automatic compressor to do its thing.
    while [ -n "$(ls /tmp/core /tmp/core.* 2>/dev/null)" ] ; do
	echo "Waiting for core file to compress..."
	sleep 15
    done

    echo `date`  Loading SAOS from $TFTP_SERVER >> $LOGFILE
    tftp -g -r leos -l $LEOS_PATH $TFTP_SERVER >> $LOGFILE 2>&1
    if [ $? -ne 0 ]; then
        echo Unable to retrieve SAOS image >> $LOGFILE
        rm -f $LEOS_PATH
    else
	chmod 775 $LEOS_PATH >>$LOGFILE 2>&1
    fi

    echo `date` Stopping SAOS TFTP loader... >> $LOGFILE
    echo -n 0 > /tmp/fifo/mon/leos.loader

else
    LEOS_PATH=/mnt/apps/bin/leos
fi


##########################################################
#   Stop previous instance of DHCP-C if running &
#   Unconfigure the interface, gw etc.
##########################################################
/sbin/stopDhcpc.sh 

##########################################################
#   Kill any existing children of a prior LEOS server.
##########################################################
if [ -r /tmp/fifo/leos/LEOS_IPC_PID ] ; then
    kill -TERM -`cat /tmp/fifo/leos/LEOS_IPC_PID` 2>/dev/null
fi

##########################################################
# Check for Monitor (xgrade) script and run it if required.
# Stops various system services first.
##########################################################
if [ -x /tmp/xgrade/monitor ]; then 	
   echo "Shutting down all kernel modules!!!!"	
  # sleep 10		
   /sbin/shutdown
   killall -STOP getty login inetd telnetd sshd 2>/dev/null
   echo "Running Monitor (xgrade) script now!!!!"
   (while :; do sleep 5; echo "Software installation in progress..."; done) &
   NOISE=$!
   /tmp/xgrade/monitor   
   kill $NOISE	# Should never actually get here, it resets first.
fi


if [ ! -f /tmp/console_enable ] ; then
    ##########################################################
    #   There is no console enabled, so glue stdout and
    #   stderr to CONSOLE_COLLECTOR.
    ##########################################################
    CONSOLE_COLLECTOR=/tmp/log/console_collector
    exec </dev/null &>$CONSOLE_COLLECTOR
else
    ##########################################################
    #   Determine disposition of serial port (console).
    #   If in normal mode, only stderr makes it out.
    ##########################################################
    if [ "$KRN_CONSOLE" = "normal" ]; then
        CONSOLE_MIRROR=/tmp/log/console_mirror
        exec </dev/null >$CONSOLE_MIRROR
    fi
fi

##########################################################
#   Find any earlier run history, for flash-based respawns
##########################################################
STATEFILE=/tmp/fifo/leos/LEOS_STATE
STARTFILE=/tmp/fifo/leos/LEOS_STARTING
RUNFILE=/tmp/fifo/leos/LEOS_RUNNING
if [ -r $STATEFILE ]; then
    STATE=`cat $STATEFILE`
else
    STATE=0
fi

if [ $STATE = '1' ]; then	# We died during config, try without?
    NOCONFIG=-n
else
    NOCONFIG=
fi

##########################################################
#   Finally start LEOS!!
##########################################################

# If leos is told to die, pass it on, and make for a fresh start next time.
trap 'kill -TERM $LEOS; wait $LEOS; rm -f $STARTFILE $RUNFILE $STATEFILE; exit 0' SIGTERM

if [ -f $LEOS_PATH ]; then
    chmod g=u /tmp/core* 2>/dev/null # Allow examination of any wreckage
    # leos core files are huge, and could even prevent downloading a
    # new leos.  Wait for the automatic compressor to do its thing.
    while [ -n "$(ls /tmp/core /tmp/core.* 2>/dev/null)" ] ; do
	echo "Waiting for core file to compress..."
	sleep 15
    done
   # Does no harm, but useful in case we ever run Bullseye;
   # but it only captures the coverage for server process.
   # For CLI process(es), it's a manual procedure.
   if [ -f /tmp/be_test.cov ] ; then
      export COVFILE=/tmp/be_test.cov
   fi
   touch /etc/nologin
   echo `date` Starting SAOS from $LEOS_PATH >> $LOGFILE
   rootfs_location=$(get_rootfs_location)
   if [ $rootfs_location = "flash" -a $KRN_RESPAWN = "enable" ]
   then			# Only get tricky with flash-based respawns.
       if [ -n $NOCONFIG ]
       then
          /bin/tar xzf /etc/etc.tar.gz -C /
          chmod o-w /etc
          /ciena/scripts/fixup_etc_issue
       fi
       rm -f $RUNFILE
#       if [ -r /MANIFEST -a -x /usr/bin/md5sum ]; then
#	   if grep bin/leos /MANIFEST | md5sum -s -c - ; then
#	       $LEOS_PATH $DEBUG $NOCONFIG -s &	# Run leos.
#	       LEOS=$!
#	       wait $LEOS # Allows SIGTERM to propagate to leos via trap.
#	       ES=$?
#	   else
#	       ES=1	# Bad leos checksum.
#	       echo `date` $LEOS_PATH: Failed md5sum check >> $LOGFILE
#	   fi
#       else		# No MANIFEST file, just run it.
	   $LEOS_PATH $DEBUG $NOCONFIG -s &	# Run leos.
	   LEOS=$!

           # While leos is running, look for CLI temp files in /tmp that do not
           # have a corresponding process and remove them.  This helps prevent
           # a full ramdisk.  The check is run every 60 seconds.
           (while :; do
               sleep 60
               for f in /tmp/[0-9].out                     \
                        /tmp/[0-9][0-9].out                \
                        /tmp/[0-9][0-9][0-9].out           \
                        /tmp/[0-9][0-9][0-9][0-9].out      \
                         /tmp/[0-9][0-9][0-9][0-9][0-9].out ; do
                   if [ -f "$f" ] ; then              # avoid the no match case
                       PID=$(basename $f .out)
                       if [ ! -d "/proc/$PID" ] ; then
                           rm -f $f
                       fi
                   fi
               done
           done) &
           CLEANER=$!

	   wait $LEOS	# Allows SIGTERM signal to propagate to leos via trap.
	   ES=$?
	   kill $CLEANER
#       fi
       suckupKrn	# Check for respawn changes while leos was running.
       if [ $KRN_RESPAWN != "enable" ]; then
	   rm -f $STARTFILE $RUNFILE $STATEFILE
	   exit $ES
       fi

       if [ $ES -ne 0 ]	# Post-mortem time...
       then		# Died abnormally, or never even ran.
	   if [ ! -r $STARTFILE -a  ! -r $RUNFILE ]
	   then		# Died very early, before config.
#	       flipBank
	       reboot	# To (presumably) alternate flash bank.
	   elif [ -r $STARTFILE ]
	   then		# Died during config.
	       if [ $STATE = '1' ]
	       then	# Already tried with no config file?
		   reboot # To (presumably) alternate flash bank.
	       else	# Try next time with no config file.
		   echo -n 1 >$STATEFILE
	       fi
	   else		# Died after running 1+ minutes, back to normal.
	       echo -n 0 >$STATEFILE
	   fi
       else		# Ran successfully, back to normal.
	   echo -n 0 >$STATEFILE
       fi
   else			# Non-flash, or non-respawn.  Just run leos.
       rm -f $STATEFILE
       exec $LEOS_PATH $DEBUG -s
   fi
else
    echo `date` $LEOS_PATH: No such file >> $LOGFILE
    sleep 5
fi
