1N/A##
1N/A## Generic data connection package
1N/A##
1N/A
1N/Apackage Net::FTP::dataconn;
1N/A
1N/Ause Carp;
1N/Ause vars qw(@ISA $timeout $VERSION);
1N/Ause Net::Cmd;
1N/Ause Errno;
1N/A
1N/A$VERSION = '0.11';
1N/A@ISA = qw(IO::Socket::INET);
1N/A
1N/Asub reading
1N/A{
1N/A my $data = shift;
1N/A ${*$data}{'net_ftp_bytesread'} = 0;
1N/A}
1N/A
1N/Asub abort
1N/A{
1N/A my $data = shift;
1N/A my $ftp = ${*$data}{'net_ftp_cmd'};
1N/A
1N/A # no need to abort if we have finished the xfer
1N/A return $data->close
1N/A if ${*$data}{'net_ftp_eof'};
1N/A
1N/A # for some reason if we continously open RETR connections and not
1N/A # read a single byte, then abort them after a while the server will
1N/A # close our connection, this prevents the unexpected EOF on the
1N/A # command channel -- GMB
1N/A if(exists ${*$data}{'net_ftp_bytesread'}
1N/A && (${*$data}{'net_ftp_bytesread'} == 0)) {
1N/A my $buf="";
1N/A my $timeout = $data->timeout;
1N/A $data->can_read($timeout) && sysread($data,$buf,1);
1N/A }
1N/A
1N/A ${*$data}{'net_ftp_eof'} = 1; # fake
1N/A
1N/A $ftp->abort; # this will close me
1N/A}
1N/A
1N/Asub _close
1N/A{
1N/A my $data = shift;
1N/A my $ftp = ${*$data}{'net_ftp_cmd'};
1N/A
1N/A $data->SUPER::close();
1N/A
1N/A delete ${*$ftp}{'net_ftp_dataconn'}
1N/A if exists ${*$ftp}{'net_ftp_dataconn'} &&
1N/A $data == ${*$ftp}{'net_ftp_dataconn'};
1N/A}
1N/A
1N/Asub close
1N/A{
1N/A my $data = shift;
1N/A my $ftp = ${*$data}{'net_ftp_cmd'};
1N/A
1N/A if(exists ${*$data}{'net_ftp_bytesread'} && !${*$data}{'net_ftp_eof'}) {
1N/A my $junk;
1N/A $data->read($junk,1,0);
1N/A return $data->abort unless ${*$data}{'net_ftp_eof'};
1N/A }
1N/A
1N/A $data->_close;
1N/A
1N/A $ftp->response() == CMD_OK &&
1N/A $ftp->message =~ /unique file name:\s*(\S*)\s*\)/ &&
1N/A (${*$ftp}{'net_ftp_unique'} = $1);
1N/A
1N/A $ftp->status == CMD_OK;
1N/A}
1N/A
1N/Asub _select {
1N/A my ($data, $timeout, $do_read) = @_;
1N/A my ($rin,$rout,$win,$wout,$tout,$nfound);
1N/A
1N/A vec($rin='',fileno($data),1) = 1;
1N/A
1N/A ($win, $rin) = ($rin, $win) unless $do_read;
1N/A
1N/A while (1) {
1N/A $nfound = select($rout=$rin, $wout=$win, undef, $tout=$timeout);
1N/A
1N/A last if $nfound >= 0;
1N/A
1N/A croak "select: $!"
1N/A unless $!{EINTR};
1N/A }
1N/A
1N/A $nfound;
1N/A}
1N/A
1N/Asub can_read
1N/A{
1N/A _select(@_[0,1],1);
1N/A}
1N/A
1N/Asub can_write
1N/A{
1N/A _select(@_[0,1],0);
1N/A}
1N/A
1N/Asub cmd
1N/A{
1N/A my $ftp = shift;
1N/A
1N/A ${*$ftp}{'net_ftp_cmd'};
1N/A}
1N/A
1N/Asub bytes_read {
1N/A my $ftp = shift;
1N/A
1N/A ${*$ftp}{'net_ftp_bytesread'} || 0;
1N/A}
1N/A
1N/A1;