I have been working on a script for almost a month now, which takes in an XML file and uses it to either download or upload files from an ftp site. It also copies the files to a history directory for historical purposes.
This thing has to be flawless so any suggestions to make the script more stable, reliable, error free (should able to capture errors and continue with out ending the script just because one file was not found). Eventually there will be an email function to let me know of any errors and warnings. I will also me updating a database with information but more on that later here is the script and a sample XML file.
Perl
#! /usr/bin/perl -w
use DBI;
use strict;
use Switch;
use Net::FTP;
use Net::FTP::File;
use File::Copy;
use Getopt::Long;
use File::Basename;
use XML::Simple qw(:strict);
use Mail::Sender::Easy qw(email);
my ($e, $w, $p);
my (@files, @history);
my (%failed, %delete, %missing);
my ($config, $options, $xml, $ftp, $sbj, $msg, $error, $fi);
$options = GetOptions ("config=s" => \$config);
unless(-e $config){print "Could not find $config.\n";exit;}
$xml = XMLin($config, ForceArray=>0, KeyAttr=>[]);
if(exists $xml->{files}->{file}){
if (ref($xml->{files}->{file}) eq ""){
unless(-e $xml->{files}->{file}){$missing{$xml->{files}->{file}} = $!;next;}
if(lc($xml->{type}) eq "upload"){
push(@files, "$xml->{localpath}/$xml->{files}->{file}");
}
elsif(lc($xml->{type}) eq "download"){
push(@files, $xml->{files}->{file});
}
}
if(ref($xml->{files}->{file}) eq "ARRAY"){
if(lc($xml->{type}) eq "upload"){
foreach $fi ((@{$xml->{files}->{file}})){
unless(-e $fi){$missing{$fi} = $!; next;}
push(@files, "$xml->{localpath}/$fi");
}
}
elsif(lc($xml->{type}) eq "download"){
foreach $fi ((@{$xml->{files}->{file}})){
push(@files,$fi);
}
}
}
}
elsif(exists $xml->{files}->{regex}){
if(lc($xml->{type}) eq "upload"){
@files = glob("$xml->{localpath}/$xml->{files}->{regex}");
}
elsif(lc($xml->{type}) eq "download"){
@files = ();
}
}
else{print "No files specified\n";}
$ftp = Net::FTP->new($xml->{host});
if($@ ne ""){$e=1;}
unless ($ftp->login($xml->{user}, $xml->{password})){print $ftp->message;}
unless($ftp->cwd($xml->{serverpath})){print $ftp->message; exit;}
switch ($xml->{type}){
case "upload"{
foreach my $file (@files){
if(exists $xml->{name}){
unless($ftp->put($file, $xml->{name})){$failed{$file} = $ftp->message;next;}
}
else{
unless($ftp->put($file)){$failed{$file} = $ftp->message;next;}
}
push(@history, $file) if(exists $xml->{historypath});
}
}
case "download"{
if(scalar(@files) > 0){
foreach my $file (@files){
unless($ftp->exists($file)){$missing{$file} = "not found on server.";next;}
unless(exists $xml->{name}){$ftp->get($file, "$xml->{localpath}/$xml-> {name}");}
unless($ftp->get($file, "$xml->{localpath}/$file")){$failed{$file} = $ftp->message; next;}
}
}
elsif(scalar(@files) == 0){
@files = $ftp->ls($xml->{files}->{regex}) if($xml->{files}->{regex});
}
}
else{print "job type not defined.\n";}
}
$ftp->quit;
if( @history > 0 ){
if($xml->{date} == 0){
foreach my $h(@history){
unless(copy($h, "$xml->{historypath}/")){$delete{$h} = $!; next};
unlink($h) if($xml->{del} == 1);
}
}
elsif($xml->{date} == 1){
foreach my $h(@history){
(my $n, my $p, my $s) = fileparse($h, qr/\.[^.]*/);
use POSIX qw(strftime);
my $file = $n . "-" . strftime("%b-%e-%H-%M", localtime) . $s;
unless(copy($h,"$xml->{historypath}/$file")){$delete{$h} = $!; next;}
unlink($h) if($xml->{del} == 1);
}
}
}
while ((my $k, my $v) = each %missing){print "$k => $v\n";}
while ((my $k, my $v) = each %failed) {print "$k => $v\n";}
while ((my $k, my $v) = each %delete) {print "$k => $v\n";}
XML
<?xml version="1.0" encoding="ISO-8859-1"?>
<site>
<job>zenadown</job>
<type>download</type>
<host>zena.leegin.com</host>
<ip>128.222.79.75</ip>
<user>leo</user>
<password>green97</password>
<serverpath>/leo</serverpath>
<localpath>/temp</localpath>
<historypath>/temp/leo</historypath>
<files>
<file>jo.png</file>
<file>jo2.png</file>
<file>jo3.png</file>
<file>jo4.png</file>
<file>Blogger.png</file>
</files>
<logfile>/zena/AUTOMIZE/leotest.txt</logfile>
<del>0</del>
<date>0</date>
</site>