#!/bin/sh
#
#
#ident "@(#)smcwebserver.solaris	1.7 10/03/31 SMI"
# Copyright (c) 2006, 2011, Oracle and/or its affiliates. All rights reserved.

# Console start and stop command for Solaris that interfaces
# to the Service Management Facility (SMF) on Solaris 10 and up.

# Fixed constants for command script.
CONSOLE_CONF=/etc/webconsole
CONSOLE_PROP=config.properties
DEFAULT_INST=console
VERSION_FILE=version.txt

# SMF service name and roperty names
SERVICE_NAME=system/webconsole
ENABLE_PROP=general/enabled
USER_PROP=options/user
DEBUG_PROP=options/debug
LOCAL_PROP=options/local

# Command line options
INST_FLAG_SHORT="-i"
INST_FLAG_LONG="--instance"
USER_FLAG_SHORT="-u"
USER_FLAG_LONG="--user"
LOCAL_FLAG_LONG="--local"
DEBUG_FLAG_LONG="--debug"

# Values determined from command line arguments.
FMRI=""
SUBCMD=""
INSTANCE=""
USERNAME=""
LOCAL=false
DEBUG=false

# Status information from SMF service
STATE=""
STATUS=""

# Wait times for status change in seconds
# Overall wait time should match service timeout
WAIT_TIME=180
WAIT_TIME_STOP=30
WAIT_INIT=3
WAIT_INCR=1

# Information messages
PROD_NAME="Oracle Java(TM) Web Console"

# Relocation - indicates running in a bundled package script
# during Solaris installation or diskless client installation.
# Return an error and exit.
if [ -n "$PKG_INSTALL_ROOT" -a "$PKG_INSTALL_ROOT" != "/" ]; then
    echo "Cannot execute command in this package installation" 1>&2
    exit 1
fi

