diff options
author | Chris Lindee <chris.lindee@cpanel.net> | 2014-12-03 13:02:38 -0600 |
---|---|---|
committer | Chris Lindee <chris.lindee@cpanel.net> | 2014-12-03 15:43:06 -0600 |
commit | b99b8b4b6b733f94f5cbe0c8ad87b04bc7e64913 (patch) | |
tree | b2ed824d8d51662134d40b457a3209d6a3196126 | |
parent | beeea5ae701fe425397f4452562747d25bc40528 (diff) | |
download | perl-libnet-b99b8b4b6b733f94f5cbe0c8ad87b04bc7e64913.tar.gz |
Make rmdir() more robust against faulty FTP servers
[RT #100694] Some FTP servers simply don't process NLST properly. Use the RFC standardized MLSD command first, then fallback onto NLST if no data is provided. Caveat: MLSD will return 501 if given a file instead of a directory. We ignore this error and try NLST anyway. That command should subsequently fail and then we return the empty list.
-rw-r--r-- | lib/Net/FTP.pm | 12 |
1 files changed, 8 insertions, 4 deletions
diff --git a/lib/Net/FTP.pm b/lib/Net/FTP.pm index ea0d7ae..f34636b 100644 --- a/lib/Net/FTP.pm +++ b/lib/Net/FTP.pm @@ -661,8 +661,12 @@ sub rmdir { or !$recurse; # Try to delete the contents - # Get a list of all the files in the directory - my @filelist = grep { !/^\.{1,2}$/ } $ftp->ls($dir); + # Get a list of all the files in the directory, excluding the current and parent directories + my @filelist = map { /^(?:\S+;)+ (.+)$/ ? ($1) : () } grep { !/^(?:\S+;)*type=[cp]dir;/ } $ftp->_list_cmd("MLSD", $dir); + + # Fallback to using the less well-defined NLST command if MLSD fails + @filelist = grep { !/^\.{1,2}$/ } $ftp->ls($dir) + unless @filelist; return unless @filelist; # failed, it is probably not a directory @@ -1141,7 +1145,7 @@ sub _data_cmd { my $data = $ftp->_dataconn(); if (CMD_INFO == $ftp->response()) { $data->reading - if $data && $cmd =~ /RETR|LIST|NLST/; + if $data && $cmd =~ /RETR|LIST|NLST|MLSD/; return $data; } $data->_close if $data; @@ -1180,7 +1184,7 @@ sub _data_cmd { my $data = $ftp->_dataconn(); $data->reading - if $data && $cmd =~ /RETR|LIST|NLST/; + if $data && $cmd =~ /RETR|LIST|NLST|MLSD/; return $data; } |