#!/bin/sh
# $Header: /global/src/usr.bin/X11/RCS/xon,v 1.45 2016/05/24 10:34:12 pb22 Exp $
# start up xterm (or any other X command) on the specified host
# Usage: xon host [arguments] [command]
#
# cl.cam mods:
# Not setting PATH means that even "xon mc" fails as no xterm
# Use RDISPLAY if set. Use XONOPTS if set.
# Use remsh if avbailable. Pass "-n" AFTER hostname (e.g. for Ultrix)
#
case $# in
0)	cat <<EOF
Usage: $0 <hostname> [-user user] [-name window-name] [-debug] [-ssh|-nossh] 
    [-screen screen-number] [-Y|-x|-C|-v|-noxchain|-1|-2|-4|-6] [-K|-noK]
    [-cd dir] [-p port] [-rshopts opts] [-xc] [-geom geometry] [-exec] [-tx]
    [-xterm] [-relay] [-zaplang] [-keeplang] [-relayvia host] [-noptr]
    [command ...]
EOF
	exit 1
	;;
esac
redirect=" </dev/null >&0 2>&0 3>&- 4>&- 5>&- 6>&- 7>&- 8>&- &"
command=
ls=-ls
continue=:
cd=/
usesh=false	# local command -- use sh rather than rsh ...
rsh=rsh
if type rpm > /dev/null 2>&1; then
  case `rpm -q openssh-clients 2>&1` in
  # FC3 and later need -Y
  openssh-clients-[5-9]*|openssh-clients-4.[7-9]*)Xopt="-Y" Kopt="-K";;
  openssh-clients-4*)			Xopt="-Y";;
  openssh-clients-3.[1-9][0-9]*)	Xopt="-Y";;
  openssh-clients-3.9*)			Xopt="-Y";;
  # FC2 needs -X
  openssh-clients-3.5*)			Xopt="-X";;
  # Default
  *)					Xopt="-Y" Kopt="-K";;
  esac
else
  Xopt="-Y"
  Kopt="-K"
fi
sshf=-f
SendEnv=
rcmd1=-n
rcmd2=
rcmd3=
rcmd4=
rcmd5=
rcmd6=
relay=
exec=
xtermarg=
xauth=
xhome='HOME=${HOME-`pwd`} '

case "$XONRSH" in
'')	[ -f /usr/bin/remsh ] && rsh=remsh;;
*)	rsh=$XONRSH;;
esac
ssh="$XONSSH"
rcmd0="$XONRSHOPTS"

# Remember the original display, so that it can be used if using ssh
ORIGDISPLAY="$DISPLAY"

# If user has (manually) set RDISPLAY (e.g. to include FQDN) use it.
case "$RDISPLAY" in ?*) DISPLAY="$RDISPLAY";; esac

# If the real display is within the dept, don't chain ssh relays.
case "$REALDISPLAY" in
:*|unix:*|*cl.cam.ac.uk:*)	DISPLAY="$REALDISPLAY";;
esac

rcmd="$1" target="$1" label="$1" resource=xterm-"$1"
shift

# Decide whether to ssh agent forward and kerberos delegation
case "$rcmd" in
*.*.cl.cam.ac.uk)	Kopt="";;
*.cl.cam.ac.uk)		relay=-A;;
*.*)			Kopt="";;
?*)			relay=-A;;
esac

# Ensure DISPLAY is a FQDN
case "$DISPLAY" in unix:*) DISPLAY=`echo $DISPLAY | sed 's/unix//'` ;; esac
case "$DISPLAY" in
:*)	# Local host ....
	fullname=`hostname`
	hostname=`echo $fullname | sed 's/\..*$//'`
	if [ $hostname = $target -o $fullname = $target ]
	then	DISPLAY=$DISPLAY usesh=true
	else	case "$fullname" in *.*) DISPLAY=$fullname$DISPLAY;; esac
	fi
	;;
