#!/bin/ksh -p
#
# ident "@(#)utrestart.ksh	1.25 05/06/23 SMI"
#
# Copyright 2002-2005 Sun Microsystems, Inc.  All rights reserved.
# Use is subject to license terms.
#

umask 022

PATH=/bin:/usr/bin
export PATH

PROG=$(basename $0)

BASEDIR=/etc/opt/SUNWut/basedir
SUNWUT=`${BASEDIR}/lib/utprodinfo -r SUNWuto 2>/dev/null`/SUNWut
SUNWUTSBIN=$SUNWUT/sbin
SUNWUTLIB=$SUNWUT/lib
SUNWUTETC=/etc/opt/SUNWut
SUNWUTLOG=/var/opt/SUNWut/log
SUNWUTLOGGER=$SUNWUTLIB/utlog
SUNWUTPROCDIR=/tmp/SUNWut/session_proc
SUNWUTTOKENS=/var/opt/SUNWut/tokens
SUNWUTXLOCK=/etc/dt/config/config.lock
SUNWUTDPYDIR=/var/opt/SUNWut/displays
TMP=/var/opt/SUNWut/tmp/utrestart.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 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

	case "$OS" in
	SunOS)
		PIDS=`pidproc utmountd`
		if [ -z "$PIDS" -a -x ${SUNWUTLIB}/utmountd ];
		then
			(exec 1>&- ; \
			exec 2>&-; \
			${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
			(exec 1>&- ; \
			exec 2>&-; \
			${SUNWUTLIB}/utstoraged -r $SRMS_DEBUG < /dev/null 2>&1 \
			    | $SUNWUTLOGGER -o ${SUNWUTLOG}/utstoraged.log) &
		fi
		;;
	esac

        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)
	                (exec 1>&- ; \
			exec 2>&-; \
			nohup \
				priocntl -c TS -p 30 -m 30 -e \
				${SUNWUTLIB}/utauthd -b 2>&1 </dev/null \
				    | $SUNWUTLOGGER -o ${SUNWUTLOG}/auth_log) &
			;;
		Linux)
			(exec 1>&- ; \
			exec 2>&-; \
	                nohup \
				${SUNWUTLIB}/utauthd -b 2>&1 </dev/null \
				    | $SUNWUTLOGGER -o ${SUNWUTLOG}/auth_log) &
			;;
		esac
        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 utrestart to recurse forever. Setting RECURSE=STOP before the program
	# as a terminating condition
	#
	if [[ -z "${RECURSE:-}"  ]]
	then
		(nohup /bin/ksh -p -c "RECURSE=STOP ${SUNWUTSBIN}/${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..."

		case "$OS" in
		SunOS)
			/etc/init.d/utstorage stop
			;;
		esac

		/etc/init.d/utsvc stop

		# 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
		/etc/opt/SUNWut/xmgr/notify

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

		# 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 | logger -p user.info -t utrestart) > /dev/null 2>&1
	        fi

		(/etc/init.d/utsvc start | logger -p user.info -t utrestart) >/dev/null 2>&1

		case "$OS" in
		SunOS)
			(/etc/init.d/utstorage start | logger -p user.info -t utrestart) > /dev/null 2>&1
			;;
		esac

		# clean up temp file after messages are logged
		[ -w $TMP ] && rm $TMP
		exit 0
	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=/var/opt/SUNWut/displays/$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

        exit 0
}
               
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

if [ $# -eq 0 ]
then
	justRestart
fi

if [ $# -gt 1 ]
then
	usage 1 "Invalid or extraneous arguments on command line: $*"
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 $USAGE && $RESTART; then
	usage 1 "Please specify only -c or -h."
fi

if $USAGE; then
	usage 0
fi

if $RESTART; then
	purgeAndRestart
	exit 0
fi
