We help IT Professionals succeed at work.

"rsh" command in Perl

skundu
skundu asked
on
I need to use "rsh" command to remote login to
other hosts and execute some commands (for
simplicity say commands like "domainname" or
"last", etc). Now all remote hosts do not
permit rsh login to them. But my script, that
attempts login to those hosts (that will eventually
deny rsh login), takes too much time (several
minutes) before it (the script) outputs the
error ("permission denied"). Whereas those host that
allow rsh login take seconds to execute the rsh command.
I need to write a function in perl in the script itself, that will let me know if the remote host will permit
rsh login or not (before actually trying to rsh
login)...And if it permits, I will go ahead with
that host otherwise will leave that host.
Please note I used "ping" to solve this problem but all hosts respond to it (including those that denies rsh).
Working on the return value of rsh command will
not help because that command (rsh) will take
that several minutes to execute for those hosts
that denies login.

I tried with some socket scripts...but I am not sure
how I can create a socket to connect to another host
and see if connection can be established or not...but
could not make it work...(did not work on it before)
I'm writing a part of script, please let me know how
I can make it work:
***************************
#!/usr/misc/bin/perl
use strict;
use Socket;

$| = 1;

my $port = getservbyname('echo', 'tcp');
my $proto = getprotobyname('tcp');
my $host = 'myhost.mydomain.com';
my $hostaddr = inet_aton($host) or die "unknown host";

my $hostpaddr = sockaddr_in($port, $hostaddr);

socket(SOCKET, PF_INET, SOCK_STREAM, $proto) or die "socket: $!";
connect(SOCKET, $hostpaddr) or die "socket: $!";
.....
.....
***************************

Else, if you have any other idea about it, please let
me know.

thanks alot.
su
Comment
Watch Question

Commented:

This perl will test for an open rsh port on host $hostname, with a 5 second timeout on the initial connection...


use IO::Socket;

my $s = new IO::Socket::INET( 'PeerAddr' => $hostname,
                              'PeerPort' => 514,
                              'Timeout'  => 5
                            );
if ( defined $s )
{
   print "the rsh port on $hostname is open\n";
}
else
{
   print "the rsh port on $hostname is closed\n";
}


Hope that helps.

Author

Commented:
Thanks. I tried your code...
Actually in this code

my $hostname="fish.uic.edu";
my $s = new IO::Socket::INET( 'PeerAddr' => $hostname,'PeerPort' => 514,'Timeout'  => 5);

$s returned some value (like "IO::Socket::INET=GLOB(0x1826fc)") for all existing correct hostnames. For an
incorrect (that does not exist or so), it returns
nothing.

The code correctly says if the rsh port of the
host $hostname is open. But even if it is open
it may not let me rsh to it ($hostname) with
my (owner of the script) login. So even if $s is
defined, I may not be able to login to the host
$hostname from my script.....problem remains..

Ok, is there any way, I could put a "Timeout" constraint
in my Perl code that executes a system command (that
include rsh)??
Example: In my script I write:
#####
my $hostname="fish.uic.edu";
my $ret=`rsh $hostname ls`;
#above line attempts to rsh to host $hostname
#to execute the command "ls"...Can I put a
"Timeout" constraint for this line of code?
I mean, if that line cannot execute in 5sec,
it will abort execution and continue...

Help!
thanks alot...
su

Commented:
You can put a timeout on a system command like this:

sub alarm_timemout
{
   die "rsh timed out";
}

my $ret = eval {
  alarm(5);
  $SIG{ALRM} = \&alarm_timeout;
   `rsh $hostname ls`;
   alarm(0);
}

if ( $@ )
{
   print "rsh to $hostname timed out\n";
}
else
{
   print "rsh to $hostname returned $ret\n";
}

Commented:
I messed up.  I meant like this:


sub alarm_timemout
{
   die "rsh timed out";
}

my $ret = eval {
   alarm(5);
   $SIG{ALRM} = \&alarm_timeout;
   my $r = `rsh $hostname ls`;
   alarm(0);
   $r;
}

if ( $@ )
{
   print "rsh to $hostname timed out\n";
}
else
{
   print "rsh to $hostname returned $ret\n";
}
Commented:
I'm not having a good day today :)

this one works though:



sub alarm_timeout
{
   die "rsh timed out";
}

my $ret = eval {
   $SIG{ALRM} = \&alarm_timeout;
   alarm(5);
   my $r = `rsh $hostname ls`;
   alarm(0);
   $r;
};

if ( $@ )
{
   print "rsh to $hostname timed out\n";
}
else
{
   print "rsh to $hostname returned $ret\n";
}

Explore More ContentExplore courses, solutions, and other research materials related to this topic.