#!/usr/bin/sh
#Copyright 09/02/98 Sun Microsystems, Inc. All rights reserved.
#pragma ident "@(#)em_services	1.163 98/09/02 Sun Microsystems"
#

###############################################################################
# em_services
###############################################################################
#
# Start/stop Solstice EM MIS services.
#
###############################################################################

###############################################################################
# errmsg
###############################################################################
#
# Echo arguments.
#
###############################################################################

errmsg()
{
    if [ "$1" = "-n" ] ; then
	shift
	gettext em_services "$*"		# no newline
    else
	gettext em_services "$*\\n"
    fi
}

###############################################################################
# Environment
###############################################################################
#
# Set up the environment.
#
###############################################################################

trap 'errmsg "\\nem_services terminated."; exit 1' 1 3 15
trap 'interrupt' 2

#
# To debug, switch the shell to ksh and uncomment out the following.
#
# single_step()
# {
#     echo "${PS2}\c"
#     read
# }
# 
# set -x
# trap 'single_step' DEBUG

umask 002					# make it something sane

#
# Set local variables.  These variables control the behavior of em_services.
#

#
# Required diskspace for $EM_RUNTIME in KB.  If $EM_RUNTIME doesn't have
# this much free space, the database won't be created.  To change, run
# em_services init to get a virgin database then run du -sk $EM_RUNTIME
# to see what the minimum required diskspace is.
#

required_diskspace=73000

#
# If $EM_RUNTIME has a capacity >= diskspace_threshold, a warning is
# generated.  diskspace_threshold is the percentage free.
#

diskspace_threshold=98

#
# This variable controls the amount of time em_services will wait for the
# MPAs to finish initializing.  The unit is seconds.
# If 0 is specified, it means wait forever.
#

mpa_timeout=0


#
# Set environment variables.
#

SYSTEMID=`/usr/bin/uname -n`; export SYSTEMID
EM_HOME=/opt/SUNWconn/em; export EM_HOME
EM_MIS_HOME=/opt/SUNWconn/em; export EM_MIS_HOME
EM_LOGIN_SERVER_PORT=5561; export EM_LOGIN_SERVER_PORT
EM_RUNTIME=/var/opt/SUNWconn/em; export EM_RUNTIME
OPENWINHOME="${OPENWINHOME:-/usr/openwin}"; export OPENWINHOME
RESTARTDIR=$EM_HOME/install/em_platform

#
# Make sure the daemons started by em_services connect to the MIS we start.
# The user may have EM_SERVER set to another host.
#

EM_SERVER=$SYSTEMID; export EM_SERVER

#
# work from EM_HOME
#

if [ -d $EM_HOME ]; then
    cd $EM_HOME 
fi

#
# Figure out which database we're using.
#

if [ -f $EM_RUNTIME/conf/EM-config ]; then

    if [ -z "$EM_DB_SERVER_TYPE" ] ; then
        found=`grep -s EM_DB_SERVER_TYPE $EM_RUNTIME/conf/EM-config`
        EM_DB_SERVER_TYPE=`echo $found | sed -e 's/[   ]*EM_DB_SERVER_TYPE[    ]*:[    ]*//'`
    fi

    if [ "$EM_DB_SERVER_TYPE" != "informix" -a \
	 "$EM_DB_SERVER_TYPE" != "DBM" -a \
	 "$EM_DB_SERVER_TYPE" != "OCI" ] ; then
        EM_DB_SERVER_TYPE=informix
    fi
else
    EM_DB_SERVER_TYPE=informix
fi

export EM_DB_SERVER_TYPE 

#
# Load functions specific to the database we're using.
#

# if whitebox; then
#     . ${EM_HOME}/bin/${EM_DB_SERVER_TYPE}/db_services
# elif blackbox; then...

. ${EM_HOME}/bin/db_services

#
# Environment variables required by licensing.
#

#
# set for usage license support
#

