#!/bin/sh

source /ciena/scripts/saos_utils.sh
source /ciena/scripts/kernel_arg.sh

KRN_CONF=/mnt/sysfs/system/krn.conf
LEOS_USER_FIFO=/tmp/fifo/mon/saos

if [ -f $KRN_CONF ]; then
    . $KRN_CONF
fi

if [ -z "$KRN_MODE" ]; then KRN_MODE=normal; fi
if [ -z "$KRN_CONSOLE" ]; then KRN_CONSOLE=normal; fi
if [ -z "$KRN_AUTO" ]; then KRN_AUTO=enable; fi
if [ -z "$KRN_RESPAWN" ]; then KRN_RESPAWN=enable; fi

nosaos=$(kernel_arg nosaos 1)
if [ "$?" -eq "0" ]; then
    KRN_MODE=debug;
    KRN_CONSOLE=debug;
    KRN_AUTO=disable;
    KRN_RESPAWN=disable;
    nosaos=enabled
fi

stopKrn()
{
    echo "$0: sending stop opcode to $LEOS_USER_FIFO..."
    echo -n 2 > $LEOS_USER_FIFO
}

startKrn()
{
    if $(saos_server_running) ; then
	echo "SAOS appears to already be running";
    else
	echo "$0: sending start opcode to $LEOS_USER_FIFO..."
	echo -n 1 > $LEOS_USER_FIFO
    fi
}

getChoice()
{
    echo -n "$1 [$2] "
    read choice
    case $choice in
    "")
        choice=$2
        return
    ;;
    *)
        for opt in $@; do
            if [ "$opt" = "$choice" ]; then return; fi
        done
        echo "Invalid option: $choice"
        exit 1
    ;;
    esac
}

# Forward collected settings to anyplace that needs them immediately.

propagate()
{
    $0 respawn $KRN_RESPAWN

    if [ $KRN_CONSOLE = "debug" ]; then
	$(param_cmd swrite 9 1)
    else
	$(param_cmd swrite 9 0)
    fi
}

echo_nosaos_warning()
{
    if [ -n "$nosaos" ] ; then
        echo
        echo "WARNING: nosaos was specified on the kernel command line by the"
        echo "         the boot loader; local settings are ignored."
        echo
    fi
}

case "$1" in
set)
    echo_nosaos_warning

    stty icrnl		# Just in case!
    echo "Configure kernel parameters."
    echo "Press <RETURN> for default values, if any."

    getChoice "Kernel Mode (normal,debug) :" $KRN_MODE normal debug
    KRN_MODE=$choice

    getChoice "Serial Port (normal,debug) :" $KRN_CONSOLE normal debug
    KRN_CONSOLE=$choice

    getChoice "AutoStart (enable,disable) :" $KRN_AUTO enable disable
    KRN_AUTO=$choice

    getChoice "Respawn (enable,disable)   :" $KRN_RESPAWN enable disable
    KRN_RESPAWN=$choice

    echo "KRN_MODE=$KRN_MODE" > $KRN_CONF
    echo "KRN_CONSOLE=$KRN_CONSOLE" >> $KRN_CONF
    echo "KRN_AUTO=$KRN_AUTO" >> $KRN_CONF
    echo "KRN_RESPAWN=$KRN_RESPAWN" >> $KRN_CONF
    propagate

    echo_nosaos_warning
;;

show)
    echo "Kernel Mode: $KRN_MODE"
    echo "Serial Port: $KRN_CONSOLE"
    echo "AutoStart  : $KRN_AUTO"
    echo "Respawn    : $KRN_RESPAWN"
;;

# start|stop|kill notes:
#	The monitor process accepts single-character (ASCII) opcodes
#	over a named-pipe.  The pipes are:
#		leos = /tmp/fifo/mon/leos
#
#	The opcodes are:
#		OPCODE	| action		| notes
#		---------------------------------------------------------------
#		0	| kill			| sends SIGKILL
#		1	| start			| launches program
#		2	| stop			| sends SIGTERM
#		3*	| respawn enable	| enable respawn on child death
#		4	| respawn disable	| disable respawn on child death
#
#	* default
kill)
    if [ "$KRN_RESPAWN" = "enable" ]; then
        OPSTRING=403
    else
        OPSTRING=0
    fi
    echo "$0: sending kill opstring $OPSTRING to $LEOS_USER_FIFO..."
    echo -n $OPSTRING > $LEOS_USER_FIFO
;;
restart)
    stopKrn
    startKrn
;;
start)
    startKrn
;;
stop)
    stopKrn
;;
res|respawn)
    case "$2" in
    en|enable|on)
	echo $0: sending respawn $2 opcode to $LEOS_USER_FIFO...
    	echo -n 3 > $LEOS_USER_FIFO
    ;;
    dis|disable|off)
        echo $0: sending respawn $2 opcode to $LEOS_USER_FIFO...
    	echo -n 4 > $LEOS_USER_FIFO
    ;;
    *)
    	echo "invalid argument: $2"
	exit 1
    ;;
    esac
;;
debug)
    FIREWALL_CRACK="INPUT -p tcp --dport 2159 -j ACCEPT"

    case "$2" in
    on)
	if pidof gdbserver >/dev/null ; then
	    echo "Debug process already running, use \"krn debug off\"."
	    exit 1
	fi

	if ! $(saos_server_running) ; then
	    echo "Unable to find running leos server process!"
	    exit 1
	fi

	if ! iptables -C ${FIREWALL_CRACK} 2>/dev/null; then
	    # Gotta open up the firewall too.
	    iptables -A ${FIREWALL_CRACK}
	fi

	echo "Creating debug process..."
	/usr/bin/gdbserver localhost:2159 --attach $(saos_server_pid) &
    ;;
    off)
	if killall -9 gdbserver 2>/dev/null ; then
	    echo "Removing gdbserver debug process..."
	else
	    echo "Debug process gdbserver not running."
	fi

	if iptables -C ${FIREWALL_CRACK} 2>/dev/null; then
	    # Close the firewall
	    iptables -D ${FIREWALL_CRACK}
	fi
    ;;
    *)
	echo "invalid argument: \"$2\""
        echo "Usage: $(basename $0) $1 <on|off>"
	exit 1
    ;;
    esac
;;
getenv)
;;
*)
    echo "Kernel Executive Shell Commands"
    echo "================================================================================"
    echo "krn debug on|off              | enable/disable debug server"
    echo "krn kill                      | kill SAOS server"
    echo "krn restart                   | do stop followed by start"
    echo "krn set                       | configure kernel executive behavior"
    echo "krn show                      | show kernel executive configuration"
    echo "krn start                     | start SAOS server"
    echo "krn stop                      | graceful shutdown of SAOS server"
;;
esac
