#!/usr/bin/perl -w # # bsh - choose an appropriate remote shell command # # Some hosts you want to connect to with ssh, others with fsh, perhaps # others with a different remote shell program. Yet things like CVS # let you choose only one remote shell, set with an environment # variable. Rather than fixing CVS it is easier to create a wrapper # which knows how to connect to a given host. # use strict; my $NAME = 'bsh'; $SIG{__WARN__} = sub( $ ) { my $msg = shift; $msg = "$NAME: $msg" if defined $msg; warn $msg; }; $SIG{__DIE__} = sub( $ ) { my $msg = shift; $msg = "$NAME: $msg" if defined $msg; die $msg; }; my $CONF = "$ENV{HOME}/.$NAME"; my $DEFAULT_CONF = <$CONF") or die "cannot write to $CONF: $!"; print FH $DEFAULT_CONF or die "cannot write to $CONF: $!"; close FH or die "cannot close $CONF: $!"; } open(FH, $CONF) or die "cannot open $CONF: $!"; my @try; my %seen_try; my %host_rsh; while () { s/\#.*//; s/^\s+//; s/\s+$//; next if not length; my @f = split; if ($f[0] eq 'try') { if (@f != 2) { warn "$CONF:$.: syntax 'try COMMAND'\n"; next; } my $rsh = $f[1]; if ($seen_try{$rsh}++) { warn "$CONF:$.: $rsh already on try list, skipping\n"; next; } push @try, $rsh; } elsif ($f[0] eq 'host') { if (@f != 3) { warn "$CONF:$.: syntax 'host HOST COMMAND'\n"; next; } my ($host, $rsh) = @f[1, 2]; if (defined $host_rsh{$host}) { warn "$CONF:$.: host $host seen before, skipping\n"; next; } $host_rsh{$host} = $rsh; } else { warn "$CONF:$.: unrecognized word $f[0]\n"; } } # This program takes no arguments itself; all arguments are passed on # to the remote command. # my ($host, @cmd) = @ARGV; die "usage: $0 host command\nwhere command is multiple words\n" if not @cmd; my $rsh = $host_rsh{$host}; if (not defined $rsh) { warn "unknown host $host, trying to find out the remote shell command\n"; foreach (@try) { warn "trying $_\n"; if (system($_, $host, '/bin/true')) { warn "$_ failed\n"; } else { my $line = "host $host $_\n"; warn "succeeded, adding to $CONF: $line"; open(FH, ">>$CONF") or die "cannot append to $CONF: $!"; print FH $line or die "cannot write to $CONF: $!"; close FH or die "cannot close $CONF: $!"; $rsh = $_; last; } } } if (not defined $rsh) { die "unable to find any remote shell program that works\n"; } exit(system($rsh, $host, @cmd));