#!/usr/bin/perl -w ## ## rterm: A fancy way to do "xterm -e rlogin host" ## Author: Bart Robinson ## $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-" 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 = $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; }