summaryrefslogtreecommitdiff
path: root/lib/Net/FTP.pm
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Net/FTP.pm')
-rw-r--r--lib/Net/FTP.pm113
1 files changed, 96 insertions, 17 deletions
diff --git a/lib/Net/FTP.pm b/lib/Net/FTP.pm
index dd863005e8..a1daedc00d 100644
--- a/lib/Net/FTP.pm
+++ b/lib/Net/FTP.pm
@@ -21,7 +21,7 @@ use Net::Cmd;
use Net::Config;
# use AutoLoader qw(AUTOLOAD);
-$VERSION = "2.56"; # $Id:$
+$VERSION = "2.58"; # $Id: //depot/libnet/Net/FTP.pm#57 $
@ISA = qw(Exporter Net::Cmd IO::Socket::INET);
# Someday I will "use constant", when I am not bothered to much about
@@ -36,6 +36,12 @@ sub pasv_xfer_unique {
$sftp->pasv_xfer($sfile,$dftp,$dfile,1);
}
+BEGIN {
+ # make a constant so code is fast'ish
+ my $is_os390 = $^O eq 'os390';
+ *trEBCDIC = sub () { $is_os390 }
+}
+
1;
# Having problems with AutoLoader
#__END__
@@ -205,7 +211,7 @@ sub size {
my $io;
if($ftp->supported("SIZE")) {
return $ftp->_SIZE($file)
- ? ($ftp->message =~ /(\d+)/)[0]
+ ? ($ftp->message =~ /(\d+)$/)[0]
: undef;
}
elsif($ftp->supported("STAT")) {
@@ -399,7 +405,7 @@ sub abort
send($ftp,pack("CCC", $TELNET_IAC, $TELNET_IP, $TELNET_IAC),MSG_OOB);
$ftp->command(pack("C",$TELNET_DM) . "ABOR");
-
+
${*$ftp}{'net_ftp_dataconn'}->close()
if defined ${*$ftp}{'net_ftp_dataconn'};
@@ -469,6 +475,13 @@ sub get
while(1)
{
last unless $len = $data->read($buf,$blksize);
+
+ if (trEBCDIC && $ftp->type ne 'I')
+ {
+ $buf = $ftp->toebcdic($buf);
+ $len = length($buf);
+ }
+
if($hashh) {
$count += $len;
print $hashh "#" x (int($count / $hashb));
@@ -487,10 +500,20 @@ sub get
print $hashh "\n" if $hashh;
- close($loc)
- unless defined $localfd;
-
- $data->close(); # implied $ftp->response
+ unless (defined $localfd)
+ {
+ unless (close($loc))
+ {
+ carp "Cannot close file $local (perhaps disk space) $!\n";
+ return undef;
+ }
+ }
+
+ unless ($data->close()) # implied $ftp->response
+ {
+ carp "Unable to close datastream";
+ return undef;
+ }
return $local;
}
@@ -542,7 +565,7 @@ sub rmdir
my $ok;
return $ok
- if $ftp->_RMD( $dir ) || !$recurse;
+ if $ok = $ftp->_RMD( $dir ) or !$recurse;
# Try to delete the contents
# Get a list of all the files in the directory
@@ -573,6 +596,18 @@ sub rmdir
return $ftp->_RMD($dir) ;
}
+sub restart
+{
+ @_ == 2 || croak 'usage: $ftp->restart( BYTE_OFFSET )';
+
+ my($ftp,$where) = @_;
+
+ ${*$ftp}{'net_ftp_rest'} = $where;
+
+ return undef;
+}
+
+
sub mkdir
{
@_ == 2 || @_ == 3 or croak 'usage: $ftp->mkdir( DIR [, RECURSE ] )';
@@ -606,7 +641,7 @@ sub mkdir
{
my($status,$message) = ($ftp->status,$ftp->message);
my $pwd = $ftp->pwd;
-
+
if($pwd && $ftp->cwd($dir))
{
$path = $dir;
@@ -701,6 +736,12 @@ sub _store_cmd
{
last unless $len = sysread($loc,$buf="",$blksize);
+ if (trEBCDIC)
+ {
+ $buf = $ftp->toascii($buf);
+ $len = length($buf);
+ }
+
if($hashh) {
$count += $len;
print $hashh "#" x (int($count / $hashb));
@@ -726,8 +767,11 @@ sub _store_cmd
$sock->close() or
return undef;
- ($remote) = $ftp->message =~ /unique file name:\s*(\S*)\s*\)/
- if ('STOU' eq uc $cmd);
+ if ('STOU' eq uc $cmd and $ftp->message =~ m/unique\ file\ name:(.*)\)|"(.*)"/)
+ {
+ require File::Basename;
+ $remote = File::Basename::basename($+)
+ }
return $remote;
}
@@ -747,11 +791,13 @@ sub port
${*$ftp}{'net_ftp_listen'} ||= IO::Socket::INET->new(Listen => 5,
Proto => 'tcp',
+ Timeout => $ftp->timeout,
+ LocalAddr => $ftp->sockhost,
);
-
+
my $listen = ${*$ftp}{'net_ftp_listen'};
- my($myport, @myaddr) = ($listen->sockport, split(/\./,$ftp->sockhost));
+ my($myport, @myaddr) = ($listen->sockport, split(/\./,$listen->sockhost));
$port = join(',', @myaddr, $myport >> 8, $myport & 0xff);
@@ -923,6 +969,11 @@ sub _list_cmd
$data->close();
+ if (trEBCDIC)
+ {
+ for (@$list) { $_ = $ftp->toebcdic($_) }
+ }
+
wantarray ? @{$list}
: $list;
}
@@ -996,9 +1047,9 @@ sub _data_cmd
return $data;
}
-
+
close(delete ${*$ftp}{'net_ftp_listen'});
-
+
return undef;
}
@@ -1151,7 +1202,7 @@ Net::FTP - FTP Client class
=head1 SYNOPSIS
use Net::FTP;
-
+
$ftp = Net::FTP->new("some.host.name", Debug => 0);
$ftp->login("anonymous",'me@here.there');
$ftp->cwd("/pub");
@@ -1307,6 +1358,13 @@ Change directory to the parent of the current directory.
Returns the full pathname of the current directory.
+=item restart ( WHERE )
+
+Set the byte offset at which to begin the next data transfer. Net::FTP simply
+records this value and uses it when during the next data transfer. For this
+reason this method will not return an error, but setting it may cause
+a subsequent data transfer to fail.
+
=item rmdir ( DIR )
Remove the directory with the name C<DIR>.
@@ -1343,7 +1401,7 @@ not be transfered, and the remaining bytes will be appended to
the local file if it already exists.
Returns C<LOCAL_FILE>, or the generated local file name if C<LOCAL_FILE>
-is not given.
+is not given. If an error was encountered undef is returned.
=item put ( LOCAL_FILE [, REMOTE_FILE ] )
@@ -1546,6 +1604,10 @@ given the the timeout value from the command connection will be used.
Returns the number of bytes written before any <CRLF> translation.
+=item bytes_read ()
+
+Returns the number of bytes read so far.
+
=item abort ()
Abort the current data transfer.
@@ -1625,6 +1687,19 @@ L<Net::Cmd>
ftp(1), ftpd(8), RFC 959
http://www.cis.ohio-state.edu/htbin/rfc/rfc959.html
+=head1 USE EXAMPLES
+
+For an example of the use of Net::FTP see
+
+=over 4
+
+=item http://www.csh.rit.edu/~adam/Progs/autoftp-2.0.tar.gz
+
+C<autoftp> is a program that can retrieve, send, or list files via
+the FTP protocol in a non-interactive manner.
+
+=back
+
=head1 CREDITS
Henry Gabryjelski <henryg@WPI.EDU> - for the suggestion of creating directories
@@ -1640,4 +1715,8 @@ Copyright (c) 1995-1998 Graham Barr. All rights reserved.
This program is free software; you can redistribute it and/or modify it
under the same terms as Perl itself.
+=for html <hr>
+
+I<$Id: //depot/libnet/Net/FTP.pm#57 $>
+
=cut