/usr/share/perl5/Net/INET6Glue/FTP.pm is in libnet-inet6glue-perl 0.603-2.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 | use strict;
use warnings;
package Net::INET6Glue::FTP;
our $VERSION = 0.6;
############################################################################
# implement EPRT, EPSV for Net::FTP to support IPv6
############################################################################
use Net::INET6Glue::INET_is_INET6;
use Net::FTP; # tested with 2.77, 2.79
BEGIN {
my %tested = map { $_ => 1 } qw(2.77 2.79);
warn "Not tested with Net::FTP version $Net::FTP::VERSION"
if ! $tested{$Net::FTP::VERSION};
}
use Socket;
use Carp 'croak';
if ( defined &Net::FTP::_EPRT ) {
# Net::SSLGlue::FTP and Net::FTP 2.80 implement IPv6 too
warn "somebody else already implements FTP IPv6 support - skipping ".
__PACKAGE__."\n";
} else {
# implement EPRT
*Net::FTP::_EPRT = sub {
shift->command("EPRT", @_)->response() == Net::FTP::CMD_OK
};
*Net::FTP::eprt = sub {
@_ == 1 || @_ == 2 or croak 'usage: $ftp->eprt([PORT])';
my ($ftp,$port) = @_;
delete ${*$ftp}{net_ftp_intern_port};
unless ($port) {
my $listen = ${*$ftp}{net_ftp_listen} ||=
$Net::INET6Glue::INET_is_INET6::INET6CLASS->new(
Listen => 1,
Timeout => $ftp->timeout,
LocalAddr => $ftp->sockhost,
);
${*$ftp}{net_ftp_intern_port} = 1;
my $fam = ($listen->sockdomain == AF_INET) ? 1:2;
$port = "|$fam|".$listen->sockhost."|".$listen->sockport."|";
}
my $ok = $ftp->_EPRT($port);
${*$ftp}{net_ftp_port} = $port if $ok;
return $ok;
};
# implement EPSV
*Net::FTP::_EPSV = sub {
shift->command("EPSV", @_)->response() == Net::FTP::CMD_OK
};
*Net::FTP::epsv = sub {
my $ftp = shift;
@_ and croak 'usage: $ftp->epsv()';
delete ${*$ftp}{net_ftp_intern_port};
$ftp->_EPSV && $ftp->message =~ m{\(([\x33-\x7e])\1\1(\d+)\1\)}
? ${*$ftp}{'net_ftp_pasv'} = $2
: undef;
};
# redefine PORT and PASV so that they use EPRT and EPSV if necessary
no warnings 'redefine';
my $old_port = \&Net::FTP::port;
*Net::FTP::port =sub {
goto &$old_port if $_[0]->sockdomain == AF_INET or @_<1 or @_>2;
goto &Net::FTP::eprt;
};
my $old_pasv = \&Net::FTP::pasv;
*Net::FTP::pasv = sub {
goto &$old_pasv if $_[0]->sockdomain == AF_INET or @_<1 or @_>2;
goto &Net::FTP::epsv;
};
# redefined _dataconn to make use of the data it got from EPSV
# copied and adapted from Net::FTP::_dataconn
my $old_dataconn = \&Net::FTP::_dataconn;
*Net::FTP::_dataconn = sub {
goto &$old_dataconn if $_[0]->sockdomain == AF_INET;
my $ftp = shift;
my $pkg = "Net::FTP::" . $ftp->type;
eval "require $pkg";
$pkg =~ s/ /_/g;
delete ${*$ftp}{net_ftp_dataconn};
my $data;
if ( my $port = ${*$ftp}{net_ftp_pasv} ) {
$data = $pkg->new(
PeerAddr => $ftp->peerhost,
PeerPort => $port,
LocalAddr => ${*$ftp}{net_ftp_localaddr},
);
} elsif (my $listen = delete ${*$ftp}{net_ftp_listen}) {
$data = $listen->accept($pkg);
close($listen);
}
return if ! $data;
$data->timeout($ftp->timeout);
${*$ftp}{net_ftp_dataconn} = $data;
${*$data} = "";
${*$data}{net_ftp_cmd} = $ftp;
${*$data}{net_ftp_blksize} = ${*$ftp}{net_ftp_blksize};
return $data;
};
}
1;
=head1 NAME
Net::INET6Glue::FTP - adds IPv6 support to L<Net::FTP> by hotpatching
=head1 SYNOPSIS
use Net::INET6Glue::FTP;
use Net::FTP;
my $ftp = Net::FTP->new( '::1' );
$ftp->login(...)
=head1 DESCRIPTION
This module adds support for IPv6 by hotpatching support for EPRT and EPSV
commands into L<Net::FTP> and hotpatching B<pasv>, B<port> and B<_dataconn>
methods to make use of EPRT and EPSV on IPv6 connections.
It also includes L<Net::INET6Glue::INET_is_INET6> to make the L<Net::FTP>
sockets IPv6 capable.
=head1 COPYRIGHT
This module is copyright (c) 2008..2014, Steffen Ullrich.
All Rights Reserved.
This module is free software. It may be used, redistributed and/or modified
under the same terms as Perl itself.
|