TMP_LM_LICENSE_FILE=""
LICENSE_PATH=/etc/opt/licenses
for LICENSE_FILE in $LICENSE_PATH/licenses_combined $LICENSE_PATH/ssp.em.lic* ; do
    if [ -f "$LICENSE_FILE" ]; then
        if [ ! -z "$TMP_LM_LICENSE_FILE" ]; then
            TMP_LM_LICENSE_FILE="$TMP_LM_LICENSE_FILE:$LICENSE_FILE"
        else
            TMP_LM_LICENSE_FILE="$LICENSE_FILE"
        fi
    fi
done

if [ ! -z "$TMP_LM_LICENSE_FILE" ]; then
    LM_LICENSE_FILE=$TMP_LM_LICENSE_FILE:$LM_LICENSE_FILE
fi

export LM_LICENSE_FILE

#
# Paths.
#

PATH=$EM_DB_HOME/bin:$EM_HOME/bin:$EM_HOME/etc:/bin:/usr/bin:/usr/ucb:$PATH
export PATH


LD_LIBRARY_PATH=$EM_MIS_HOME/lib:$EM_DB_HOME/lib:$EM_DB_HOME/lib/esql:$LD_LIBRARY_PATH:/usr/openwin/lib
export LD_LIBRARY_PATH

SHLIB_PATH=$LD_LIBRARY_PATH; export SHLIB_PATH


###############################################################################
# interrupt  
###############################################################################
#
# When the user interrupts em_services, ask him what he wants to do.
#
###############################################################################

interrupt()
{
    errmsg '\n\nem_services interrupted.  What would you like to do?\n'
    errmsg '	c	continue'
    errmsg '	d <opt>	start em_debug with options <opt> and continue'
    errmsg '	q	quit without changing state (default)'
    errmsg '	s	stop all EM processes and quit'
    errmsg -n '\n> '
    read answer options

    case "$answer" in
	c) 
	    errmsg 'Continuing...'
	    return
	    ;;

	d)
	    errmsg -n "Starting em_debug "
	    errmsg "$options..."
	    eval em_debug $options &
	    return
	    ;;

	s)
	    errmsg 'Shutting down EM...'
	    kill_procs -HUP
	    exit 2
	    ;;

	*)
	    errmsg 'Quitting...'
	    exit 2
	    ;;
    esac
}



###############################################################################
# info  
###############################################################################
#
# Echo the arguments only if the -q option hasn't been given. All errors 
# should be displayed using echo.  Use info only for informative messages.
#
###############################################################################

info() 
{
    if [ "$1" = "-n" ] ; then
	shift
	gettext em_services "$*" > $display_device 2>&1		# no newline
    else
	gettext em_services "$*\\n" > $display_device 2>&1
    fi
}



###############################################################################
# debugmsg  
###############################################################################
#
# Echo the arguments only if the -d option hasn't been given. 
#
###############################################################################

debugmsg()
{
    if [ "$1" = "-n" ] ; then
	shift
	gettext em_services "$*" > $debug_device 2>&1	# no newline
    else
	gettext em_services "$*\\n" > $debug_device 2>&1
    fi
}


###############################################################################
# progress
###############################################################################
#
# Mark the passage of time to convince the user we haven't really hung at all.
#
###############################################################################

progress()
{
    if [ "$quiet" = TRUE -o "$debug" = TRUE ] ; then
	return
    fi

    progress_counter=`expr $progress_counter + 1`   
    position=`expr $progress_counter % 4`

    if [ $position -eq 0 ] ; then
	echo '|\b\c'
    elif [ $position -eq 1 ] ; then
	echo '/\b\c'
    elif [ $position -eq 2 ] ; then
	echo '-\b\c'
    else
	echo '\\\b\c'
    fi
}


###############################################################################
# ask_confirm
###############################################################################
#
# Prompt the user with $1.  If they answer anything other than 'y', echo $2 
# and exit.  Note that a -f on the command line is equivalent to automatically
# answering 'y' to all questions.
#
###############################################################################

