#!/bin/ksh -p
#
# ident "@(#)utstartimpl.ksh	1.43	11/03/06 Oracle"
#
# Copyright (c) 2002, 2011, Oracle and/or its affiliates. All rights reserved.
#

#
# Solaris 10 Trusted Extension guard
#
ORIGIN=`/usr/bin/dirname $0`
UTIL_LIB=${ORIGIN:-/opt/SUNWut/lib}/../lib/support_lib/util_lib
. $UTIL_LIB
FailExecInLocalZoneOnTx 
#
# Solaris 10 Trusted Extension guard 
#


umask 022

PATH=/bin:/usr/bin
export PATH

PROG=$(basename $0)

BASEDIR=/etc/opt/SUNWut/basedir
SUNWUTSBIN=/opt/SUNWut/sbin
SUNWUTLIB=/opt/SUNWut/lib
SUNWUTETC=/etc/opt/SUNWut
SUNWUTVAR=/var/opt/SUNWut
SUNWUTTMP=/tmp/SUNWut
SUNWUTLOG=$SUNWUTVAR/log
SUNWUTLOGGER=$SUNWUTLIB/utlog
SUNWUTPROCDIR=$SUNWUTTMP/session_proc
SUNWUTTOKENS=$SUNWUTVAR/tokens
SUNWUTXLOCK=/etc/dt/config/config.lock
SUNWUTDPYDIR=$SUNWUTVAR/displays
SUNWUTENABLED=$SUNWUTETC/utenabled
TMP=$SUNWUTVAR/tmp/utstart.log.$$

SRMS_DEBUG=""

#
# Functions
#
#
# Command syntax
#
function usage {
        typeset ecode=${1:-99}
        typeset message=${2:-}
        if [[ -n "$message" ]]
        then
                print -u2 -- ERROR: $message
        fi

	utcmd=${PROG##*/}

        cat <<!
Usage:
${utcmd}
${utcmd} -c
${utcmd} -h

        			# Restart/init SunRay services.
				# With no options the sessions are left intact.
        -c                      # Clears out all existing sessions.

        -h                      # Print this message.

!
        exit $ecode
}

#
# Return 0 if system is labeled (running TX)
#
smf_is_system_labeled() {
	[ ! -x /bin/plabel ] && return 1
	/bin/plabel > /dev/null 2>&1
	return $?
}

activateIfNecessary () {
	if [ ! -f ${SUNWUTETC}/utctl.run ]; then
		print "Activating product"
		${SUNWUTLIB}/utctl enable
	fi
}

#
# Return pid(s) of process named in argument
#
pidproc() {
	ps -u root -o pid -o args | 
	grep -w "$1" | 
	${NAWK} '($2 ~ PROCNAME) { print $1 }' PROCNAME=$1
}

checkAndStartDaemons() {

        ${SUNWUTLIB}/utauthd -e
	SLEEP=5

	sleep $SLEEP

	#
        # Clean up old lock files from utdtsession
        #
        find $SUNWUTTOKENS -type f \
             -name '*.lock' -print | xargs rm -f
        rm -f $SUNWUTXLOCK

        PIDS=`pidproc utsessiond`
        if [ -z "$PIDS" -a -x ${SUNWUTLIB}/utsessiond ];
        then
		(
			cd ${SUNWUTLOG}

			auth_permit=${SUNWUTETC}/auth.permit
			if [ -f ${auth_permit} ]
			then
				autharg="-c ${auth_permit}"
			else
				autharg=""
			fi

			case "$OS" in
			SunOS)
				priocntl -e -c TS -p 30 -m 30 \
					${SUNWUTLIB}/utsessiond -r ${autharg} \
					< /dev/null > /dev/null 2>&1 &
				;;
			Linux)
				${SUNWUTLIB}/utsessiond -r ${autharg} \
					< /dev/null > /dev/null 2>&1 &
				;;
			esac

		)
        fi

        PIDS=`pidproc utdevmgrd`
        if [ -z "$PIDS" -a -x ${SUNWUTLIB}/utdevmgrd ];
        then
                (
                        cd ${SUNWUTLOG}

                        auth_permit=${SUNWUTETC}/auth.permit
                        if [ -f ${auth_permit} ]
                        then
                                autharg="-c ${auth_permit}"
                        else
                                autharg=""
                        fi

                        ${SUNWUTLIB}/utdevmgrd -r ${autharg} \
                                < /dev/null > /dev/null 2>&1 &
                )
        fi

        PIDS=`pidproc utparalleld`
        if [ -z "$PIDS" -a -x ${SUNWUTLIB}/utparalleld ]; 
	then
                ${SUNWUTLIB}/utparalleld -r < /dev/null > /dev/null 2>&1 &
        fi

        PIDS=`pidproc utseriald`
        if [ -z "$PIDS" -a -x ${SUNWUTLIB}/utseriald ]; 
	then
                ${SUNWUTLIB}/utseriald -r < /dev/null > /dev/null 2>&1 &
        fi

	# only start utaudiod if we're on a TX system
	if smf_is_system_labeled ; then
        	PIDS=`pidproc utaudiod`
		if [ -z "$PIDS" -a -x ${SUNWUTLIB}/utaudiod ]; 
		then
			${SUNWUTLIB}/utaudiod -r < /dev/null > /dev/null 2>&1 &
		fi
	fi

	PIDS=`pidproc utmountd`
	if [ -z "$PIDS" -a -x ${SUNWUTLIB}/utmountd ];
	then
		${SUNWUTLIB}/utmountd $SRMS_DEBUG < /dev/null 2>&1 \
			| $SUNWUTLOGGER -o ${SUNWUTLOG}/utmountd.log &
	fi

	PIDS=`pidproc utstoraged`
	if [ -z "$PIDS" -a -x ${SUNWUTLIB}/utstoraged ];
	then
		${SUNWUTLIB}/utstoraged -r $SRMS_DEBUG < /dev/null 2>&1 \
		    | $SUNWUTLOGGER -o ${SUNWUTLOG}/utstoraged.log &
	fi

        PIDS=`pidproc utdsd`
        if [ -z "$PIDS" -a -x /etc/init.d/utds ]; 
	then
                /etc/init.d/utds start < /dev/null > /dev/null 2>&1
        fi

	if [ -f ${SUNWUTETC}/auth.props -a -x ${SUNWUTLIB}/utauthd ]; then
		case "$OS" in
		SunOS)
			nohup \
				priocntl -c TS -p 30 -m 30 -e \
				${SUNWUTLIB}/utauthd -b 2>&1 </dev/null \
				    | $SUNWUTLOGGER -o ${SUNWUTLOG}/auth_log &
			;;
		Linux)
	                nohup \
				${SUNWUTLIB}/utauthd -b 2>&1 </dev/null \
				    | $SUNWUTLOGGER -o ${SUNWUTLOG}/auth_log &
			;;
		esac
        fi
        
	if [ $OS = "SunOS" ]; then
	    PIDS=`pidproc pcscd`
	    if [ -z "$PIDS" ]; then
		/usr/sbin/svcadm enable svc:/application/security/pcscd:default
	    fi
	fi
	
	startWebserver

        PIDS=`pidproc uttscpd`
        if [ -z "$PIDS" -a -x /etc/init.d/uttscp ]; 
	then
                /etc/init.d/uttscp start
        fi
}

