Skip Menu |

This queue is for tickets about the Net-SCP CPAN distribution.

Report information
The Basics
Id: 29985
Status: open
Priority: 0/
Queue: Net-SCP

People
Owner: Nobody in particular
Requestors: juice [...] lerch.org
Cc:
AdminCc:

Bug Information
Severity: Normal
Broken in: 0.04
Fixed in: (no value)



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