X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=lib%2FNet%2FFTP.pm;h=28ea97d947570a68abc0d66e4a432c534fbfce29;hb=564e2e78a483fb2c19eb2fe907d0dd36ce81fddb;hp=a1daedc00dbf168bbc3d615dcf724ab45337cc9e;hpb=686337f3173d259f9dc05f9d6c19a8c95e2cb00b;p=p5sagit%2Fp5-mst-13.2.git diff --git a/lib/Net/FTP.pm b/lib/Net/FTP.pm index a1daedc..28ea97d 100644 --- a/lib/Net/FTP.pm +++ b/lib/Net/FTP.pm @@ -19,9 +19,10 @@ use IO::Socket; use Time::Local; use Net::Cmd; use Net::Config; +use Fcntl qw(O_WRONLY O_RDONLY O_APPEND O_CREAT O_TRUNC); # use AutoLoader qw(AUTOLOAD); -$VERSION = "2.58"; # $Id: //depot/libnet/Net/FTP.pm#57 $ +$VERSION = "2.64"; # $Id: //depot/libnet/Net/FTP.pm#67 $ @ISA = qw(Exporter Net::Cmd IO::Socket::INET); # Someday I will "use constant", when I am not bothered to much about @@ -54,6 +55,7 @@ sub new my $host = $peer; my $fire = undef; + my $fire_type = undef; if(exists($arg{Firewall}) || Net::Config->requires_firewall($peer)) { @@ -66,6 +68,9 @@ sub new { $peer = $fire; delete $arg{Port}; + $fire_type = $arg{FirewallType} + || $ENV{FTP_FIREWALL_TYPE} + || undef; } } @@ -83,6 +88,8 @@ sub new ${*$ftp}{'net_ftp_firewall'} = $fire if(defined $fire); + ${*$ftp}{'net_ftp_firewall_type'} = $fire_type + if(defined $fire_type); ${*$ftp}{'net_ftp_passive'} = int exists $arg{Passive} @@ -115,28 +122,16 @@ sub new sub hash { my $ftp = shift; # self - my $prev = ${*$ftp}{'net_ftp_hash'} || [\*STDERR, 0]; - unless(@_) { - return $prev; - } my($h,$b) = @_; - if(@_ == 1) { - unless($h) { - delete ${*$ftp}{'net_ftp_hash'}; - return $prev; - } - elsif(ref($h)) { - $b = 1024; - } - else { - ($h,$b) = (\*STDERR,$h); - } + unless($h) { + delete ${*$ftp}{'net_ftp_hash'}; + return [\*STDERR,0]; } + ($h,$b) = (ref($h)? $h : \*STDERR, $b || 1024); select((select($h), $|=1)[0]); $b = 512 if $b < 512; ${*$ftp}{'net_ftp_hash'} = [$h, $b]; - $prev; } sub quit @@ -147,11 +142,7 @@ sub quit $ftp->close; } -sub DESTROY -{ - my $ftp = shift; - defined(fileno($ftp)) && $ftp->quit -} +sub DESTROY {} sub ascii { shift->type('A',@_); } sub binary { shift->type('I',@_); } @@ -221,14 +212,14 @@ sub size { my $line; foreach $line (@msg) { return (split(/\s+/,$line))[4] - if $line =~ /^[-rw]{10}/ + if $line =~ /^[-rwx]{10}/ } } else { my @files = $ftp->dir($file); if(@files) { return (split(/\s+/,$1))[4] - if $files[0] =~ /^([-rw]{10}.*)$/; + if $files[0] =~ /^([-rwx]{10}.*)$/; } } undef; @@ -250,7 +241,9 @@ sub login { $user ||= "anonymous"; $ruser = $user; - $fwtype = $NetConfig{'ftp_firewall_type'} || 0; + $fwtype = ${*$ftp}{'net_ftp_firewall_type'} + || $NetConfig{'ftp_firewall_type'} + || 0; if ($fwtype && defined ${*$ftp}{'net_ftp_firewall'}) { if ($fwtype == 1 || $fwtype == 7) { @@ -313,7 +306,7 @@ sub login { ($ruser,$pass,$acct) = $rc->lpa() if ($rc); - $pass = "-" . (eval { (getpwuid($>))[0] } || $ENV{NAME} ) . '@' + $pass = '-anonymous@' if (!defined $pass && (!defined($ruser) || $ruser =~ /^anonymous/o)); } @@ -418,12 +411,10 @@ sub get { my($ftp,$remote,$local,$where) = @_; - my($loc,$len,$buf,$resp,$localfd,$data); + my($loc,$len,$buf,$resp,$data); local *FD; - $localfd = ref($local) || ref(\$local) eq "GLOB" - ? fileno($local) - : undef; + my $localfd = ref($local) || ref(\$local) eq "GLOB"; ($local = $remote) =~ s#^.*/## unless(defined $local); @@ -440,7 +431,7 @@ sub get $data = $ftp->retr($remote) or return undef; - if(defined $localfd) + if($localfd) { $loc = $local; } @@ -448,7 +439,7 @@ sub get { $loc = \*FD; - unless(($where) ? open($loc,">>$local") : open($loc,">$local")) + unless(sysopen($loc, $local, O_CREAT | O_WRONLY | ($where ? O_APPEND : O_TRUNC))) { carp "Cannot open Local file $local: $!\n"; $data->abort; @@ -493,14 +484,14 @@ sub get carp "Cannot write to Local file $local: $!\n"; $data->abort; close($loc) - unless defined $localfd; + unless $localfd; return undef; } } print $hashh "\n" if $hashh; - unless (defined $localfd) + unless ($localfd) { unless (close($loc)) { @@ -679,17 +670,15 @@ sub appe { shift->_data_cmd("APPE",@_) } sub _store_cmd { my($ftp,$cmd,$local,$remote) = @_; - my($loc,$sock,$len,$buf,$localfd); + my($loc,$sock,$len,$buf); local *FD; - $localfd = ref($local) || ref(\$local) eq "GLOB" - ? fileno($local) - : undef; + my $localfd = ref($local) || ref(\$local) eq "GLOB"; unless(defined $remote) { croak 'Must specify remote filename with stream input' - if defined $localfd; + if $localfd; require File::Basename; $remote = File::Basename::basename($local); @@ -698,7 +687,7 @@ sub _store_cmd croak("Bad remote filename '$remote'\n") if $remote =~ /[\r\n]/s; - if(defined $localfd) + if($localfd) { $loc = $local; } @@ -706,7 +695,7 @@ sub _store_cmd { $loc = \*FD; - unless(open($loc,"<$local")) + unless(sysopen($loc, $local, O_RDONLY)) { carp "Cannot open Local file $local: $!\n"; return undef; @@ -736,7 +725,7 @@ sub _store_cmd { last unless $len = sysread($loc,$buf="",$blksize); - if (trEBCDIC) + if (trEBCDIC && $ftp->type ne 'I') { $buf = $ftp->toascii($buf); $len = length($buf); @@ -753,7 +742,7 @@ sub _store_cmd { $sock->abort; close($loc) - unless defined $localfd; + unless $localfd; print $hashh "\n" if $hashh; return undef; } @@ -762,7 +751,7 @@ sub _store_cmd print $hashh "\n" if $hashh; close($loc) - unless defined $localfd; + unless $localfd; $sock->close() or return undef; @@ -848,10 +837,9 @@ sub supported { my $text = $ftp->message; if($text =~ /following\s+commands/i) { $text =~ s/^.*\n//; - $text =~ s/\n/ /sog; - while($text =~ /(\w+)([* ])/g) { - $hash->{"\U$1"} = $2 eq " " ? 1 : 0; - } + while($text =~ /(\*?)(\w+)(\*?)/sg) { + $hash->{"\U$2"} = !length("$1$3"); + } } else { $hash->{$cmd} = $text !~ /unimplemented/i; @@ -1204,7 +1192,7 @@ Net::FTP - FTP Client class use Net::FTP; $ftp = Net::FTP->new("some.host.name", Debug => 0); - $ftp->login("anonymous",'me@here.there'); + $ftp->login("anonymous",'-anonymous@'); $ftp->cwd("/pub"); $ftp->get("that.file"); $ftp->quit; @@ -1251,17 +1239,22 @@ this if you really know what you're doing). =item new (HOST [,OPTIONS]) This is the constructor for a new Net::FTP object. C is the -name of the remote host to which a FTP connection is required. +name of the remote host to which an FTP connection is required. C are passed in a hash like fashion, using key and value pairs. Possible options are: -B - The name of a machine which acts as a FTP firewall. This can be +B - The name of a machine which acts as an FTP firewall. This can be overridden by an environment variable C. If specified, and the given host cannot be directly connected to, then the connection is made to the firewall machine and the string C<@hostname> is appended to the login identifier. This kind of setup is also refered to -as a ftp proxy. +as an ftp proxy. + +B - The type of firewall running on the machine indicated by +B. This can be overridden by an environment variable +C. For a list of permissible types, see the description of +ftp_firewall_type in L. B - This is the block size that Net::FTP will use when doing transfers. (defaults to 10240) @@ -1304,8 +1297,8 @@ Log into the remote FTP server with the given login information. If no arguments are given then the C uses the C package to lookup the login information for the connected host. If no information is found then a login of I is used. -If no password is given and the login is I then the users -Email address will be used for a password. +If no password is given and the login is I then I +will be used for password. If the connection is via a firewall then the C method will be called with no arguments. @@ -1393,7 +1386,7 @@ a scalar context, returns a reference to a list. =item get ( REMOTE_FILE [, LOCAL_FILE [, WHERE]] ) Get C from the server and store locally. C may be -a filename or a filehandle. If not specified the the file will be stored in +a filename or a filehandle. If not specified, the file will be stored in the current directory with the same leafname as the remote file. If C is given then the first C bytes of the file will @@ -1475,7 +1468,7 @@ reference to a C based object. =item nlst ( [ DIR ] ) -Send a C command to the server, with an optional parameter. +Send an C command to the server, with an optional parameter. =item list ( [ DIR ] ) @@ -1516,7 +1509,7 @@ C and those that do not require data connections. =item port ( [ PORT ] ) Send a C command to the server. If C is specified then it is sent -to the server. If not the a listen socket is created and the correct information +to the server. If not, then a listen socket is created and the correct information sent to the server. =item pasv () @@ -1592,7 +1585,7 @@ be performed using these. Read C bytes of data from the server and place it into C, also performing any translation necessary. C is optional, if not -given the the timeout value from the command connection will be used. +given, the timeout value from the command connection will be used. Returns the number of bytes read before any translation. @@ -1600,7 +1593,7 @@ Returns the number of bytes read before any translation. Write C bytes of data from C to the server, also performing any translation necessary. C is optional, if not -given the the timeout value from the command connection will be used. +given, the timeout value from the command connection will be used. Returns the number of bytes written before any translation. @@ -1717,6 +1710,6 @@ under the same terms as Perl itself. =for html
-I<$Id: //depot/libnet/Net/FTP.pm#57 $> +I<$Id: //depot/libnet/Net/FTP.pm#67 $> =cut