#!/bin/bash
# Karsten M. Self Tue Apr 26 14:40:29 PDT 2005
# ----------------------------------------------------------------------
# ssh-x-session:  Start an ssh-forwarded X session to an empty display
#
# Copyright (C) 2005  Karsten M. Self
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or (at
# your option) any later version.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307
# USA
# ----------------------------------------------------------------------

export PATH=/usr/bin:/bin:/usr/bin/X11

# Assume user == $USER unless -u specified.
# Assume host == 10.9.12.22 unless specified

SSH=/usr/bin/ssh
REMOTE_USER=$USER
REMOTE_HOST=""
REMOTE_COMMAND=""
MYPARENTPID=$PPID

SSH_CIPHER="-c blowfish"
SSH_OPTS="-o RSAAuthentication=yes -o PasswordAuthentication=no"

function help_text () {
echo "usage: $( basename $0 ) [-u user] [-c command] [host]"
cat <<EOF
    Start an X session on a remote host
    Default user is  your local username ($USER)
    Default host is ${REMOTE_HOST:-not set}
    Default command (client) is null, can use specified command if given, 
      otherwise sane defaults of .Xsession, .xsession, .xinitrc, 
      x-session-manager, x-window-manager, twm, or xterm.
EOF
exit 1
}

while test $# -gt 0; do
    case $1 in
       -h) help_text;;
       -u) shift; REMOTE_USER=$1; shift;;
       -c) shift; REMOTE_COMMAND="$1"; shift;;
       *)  REMOTE_HOST=$1; shift;;
    esac
done

SSH_CON="$REMOTE_USER@$REMOTE_HOST"

# start an agent if not already set (not foolproof, should check PID)
if [ "$SSH_AUTH_SOCK"x = x -o "$SSH_AGENT_PID"x = x ]; then
    KILL_SSH_AGENT='YES'
    eval $( ssh-agent )
fi

# Add keys
if ! ssh-add -l > /dev/null;  then
    ssh-add
fi


# Find out what sort of environment we've got on the remote side --
# basically sit here and test for stuff.   Hrm...

echo -e "Checking startup options ... \c"
if [ "$REMOTE_COMMAND"x = x ]; then
    REMOTE_COMMAND=$(
	$SSH $SSH_CIPHER $SSH_OPTS $SSH_CON '
	    if test -f ~/.xsession; then echo ". ~/.xsession";
	    elif test -f ~/.Xsession; then echo ". ~/.Xsession";
	    elif test -f ~/.xinitrc;  then echo ". ~/.xinitrc";
	    elif which x-session-manager >/dev/null; 
		  then echo "x-session-manager";
	    elif which x-window-manager  >/dev/null; 
		then echo "x-window-manager";
	    elif which twm >/dev/null; then echo "twm";
	    else echo "xterm";
	    fi' )
    fi

echo "OK: using $REMOTE_COMMAND"
sleep 1

# Kick off X at lowest free session between 0 and 9...
for i in $( seq 0 9 );
do
    if ! test -f /tmp/.X${i}-lock; then
        echo "Trying to start X at :${i}"
	export DISPLAY=:${i}

	# Background our slayer...
	( sleep 30;
	    if [ "$KILL_SSH_AGENT"x = "YESx" ]; then
		echo "Killing SSH agent $SSH_AGENT_PID"
		kill -15 $SSH_AGENT_PID || sleep 5; kill -9 $SSH_AGENT_PID
	    fi

	    echo "Process stuff:"
	    cat <<-EOF
		Current \$\$:    $$
		Current \$PPID: $PPID
		MYPID:         $MYPID
		MYPARENTPID:   $MYPARENTPID
EOF
	    bg   $MYPID
	    kill $MYPARENTPID
	    exit  # We should die here
	) & 

        # Does exec fly past Xwrapper.config?
        nohup xinit $SSH -X $SSH_CIPHER $SSH_OPTS $SSH_CON "$REMOTE_COMMAND" -- ${DISPLAY} 

        break # Never happens ... right?
    fi
done