ask_confirm() 
{
    if [ $force = TRUE ] ; then			# don't bother asking
	return
    fi

    if [ -z "$1" ] ; then
	errmsg -n 'Do you really want to do this (y/n)? '	
    else
	errmsg -n "$1 "
    fi

    read answer

    if [ "$answer" != "y" ] && [ "$answer" != "Y" ] ; then
	if [ -z "$2" ]; then
	    errmsg "No action has been taken."
	else
	    errmsg "$2"
	fi
	exit 1
    fi
}


###############################################################################
# start_purged
###############################################################################
#
# Start the purge daemon if the user so wishes.  This can be a performance
# burden, so you may not wish to always start it.
#
###############################################################################

start_purged()
{
    if [ -f $EM_RUNTIME/conf/EM-config ]; then
	if [ -z "$EM_ENABLEPURGE" ] ; then
	    found=`grep -s EM_ENABLEPURGE $EM_RUNTIME/conf/EM-config`
	    EM_ENABLEPURGE=`echo $found | sed -e 's/[   ]*EM_ENABLEPURGE[    ]*:[    ]*//'`
	fi

	if [ "$EM_ENABLEPURGE" = "TRUE" ] ; then
	    info "Starting em_purged..."
	    em_purged&
	fi
    fi
}



###############################################################################
# getpid
###############################################################################
#
# Return the pid(s) of the processes with the given name.  A null string is
# returned if the process isn't running.
#
###############################################################################

getpid()
{
    short_daemon=`echo $1 | cut -b-8`
    ps -e | grep "$short_daemon\$" | sed -e 's/^  *//' -e 's/ .*//'
}



###############################################################################
# kill_procs
###############################################################################
#
# Kill all the EM daemons.
#
###############################################################################

kill_procs() 
{
    info "Terminating daemons..."
    progress

    for daemon in em_login em_ncam em_mis em_snmp-trap em_snmfwd em_autod \
	        em_datad em_nnmpa em_dmuxd em_log2hist em_log em_autoexd \
		em_cmip em_purged
    do
	pid=`getpid $daemon`
    
        for p in $pid ; do
            debugmsg -n "Terminating "
	    debugmsg "$daemon: PID=$p "
	    progress
	    kill $1  $p > $debug_device 2>&1
        done
    done

    progress
    rm -f /tmp/sysmgr.pids /tmp/dmuxd.pid

    if pkginfo -q SUNWemipa ; then
	/etc/rc2.d/S98ipmpa stop > $debug_device 2>&1
    fi

    progress

    if pkginfo -q SUNWsnmag ; then
  	snm_kill -A > $debug_device
    fi

    progress

    kill_database $1
    progress

    # Wait for all the processes to die before exiting the shell
    # If any process is alive wait for 2 seconds before resuming
    # existance check

    info "Waiting..."

    process_is_alive=1
    while [ $process_is_alive -eq 1 ]
    do
        process_is_alive=0
        # Assumption : All the processes checked in this loop donot restart
        # after dying
        for daemon in em_login em_ncam em_mis em_snmp-trap em_snmfwd em_autod \
                em_datad em_nnmpa em_dmuxd em_log2hist em_log em_autoexd \
                em_purged
        do
            pid=`getpid $daemon`
            if [ -n ""$pid ] ; then
                process_is_alive=1
                progress
                break
        fi
        done
        sleep 2
    done

    info "Done"

}


###############################################################################
# stat_procs
###############################################################################
#
# Display the process status.
#
###############################################################################

stat_procs() 
{
    for daemon in em_login em_ncam em_mis em_snmp-trap em_snmfwd em_autod \
	          em_datad em_nnmpa em_dmuxd em_mpa_snmp em_mpa_rpc \
		  em_log2hist em_log em_autoexd oninit em_cmip \
		  em_purged
    do
	pid=`getpid $daemon`
    
	if [ -z "$pid" ] ; then
           errmsg -n "$daemon:" | awk '{ printf "%-15s ", $1 }'
	   errmsg "not running"
	else
	    for p in $pid ; do
                echo "$daemon:\tPID=$p " | awk '{ printf "%-15s %s\n", $1, $2 }'
	    done
	fi
    done
}


