Wednesday, October 24, 2007

Exceed, Cygwin, and Terminal Server

... or "How to waste an afternoon"

I've been having trouble getting the combination of MS Terminal Server 2003, Hummingbird Exceed 2006, and Cygwin to work together.

Cygwin's Xfree86 doesn't work well for Terminal Server, since Cygwin's X has one global X.log file that is owned by and read-only for only one user at a time. So we use Hummingbird Exceed on the Terminal Server.

But Exceed doesn't come with xterm, ssh, etc. They expect you to use rsh, rexec, or a program you configure with their proprietary goo to connect to your remote systems. Not my style.

Background

X programs running on a remote host can display on your computer through the use of a lot of complicated technology, much of which depends on a properly set environment variable named DISPLAY. It's format is

DISPLAY=your.hostname:N.m

where "your.hostname" is either the domain name your ISP gives you, an IP address, or the special name "localhost". All computers on the Internet believe that they themselves are "localhost".

Ssh programs (either the proprietary ones from SSh, Inc., or free versions such as openssh or putty) have a wonderful feature: they can hijack data to be sent to your local computer, encrypt it, send it over their secure connection, and deliver it to your local computer for display. They do this by setting the remote DISPLAY variable to (for example) "localhost:10.0". Remote programs you run send their output to remote display 10, screen 0. Ssh receives the data, encrypts, delivers, decrypts, and sends to whatever your local DISPLAY variable says.

But I've not been able to find a Windows-based Ssh program that is able to tunnel X11 connections with remote hosts to Exceed. In the past, I've just looked at the display number in the Exceed taskbar button and set DISPLAY manually, losing the benefits of tunneling.

A little digging turned up some documentation (pdf), which says:

While Exceed sessions are running, the display numbers are tracked through a dynamic file called Display Snapshot.HumTable. This is located in

C:\Documents and Settings\All Users\Application Data\Hummingbird\Connectivity\11.00\Global\Exceed\Display Snapshot.HumTable

As this is dynamic, it should not be edited manually.
Ok, now I know what to do. I can grab the DISPLAY number from that file, which by the grace of Hummingbird is a text file and not more proprietary goo. Unfortunately, it's a Windows file, with an ugly filename with spaces in it. So I need a script to turn that into a Cygwin name:

In /etc/profile on your Terminal Server, put the following:


HUMTABLE="C:\Documents and Settings\All Users\Application \
\Data\Hummingbird\Connectivity\11.00\Global\Exceed\Display Snapshot.HumTable"

#
# sanify - turn a Windows directory name into a Unix name
# - turns drive letters into /cygdrive/drive,
# - flips slashes, removes enclosing quotes,
# - replaces unusual characters with '?'
function sanify() {
echo ${@} | sed \
-e 's,^[A-Za-z]:,/cygdrive/&,'\
-e 's,:,,g' \
-e 's,\\,/,g' \
-e 's,^\",,g' \
-e 's,\"$,,g' \
-e 's,[^A-Za-z0-9_\.-],\?,g'
}
# disp() grabs the information from the Humtable file
# and puts it in the right format.

DOMAIN=your_windows_domain

function disp() {
EX_LF="`sanify ${HUMTABLE}`"
[ -r $EX_LF ] && {
cat $EX_LF | awk -v d=$DOMAIN u=${USERNAME} \
'BEGIN {FS=","}\
$3 ~ d "." u {print "localhost:" $4 ".0";}'
}
}
export DISPLAY=`disp`


[Updated 20071026 to touch the script a bit]

Thursday, October 04, 2007