function purgeAndRestart {

	# User might execute the -c when on a sunray box. Though the message displayed
	# will be too quick to see, the warning is still given.

	if [[ -n "${SUN_SUNRAY_TOKEN:-}" ]]
	then
		print "Your session will also be terminated as the command executes."
		sleep 5
	else
		print "A cold restart has been initiated... messages will be logged to $SUNWUTLOG/messages."
	fi

	#
	# Prevent utstart to recurse forever. Setting RECURSE=STOP before the program
	# as a terminating condition
	#
	if [[ -z "${RECURSE:-}"  ]]
	then
		(nohup /bin/ksh -p -c "RECURSE=STOP ${SUNWUTLIB}/${PROG} -c " \
		                                    > /dev/null 2>&1 </dev/null &)
	else
		# The output will be logged to messages
		exec > $TMP 2>&1

		print "A cold restart of Sun Ray Services is in progress..."

		PIDS=`pidproc uttscpd`
		if [ -z "$PIDS" -a -x /etc/init.d/uttscp ]; 
		then
			/etc/init.d/uttscp stop
		fi

		/etc/init.d/utstorage stop
		/etc/init.d/utsvc stop
		if [ $OS = "SunOS" ]; then
		    /usr/sbin/svcadm disable svc:/application/security/pcscd:default
		fi

		# XXX Need to change `listNonDtloginDisplays` function for linux
		DISPS_TO_KILL=`listNonDtloginDisplays`
		PIDS_TO_KILL=`identifyNonDtloginSessions $DISPS_TO_KILL`

		# Kill the non-dtlogin sessions
		[[ ! -z ${PIDS_TO_KILL} ]] && kill -9 -- ${PIDS_TO_KILL} 2>/dev/null

		#
		# Clean out the SunRay sessions configuration
		# (utacleanup with no arg does this unconditionally)
		#
		/etc/init.d/utacleanup
		[[ -x /etc/init.d/bbinit ]] && /etc/init.d/bbinit cleanup

		# Let parent dtlogin kill the outstanding dtlogin sessions
		${SUNWUTETC}/xmgr/notify

		logger -f $TMP -p user.info -t utstart

		# make sure that SRDS daemon is running (if needed) 
	        PIDS=`pidproc utdsd`
	        if [ -z "$PIDS" -a -x /etc/init.d/utds ]; 
		then
	                /etc/init.d/utds start 2<&1 | logger -p user.info -t utstart
	        fi

		/etc/init.d/utsvc start 2<&1 | logger -p user.info -t utstart
		/etc/init.d/utstorage start 2<&1 | logger -p user.info -t utstart

		if [ $OS = "SunOS" ]; then
		    /usr/sbin/svcadm enable svc:/application/security/pcscd:default
		fi

		PIDS=`pidproc uttscpd`
		if [ -z "$PIDS" -a -x /etc/init.d/uttscp ]; 
		then
			/etc/init.d/uttscp start
		fi

		startWebserver

		# clean up temp file after messages are logged
		[ -w $TMP ] && rm $TMP
		exit 0
	fi
}