localhost:*) # localhost -- leave ASIS
	;;
*.*:*)	# Assume it is a FQDN ...
	;;
*)	# UQDN: append domain ...
	if test -r /etc/rc.scripts/findhostnames
	then	. /etc/rc.scripts/findhostnames
		case "$DOMAIN" in
		?*)	DISPLAY=`echo "$DISPLAY" | sed "s/:/.$DOMAIN:/"`;;
		esac
	fi
	;;
esac

# What *IS* XUSERFILESEARCHPATH, and what uses it ?
# Is it meaningful to copy PATHs between machines ?
case "$XUSERFILESEARCHPATH" in '') XUSERFILESEARCHPATH="$PATH";; esac

case "x$XUSERFILESEARCHPATH" in
x)	;;
*)	xpath='XUSERFILESEARCHPATH=${XUSERFILESEARCHPATH-"'"$XUSERFILESEARCHPATH"'"} PATH=${XUSERFILESEARCHPATH-"'"$XUSERFILESEARCHPATH"'"} ';;
esac

case "$XONOPTS+++$*" in
?*+++)		set X $XONOPTS; shift;;
?*+++?*)	set X $XONOPTS "$@"; shift;;
esac

while $continue; do
	: case "$1" ,,,
	case "$1" in
	-noptr)	# Do not try to use PTR lookup for UQDN hosts
		shift
		NOPTR="not.UQDN."
		;;
	-user)	# Set the user on the remote machine
		shift
		usesh=false
		rcmd2="-l $1"
		label="$target $1"
		shift
		xhome=''
		;;
	-access) # HACK -- allow xhost based access -- should be banned !
		shift
		xhost +$target
		;;
	-ssh)	# Want ssh (the default anyway)
		shift
		ssh=full
		;;
	-nossh)	# Do NOT want ssh -- ban.
		shift
		ssh=false
		;;
	-xterm)	# use a local xterm
		shift
		ssh=xterm
		;;
	-x)	# Want ssh NOT to relay X.
		shift
		ssh=setup
		;;
	-cd)	# Whither should the process cd ?
		shift
		cd=$1
		shift
		;;
	-X|-Y)	# Use -Y rather than -X
		Xopt=$1
		shift;;
	-A)	# ssh agent relay requested
		relay=$1
		shift;;
	-noA)	# force no ssh agent relaying
		relay=
		shift;;
	-relayvia)	# use a user specified relay
		relay=-A
		shift
		relaymc="$1"
		case "$relaymc" in [0-9]) relaymc=ssh-relay"$relaymc";; esac
		case "$relaymc" in *.*) : OK;; *) relaymc="$relaymc".cl.cam.ac.uk;; esac
		case "$relaymc" in *@*) xhome=;; esac
		HOP="$relaymc ssh -A $Xopt"
		shift
		;;
	-relay)	# use "the" relay
		relay=-A
		HOP="ssh-relay1.cl.cam.ac.uk ssh -A $Xopt"
		shift
		;;
	-exec)	# use exec to remove one more process
		exec=exec
		shift
		;;
	# generic ssh arguments to pass over ASIS
	# single arg to rcmd5; single arge to rcmd6; dual arg to rcmd5
	-[Cv1246]|-[LR]?*) # Want ssh to compress, be verbose,
		# use SSHv[12] or IPv[46], or port forward
		rcmd5="$rcmd5 $1"
		shift
		;;
	-K)	Kopt=$1; shift;;
	-noK)	Kopt=""; shift;;
	-[t])	# register the calling host by allocating a tty for sshd
		rcmd6="$rcmd6 $1"
		shift
		;;
	-[opLR]) # Want ssh to use a specified port or port forward
		rcmd5="$rcmd5 $1 $2"
		shift
		shift
		;;
	-keeplang) # Do not HACK LANG
		XON_KEEP_LANG=true;
		shift
		;;
	-zaplang) # Do HACK LANG
		XON_KEEP_LANG=false;
		shift
		;;
	-noxchain) # Do not set up up a relay chain.
		noxchain=true;
		shift
		;;
	-rshopts) # set opts for rsh
		shift
		rcmd0="$1"
		shift
		;;
	-geom)	# misc args to xterm
		xtermarg="$xtermarg $1 $2";
		shift
		shift
		;;
	-xauthority)
		shift
		XAUTHORITY="$HOME/.Xauthority";;
	-tx)
		# make use of "AcceptEnv XAUTHORITY" in /etc/ssh/sshd_config
		# on remote host to allow X forwarding to work even if $HOME
		# isn't writable
		shift
		export XAUTHORITY
		T=/tmp/${USER}_Xa
		# Do we trust xauth at the other end to get protection right,
		# or might a CRACKer create the named file with open permissons?
		# Seems that xauth sorts such things out, can can used fixed name
		# thus avoiding junk files at both ends -- whew!
		# rm -f /tmp/$(USER)_Xa.*
		# T=$(mktemp /tmp/$(USER)_Xa.XXXXXXXXXX)
		ln -sf ${XAUTHORITY-$HOME/.Xauthority} $T
		SendEnv="-oSendEnv=XAUTHORITY"
		XAUTHORITY="$T"
		;;
	-name)	# Set the name of the window (etc)
		shift
		label="$1"
		resource="$1"
		shift
		;;
	-nols)	# do not use "xterm -ls"
		shift
		ls=
		;;
	-debug)	# Disable redirection of std* etc, and add the "-v" flag to ssh
		shift
		redirect=
		sshf=-v
		;;
	-xc)	# Old HACK probably warn out -- call a special filtering X relay
		shift
		newDISPLAY=`head -1 ${XCDATA-$HOME/.xcenv}`
		case "$newDISPLAY" in
		?*:[0-9]*)	DISPLAY="$newDISPLAY";;
		*)	echo "Failed to read new display from ${XCDATA-$HOME/.xcenv}" 1>&2;
			exit 1;
		esac
		;;
	-screen)# Set the screen to use
		shift
		DISPLAY=`echo $DISPLAY | sed 's/:\\([0-9][0-9]*\\)\\.[0-9]/:\1/'`.$1
		shift
		;;
	--)	# std convention for "pass rest on to next level"
		shift;
		continue=false
		;;
	*)	# Not recognised -- assume arg to be passed on.
		continue=false
		;;
	esac
