#!/bin/ksh -p
#
# ident "@(#)utxinit.sh	1.13 04/10/01 SMI"
#
# Copyright 1999-2002,2004 Sun Microsystems, Inc.  All rights reserved.
# Use is subject to license terms.
#
# Xinit replacement that works
#

#
# cleanup function -- temporary only
# XXXX: this should be removed once the official fix is integrated
#
function cleanup {
        session_proc=$1
	
	/bin/rm -f $session_proc 2> /dev/null
}

function finiserver {
    serverpid=$1
    session_proc=$2

    kill -9 $serverpid
    cleanup $session_proc
}

function disconnect {
	control_ipa=0.0.0.0
	control_port=7010
        sid=$1

	print "control $sid
request disconnect
end
" | $SUNWUTNETPIPE $control_ipa $control_port | while read line
	do
		case $line in
		(ok*|end*)
			;;
		(error*)
			print -u2 -- $line
			;;
		(quit*)
			;;
		*)
			;;
		esac
	done
}

# main

SUNWUTLIB=/etc/opt/SUNWut/basedir/lib
SUNWUTXEXEC=$SUNWUTLIB/utxexec
SUNWUTDTSESSION=$SUNWUTLIB/utdtsession
SUNWUTNETPIPE=$SUNWUTLIB/utnetpipe

#
# This part parses the client and server commands (separated by "--")
#
cprog=""
sprog=""

client=t

sep=""

for i
do
	if [ "$i" = "--" ]
	then
		client=f
		sep=""
	elif [ "$client" = t ]
	then
		cprog="$cprog$sep$i"
		sep=" "
	else
		sprog="$sprog$sep$i"

		case "$i" in
		:[0-9]*)
			display="$i"
			;;
		esac
		sep=" "
	fi
done

#
# Set up defaults
#
if [ "$display" = "" ]
then
	display=":0"
fi

if [ "$sprog" = "$display" ]
then

	XSERVER="/bin/false"
	for XSERVERBIN in /usr/openwin/bin/Xsun /usr/X11R6/bin/Xnewt ; do
		if [ -x $XSERVERBIN ] ; then
			XSERVER=$XSERVERBIN
			break
		fi
	done

	sprog="$XSERVER $display"
fi

if [ "$cprog" = "" ]
then
	XTERM="/bin/false"
	for XTERMPATH in /usr/openwin/bin /usr/X11R6/bin /usr/bin ; do
		if [ -x $XTERMPATH/xterm ] ; then
			XTERM=$XTERMPATH/xterm
			break
		fi
	done
	cprog="$XTERM -geometry  +1+1  -n  login"
fi

#
# Now we know what to run; do the work
#

#
# Setup the session_prof file
# 
DPY=${display#*:}
DPY=${DPY%.*}
SESSION_PROC=/tmp/SUNWut/session_proc/$DPY

#
# Get ready to catch SIGUSR1
#
ready=0
trap "ready=1" USR1

#
# To be considered a "smart" parent we must pass SIGIGN on SIGUSR1
#
( trap "" USR1 ; exec $sprog 1>/dev/null 2>&1 ) &

DPY=${display#*:}
DPY=${DPY%.*}

SID=$(sed -n 's/SESSION=\(.*\)/\1/p' /var/opt/SUNWut/displays/$DPY)

#
# Pid is the X server's pid; on exit kill it
#
pid=$!
trap "kill -9 $pid; cleanup $SESSION_PROC; exit" 0 1 2 15

#
# Get ready
#
DISPLAY=$display
export DISPLAY

#
# Wait for the callback or time-out
#
incr=0
while [ $ready -eq 0 -a $incr -lt 15 ]
do
	sleep 1
	incr=$(($incr + 1))
done

#
# Run the client program while keeping the display open via utxexec
#
$SUNWUTXEXEC $cprog 1>/dev/null 2>&1 &
apppid=$!

#
# Generate the session_proc file
#
echo XID=$DPY > $SESSION_PROC
echo pid=$apppid >> $SESSION_PROC
echo program=$SUNWUTXEXEC >> $SESSION_PROC
echo server_pid=$pid >> $SESSION_PROC
echo server_prog=$(echo $sprog | cut -d' ' -f1) >> $SESSION_PROC
/bin/chmod 644 $SESSION_PROC

# 
# Wait for app to exit
#
wait $apppid
retcode=$?

#
# 1. If Xserver has exited (retcode == 3), then disconnect
# 2. If Xserver didn't start up properly (retcode == 4), kill session and cleanup
# 3. If Xserver is still there (retcode != 3 or 4), that means 
#    app exited first, then kill the Xserver and exit
#

case "$retcode" in
0|1|2)
    #
    # App exited first, This is the normal case
    # Kill the X server
    #
    finiserver $pid $SESSION_PROC
    ;;
4)
    #
    # Something horrible happened and X server didn't fully initialize in time
    # Kill the X server
    #
    logger -p user.error "utxinit ERROR: X session startup timeout, display $DPY"
    finiserver $pid $SESSION_PROC
    wait $pid
    $SUNWUTDTSESSION -n $DPY delete
    ;;
*)
    #
    # retcode 3 :: X Server exited, This could happen if a
    # "Ctrl-alt-bksp-bksp" sequence was used. 3 is a valid
    # error code returned from handler in utxexec.
    # do a disconnect
    #   
    # This is also a catch-all case for all other unknown return codes
    # which might be generated as a result of un-trapped signals.
    # Log these before disconnecting to cleanup.
    
    if [ $retcode != 3 ]
    then
	logger -p user.error "utxinit ERROR: Return code $retcode. Disconnecting display $DPY"
    fi
    disconnect $SID
    ;;
esac
trap "" 0 1 2 15

exit 0
