#!/bin/sh

# Copyright (C)2007 Sun Microsystems, Inc.
# Copyright (C)2009-2011, 2014-2018 D. R. Commander
#
# This library is free software and may be redistributed and/or modified under
# the terms of the wxWindows Library License, Version 3.1 or (at your option)
# any later version.  The full license is in the LICENSE.txt file included
# with this distribution.
#
# This library 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
# wxWindows Library License for more details.

maketemp()
{
	umask 077
	mktemp /tmp/$1.XXXXXX || exit 1
}

VGLTUNNEL=0
X11TUNNEL=1
CONNECT=1
FORCE=0
IPV6=0
SSHCMD=ssh

usage()
{
	echo
	echo "USAGE: $0"
	echo "       [vglconnect options] [user@]hostname [Additional SSH options]"
	echo
	echo "vglconnect options:"
	echo "-display <d> = X display name of the 2D X server, the X server on which the"
	echo "               VirtualGL Client will be started"
	echo "               (default: read from DISPLAY environment variable)"
	echo "-s = Tunnel VGL Transport and forward X11 through SSH"
	echo "     (default: only forward X11 through SSH)"
	echo "-ipv6 = Use IPv6 sockets"
	echo "-e <program> = Execute <program> on the VirtualGL server (if using the -s or -x"
	echo "               options, <program> is executed after running vgllogin.)"
	echo "-x = Do not forward X11 or tunnel VGL Transport through SSH, but create an"
	echo "     xauth key and add it to the VirtualGL server's keyring so that the"
	echo "     VirtualGL server (and any machines that share its home directory) can use"
	echo "     the 2D X server on this machine"
	echo "-k = Create an xauth key, as with -x, but do not connect to the VirtualGL"
	echo "     server"
	echo "-g = Use gsissh from Globus Toolkit to make all SSH connections"
	echo "-force = Force a new vglclient instance (use with caution)"
	echo "-bindir <d> = Path in which the VGL executables and scripts are installed on"
	echo "              the server (default: /opt/VirtualGL/bin).  Can also be set"
	echo "              with the VGL_BINDIR environment variable on the client."
	echo
	exit $1
}

if [ -z $VGL_BINDIR ]; then
	VGL_BINDIR=/opt/VirtualGL/bin
fi

while [ $# -gt 0 ]
do
	case "$1" in
	-d*) DISPLAY=$2; shift ;;
	-b*) VGL_BINDIR=$2; shift ;;
	-f*) FORCE=1 ;;
	-ipv6) IPV6=1 ;;
	-s*) X11TUNNEL=1; VGLTUNNEL=1; CONNECT=1 ;;
	-x*) X11TUNNEL=0; VGLTUNNEL=0; CONNECT=1 ;;
	-k*) X11TUNNEL=0; VGLTUNNEL=0; CONNECT=0 ;;
	-g*) SSHCMD=gsissh; GLOBUS=1 ;;
	-e*) COMMAND=$2; shift ;;
	-h*) usage ;;
	-?) usage ;;
	*) break ;;
	esac
	shift
done

if [ $# -eq 0 -a $CONNECT -eq 1 ]; then
	usage 0
fi

if [ "$DISPLAY" = "" ]; then
	echo "[VGL] ERROR: An X display must be specified, either by using the -display"
	echo "[VGL]    argument to vglconnect or by setting the DISPLAY environment variable"
	exit 1
fi

LOGDIR=$HOME/.vgl
if [ ! -d $LOGDIR ]; then mkdir $LOGDIR; fi
LOGDISPLAY=`basename $DISPLAY`
LOGFILE=$LOGDIR/vglconnect-$HOSTNAME-$LOGDISPLAY.log

VGLARGS="-l "$LOGFILE" -display "$DISPLAY" -detach"
if [ "$FORCE" = "1" ]; then VGLARGS=$VGLARGS" -force"; fi
if [ "$IPV6" = "1" ]; then VGLARGS=$VGLARGS" -ipv6"; fi
if [ ! "$VGL_PORT" = "" -a "$__VGL_SSHTUNNEL" = "1" ]; then
	PORT=$VGL_PORT
else
	VGLCLIENT=`dirname $0`/vglclient
	if [ ! -x $VGLCLIENT ]; then
		if [ -x /opt/VirtualGL/bin/vglclient ]; then
			VGLCLIENT=/opt/VirtualGL/bin/vglclient
		else
			VGLCLIENT=vglclient
		fi
	fi
	PORT=`$VGLCLIENT $VGLARGS`
	if [ $? -ne 0 -o "$PORT" = "" ]; then
		echo "[VGL] ERROR: vglclient failed to execute."
		exit 1
	fi
	echo
fi

if [ $VGLTUNNEL = 1 ]; then
	echo Making preliminary SSH connection to find a free port on the server ...
	REMOTEPORT=`$SSHCMD ${1+"$@"} "$VGL_BINDIR/nettest -findport && $VGL_BINDIR/vgllogin -check"`
	if [ $? -ne 0 -o "$REMOTEPORT" = "" ]; then
		echo "[VGL] ERROR: The server does not appear to have VirtualGL 2.1 or later"
		echo "[VGL]    installed."
		exit 1
	fi
	echo Making final SSH connection ...
	if [ "$COMMAND" != "" ]; then
		$SSHCMD -t -Y -R$REMOTEPORT:localhost:$PORT ${1+"$@"} <<EOF
$VGL_BINDIR/vgllogin -s $REMOTEPORT
$COMMAND
EOF
	else
		$SSHCMD -t -Y -R$REMOTEPORT:localhost:$PORT ${1+"$@"} "$VGL_BINDIR/vgllogin -s "$REMOTEPORT
	fi
	exit 0
fi

if [ $X11TUNNEL = 1 ]; then
	if [ "$COMMAND" != "" ]; then
		$SSHCMD -Y ${1+"$@"} <<EOF
$COMMAND
EOF
	else
		$SSHCMD -Y ${1+"$@"}
	fi
	exit 0
fi

XAUTH=xauth
if [ -x /usr/X11R6/bin/xauth ]; then
	XAUTH=/usr/X11R6/bin/xauth
else
	if [ -x /usr/openwin/bin/xauth ]; then
		XAUTH=/usr/openwin/bin/xauth
	fi
fi
XAUTHFILE=`maketemp vglconnect`
$XAUTH -f $XAUTHFILE generate $DISPLAY . trusted timeout 0
if [ $? -ne 0 ]; then
	echo "[VGL] ERROR: Could not generate xauth key, possibly because the X server does"
	echo "[VGL]    not have the SECURITY extension or because the xauth command could "
	echo "[VGL]    not be found."
	rm -f $XAUTHFILE
	exit 1
fi
XAUTHCOOKIE=`$XAUTH -f $XAUTHFILE list | sed "s/.*[ ]//g"`
rm -f $XAUTHFILE
if [ "$CONNECT" = "1" ]; then
	if [ "$COMMAND" != "" ]; then
		$SSHCMD -t -x ${1+"$@"} <<EOF
$VGL_BINDIR/vgllogin -x $DISPLAY $XAUTHCOOKIE
$COMMAND
EOF
	else
		$SSHCMD -t -x ${1+"$@"} "exec $VGL_BINDIR/vgllogin -x "$DISPLAY" "$XAUTHCOOKIE
	fi
else
	DNUM=`echo $DISPLAY | sed 's/.*[:]//g'`
	xauth add `hostname`":"$DNUM . $XAUTHCOOKIE
fi