###############################################################################
# drop_dbm
###############################################################################
#
# Delete all the DBM files.
#
###############################################################################

drop_dbm()
{
    rm -rf ${EM_RUNTIME}/data/DBM
    rm -rf ${EM_RUNTIME}/data/LOG
    rm -rf ${EM_RUNTIME}/data/EM.DBM
}


###############################################################################
# reinit_platform
###############################################################################
#
# Reinitialize the platform
#
###############################################################################

reinit_platform()
{
    info "Running reinitialization of platform..."
    progress
    cd $EM_MIS_HOME
    var-install

    if [ $? -ne 0 ] ; then
	errmsg "Reinitialization failed."
	exit 1
    fi

    cd bin
}

###############################################################################
# start_procs
###############################################################################
#
# Start the EM daemons.
#
###############################################################################

start_procs()
{
    info "Starting daemons..."
    mode=$1
    progress

    #
    # Check the diskspace in $EM_RUNTIME.  If it's close to full, put out a
    # warning.  
    #

    capacity=`df -k $EM_RUNTIME | tail -1 | 	
	      awk '{ print substr($5, 0, length($5) - 1) }'`

    if [ "$capacity" -ge "$diskspace_threshold" ] ; then
	errmsg -n "\\nWarning: "
	errmsg -n "$EM_RUNTIME "
	errmsg -n "is "
	errmsg -n "${capacity}% "
	errmsg "full.\\n"
	ask_confirm 'Start Solstice EM (y/n)?' "Solstice EM not started"
	errmsg "\\n"
    fi

    check_runtime $mode

    if [ $mis_installed = TRUE ] ; then
	if [ -x /etc/opt/licenses/lmstat ]; then
	    rm -f /tmp/all_licenses_combined

	    for LM_FILE in `echo $LM_LICENSE_FILE | awk -F: '{print $1 " " $2 " " $3 " " $4 " " $5}'`
	    do
		if [ -n "$LM_FILE" ] && [ -r "$LM_FILE" ]; then
		    cat $LM_FILE >> /tmp/all_licenses_combined
		fi
	    done
	    /etc/opt/licenses/lmstat -i ssp.em.mis -c /tmp/all_licenses_combined | grep ssp.em.mis > $debug_device 2>&1
   	    if [ $? -ne 0 ]; then
		errmsg "A usage license is not available."
		kill_procs -ABRT
		rm -f /tmp/all_licenses_combined
		exit 1
	    fi
	else
	    errmsg "Warning: Unable to verify license, continuing anyway."
	fi

	rm -f /tmp/sysmgr.pids /tmp/dmuxd.pid /tmp/all_licenses_combined

	#
	# In case the database is full, the auto-extend daemon must run
	# before any database app (like the MIS and log server) so it can
	# create another chunk if necessary, otherwise the database app will
	# complain.
	#

	progress
	em_autoexd -config $EM_RUNTIME/conf/em_autoexd.cfg > $debug_device 2>&1
	ret=$?
	while [ $ret -ne 0 ]
	do
		debugmsg "Attempting to restart em_autoexd.."
		sleep 5
		em_autoexd -config $EM_RUNTIME/conf/em_autoexd.cfg > $debug_device 2>&1
		ret=$?
	done
	debugmsg "em_autoexd started successfully."

	progress

	debugmsg "Starting em_ncam..."
	em_ncam&
	progress

	debugmsg "Starting em_mis..."

	#
	# Create the lock file.  When the MIS is done initializing, it'll
	# remove the lock file.
	#

	cp /dev/null /tmp/mis-single-user
	chmod 666    /tmp/mis-single-user

	em_mis -d &
	MIS_PID=$!

	progress

	#
	# To debug the MIS, uncomment the following lines.  When prompted,
	# start the debugger in another window and attach to the MIS, then
	# hit <return> in this window to continue.
	#

	#echo "Start dbx em_mis \c" 
	#getpid em_mis
	#echo "Hit return when ready...\c"
	#read answer

	#
	# Wait for the lock file to be removed.  This tells us the MIS is
	# done initializing.
	#

	while [ -f /tmp/mis-single-user ] ; do
	    ps -p $MIS_PID > /dev/null 2>&1
            if [ $? -ne 0 ]; then
		# mis is not running so we must abort startup
		kill_procs -ABRT
	        
		exit 1
	    fi
	    sleep 5
	    progress
	done

	debugmsg "Starting em_login..."

	#
	# Create the lock file.  When em_login is done initializing, it'll
	# remove the lock file.
	#

	cp /dev/null /tmp/login-not-ready
	chmod 666    /tmp/login-not-ready

	em_login&
	progress

	#
	# Wait for the lock file to be removed.  This tells us em_login is
	# done initializing.
	#

	while [ -f /tmp/login-not-ready ] ; do
	    sleep 5
	    progress
	done

	if [ $mode = "start" ] ; then
	    em_startup $logs_dropped 
	else
	    em_restart 
	fi

	progress

	if [ -x $EM_HOME/bin/em_snmp-trap ] ; then
	    debugmsg "Starting em_snmp-trap..."
	    em_trapd start &
        fi

	progress
	sleep 5

	if pkginfo -q SUNWemipa ; then
	    debugmsg "Starting em_mpa_rpc..."
            debugmsg "Starting em_mpa_snmp..."
	    /etc/rc2.d/S98ipmpa start > $debug_device 2>&1
	fi

	progress 

	if pkginfo -q SUNWsnmag ; then
	    debugmsg "Starting em_snmfwd..."
	    em_snmfwd&
	fi

	if pkginfo -q  SUNWemcpa ; then
	    /etc/rc2.d/S98cmipmpa start	> $debug_device 2>&1
	fi

	debugmsg "Starting em_nnmpa..."
	em_nnmpa&
	progress

	debugmsg "Starting em_datad..."
	em_datad&
	progress

	start_purged
    else					# MIS not installed
        if [ -x $EM_HOME/bin/em_snmp-trap ] ; then
	    debugmsg "Starting em_snmp-trap..."
	    em_trapd start
        fi

	progress

	if pkginfo -q SUNWemipa ; then
            debugmsg "Starting em_mpa_snmp..."
	    debugmsg "Starting em_mpa_rpc..."
	    /etc/rc2.d/S98ipmpa start > $debug_device 2>&1
	fi

    fi
   progress

   if pkginfo -q SUNWemipa ; then
	debugmsg "Waiting for SNMP and RPC MPAs to finish initialization..."
	em_objop -wait $mpa_timeout $RESTARTDIR/mandatory_ip_objects 
   fi

   if [ $mis_installed = TRUE ] ; then
	debugmsg "Starting em_autod..."
	em_autod&
   fi


}



