Subject: | PATCH: clean up OO, other fixes |
I'm believe I made it a little more robust. For instance, when the
remote server was down/not response/refusing connections, $? is not
set leaving you think everything succeed until you looked for the file
you requested. Now those type of warnings/errors are stored in
warnstr().
Here's an example script of how you'd look for some of those warnings:
print "connecting to $host as user $user\n";
my $scp = Net::SCP->new( { 'host' => $host,
'user' => $user,
}
);
print "attempting to get file $file\n";
unless ($scp->get($file,$dest)) {
print 'SCP failed! ',$scp->errstr(),"\n";
exit(0);
}
unless (-e $dest) {
print 'why no file? ',$scp->warnstr(),"\n";
}
exit(1);
===================================================================
When you do a put, that's when it would be nice to see size() work
so you could run a similar test.
Some of the tests I ran included when the file did not exist on the
remote server, when the remote server was down, when the file did
not exist on the local server and when the remote server required
a password doing both put & gets. I guess I
should scripted it all up.
Here's the list of my changes and a couple of comments:
- changes all interact to interactive to match the documentation.
now when I instantiate an object and set 'interactive', all
the code recognizes it.
- within the get method, called scp() with $self->scp().
this helped with getting back error messages and also
gave it the ability to see the 'interactive' flag
on the object. this is assuming get() isn't suppose
to be used in the procedural interface.
- within the put method, called scp() with $self->scp().
- added method errstr for cleaner access to that member variable.
maybe not the best name.
- added method warnstr. if you cannot connect to the remote
host it does not set $!, but there is a message in ERRFH.
maybe not the best name.
- grabbed what was in the ERRFH and saved it off. then used it as an
addition check at the if ( $? ) statement. it catches warnings
warnings like "warning: Executing scp1 compatibility." when the
overall procedure was a success.
- removed $scp as a global.
- in SYNOPSIS, it mentions a quit method that does not exist.
- Net::SCP->size() doesn't work
- it would be nice to be able to get error messages back when using
procedural interface.
I'll probably look into why size() isn't working because that would
be a nice to have to verify puts.
Just so you know, I'm running Linux 2.2.16, OpenSSH 2 and
Perl 5.005_03.
I hope this is helpful.
Justin
Subject: | SCP.diff |
--- /home/jbedard/downloads/docs/work/comcast/downloads/Net-SCP-0.04/SCP.pm Thu Feb 22 02:43:17 2001
+++ SCP.pm Wed Jun 6 18:16:05 2001
@@ -1,7 +1,7 @@
package Net::SCP;
use strict;
-use vars qw($VERSION @ISA @EXPORT_OK $scp);
+use vars qw($VERSION @ISA @EXPORT_OK);
use Exporter;
use Carp;
use File::Basename;
@@ -14,8 +14,6 @@
@EXPORT_OK = qw( scp iscp );
$VERSION = '0.04';
-$scp = "scp";
-
=head1 NAME
Net::SCP - Perl extension for secure copy protocol
@@ -68,36 +66,46 @@
=cut
sub scp {
- my $self = ref($_[0]) ? shift : {};
- my($src, $dest, $interact) = @_;
+ my $self = ref($_[0]) ? shift : Net::SCP->new();
+ my($src, $dest, $interactive) = @_;
+ my $scp = 'scp';
+ # reset in case you do a size() then scp() or something like that.
+ # you should check these after each call to one of these methods.
+ $self->errstr(undef);
+ $self->warnstr(undef);
+
my $flags = '-p';
$flags .= 'r' unless &_islocal($src) && ! -d $src;
my @cmd;
- if ( ( defined($interact) && $interact )
- || ( defined($self->{interact}) && $self->{interact} ) ) {
+ if ( ( defined($interactive) && $interactive )
+ || ( defined($self->{'interactive'}) && $self->{'interactive'} ) ) {
@cmd = ( $scp, $flags, $src, $dest );
print join(' ', @cmd), "\n";
unless ( &_yesno ) {
- $self->{errstr} = "User declined";
+ $self->errstr('User declined');
return 0;
}
} else {
$flags .= 'qB';
@cmd = ( $scp, $flags, $src, $dest );
}
+
my($reader, $writer, $error ) =
( new IO::Handle, new IO::Handle, new IO::Handle );
$writer->autoflush(1);# $error->autoflush(1);
my $pid = open3($writer, $reader, $error, @cmd );
+ my $errstr = join('',<$error>);
+ chomp($errstr);
+
waitpid $pid, 0;
+
if ( $? >> 8 ) {
- my $errstr = join('', <$error>);
- #chomp(my $errstr = <$error>);
- $self->{errstr} = $errstr;
- 0;
- } else {
- 1;
+ $self->errstr($errstr);
+ return 0;
+ } elsif ( $errstr ) {
+ $self->warnstr($errstr);
}
+ return 1;
}
=item iscp SOURCE, DESTINATION
@@ -115,7 +123,7 @@
sub iscp {
if ( ref($_[0]) ) {
my $self = shift;
- $self->{'interact'} = 1;
+ $self->{'interactive'} = 1;
$self->scp(@_);
} else {
scp(@_, 1);
@@ -158,6 +166,7 @@
if ( ref($_[0]) ) {
$self = shift;
} else {
+
$self = {
'host' => shift,
'user' => ( scalar(@_) ? shift : '' ),
@@ -179,6 +188,33 @@
$self->{'user'} = $user if $user;
}
+=item errstr [MESSAGE]
+
+get/set for error messages.
+
+=cut
+
+sub errstr {
+ my($self,$err) = @_;
+ $self->{'errstr'} = $err if $err;
+ return $self->{'errstr'};
+}
+
+=item warnstr [ MESSAGE ]
+
+Exactly like errstr() but should be used for lower
+level warnings like: "warning: Executing scp1 compatibility."
+Also, when connections are refused, $? is never set, so you
+can see "Secure connection to localhost refused." in warnstr().
+
+=cut
+
+sub warnstr {
+ my($self,$err) = @_;
+ $self->{'warnstr'} = $err if $err;
+ return $self->{'warnstr'};
+}
+
=item cwd CWD
Sets the cwd (used for a subsequent get or put request without a full pathname).
@@ -203,7 +239,7 @@
$local ||= basename($remote);
my $source = $self->{'host'}. ":$remote";
$source = $self->{'user'}. '@'. $source if $self->{'user'};
- scp($source,$local);
+ $self->scp($source,$local);
}
=item size FILE
@@ -220,6 +256,10 @@
sub size {
my($self, $file) = @_;
+ # reset in case you do a size() then scp() or something like that.
+ # you should check these after each call to one of these methods.
+ $self->errstr(undef);
+
$file = $self->{'cwd'}. "/$file" if $self->{'cwd'} && $file !~ /^\//;
my $host = $self->{'host'};
$host = $self->{'user'}. '@'. $host if $self->{'user'};
@@ -230,16 +270,17 @@
my $pid =
sshopen3($host, $writer, $reader, $error, 'wc', '-c ', shell_quote($file) );
waitpid $pid, 0;
- if ( $? >> 8 ) {
- chomp(my $errstr = <$error>);
- $self->{errstr} = $errstr || "wc exited with status ". $?>>8;
+
+ chomp(my $errstr = <$error>);
+ if ( $? >> 8 || $errstr ) {
+ $self->errstr($errstr || "wc exited with status ". $?>>8);
0;
} else {
chomp( my $size = <$reader> || 0 );
if ( $size =~ /^\s*(\d+)/ ) {
$1 ? $1 : '0e0';
} else {
- $self->{errstr} = "unparsable output from remote wc: $size";
+ $self->errstr("unparsable output from remote wc: $size");
0;
}
}
@@ -259,7 +300,7 @@
my $dest = $self->{'host'}. ":$remote";
$dest = $self->{'user'}. '@'. $dest if $self->{'user'};
warn "scp $local $dest\n";
- scp($local, $dest);
+ $self->scp($local, $dest);
}
=item binary