########################################
# Function to parse command line arguments
#   Subcommand name has already been parsed
#   Returns values in global variables
########################################
parseArguments() {

    while [ $# -gt 0 ]; do
	if [ "$1" = "${INST_FLAG_SHORT}" -o \
	     "$1" = "${INST_FLAG_LONG}" ]; then
	    shift 1
	    INSTANCE="$1"
	    shift 1
	    continue
	fi
	if [ "$1" = "${USER_FLAG_SHORT}" -o \
	     "$1" = "${USER_FLAG_LONG}" ]; then
	    shift 1
	    USERNAME="$1"
	    shift 1
	    continue
	fi
	if [ "$1" = "${DEBUG_FLAG_SHORT}" -o \
	     "$1" = "${DEBUG_FLAG_LONG}" ]; then
	    DEBUG=true
	    shift 1
	    continue
	fi
	if [ "$1" = "${LOCAL_FLAG_SHORT}" -o \
	     "$1" = "${LOCAL_FLAG_LONG}" ]; then
	    LOCAL=true
	    shift 1
	    continue
	fi
	shift 1
    done

    # Use default instance if no -i option specified.
    if [ "${INSTANCE}" = "" ]; then
	INSTANCE=${DEFAULT_INST}
    fi
}


########################################
# Function to get the service runtime status
#   Status is returned in STATUS global variable
########################################
getServiceStatus() {

    STATUS="transient"
    temp=`/bin/svcs -H ${FMRI}`
    if [ $? -ne 0 ]; then
        echo "Console instance \"${INSTANCE}\" is not an SMF service." 1>&2
        exit 1
    fi
    temp=`echo "${temp}" | /usr/bin/cut -f1 -d" "`
    if [ "${temp}" = "online" -o "${temp}" = "ONLINE" ]; then
	STATUS="running"
    fi
    if [ "${temp}" = "disabled" -o "${temp}" = "DISABLED" ]; then
	STATUS="stopped"
    fi
    if [ "${temp}" = "maintenance" -o "${temp}" = "MAINTENANCE" ]; then
	STATUS="repair"
    fi

}

########################################
# Function to get the service enabled state
#   State is returned in STATE global variable
########################################
getServiceState() {

    STATE="disabled"
    # Get state from current values set.
    temp=`/usr/bin/svcprop -C -p ${ENABLE_PROP} ${FMRI}`
    if [ $? -ne 0 ]; then
        echo "Unable to obtain service enabled state" 1>&2
        exit 1
    fi
    if [ "${temp}" = "true" -o "${temp}" = "TRUE" ]; then
	STATE="enabled"
    fi

}

########################################
# Function to set the service properties
########################################
setServiceProperties() {

    stat=0
    if [ "${USERNAME}" != "" ]; then
	/usr/sbin/svccfg -s ${FMRI} setprop ${USER_PROP} = "${USERNAME}"
	stat=$?
    fi
    if [ $stat -eq 0 ]; then
	/usr/sbin/svccfg -s ${FMRI} setprop ${DEBUG_PROP} = boolean: "${DEBUG}"
	stat=$?
    fi
    if [ $stat -eq 0 ]; then
	/usr/sbin/svccfg -s ${FMRI} setprop ${LOCAL_PROP} = boolean: "${LOCAL}"
	stat=$?
    fi
    if [ $stat -ne 0 ]; then
        echo "Unable to set command argument properties in SMF service." 1>&2
        exit 1
    fi

}

########################################
# Function to wait for service status change
#   $1 - Service status to wait for: running or stopped
#   Overwrites STATUS global variable
########################################
waitServiceStatus() {

    endstate=$1
    timer=0
    interval=$WAIT_INIT
    while [ $timer -lt $WAIT_TIME ]; do
	# Sleep first to give restarter time to react
	sleep $interval
	getServiceStatus
	if [ "${STATUS}" = "${endstate}" -o "${STATUS}" = "repair" ]; then
	    break;
	fi
	timer=`(expr $timer + $interval)`
	interval=$WAIT_INCR
    done

}

########################################
# Function to start the service instance
########################################
startService() {

    getServiceState
    setServiceProperties

    # if service is disabled, enable only in current boot session.
    OPT=""
    if [ "${STATE}" = "disabled" ]; then
	OPT="-t"
    fi
    /usr/sbin/svcadm enable ${OPT} ${FMRI}

    # Wait while service starts up and report its status.
    waitServiceStatus "running"
    if [ "${STATUS}" != "running" ]; then
	temp=`/usr/bin/svcprop -p restarter/logfile ${FMRI}`
	echo "Cannot determine if console service is running." 1>&2
	echo "Check log file: ${temp}" 1>&2
	echo "Run \"svcs ${FMRI}\" to determine its status." 1>&2
	exit 1
    fi

}

########################################
# Function to stop the service instance
########################################
stopService() {

    # We always execute a stop, even if the service is not running.
    getServiceState
    setServiceProperties

    # If service is enabled, disable only in current boot session.
    OPT=""
    if [ "${STATE}" = "enabled" ]; then
	OPT="-t"
    fi
    /usr/sbin/svcadm disable ${OPT} ${FMRI}

    # Wait while service shuts down and report its status.
    waitServiceStatus "stopped"
    if [ "${STATUS}" != "stopped" ]; then
	temp=`/usr/bin/svcprop -p restarter/logfile ${FMRI}`
	echo "Cannot determine if console service is stopped." 1>&2
	echo "Check log file: ${temp}" 1>&2
	echo "Run \"svcs ${FMRI}\" to determine its status." 1>&2
	exit 1
    fi

}

################################################################################
#
# validateUID
#
# ensure the uid given exists
#
# $1 user id
#
################################################################################
validateUID() {
    # place in a meaningful name
    userid=$1
    
    id ${userid} > /dev/null 2>&1

    if [ $? -ne 0 ];then
	echo " "
	echo "The user id ${userid} is not valid"
	echo " "
	exit 1
    fi
}

########################################
## main ##
########################################

# user must be root
USERID=`id | sed -e 's/uid=\([0-9]*\).*/\1/'`
if [ $USERID -ne 0 ]; then
    echo "You must be the system's root user to manage the server." 1>&2
    exit 1
fi

# Get the subcommand and save the command line arguments.
# Must have at least a subcommand.
if [ $# -eq 0 ]; then
    echo "Invalid command syntax - must specify a subcommand." 1>&2
    exit 1
fi
SUBCMD=$1
shift 1
args=$*

# Parse the command line and get the instance name.
# Source the config.properties for the instance.
parseArguments ${args}

conf_file=${CONSOLE_CONF}/${INSTANCE}/config.properties
if [ ! -f ${conf_file} ]; then
    echo "Console instance \"${INSTANCE}\" does not exist." 1>&2
    exit 1
fi
. ${conf_file}

# if USERNAME is not empty make sure it is a valid id
if [ -n "${USERNAME}" ]; then
    validateUID ${USERNAME}
fi

VERS=""
vers_file="${console_home}/${VERSION_FILE}"
if [ -f ${vers_file} ]; then
    temp=`cat ${vers_file}`
    VERS="Version ${temp} ..."
fi
 
# Check for OS release supporting SMF service.
# If not, pass command handling to private script.
OS=`/usr/bin/uname -r`
if [ "${OS}" = "5.8" -o "${OS}" = "5.9" ]; then
    ${console_home}/private/bin/sjwcx ${SUBCMD} ${args}
    exit $?
fi

# For S10 and up systems, we use the SMF service.
# Set service instance FMRI name equal to console instance name.
FMRI="${SERVICE_NAME}:${INSTANCE}"

# Process the subcommand.
case "${SUBCMD}" in

    "start" )

	# Get service runtime status.
	# Exit if already running or in maintenance state.
	getServiceStatus
	if [ "${STATUS}" = "running" ]; then
	    echo "Console service is already running"
	    exit 0
	fi
	if [ "${STATUS}" = "repair" ]; then
	    echo "Console service cannot be started." 1>&2
	    echo "Run \"svcadm clear ${FMRI}\" to repair." 1>&2
	    exit 1
	fi

	echo "Starting ${PROD_NAME} ${VERS}"
	startService
	echo "The console is running"
	stat=0
    ;;

    "stop" )

	# Get service runtime status.
	getServiceStatus
	if [ "${STATUS}" = "stopped" ]; then
	    echo "Console service is already stopped"
	    exit 0
	fi

	# We always stop no matter what current status is.
	echo "Shutting down ${PROD_NAME} ${VERS}"
	stopService
	echo "The console is stopped"
	stat=0
    ;;

    "restart" )

	# Get service runtime status.  Exit if in maintenance state.
	# We implement restart as a stop followed by a start.
	getServiceStatus
	if [ "${STATUS}" = "repair" ]; then
	    echo "Console service cannot be restarted." 1>&2
	    echo "Run \"svcadm clear ${FMRI}\" to repair." 1>&2
	    exit 1
	fi
	echo "Restarting ${PROD_NAME} ${VERS}"
	if [ "${STATUS}" != "stopped" ]; then
	    stopService
	fi
	startService
	echo "The console is running"
	stat=0
    ;;

    "enable" )

	# Check if already enabled.  If not, enable for next boot.
	getServiceState
	if [ "${STATE}" = "enabled" ]; then
	    exit 0
	fi
	# Set disabled for current boot session so setting
	# enabled property takes affect next boot.
	getServiceStatus
	if [ "${STATUS}" = "stopped" ]; then
	    /usr/sbin/svcadm disable -t ${FMRI}
	fi
	/usr/sbin/svccfg -s ${FMRI} setprop ${ENABLE_PROP} = true
	stat=$?
    ;;

    "disable" )

	# Check if already disabled.  If not, disable for next boot.
	getServiceState
	if [ "${STATE}" = "disabled" ]; then
	    exit 0
	fi
	# Set enabled for current boot session so resetting
	# enabled property takes affect next boot.
	getServiceStatus
	if [ "${STATUS}" = "running" ]; then
	    /usr/sbin/svcadm enable -t ${FMRI}
	fi
	/usr/sbin/svccfg -s ${FMRI} setprop ${ENABLE_PROP} = false
	stat=$?
    ;;

    *)

	# Not one of our handled subcommands, just pass to executable.
	${console_home}/private/bin/sjwcx ${SUBCMD} ${args}
	stat=$?
    ;;

esac

exit $stat