function startWebserver {
	WEBADMIN_CONF="${SUNWUTETC}/webadmin/webadmin.conf"
	if [ -f ${WEBADMIN_CONF} ]; then
		CATALINA_HOME=`grep '^catalina.home=' ${WEBADMIN_CONF} | cut -f2 -d'='`
		if [ -n "${CATALINA_HOME}" ]; then
			if [ -f ${SUNWUTLIB}/utwebadmin ]; then
				${SUNWUTLIB}/utwebadmin start 2>&1 | logger -p user.info -t utstart
			fi
		fi
	fi
}


# listNonDtloginDisplays

function listNonDtloginDisplays {
	# uses private SRSS interfaces bug 5034619
        if [[ -d $SUNWUTDPYDIR ]]
        then
		( cd $SUNWUTDPYDIR &&
                awk -F= '
                $1 == "SESSION_TYPE" && $2 != "default" { print FILENAME }
                ' * 2>/dev/null )
        fi
}

# identifyNonDtloginSessions
# Output the pids for the current non-dtlogin sessions

function identifyNonDtloginSessions {
        # find the session_proc files not related to dtlogin
        NON_DTLOGIN_DISPS=$*

        # Verify each session_proc is valid: doesn't predate display file
	# uses private SRSS interfaces bug 5034619
        for DISP in $NON_DTLOGIN_DISPS; do
                SPFILE=$SUNWUTPROCDIR/$DISP
                DPYFILE=${SUNWUTDPYDIR}/$DISP

                if [[ -f $SPFILE ]] && [[ -f $DPYFILE ]] \
                    && [[ ! $SPFILE -ot $DPYFILE ]]
                then
                        # It's valid - output the pid
                        # Note: utxexec switches itself to a process group leader,
                        # so use negative pid to kill the entire group for
                        # efficiency
                        print -n -- `sed -n -e 's/^pid=/-/p' \
                                    -e 's/^server_pid=//p' $SPFILE` " "
                fi
        done
}

function justRestart {

	print "A warm restart has been initiated... messages will be logged to $SUNWUTLOG/messages."
	
	checkAndStartDaemons
}
               
function mustBeRoot {
	case "`id`" in
	'uid=0('*)	;;

	*)		Error 1 "Must be root to restart services."
			;;
	esac
}

function Error {
        typeset ecode=${1:-99}
        typeset message=${2:-}
        if [[ -n "$message" ]]
        then
                print -u2 -- ERROR: $message
        fi
        exit $ecode
}


#
# Main program
#

ROOTDIR=/
cd $ROOTDIR

#
# No argument on cmd line, simply print error and exit
#

mustBeRoot

OS=`uname -s`

if [ $OS = "Linux" ]
then
	NAWK=/usr/bin/gawk
else
	NAWK=/usr/bin/nawk
fi

RESTART=false
USAGE=false

UT_OPTIONS=$@
while getopts ch c $UT_OPTIONS 2>/dev/null
do
	case $c in
	(c)    	RESTART=true
		;;
	(h)     USAGE=true
                ;;
        (\?)
                if [[ "$1" != "-?" ]]
                then
                        usage 1 "Invalid option: $1";
                else
                        usage 1
                fi
        esac
done

if [ $OPTIND -le $# ]
then
	usage 1 "Invalid or extraneous arguments on command line: $*"
fi

if $USAGE && $RESTART; then
	usage 1 "Please specify only -c or -h."
fi

if $USAGE; then
	usage 0
fi

activateIfNecessary

if [ ! -f $SUNWUTENABLED ]; then
	touch $SUNWUTENABLED
fi

if [ -f ${SUNWUTETC}/utadmin.conf -a ! -f ${SUNWUTENABLED}.utdsd ]; then
	touch ${SUNWUTENABLED}.utdsd
fi

if [ ! -d $SUNWUTTOKENS ] && ! $RESTART ; then
	print "A cold restart is required, assuming -c option"
	RESTART=true
fi

if $RESTART; then
	purgeAndRestart
else
	justRestart
fi

exit 0
