Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations wOOdy-Soft on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

sending files to multiple ftp servers

Status
Not open for further replies.

noworyz

MIS
Jun 7, 2006
5
US
I am trying to send certain files to 3 different ftp servers. I have it working but the issue is, is when one fo the requests fail, they all fail. I would like to set it up so that if one of the servers fails, it still sends the files to the other two ftp servers.

This is the part of the code that I have for defining my ftp servers. Is there a way to rewrite this so it will send the files to all ftp servers even if one fails?
*****************
my $ftpa = Net::FTP->new("[removed]", Debug => 0) or die "Cannot connect to ftp server A: $@";
my $ftpb = Net::FTP->new("[removed]", Debug => 0) or die "Cannot connect to ftp server B: $@";
my $ftpc = Net::FTP->new("[removed]", Debug => 0) or die "Cannot connect to ftp server C: $@";
$ftpa->login('[removed]','[removed]') or die "Cannot login to FTP server A.", $ftpa->message;
$ftpb->login('[removed]','[removed]') or die "Cannot login to FTP server B.", $ftpb->message;
$ftpc->login('[removed]','[removed]') or die "Cannot login to FTP server C.", $ftpc->message;
$ftpa->ascii; $ftpb->ascii; $ftpc->ascii;
chdir("$RPTDIR/tobesent");
opendir(FTPDIR,"$RPTDIR/tobesent");
my $FILE;
foreach $FILE (readdir(FTPDIR)) {
...
***********************

Thanks for any help!
 
You just have to write a sub-routine to handle errors. As it sits now, dying is what's causing the script to stop from that point forward.

Something like the following:
Code:
sub keelover {
    my $error = shift;
    open (LOG, "/path/to/error/log.file") or die "Cannot open file: $!";
    print LOG "Error occurred: $error\n";
    close (LOG);
}

my $ftpa = Net::FTP->new("[removed]", Debug => 0) or keelover("Cannot connect to ftp server A: $@");
my $ftpb = Net::FTP->new("[removed]", Debug => 0) or keelover("Cannot connect to ftp server B: $@");
my $ftpc = Net::FTP->new("[removed]", Debug => 0) or keelover("Cannot connect to ftp server C: $@");
...

- George
 
would this be the same in this section of code

$ftpa->login('[removed]','[removed]') or die "Cannot login to FTP server A.", $ftpa->message;
$ftpb->login('[removed]','[removed]') or die "Cannot login to FTP server B.", $ftpb->message;
$ftpc->login('[removed]','[removed]') or die "Cannot login to FTP server C.", $ftpc->message;

would be

$ftpa->login('[removed]','[removed]') or keelover("Cannot login to FTP server A.", $ftpa->message);
$ftpb->login('[removed]','[removed]') or keelover("Cannot login to FTP server B.", $ftpb->message);
$ftpc->login('[removed]','[removed]') or keelover("Cannot login to FTP server C.", $ftpc->message);

Sorry for all the questions but I am fairly new to perl, Chris
 
Yes. Keep in mind that the script won't fail at all this way, just log all of the errors to a file. So, if either your initialization of the FTP object or logging into a server doesn't work, you're going to get a message every time a file is requested to be FTPed to that server.

I just thought that it might be more beneficial to die on the initialization, set a flag which is checked for each server logged into and check for that before FTPing files to it. This way, the only time you'll receive messages is when a file doesn't transfer...

Something more to the following:
Code:
my %ftpServers = { "A" => 0,
                   "B" => 0,
                   "C" => 0 };

sub loginFailed {
    my $error = shift;
    my $ftpFailed = shift;

    $ftpServer{$ftpFailed} = 1;
    keelover("$error");
}

sub keelover {
    my $error = shift;
    open (LOG, "/path/to/error/log.file") or die "Cannot open file: $!";
    print LOG "Error occurred: $error\n";
    close (LOG);
}

my $ftpa = Net::FTP->new("[removed]", Debug => 0) or die "Cannot connect to ftp server A: $@";
#repeat for your other ftp servers

$ftpa->login('[removed]','[removed]') or loginFailed("Cannot login to FTP server A. $ftpa->message", "A");

Please note, this code isn't tested so I'm not ensuring it will work out of the gate.

- George
 
ok, I am starting to see how this works. but I see that in this code

my $ftpa = Net::FTP->new("[removed]", Debug => 0) or die "Cannot connect to ftp server A: $@";
#repeat for your other ftp servers

if the ftp server was down and it couldn't connect, would the script be dead or would it move onto the next ftp server? (this is the main problem, one of the ftp servers has issues and is sometimes not available at all and when this happens, the script dies and the other two ftp servers don't get the files. I want the script to send the files to the other two ftp servers even if one of them is down.
 
Ah, sorry about that... Just a small change:

Code:
my %ftpServers = { "A" => 0,
                   "B" => 0,
                   "C" => 0 };

sub loginFailed {
    my $error = shift;
    my $ftpFailed = shift;

    $ftpServer{$ftpFailed} = 1;
    keelover("$error");
}

sub keelover {
    my $error = shift;
    open (LOG, "/path/to/error/log.file") or die "Cannot open file: $!";
    print LOG "Error occurred: $error\n";
    close (LOG);
}

my $ftpa = Net::FTP->new("[removed]", Debug => 0) or keelover("Cannot connect to ftp server A: $@");
#repeat for your other ftp servers

if ($ftpa) {
    $ftpa->login('[removed]','[removed]') or loginFailed("Cannot login to FTP server A. $ftpa->message", "A");
    $ftpa->ascii; 
}
#repeat for other ftp servers

chdir("$RPTDIR/tobesent");
opendir(FTPDIR,"$RPTDIR/tobesent");
my $FILE;
foreach $FILE (readdir(FTPDIR)) {
    foreach my $key (keys %ftpServers) {
        if ($ftpServers{$key} == 1) {
            #send file only if server was logged into
        }
    }
}

- George
 
Ok, thanks again for all your help. I just want to make sure this looks right.

*********************************
my %ftpServers = { "A" => 0,
"B" => 0,
"C" => 0 };
sub loginFailed {
my $error = shift;
my $ftpFailed = shift;

$ftpServer{$ftpFailed} = 1;
keelover("$error");
}
sub keelover {
my $error = shift;
open (LOG, "$RPTDIR/errors/errors.log") or die "Cannot open file: $!";
print LOG "Error occurred: $error\n";
close (LOG);
}

my $ftpa = Net::FTP->new("[removed]", Debug => 0) or keelover("Cannot connect to ftp server A: $@");
my $ftpb = Net::FTP->new("[removed]", Debug => 0) or keelover("Cannot connect to ftp server B: $@");
my $ftpc = Net::FTP->new("[removed]", Debug => 0) or keelover("Cannot connect to ftp server C: $@");
if ($ftpa) {
$ftpa->login('[removed]','[removed]') or loginFailed("Cannot login to FTP server A.", $ftpa->message, "A");
$ftpa->ascii;
}
if ($ftpb) {
$ftpb->login('[removed]','[removed]') or loginFailed("Cannot login to FTP server B.", $ftpb->message, "B");
$ftpb->ascii;
}
if ($ftpc) {
$ftpc->login('[removed]','[removed]') or loginFailed("Cannot login to FTP server C.", $ftpc->message, "C");
$ftpc->ascii;
}
chdir("$RPTDIR/tobesent");
opendir(FTPDIR,"$RPTDIR/tobesent");
my $FILE;
foreach $FILE (readdir(FTPDIR)) {
foreach my $key (keys %ftpServers) {
if ($ftpServers{$key} == 1) {
#send file only if server was logged into
next unless $FILE =~ m/^CAD/;
if ($FILE =~ m/[removed]/) { $ftpa->cwd('/[removed]'); }
elsif ($FILE =~ m/[removed]/) { $ftpc->cwd('/[removed]'); }
elsif ($FILE =~ m/[removed]/) { $ftpa->cwd('/[removed]'); }
elsif ($FILE =~ m/[removed]/) { $ftpb->cwd('/[removed]'); }
elsif ($FILE =~ m/[removed]/) { $ftpa->cwd('/[removed]'); }
elsif ($FILE =~ m/[removed]/) { $ftpa->cwd('/[removed]'); }
elsif ($FILE =~ m/[removed]/) { $ftpa->cwd('/[removed]'); }
if ($FILE =~ m/[removed]/) { $ftpb->put($FILE); }
elsif ($FILE =~ m/[removed]/) { $ftpc->put($FILE); }
else { $ftpa->put($FILE); }
unlink($FILE);
}
}
}
 
Thanks a ton! I'll let you know how it works out for me!
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top