###############################################################################
# usage
###############################################################################
#
# Print a usage message.
#
###############################################################################

usage()
{
    errmsg ""
    errmsg "em_services starts or stops all the necessary processes to run Solstice"
    errmsg "Enterprise Manager."
    errmsg ""
    errmsg "Usage: em_services <command>"
    errmsg ""
    errmsg "<command> instructs em_services what operation to perform:"
    errmsg ""
    errmsg "-abort    abort the MIS daemons immediately"
    errmsg "-debug    enable debugging"
    errmsg "-force    force the command to work without prompting you for confirmation"
    errmsg "-help     this message"
    errmsg "-init     reinitialize the platform"
    errmsg "-quiet    quiet: suppress all output"
    errmsg "-reload   create the data repository and reinitialize the platform"
    errmsg "-start    restart the MIS daemons in the state in which they were last shutdown"
    errmsg "-status   display the status of the MIS daemons"
    errmsg "-stop     stop the MIS daemons"
    errmsg "-version  to display the current version number"
    errmsg ""
    errmsg "-debug, -force, and -quiet only work in conjunction with another option,"
    errmsg 'for example, "em_services -force -stop".'
    errmsg ""
}


###############################################################################
# main
###############################################################################
#
# The main part of this script.
#
###############################################################################

#
# Check if SUNWemmis is installed.
#

