#!/bin/ksh -p
#
# ident "@(#)utxinit.sh	1.9 03/08/08 SMI"
#
# Copyright 1999-2002 Sun Microsystems, Inc.  All rights reserved.
#
#
# 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 openControl {
	exec 8<> /dev/tcp/$1/$2
}

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

	openControl $control_ipa $control_port

	print -u8 "control $sid
request disconnect
end
"

	cat < /dev/fd/8 | while read line
	do
		case $line in
		(ok*|end*)
			print -u8 quit 2>/dev/null
			;;
		(error*)
			print -u2 -- $line
			;;
		(quit*)
			;;
		*)
			;;
		esac
	done
	exec 8<> /dev/null
}

# main

SUNWUTLIB=$(pkginfo -r SUNWuto 2>/dev/null)/SUNWut/lib
SUNWUTXEXEC=$SUNWUTLIB/utxexec
SUNWUTDTSESSION=$SUNWUTLIB/utdtsession

#
# 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
	sprog="/usr/openwin/bin/Xsun $display"
fi

if [ "$cprog" = "" ]
then
	cprog="/usr/openwin/bin/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 ) &

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 &
apppid=$!

#
# Generate the session_proc file
#
echo XID=$DPY > $SESSION_PROC
echo pid=$apppid >> $SESSION_PROC
echo program=$SUNWUTLIB/utxexec >> $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
3)
    #
    # X Server exited, This could happen if a
    # "Ctrl-alt-bksp-bksp" sequence was used.
    # do a disconnect
    #
    disconnect $SID
    ;;
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
    ;;
*)
    #
    # App exited first, This is the normal case
    # Kill the X server
    #
    finiserver $pid $SESSION_PROC
    ;;
esac
trap "" 0 1 2 15

exit 0
