This file is indexed.

/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.