#!/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

REMOTE_USER=$USER
REMOTE_HOST=""
REMOTE_COMMAND=""

SSH_OPTS="-c blowfish -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

# 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

# Kick off X at lowest free session between 0 and 9...

for i in $( seq 0 9 );
do
    if ! test -S /tmp/.X11-unix/X${i}; then
       echo "Trying to start X at :${i}"
       export DISPLAY=:${i}

       (
	   # Sleep a bit then try the SSH stuff
	   sleep 4
	   xmessage "Trying to start an SSH session to $DISPLAY" & 

	   if [ "$REMOTE_COMMAND"x != x ]; then
	       eval ssh $SSH_OPTS -fX $REMOTE_USER@$REMOTE_HOST \
		   "$REMOTE_COMMAND"
	       exit
	   fi

	   # Find out if there's an .Xsession, .xsession, or .xinitrc file
	   # remotely, use it, otherwise bail and do x-session-manager, else do 
	   # x-window-manager.
	   if eval ssh $SSH_OPTS $REMOTE_USER@$REMOTE_HOST 'test -f ~/.xsession'; 
	   then
	       eval ssh $SSH_OPTS -fX $REMOTE_USER@$REMOTE_HOST '. ~/.xsession'
	       exit
	   elif eval ssh $SSH_OPTS $REMOTE_USER@$REMOTE_HOST 'test -f ~/.Xsession'; 
	   then
	       eval ssh $SSH_OPTS -fX $REMOTE_USER@$REMOTE_HOST '. ~/.Xsession' 
	       exit
	   elif eval ssh $SSH_OPTS $REMOTE_USER@$REMOTE_HOST 'test -f ~/.xinitrc'; 
	   then
	       eval ssh $SSH_OPTS -fX $REMOTE_USER@$REMOTE_HOST '. ~/.xinitrc' 
	       exit
	   fi

	   eval ssh $SSH_OPTS -fX $REMOTE_USER@$REMOTE_HOST x-session-manager  &&\
	       exit
	   eval ssh $SSH_OPTS -fX $REMOTE_USER@$REMOTE_HOST x-window-manager   &&\
	       exit
	   # Minimal
	   eval ssh $SSH_OPTS -fX $REMOTE_USER@$REMOTE_HOST twm      && exit
	   # Failsafe
	   eval ssh $SSH_OPTS -fX $REMOTE_USER@$REMOTE_HOST xterm    && exit


       ) &

       X :${i} 
       break
    fi
done


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