done

# HACK -- if it's "pb", select a machine
case "$rcmd" in pb) t=`if type cl-rr-select > /dev/null 2>&1; then cl-rr-select $rcmd; elif type rr-select > /dev/null 2>&1; then rr-select $rcmd; fi`;case "$t" in pb*) rcmd="$t";;esac;;esac

# HACK -- if it's local, then try to access the server rather than the alias
# To disable, use -noptr
case "$NOPTR$rcmd" in
*.*)	: SKIP;;
*)	c="$(host -t ptr $rcmd)";
	: $rcmd / $c
	case "$c" in
	*" domain name pointer "*)
		t=$(echo "$c" | sed -n 's/.cl.cam.ac.uk\.//g;s/.* domain name pointer //'p | head -1)
		case "$t" in ?*) rcmd="$t";; esac
	esac
	: $rcmd
esac

case "$XAUTHORITY" in /tmp/*|/var/*) ;; ?*) xauth="XAUTHORITY=$XAUTHORITY ";; esac

xportlist="$xportlist DISPLAY REALDISPLAY XUSERFILESEARCHPATH PATH XAUTHORITY"
shc="sh -c"
quote="'"
xonrc="test -f .xonrc && . ./.xonrc;"

case "$ssh" in
''|true|full)# Do not override the DISPLAY variable, as ssh sets it.
	# Change the command to run to be ssh instead of rsh or remsh
	# Use the "-f" flag to make it background itself after setup.
	usesh=false
	rsh=ssh
	rcmd1="$sshf"
	rcmd3="$rcmd5 $XONSSHARGS"
	rcmd4=-oFallBackToRsh=no
	rcmd0="$rcmd0 $Xopt $Kopt"
	# Do not background ssh (-f does that); do not redirect stderr (irix6.4)
	redirect=`echo "$redirect" | sed 's/2>&0 //;s/ &$//'`
	vars="$xhome$xpath$xauth"
	case "$noxchain" in
	'') vars="$vars"REALDISPLAY="${REALDISPLAY-$DISPLAY}";;
	esac
	# Reset DISPLAY, as ssh sorts that out AND the X server may not be
	# listening on `hostname`:0, e.g. a PPP connected host.
	DISPLAY="${ORIGDISPLAY-$DISPLAY}";;
setup)	# use ssh to start the remote command (for security),
	# but do not do X relaying
	rsh=ssh
	rcmd1="$sshf"
	rcmd3="$rcmd5 $XONSSHARGS"
	rcmd4=-oFallBackToRsh=no
	usesh=false
	rcmd0="$rcmd0 -x -a"
	vars="$xhome$xpath$xauth"DISPLAY="$DISPLAY";;
xterm)	# use a local xterm, and run slogin within it
	usesh=false
	sshf=
	rsh=ssh
	rcmd1="$sshf"
	rcmd3="$rcmd5 $XONSSHARGS"
	rcmd4=-oFallBackToRsh=no
	rcmd0="$rcmd0 $Xopt $Kopt"
	xterm="xterm -T \"$label\" -e"
	redirect=
	background=" &"
	vars=
	xportlist=
	shc=
	quote=
	xonrc=
	;;
# Some people have "rsh" as a link to ssh -- allow them to make things faster
false)	case "$rsh" in /*) : OK ;; *) rsh="/usr/bin/$rsh";; esac
	vars="$xhome$xpath$xauth"DISPLAY="$DISPLAY";;
*)	vars="$xhome$xpath$xauth"DISPLAY="$DISPLAY";;
esac


# If no args, assume "xterm -ls"
case $#+$ssh in
*+xterm) : Nothing;;
0+*) set "$exec xterm $ls $xtermarg -name \"$resource\" -T \"$label\" -n \"$label\""
esac

# Avoid sitting in CWD
cd $cd

case "$vars" in ?*) vars="$vars;";; esac
case "$xportlist" in ?*) xportlist="export $xportlist;";; esac

# Using UTF8 causes lots of traffic (blocks an ADSL line for 30s),
# so if requested, remove .UTF-8 from LANG
case "$XON_LANG++$XON_KEEP_LANG++$LANG" in
?*++*++*)  		LANG="$XON_LANG";;
++true++*.UTF-8)	LANG=`echo $LANG | sed 's/.UTF-8//'`;
#++++*.UTF-8)    	LANG=`echo $LANG | sed 's/.UTF-8//'`;
esac

# Local session, or use ssh ?
case $usesh in
false)	run="$quote$vars$xportlist$xonrc$*$redirect$quote"
	# If we have an extra HOP, quote all the quotes.
	case "$HOP" in ?*) run=\"`echo "$run" | sed 's/"/\\\"/g'`\";; esac
	case "$background" in
	'') $echo $xterm $rsh $relay $rcmd0 $rcmd1 $rcmd2 $rcmd3 $rcmd4 $SendEnv $HOP $rcmd $rcmd6 $shc $run;;
	*)  $echo $xterm $rsh $relay $rcmd0 $rcmd1 $rcmd2 $rcmd3 $rcmd4 $SendEnv $HOP $rcmd $rcmd6 $shc $run&;;
	esac
	;;
true)	$echo $shc "$vars$xportlist$xonrc$*$redirect";;
esac