if pkginfo -q SUNWemmis.* ; then
    mis_installed=TRUE
else
    mis_installed=FALSE

    if pkginfo -q SUNWemdmn.* ; then
	errmsg "There are no Solstice Enterprise Manager daemons installed."
	errmsg "Nothing to do; exiting."
	exit 1
    fi
fi

#
# Parse command-line arguments
#

quiet=FALSE; export quiet
force=FALSE; export force
debug=FALSE; export debug
progress_counter=0; export progress_counter

display_device=/dev/tty; export display_device
debug_device=/dev/null;  export debug_device

logs_dropped=""			# non-null if the logs have been dropped

#
# In previous versions, no arguments meant to start the MIS.  We're keeping
# this idea for backwards compatability, but the preferred approach is
# em_services start.
#

if [ $# -eq 0 ] ; then
    command="start"
else
    arg=$1
    while [ ! -z "$arg" ] ; do
	case $arg in
	    -abort )
		command=abort
		;;
	    -f | -force )  
		force=TRUE
		;;
	    -q | -quiet )  
		quiet=TRUE
		display_device=/dev/null
		;;
	    -d | -debug )
		debug=TRUE
		debug_device=/dev/tty
		;;
	    -i | -init )
		command=init
		;;
	    -r | -reload )
		command=reload
		;;
	    -s | -stop )
		command=stop
		;;
	    -start )
		command=start
		;;
	    -status )
		command=status
		;;
	    -V | -version )
		errmsg -n "Solstice (TM) Enterprise Manager (TM) "
		cat $EM_HOME/.version
		errmsg ""
		exit 0
		;;
	    -h | -help | * )
		usage
		exit 2
		;;
	esac
	shift 1
	arg=$1
    done
fi

#
# Check if root user.
#

my_uid=`/usr/xpg4/bin/id -u`

if [ $my_uid -ne 0 -a $my_uid -ne $EM_DB_USER_ID ] ; then
    errmsg "You must be the root user to run em_services."
    exit 1
fi

force_create

case $command in
    start) 
	kill_procs -HUP
        start_procs restart
	;;

    init)     
	if [ $force = FALSE -a $quiet = FALSE -a \
	     -f $EM_RUNTIME/data/db/rootdbs1 ]; then
	    ask_confirm 'Warning: All current MIS information will be lost.\nDo you want to continue (y/n)? ' 'The MIS has not been altered.'
	fi

	kill_procs -HUP

	if [ $mis_installed = TRUE ] ; then
	    clean_database
	fi

	start_procs start
	;;

    reload)     
	ask_confirm 'Warning: The database will be destroyed and all information will be lost.\nDo you want to continue (y/n)?: ' 'EM not reloaded.'
        kill_procs -ABRT
	drop_dbm
	# Perf : spawn a shell and execute db init and asn1/gdmo complies
	# in parallel
	(
		create_rdb &
		reinit_platform &
		wait  # sync up
	)
        logs_dropped="-dropped"
        start_procs start
	;;

    stop)	
	ask_confirm 'Do you want to gracefully halt EM (y/n)?: ' 'EM not halted.'
	kill_procs -HUP
	debugmsg "em_services shutdown complete."
	exit 0
	;;

    abort)
	ask_confirm 'Do you want to immediately abort EM (y/n)?: ' 'EM not aborted.'
	kill_procs -ABRT
	debugmsg "em_services abort complete."
	exit 0
	;;

    status)
	stat_procs
	exit 0
	;;

    *) 
	usage
	exit 1
	;;
esac

info "em_services start-up complete."
exit 0
