Updated Rexec to handle setting of prompt to @@@ properly.
authorandrew <Andrew@DeFaria.com>
Mon, 7 Apr 2014 03:49:27 +0000 (20:49 -0700)
committerandrew <Andrew@DeFaria.com>
Mon, 7 Apr 2014 03:49:27 +0000 (20:49 -0700)
lib/Rexec.pm
test/testrexec.pl

index bf59072..71fdd22 100644 (file)
@@ -160,6 +160,18 @@ our @EXPORT = qw (
 
 my @lines;
 
+sub _debug ($) {\r
+  my ($msg) = @_;
+  
+  my $logfile = "/tmp/rexex_debug.log";
+  
+  open my $file, '>>', $logfile or die "Unable to open $logfile for writing - $!";
+  
+  print $file "DEBUG: $msg\n";
+  
+  close $file;\r
+} # _debug
+
 sub ssh {
   my ($self) = shift;
 
@@ -228,12 +240,19 @@ sub ssh {
     $self->{prompt} = '@@@';
     $self->{handle} = $remote;
 
+    # OK this is real tricky. If we call execute with a command of PS1=@@@
+    # and we've changed our prompt to '@@@' then we'll see the '@@@' in the
+    # PS1=@@@ statement as the prompt! That'll screw us up so we instead say
+    # PS1=\@\@\@. The shell then removes the extra backslashes for us and sets
+    # the prompt to just "@@@" for us. We catch that as our prompt and now we
+    # have a unique prompt that we can easily recognize.
     if ($self->{shellstyle} eq 'sh') {
-      $self->execute ('PS1=@@@');
+      $self->execute ('PS1=\@\@\@');
     } else {
-      $self->execute ('set prompt=@@@');
+      $self->execute ('set prompt=\@\@\@');
     } # if
 
+    $self->{handle}->flush;
     return $remote;
   } elsif ($timedout) {
     carp "WARNING: $self->{host} is not responding to $self->{protocol} protocol";
@@ -313,10 +332,16 @@ sub rlogin {
     $self->{prompt} = '@@@';
     $self->{handle} = $remote;
 
+    # OK this is real tricky. If we call execute with a command of PS1=@@@
+    # and we've changed our prompt to '@@@' then we'll see the '@@@' in the
+    # PS1=@@@ statement as the prompt! That'll screw us up so we instead say
+    # PS1=\@\@\@. The shell then removes the extra backslashes for us and sets
+    # the prompt to just "@@@" for us. We catch that as our prompt and now we
+    # have a unique prompt that we can easily recognize.
     if ($self->{shellstyle} eq 'sh') {
-      $self->execute ('PS1=@@@');
+      $self->execute ('PS1=\@\@\@');
     } else {
-      $self->execute ('set prompt=@@@');
+      $self->execute ('set prompt=\@\@\@');
     } # if
 
     return $remote;
@@ -412,10 +437,16 @@ sub telnet {
     $self->{prompt} = '@@@';
     $self->{handle} = $remote;
 
+    # OK this is real tricky. If we call execute with a command of PS1=@@@
+    # and we've changed our prompt to '@@@' then we'll see the '@@@' in the
+    # PS1=@@@ statement as the prompt! That'll screw us up so we instead say
+    # PS1=\@\@\@. The shell then removes the extra backslashes for us and sets
+    # the prompt to just "@@@" for us. We catch that as our prompt and now we
+    # have a unique prompt that we can easily recognize.
     if ($self->{shellstyle} eq 'sh') {
-      $self->execute ('PS1=@@@');
+      $self->execute ('PS1=\@\@\@');
     } else {
-      $self->execute ('set prompt=@@@');
+      $self->execute ('set prompt=\@\@\@');
     } # if
 
     return $remote;
@@ -708,7 +739,7 @@ retained in the object. Use status method to retrieve it.
   # Hopefully we will not see the following in the output string
   my $errno_str = "ReXeCerRoNO=";
   my $start_str = "StaRT";
-
+  
   my $compound_cmd;
 
   # If cmd ends in a & then it makes no sense to compose a compound
index 07ab995..8f0388e 100755 (executable)
@@ -2,6 +2,9 @@
 use strict;
 use warnings;
 
+use Getopt::Long;
+use Pod::Usage; 
+
 use FindBin;
 
 use lib "$FindBin::Bin/../lib";
@@ -10,36 +13,45 @@ use Rexec;
 
 my ($status, $cmd, @output);
 
-my $hostname = $ENV{HOST}     || 'localhost';
-my $username = $ENV{USERNAME};
-my $password = $ENV{PASSWORD};
+my %opts = (
+  usage    => sub { podusage() } ,
+  hostname => $ENV{HOST}     || 'localhost',
+  username => $ENV{USERNAME} ? $ENV{USERNAME} : $ENV{USER},
+  password => $ENV{PASSWORD},
+  command  => 'ls /tmp',
+);
 
-my $command  = $ENV{COMMAND};
+GetOptions (
+  \%opts,
+  'usage',
+  'host=s',
+  'host=s',
+  'username=s',
+  'password=s',
+  'command=s'
+);
 
 if (@ARGV) {
-  $command = join ' ', @ARGV;
-} else {
-  $command = 'ls /tmp' unless $command;  
+  $opts{command} = join ' ', @ARGV;
 } # if
 
-print "Attempting to connect to $username\@$hostname to execute \"$command\"\n";
+print "Attempting to connect to $opts{username}\@$opts{hostname} to execute \"$opts{command}\"\n";
 
 my $remote = Rexec->new (
-  host     => $hostname,
-  username => $username,
-  password => $password,
-  timeout  => 30,
+  host     => $opts{hostname},
+  username => $opts{username},
+  password => $opts{password},
 );
 
 if ($remote) {
-  print "Connected to $username\@$hostname using "
+  print "Connected to $opts{username}\@$opts{hostname} using "
       . $remote->{protocol} . " protocol\n";
 
-  print "Executing command \"$command\" on $hostname as $username\n";    
-  @output = $remote->execute ($command);
+  print "Executing command \"$opts{command}\" on $opts{hostname} as $opts{username}\n";    
+  @output = $remote->execute ($opts{command});
   $status = $remote->status;
 
-  print "\"$command\" status: $status\n";
+  print "\"$opts{command}\" status: $status\n";
 
   if (@output == 0) {
     print "No lines of output received!\n";
@@ -47,5 +59,5 @@ if ($remote) {
     print "$_\n" foreach (@output);
   } # if
 } else {
-  print "Unable to connect to $username@$hostname\n";
+  print "Unable to connect to $opts{username}\@$opts{hostname}\n";
 } # if
\ No newline at end of file