#! /bin/sh
#
# Copyright 2000-2002 Sun Microsystems, Inc.  All rights reserved.
# Use is subject to license terms. 
#
# @version "@(#)startfabric.sh 1.25     02/02/01 SMI"
#
# This script is responsible for invoking the fabric manager.
#

#USER=`id | /usr/bin/awk -F'[()]' '{print $2}'`
#if [ "$USER" != "root" ]; then
#    echo "Error: user \"$USER\" must be root to run ${0}"
#    exit 1
#fi

USAGE="Usage: ${0} [ -p rmi_port ] \n\t[ [ -i [ config_file ] ] | [ -r [ [ config_file ] | \n\t [ scname:domain, switch_name, scname:domain ...  ] ] ] | [ -v ] ]  \n\t[ -t proxy_port ] { fabric_name }\n"

# Must specify at least a fabric name
if [ $# -lt 1 ]; then
    echo $USAGE
    exit 1
fi

# Save original arguments and initialize variables
OLD_ARGS=$@
FABRIC_NAME=""
INITRESETVER=""
ENGINEERCMDS=""
CONFIG_FILE=""
RESETNODES=""

# Find the RMI port parameter if it is specified else use the default
# port number
RMI_PORT=1099
PROXY_PORT=6789

# FM flags.
RESET_FLAG="-reset"
INIT_FLAG="-init"
VERIFY_FLAG="-verify"
CFG_FILE_FLAG="-config_file"
NODES_FLAG="-nodes"

while [ $# -gt 0 ]
do
#echo "debug processing "$*
    if [ $1 = "-p" -o $1 = "--port" ]; then
        if [ -n "$2" ]; then
            RMI_PORT=$2
            echo "RMI port set to ${RMI_PORT}"
            shift
        else
            echo "Error, must specify an RMI port"
        fi
    elif [ $1 = "-t" -o $1 = "--proxyport" ]; then
        if [ -n "$2" ]; then
            PROXY_PORT=$2
            echo "proxy port set to ${PROXY_PORT}"
            shift
        else
            echo "Error, must specify an proxy port"
        fi
    elif [ $1 = "-h" -o $1 = "--help" ]; then
        echo $USAGE
        exit 1
    elif [ $1 = "-i" -o $1 = "--init" ]; then
	INITRESETVER=${INIT_FLAG}
	if [ -n "$2" ]; then
	    if [ -f "$2" ]; then
		CONFIG_FILE="$2"
		echo "Config File set to ${CONFIG_FILE}"
		shift
	    fi
        fi
    elif [ $1 = "-r" -o $1 = "--reset" ]; then
        INITRESETVER=${RESET_FLAG}
	if [ -n "$2" ]; then
	    if [ -f "$2" ]; then
		CONFIG_FILE="$2"
		echo "Config File set to ${CONFIG_FILE}"
		shift
	    else
		tst=`echo $2 | nawk '/^[-]/{print $1}'`
		# If the next parameter is not specified or is not a value 
		# then skip the nodes.
		if [ -n "$2" -a -z "$tst" ]; then
		    shift

		    # Check for node and switch values making sure that the
		    # fabric name is not included.
		    while [ $# -gt 1 ]; do
			tst=`echo $1 | nawk '/^[-]/{print $1}'`
			if [ -z "$tst" ]; then
			    RESETNODES="${RESETNODES} $1"
			    shift
			else
			    break
			fi
		    done

		    if [ -n "${RESETNODES}" ]; then
			echo "Reset Nodes set to:${RESETNODES}"
			RESETNODES="${NODES_FLAG} ${RESETNODES}"
		    fi
		    SETRNODES=y
		fi
	    fi
        fi
    elif [ $1 = "-v" -o $1 = "--verify" ]; then
        INITRESETVER=${VERIFY_FLAG}
    elif [ $1 = "--" ]; then
        if [ -n "$2" ]; then
            FABRIC_NAME=$2
            echo "Fabric name set to ${FABRIC_NAME}"
            shift
        else
            echo "Error, must specify a fabric name"
        fi

# Pass developer only options thru here
    elif [ $1 = "${CFG_FILE_FLAG}" ]; then
        if [ -n "$2" ]; then
            ENGINEERCMDS="${ENGINEERCMDS} $1 $2"
            shift
        fi
    elif [ $1 = "-remove_log" ]; then
        ENGINEERCMDS="${ENGINEERCMDS} $1"
    elif [ $1 = "-log_level" ]; then
        if [ -n "$2" ]; then
            ENGINEERCMDS="${ENGINEERCMDS} $1 $2"
            shift
        fi
    elif [ $1 = "-sc_sim" ]; then
        ENGINEERCMDS="${ENGINEERCMDS} $1"
    elif [ $1 = "-sc_port" ]; then
        if [ -n "$2" ]; then
            ENGINEERCMDS="${ENGINEERCMDS} $1 $2"
            shift
        fi
    elif [ $1 = "-sc_lkup_name" ]; then
        if [ -n "$2" ]; then
            ENGINEERCMDS="${ENGINEERCMDS} $1 $2"
            shift
        fi
    elif [ $1 = "-proxy_sim" ]; then
        ENGINEERCMDS="${ENGINEERCMDS} $1"
    elif [ $1 = "-proxy_lkup_name" ]; then
        if [ -n "$2" ]; then
            ENGINEERCMDS="${ENGINEERCMDS} $1 $2"
            shift
        fi
    elif [ $1 = "-switch_sim" ]; then
        ENGINEERCMDS="${ENGINEERCMDS} $1"
    elif [ $1 = "-switch_port" ]; then
        if [ -n "$2" ]; then
            ENGINEERCMDS="${ENGINEERCMDS} $1 $2"
            shift
        fi
    elif [ $1 = "-switch_lkup_name" ]; then
        if [ -n "$2" ]; then
            ENGINEERCMDS="${ENGINEERCMDS} $1 $2"
            shift
        fi
    elif [ $1 = "-sim_fm_node_id" ]; then
        ENGINEERCMDS="${ENGINEERCMDS} $1"

    else
        FABRIC_NAME=$1
        echo "Fabric Name set to ${FABRIC_NAME}"
    fi
    # Shift the parameter for all options other than reset nodes.
    if [ -z "$SETRNODES" ]; then
	shift
    else
	SETRNODES=""
    fi
done

# Check that the fabric name was set
if [ -z "${FABRIC_NAME}" ]; then
    echo "Fabric name must be specified"
    echo $USAGE
    exit 1
fi

# Data directory flag so we can pass the constructed data directory to the FM.
# The FM must receive a data directory, which will be constructed by this script.
DATA_DIR_FLAG="-data_dir"

# The Proxy port must be preceded by this flag.
RMI_PORT_FLAG="-port"

# The Proxy port must be preceded by this flag.
PROXY_PORT_FLAG="-proxy_port"

# The FM expects this flag in front of the fabric name.
FABRIC_NAME_FLAG="-fname"

# The name of the fabric Manager class that contains the invocation
# entry point.  This is how an instance of the fabric manager process
# is found (grep for this string).
FM_APP="com.sun.wildcat.fabric_management.wcfm.FabricManager"

# Name of the file containing the FM data directory.  This is the directory
# where all FM fabric's will store their log files and config files.  Normally
# this directory will be set by the user at package install.  The directory
# will be written to a predefined  location in the FM installation tree so
# scripts that access fabric data will know where it is.
DATA_DIR_FILENAME="wcfm_base_data_dir.cfg"

# Fabric policy file extension
POLICY_FILE_EXT=".policy"

# XML file extension
XML_FILE_EXT=".xml"

# Relative paths to fabric cfg and log data
LOG_AND_CONFIG_DIR="config"
LOG_DIR="log"
CONFIG_DIR="cfg"
BINARY_DIR="bin"

# Assume we are running the script with an installed FM package.
FM_JAR="wcfm.jar"
CLASSES=classes
FM_PKG=SUNWwcfmu
FM_PKG_DIR=SUNWwcfm
FM_BASE_DIR=`/usr/bin/pkgparam ${FM_PKG} BASEDIR`
CLASSES_DIR=${FM_BASE_DIR}/${FM_PKG_DIR}/${CLASSES}
CLASS_LOC=${CLASSES_DIR}/${FM_JAR}:${CLASSES_DIR}/jdom.jar:${CLASSES_DIR}/xerces.jar:${CLASSES_DIR}/sc_shared.jar:${CLASSES_DIR}/wcix_shared.jar:${CLASSES_DIR}/fmproxy.jar:${CLASSES_DIR}/15k.jar

# Construct the fabric data directory as well as the log and cfg directories
# so we can check their existence
FABRIC_DATA_DIR_FILE="${FM_BASE_DIR}/${FM_PKG_DIR}/${LOG_AND_CONFIG_DIR}/${DATA_DIR_FILENAME}"
FM_DATA_DIR=`/usr/bin/cat ${FABRIC_DATA_DIR_FILE}`
FABRIC_BASE_DIR="${FM_DATA_DIR}/${FABRIC_NAME}"
FM_LOG_DIR="${FABRIC_BASE_DIR}/${LOG_DIR}"     
FM_CFG_DIR="${FABRIC_BASE_DIR}/${CONFIG_DIR}" 
CMD_LOG_FILE="start_fabric.log"

####################

# The location of the policy file used to invoke the FM.
POLICY_FILE="${FM_CFG_DIR}/${FABRIC_NAME}${POLICY_FILE_EXT}"

# Ensure that the log directory exists.
if [ ! -d "${FM_LOG_DIR}" ]; then
    echo "Error: the log directory \"${FM_LOG_DIR}\" does not exist"
    echo "Run \"createfabric ${FABRIC_NAME}\" to construct a new fabric"
    exit 1
fi

# Ensure the policy file exists, if it does the fabric cfg directory must
# exist as well.
if [ ! -f "${POLICY_FILE}" ]; then
    echo "Error: the cfg directory \"${FM_CFG_DIR}\" does not exist"
    echo "Run \"createfabric ${FABRIC_NAME}\" to construct a new fabric"
    exit 1
fi

echo "Fabric \"${FABRIC_NAME}\" configured correctly"

# Assume we are running from an installed package
LOG_FILE="${FM_LOG_DIR}/${CMD_LOG_FILE}"
if [ -f  "${LOG_FILE}" ]; then
    /usr/bin/rm ${LOG_FILE}
fi
JAVA_BIN_NV=`/usr/bin/cat ${FM_BASE_DIR}/${FM_PKG_DIR}/${LOG_AND_CONFIG_DIR}/jre_home.cfg | /usr/bin/grep JAVA_BIN | /usr/bin/grep -v \#`
echo "JAVA_BIN_NV = ${JAVA_BIN_NV}" >> ${LOG_FILE}
JAVA_BIN=`echo ${JAVA_BIN_NV} | /usr/bin/cut -d = -f2`
echo "JAVA_BIN = ${JAVA_BIN}" >> ${LOG_FILE}

if [ -n "${JAVA_BIN}" ]; then
	JAVA="${JAVA_BIN}java"
	JAVA_VERSION=`${JAVA} -version 2>&1`
	echo "Using java version: \"${JAVA_VERSION}\"" >> ${LOG_FILE}
else
	echo "ERROR: no valid JVM specified, please specify one in the \"${FM_BASE_DIR}/${FM_PKG_DIR}/${LOG_AND_CONFIG_DIR}/jre_home.cfg\" file"
	exit 1
fi

####################################

# Start the RMI registry.  An attempt will be made to start the RMI
# registry every time a fabric is started.  If an error occurs it will
# be due to the fact that the registry is already running due to the
# starting of a previous fabric or the registry could not be created
# (most likely due to the specified port being in use by another process).
# In either error case, the FM will catch the case and the error will
# be reported to the user.  So the error will be ignored here and all
# output from the rmiregistry invocation will be piped to /dev/null.
#
# The unset CLASSPATH ensures that the registry is started with no
# defined CLASSPATH.  If there is a CLASSPATH set, the registry will attempt
# to find the stub class in the CLASSPATH location first instead of
# using the RMI codebase annotated on the stub class.  This is not a problem
# unless the CLASSPATH contains a copy of the stub class.
unset CLASSPATH
RMI_REGISTRY=${JAVA_BIN}rmiregistry
COMMAND="${RMI_REGISTRY} ${RMI_PORT}"
${COMMAND} 1>/dev/null 2>/dev/null &
echo "RMI registry up and running on port ${RMI_PORT}"
/usr/bin/sleep 2 # small delay to let the registry come up

# Needed to pass the FM application base directory to the FM.
FM_APP_BASE_DIR_FLAG="-base_app_dir"

# Check for the reset command, stopping the fabric if necessary
# and setting up the proper data for the FM to reset with.
if [ -n "${INITRESETVER}" -a "${INITRESETVER}" != "${INIT_FLAG}" ]; then

    # Find the fabric being reset or verified if it exists.
    FABRIC_ALREADY_RUNNING=`/usr/ucb/ps -ww -a -g -x |\
    /usr/bin/fgrep "$FM_APP" |\
    /usr/bin/fgrep "$FABRIC_NAME" |\
    /bin/nawk 'BEGIN {FS = "-fname "} {print $2}' |\
    /bin/nawk 'BEGIN {FS = " -data_dir"} {print $1}'`

    if [ "${FABRIC_NAME}" = "${FABRIC_ALREADY_RUNNING}" ]; then
	FM_BIN_DIR="${FM_BASE_DIR}/${FM_PKG_DIR}/${BINARY_DIR}"
	echo "Stopping Fabric ${FABRIC_NAME} for Reset/Verify"
	"${FM_BIN_DIR}"/stopfabric $FABRIC_NAME
    fi

    if [ "${INITRESETVER}" = "${RESET_FLAG}" ]; then
	echo "Resetting Fabric"
	if [ -z "${CONFIG_FILE}" ]; then
	    FM_XML_FILE="${FM_CFG_DIR}/${FABRIC_NAME}${XML_FILE_EXT}"
	    if [ -f ${FM_XML_FILE} ]; then
		CONFIG_FILE="${FM_XML_FILE}"
	    fi
	fi
    fi
fi

# If a config file has been specified make a copy for the FM to use.
if [ -n "${CONFIG_FILE}" ]; then
    INIT_RESET_EXT="_init_reset.xml"
    INIT_CONFIG="${FM_CFG_DIR}/${FABRIC_NAME}${INIT_RESET_EXT}"
    /usr/bin/cp ${CONFIG_FILE} ${INIT_CONFIG}
    CONFIG_OPT="${CFG_FILE_FLAG} ${INIT_CONFIG}"
fi

# Start the FM.
HOSTNAME=`/usr/bin/uname -n`

# export the load library path, without this code the proxy fails to load the
# appropriate libraries eventhough we pass the $JAVA_LIB to the java runtime.
LIB_DIR=lib
JAVA_LIB=${FM_BASE_DIR}/${FM_PKG_DIR}/${LIB_DIR}
LD_LIBRARY_PATH=$JAVA_LIB
export LD_LIBRARY_PATH

# fabname is now at the end - shift skip over fabric name
echo >> ${LOG_FILE}
COMMAND="${JAVA} -Djava.compiler=NONE -Djava.security.policy=${POLICY_FILE} \
    -Djava.library.path=$JAVA_LIB -classpath ${CLASS_LOC} ${FM_APP} \
    ${FABRIC_NAME_FLAG} ${FABRIC_NAME} ${DATA_DIR_FLAG} ${FM_DATA_DIR} \
    ${FM_APP_BASE_DIR_FLAG} ${FM_BASE_DIR} ${RMI_PORT_FLAG} ${RMI_PORT} \
    ${PROXY_PORT_FLAG} ${PROXY_PORT} ${INITRESETVER} ${CONFIG_OPT} \
    ${RESETNODES} ${ENGINEERCMDS}"
echo "${COMMAND}" >> ${LOG_FILE}
echo >> ${LOG_FILE}

${COMMAND} &
echo "SunFireLink Manager Started"
exit 0
