#!/usr/bin/perl
use Net::FTP;
use File::Listing qw(parse_dir);
use threads;
use threads::shared;
my $file_ftp = "./ftp/ftp.txt"; # File ftp list
my $file_search = "./search.txt"; # Search reguler extension.
my $threads = "2"; # Threads
my $debug = 1;
my $level = 2; # Глубина поиска
# Ftp file
open(FTP, " <$file_ftp" ) or error_logz(" $txt_er Error: Can not open Ftp list file: ".$file_ftp."\r\n\r\n");
local @FTP = <FTP>;
$FTP = @FTP;
print" $txt_i Read ftp file:\t\t $txt_ok\r\n";
print" $txt_i Count ftp:\t\t $FTP\r\n";
# Load search file Regular extention
open(SEARCH, $file_search) or error_logz(" $txt_er Error: Can not open Search file: $file_search\r\n\r\n");
@search = <SEARCH>;
chomp @search;
close(SEARCH);
$search = @search;
print" $txt_i Read search file:\t \033[32m[OK]\033[0m\r\n";
print" $txt_i Search reg:\t\t $search\r\n";
# Разпределние фтп между патоками
$count = @FTP;
$fptCount = ($count /$threads);
@drobs = split /\./,$fptCount;
@drobs[1] = "0.@drobs[1]";
#print "Count: ".int($fptCount)."\r\n Drob: $fptCount \r\nDrob2: @drobs[1]\r\n + ".@drobs[1]*$threads."\r\n";
for(1..$threads) {
@CountFtpThreads[$_] = (int($fptCount));
}
@CountFtpThreads[$threads] = (int($fptCount) + (@drobs[1]*$threads));
# Search files on ftp
sub search_files {
#eval{
if(!$_[0]) { $_[0] = "." }
if(!$_[1]) { $_[1] = 1; }
my $path = $_[0];
my $level = $_[1];
#print "\r\n Path: $path\r\nlevel: $level\r\n";
my $ls = $ftp->dir($path);
if(!$ls) { return; }
foreach my $entry (parse_dir($ls)) {
$level ++;
my ($name, $type, $size, $mtime, $mode) = @$entry;
if ($type eq 'd' ) {
if($level <= $max_level) { &search_files($path."/".$name, $level); }
}
else {
foreach(@search) {
if($name =~ /$_/) {
push @found, $path."/".$name;
#print $path."/".$name."\r\n";
}
}
}
$level = $_[1];
}
if(!@found) { return 0; }
else { return @found; }
#}
}
sub fsearch{
$uid = $_[3];
for ($_[0]..$_[1]) {
# Parse url - $login, $password, $host
chomp $FTP[$_];
next if $FTP[$_] eq '';
#print $FTP[$_]."\r\n";
$FTP[$_] =~ /
\s*
(?:
# scheme:subscheme:\/\/
([a-z]+) : (?: ([a-z]*) : )? \/\/
)?
(?:
# username:password@
( [^:@]* ) (?: : ([^:@]*) )? @
)?
(
# hostname|localhost|IP
(?: [a-z0-9_-]+ \. )+ [a-z]{2,}
|
localhost
|
(?: (?: [01]?\d\d? | 2[0-4]\d | 25[0-5] ) \. ){3}
(?: (?: [01]?\d\d? | 2[0-4]\d | 25[0-5] ) )
)
(?:
# :port
: (\d+)
)?
(?:
# \/path
([^:\?\#]+)
)?
(?:
# ?query
\? ([^\#]+)
)?
(?:
# #fragment
\# ([^\s]+)
)?
\s*
/ix;
$scheme = $1 || '';
$subscheme = $2 || '';
$login = $3 || '';
$password = $4 || '';
$host = $5 || '';
$port = $6 || '';
$path = $7 || '';
$query = $8 || '';
$fragment = $9 || '';
# Connect
if($debug) {
print
"\r\n -----\r\n".
" Count:\t\t ".$_."\r\n".
" Connect:\t\t ".$host."\r\n".
" User:\t\t ".$login."\r\n";
}
# Connet to ftp
local $ftp = Net::FTP->new($host, Debug => 0, Timeout=>$TimeOut);
if(!$ftp) {
if($debug) { print" $txt_er Connect:\t\t \033[22;31m[ERROR]\033[0m\r\n"; }
next;
}
if($debug) { print" $txt_i Connect:\t\t \033[32m[OK]\033[0m\r\n"; }
# Authorisation
if(!$ftp->login($login, $password)) {
if($debug) { print" $txt_er Authorisation:\t \033[22;31m[ERROR]\033[0m\r\n"; }
if($debug) { print" $txt_er Error: ".$ftp->message."\r\n\r\n"; }
$ftp->quit;
next;
}
@q = search_files(".", 2);
foreach(@q) { print $_."\r\n";}
}
}
# Start threads
$start = 0;
open UID, " > ./tmp/uid.tmp" or error_logz(" $txt_er Error: Can not open file: tmp/uid.tmp\r\n\r\n");
close UID;
for(0..$threads)
{
$end = ($start + $CountFtpThreads[$_]);
$conf[0] = $start;
$conf[1] = $end;
$conf[3] = $_;
$trl[$_]=threads->create(\&fsearch,@conf);
print " $txt_i Threads $_\r\n";
print " $txt_i Start start-end: $start-$end\r\n";
print " $txt_i Start threads:\t \033[32m[OK]\033[0m\r\n";
$start = ($start + $CountFtpThreads[$_]);
}
for(@trl) {
$_->join;
}
# Remove uid file;
unlink("./tmp/uid.tmp");
print"END";
Help perl net-ftp threads
Код:
Подскажите все правильно - вроде работает но не уверен что все работает верно =)
Скажите функции поиска надо передовать в аргументах переменную $ftp с конектом к фтп
меня немного путают потоки и распределение урлов фтп помоему както не очень изяшно =))
когда даю большие списки сервер вешается как быть ? пихать в паток пачками ?
как лучше оформить?
и вообше прошу коментариев по коду.
Скрипт для контроля файлов на фтп работаю с несколькими крупными хостерами списки фтп достигают 10 000
Какая версия перла стоит?
activ perl5