#!/usr/bin/perl -w
##
## rterm: A fancy way to do "xterm -e rlogin host"
## Author: Bart Robinson <lomew@cs.utah.edu>
## $Id: rterm,v 1.8 1999-07-01 13:19:06-07 lomew Exp lomew $
##
## Features:
##	- passing the DISPLAY var to the remote login process
##	- picking colors based on the hostname or a command line arg
##	- picking xterm titles based on the hostname
##	- warping to the new xterm
##
## DISPLAY passing
## ---------------
## The only environment variable that rlogin will pass to the remote
## login process is TERM.  So we stick an encoded TERM in rlogin's env
## and the .login (or similar) on the other end decodes it and sets
## DISPLAY.  One thing to note is that rlogin passes term as
## "TERM/SPEED" so we should make sure the term we pass has no slashes
## in it.  Here is the magic from my .login:
##
##	if ($TERM =~ xyzzy*) then
##	  eval `echo $TERM \
##		| awk -F, '{print "setenv TERM ", $3, "; setenv DISPLAY " $2}'`
##	  echo "*** DISPLAY set to $DISPLAY"
##	endif
##
## Color choosing
## --------------
## This program sets the xterm color by passing a -name arg to xterm.
## The -name arg tells xterm to look for resources under a different
## name than "xterm".  In my .Xresources I specify resources for
## several names such as "xterm-green", "xterm-gray", etc.  The -name
## arg is built as "-name xterm-<color>" where color chosen as
## follows: first, if a -color option was passed in front of the
## hostname, that color will be used; second, if there is an entry in
## the %htocolor table that will be used; otherwise, the color will be
## chosen by hashing the hostname and indexing into @colors.  Here are
## some examples from my .Xresources (you might call it .Xdefaults)
##
##	xterm-briteblue*background		: steelblue
##	xterm-briteblue*foreground		: lemonchiffon
##	xterm-paleblue*background		: skyblue4
##	xterm-paleblue*foreground		: lemonchiffon
##	xterm-grayblue*background		: cadetblue4
##	xterm-grayblue*foreground		: lemonchiffon
##	xterm-green*background			: aquamarine4
##	xterm-green*foreground			: lemonchiffon
##	xterm-gray*background			: gray70
##	xterm-gray*foreground			: navy
##	xterm-magenta*background		: magenta4
##	xterm-magenta*foreground		: lemonchiffon
##	xterm-purple*background			: purple4
##	xterm-purple*foreground			: yellow
##
## Title choosing
## --------------
## The title of the xterm is determined by the %htotitle table.  If a
## hostname isn't in this table, the title will be the same as the
## hostname.
##
## Warping to the new window
## -------------------------
## The pointer will be warped to the middle of the new window by a program
## called "warpto".  If this program isn't found in your path, then no
## warping will be done.  Source for "warpto" can be found in
##	~lomew/lib/c-scraps/Xlib/warpto.c
##

require 5;
use Sys::Hostname;

$rlogin = "slogin";

$0 =~ s-.*/--;			# want basename only
die "usage: $0 [-ssh] [-color] [user@]host [-ssh] [-color] [user@]host ...\n" unless $#ARGV >= 0;

$localhost = hostname();

## Map hostnames into colors.  
%htocolor = (
    "user1\@host"	=> "skyblue4",
    "host2"	=> "gray",
    "user2\@host3" => "steelblue",
);

## Map hostnames into xterm titles.  If a hostname isn't in this
## table, the title is the hostname.
%htotitle = (
    "sal" => "salabama",
    "lal" => "lalabama",
);

## List of colors we index into with a hashed hostname.
#@colors = ("blue", "green", "gray", "grayblue", "green", "blue", "gray");
@colors = ("steelblue", "skyblue4", "cadetblue4", "aquamarine4","purple","green","magenta","magenta4");

## Figure out the DISPLAY to pass and encode it.  If the DISPLAY env
## var specifies a remote host use that, otherwise replace the host
## part with our hostname.
die "no DISPLAY env var\n" unless $ENV{DISPLAY};
$displaytopass = $ENV{DISPLAY};
($h, $d) = split(':', $ENV{DISPLAY});
if ($h eq '' || $h eq 'unix' || $h eq 'localhost') {
    $displaytopass = $localhost . ":" . $d;
}
#$encodedterm = "xyzzy,$displaytopass,xterm";

## Start an xterm for each host.
for ($i = 0; $i <= $#ARGV; $i++) {
    $arg = $ARGV[$i];
   	print "XXXXXXX $arg XXXXXXXXXX\n";
    if ($arg eq "-l") {
	$who = "-l $ARGV[$i+1]";

	$arg = $ARGV[$i+2];
	$i += 2;
    }
    if ($arg eq "-ssh") {
	$rlogin = "slogin";

	$arg = $ARGV[$i+1];
	$i++;
    }
    if ($arg =~ /^-(.*)/) {		# -<color> <host>
	$color = $1;
	$host = $ARGV[++$i];
    }
    elsif ($htocolor{$arg}) {
	$color = $htocolor{$arg};
	$host = $arg;
    }
    else {
	$color = $colors[&hash($arg, scalar(@colors))];
	$host = $arg;
    }

    ## Maybe the host looks like user@host.
    $who = "";
    if ($host =~ /@/) {
	($who, $host) = split('@', $host);
	$who = "-l $who";
    }

    $title = $htotitle{$host} || $host;

    if ($rlogin eq "") {
	$fullname = (gethostbyname($host))[0];
	if (! defined($fullname)) {
	    $fullname = $host;
	}
	if (domainof($fullname) ne domainof($localhost)) {
	    $rlogin = "slogin";
	}
	else {
	    $rlogin = "rlogin";
	}
    }
    system "xterm -title $title -bg $color \\
	    -e sh -c '(warpto) >/dev/null 2>&1;  exec $rlogin $who $host' &";
	    #-e sh -c '(warpto) >/dev/null 2>&1; TERM=$encodedterm; export TERM; exec $rlogin $who $host' &";
}

## Taken from Sedgewick.
sub hash {
    my ($key, $tablesize) = @_;
    my $char = 0;
    my $hashval = 0;

    foreach $char (unpack('c*', $key)) {
	$hashval = (($hashval << 6) + $char) % $tablesize;
    }

    return $hashval;
}

sub domainof {
    my $host = shift;

    $host =~ s/.*?\.//;
    return $host;
}
