It looks like my crystal ball is batting .500, correct problem, wrong
line number.
You should start off with the two pragmas:
use warnings;
use strict;
#
#NewAutoConDir.pl
#Karin Walike
#12.01.07
#
#Connect
irect process automation for server PKSW1714
#The script sleeps and wakes up to check and see if there is a file
#has been loaded to the server for Connect
irect to customer.
#
#
#We currently have XX customers sending/receiving data to this node.
#
#Product list: xx, xx, xx, xx, xx,
use MIME::Lite;
use Cwd;
use File::Copy;
You don't appear to be using either Cwd or File::Copy?
my $dirVM="D:\\Prod_D\\BOP\\Data\\SMSDATA\\PCSWHSLE\\CD\\VM\\";
my $doneDir="D:\\Prod_D\\BOP\\Data\\SMSDATA\\PCSWHSLE\\CD\\VM\\DONE\
\";
These should be declared inside the loop instead of here.
my $ConDir1="D:\\tools\\'Sterling Commerce'\\'CONNECT Direct v4.1'\
\'Common Utilities'";
my $ConDir2="D:\\Prod_D\\BOP\\Scripts\\temp";
my $ConDir3="D:\\Prod_D\\BOP\\scripts\\triggerDir";
my $LOG="D:\\Prod_D\\BOP\\Logs\\ConDirLogVM_1.txt";
my $LOG2="D:\\Prod_D\\BOP\\Logs\\ConDirLogVM_2.txt";
my $LOG3="D:\\Prod_D\\BOP\\Logs\\ConDirLogVM_3.txt";
my $LOG4="D:\\Prod_D\\BOP\\Logs\\ConDirLogVM_4.txt";
my $EXCONDIR="D:\\Prod_D\\BOP\\Scripts\\temp\\ConDirVM.cmd";
You should use the forward slash (/) instead of the backslash (\) for
path separators.
You should *always* verify the success of open(). You should probably
use a different name for the filehandle.
if( -d $dirVM ) {
opendir( VMDIR, $dirVM ) || die "Cannot open directory $dirVM $!";
}else{
print "Directory $dirVM does not exist. Exiting....\n";
exit;
}
# Iterate through the directory VM
opendir(VMDIR, $dirVM) || die "Cannot open directory $dirVM $!";
Why open the directory twice. The whole if-else block is superfluous.
#open(VMDIR,"D:\\Prod_D\\BOP\\Data\\SMSDATA\\PCSWHSLE\\VM") || die
"Cannot open directory $dirVM $!";
#open(VMDIR,'dir "D:\Prod_D\BOP\Data\SMSDATA\PCSWHSLE\VM" |') || die;
chomp() is superfluous and *may* damage valid file names.
foreach $FILE ( @FILES ) {
if ($FILE !~ /^RU_VIRGIN_MOBILE_[0-9]_[0-9][0-9][0-9][0-9][0-9][0-9]
[0-9][0-9].*\.gz$/) {
#print "$FILE is not an EMBARQ product...\n";
goto sleeplabel;
You don't need to use goto, you should use next and a continue block
instead.
Why chomp the same variable a second time? chomp() is superfluous and
*may* damage valid file names.
print "\nFile is $FILE\n";
print "\nBeginning Connect
irect processing for VIRGIN MOBILE
customer file...\n";
print OUT "\n$date $FILE\n";
goto sleeplabel if (!$FILE);
You don't need to use goto, you should use next and a continue block
instead. How did $FILE get modified so that it became '0' or ''?
if (file_transfer_complete($FILE)) {
One of the classic beginner mistakes. Your subroutine
file_transfer_complete is using stat() on the file names but you need
the complete path to properly stat() the file.
print "\nFound file $FILE\n";
open(IN, "$ConDir3\\send_triggerVM.pl");
open(OUT, ">$ConDir2\\tmp_sendVM.cdp");
Why are you reusing the same filehandle name that you used for the log file?
while (<IN>) {
if (/ConDirFile/) {
s/ConDirFile/$dirVM$FILE/;
You don't have to use the same regular expression twice.
}
print OUT $_;
}
close(OUT);
close(IN);
print "First Connect
irect pre-processing step passed...\n";
"$ConDir2\\tmp_sendVM.cdp > D:\\Prod_D\\BOP\\scripts\\temp\\file";
If you had warnings enabled you would have received a warning about a
constant in void context here.
print "Second Connect
irect pre-processing step passed...\n";
system $EXCONDIR || errorexit(2, "\nConnect
irect process failed");
Because of the relatively high precedence of the || operator the
errorexit() sub will never be called. If you fixed the precedence then
errorexit() will only be called when system() succeeded.
print "\nConnect
irect processing for VIRGIN MOBILE customer file
completed...\n";
print OUT "\nConnect
irect Processed for $date $FILE\n";
# Send email to notify file has been C
to mainframe
my $machine = "PKSW1714";
my $email = '(e-mail address removed)';
my $email2 = '(e-mail address removed)';
my $subject = "Connect
irect Processing VIRGIN MOBILE: $FILE has
been sent to VIRGIN MOBILE node VSCPFTP01";
my $body = " Hello, \n\n $FILE has been moved from $machine to
VSCPFTP01. \n\n Please contact $email2 with questions. \n\n Thanks, \n
\n IOP Connect
irect Team\n\n";
my $server = "10.214.13.55";
$machine, $email, $email2 and $server are constants so why are they
inside the loop?
my $msg = MIME::Lite->new(
From => '(e-mail address removed)',
To => '(e-mail address removed)',
Why define variables for those strings and then not use them?
Subject => $subject,
Type => 'TEXT',
Data => $body
);
#Use SMTP to send
MIME::Lite->send('smtp', $server, Timeout=>60);
sleep 30;
$msg->send;
open(OUT, ">>$LOG"); #reopen closed LOG
If you had used a different name for the filehandle then you wouldn't
have to do this.
print "\nEmail notification of Connect
irect transfer sent...\n";
#sleeplabel2:
print"\n\n*******Waiting for VIRGIN MOBILE file processing to
complete*******\n\n";
sleep 50;
# Rename the current process to done
Why chomp the same variable a third time? chomp() is superfluous and
*may* damage valid file names.
print "File is writable\n" if -w $FILE;
You are using the file name only not the complete path so -w will not
find the file you want.
$FILEDONE = $FILE . $doneExt;
Again, why are you chomp()ing the file name? Do you know what chomp() does?
print "filedone=$FILEDONE\n";
#rename ("D:\\Prod_D\\BOP\\Data\\SMSDATA\\PCSWHSLE\\CD\\VM\
\RU_VIRGIN_MOBILE_1_20071130.007.gz", "D:\\Prod_D\\BOP\\Data\\SMSDATA\
\PCSWHSLE\\CD\\VM\\RU_VIRGIN_MOBILE_1_20071130.007.gz.done");
rename ($FILE, $FILEDONE);
You are using the file name only not the complete path so rename() will
not find the file you want.
#if (renamefiles($FILE)) {
print "\nFile successfully renamed: $FILEDONE\n" || errorexit(14,
"Could not rename $FILE");
#}
#move ($FILE,$FILEDONE) || errorexit(9, "Unable to move $FILE");
#copy ($FILE,$FILEDONE) || errorexit(12, "Unable to copy $FILE to
$FILEDONE");
You don't need to use goto, you should use next and a continue block
instead.
print"\n\n*******Waiting for VIRGIN MOBILE Connect
irect file*******
\n\n";
sleep 10;
Why are you defining your subroutines *inside* the loop?
#
# Sub file_transfer_complete
#
# monitor a file for size changes over a brief period
#
# parm1 - file name
# parm2 - delay in seconds (optional)
#
sub file_transfer_complete {
my $filename = shift;
my $waitTime = shift || 20;
my $sizefirst = -s $filename; # initial file size
sleep $waitTime; # wait a while
my $sizeDelta = -s $filename; #file size after wait
You are using the file name only not the complete path so -s will not
find the file you want.
if( $sizeDelta == $sizefirst ) {
print "transfer complete $filename 1: $sizefirst\t2: $sizeDelta" ;
return 1;
} else {
print "transfer incomplete $filename 1: $sizefirst\t2: $sizeDelta" ;
return 0;
}
}
# Sub errorexit print error message to the log and return an error
code
#
sub errorexit {
my $returncode = shift;
my $message = shift;
open (OUT, ">>$LOG");
If you had used a different name for the filehandle then you wouldn't
have to do this.
print OUT "\n### ERROR $returncode ### $message";
exit ($returncode);
}
# Sub Rename files to .done extension
#
sub renamefiles {
Why not use the $doneExt variable?
my $file2 = $file1 . $done;
rename ($file1, $file2) || die "Cannot rename $file1\n";
You are using the file name only not the complete path so rename() will
not find the file you want.
To sum up, here is the code with modifications that should work better
(*UNTESTED*):
#!/perl/bin/perl
use warnings;
use strict;
#
#NewAutoConDir.pl
#Karin Walike
#12.01.07
#
#Connect
irect process automation for server PKSW1714
#The script sleeps and wakes up to check and see if there is a file
#has been loaded to the server for Connect
irect to customer.
#
#
#We currently have XX customers sending/receiving data to this node.
#
#Product list: xx, xx, xx, xx, xx,
use MIME::Lite;
my $dirVM = 'D:/Prod_D/BOP/Data/SMSDATA/PCSWHSLE/CD/VM';
my $doneDir = 'D:/Prod_D/BOP/Data/SMSDATA/PCSWHSLE/CD/VM/DONE';
my $ConDir2 = 'D:/Prod_D/BOP/Scripts/temp';
my $ConDir3 = 'D:/Prod_D/BOP/scripts/triggerDir';
my $LOG = 'D:/Prod_D/BOP/Logs/ConDirLogVM_1.txt';
my $EXCONDIR = 'D:/Prod_D/BOP/Scripts/temp/ConDirVM.cmd';
my $date = localtime;
my $doneExt = '.done';
my $machine = 'PKSW1714';
my $email = '(e-mail address removed)';
my $email2 = '(e-mail address removed)';
my $server = '10.214.13.55';
open my $LOGFH, '>>', $LOG or die "Cannot open '$LOG' $!";
while ( 1 ) {
# Open the directory VM
# Iterate through the directory VM
opendir my $VMDIR, $dirVM or die "Cannot open directory $dirVM $!";
my @FILES = readdir $VMDIR;
closedir $VMDIR;
print "\n@FILES\n";
for my $FILE ( @FILES ) {
if ( $FILE !~ /^RU_VIRGIN_MOBILE_[0-9]_[0-9]{8}.*\.gz$/) {
#print "$FILE is not an EMBARQ product...\n";
next;
}
print "\nFile is $FILE\n";
print "\nBeginning Connect
irect processing for VIRGINMOBILE
customer file...\n";
print $LOGFH "\n$date $FILE\n";
next unless file_transfer_complete( "$dirVM/$FILE" );
print "\nFound file $FILE\n";
open my $IN, '<', "$ConDir3/send_triggerVM.pl" or die "Cannot
open '$ConDir3/send_triggerVM.pl' $!";
open my $OUT, '>', "$ConDir2/tmp_sendVM.cdp" or die "Cannot
open '$ConDir2/tmp_sendVM.cdp' $!";
while ( <$IN> ) {
s/ConDirFile/$dirVM$FILE/;
print $OUT $_;
}
close $OUT;
close $IN;
print "First Connect
irect pre-processing step passed....\n";
sleep 10;
print "Second Connect
irect pre-processing step passed....\n";
system( $EXCONDIR ) == 0 or errorexit( 2, "\nConnect
irect
process failed" );
print "\nConnect
irect processing for VIRGIN MOBILE customer
file completed...\n";
print $LOGFH "\nConnect
irect Processed for $date $FILE\n";
# Send email to notify file has been C
to mainframe
my $subject = "Connect
irect Processing VIRGIN MOBILE: $FILE
has been sent to VIRGIN MOBILE node VSCPFTP01";
my $body = <<BODY;
Hello,
$FILE has been moved from $machine to VSCPFTP01.
Please contact $email2 with questions.
Thanks,
IOP Connect
irect Team
BODY
my $msg = MIME::Lite->new(
From => $email2,
To => $email,
Subject => $subject,
Type => 'TEXT',
Data => $body,
);
#Use SMTP to send
MIME::Lite->send( 'smtp', $server, Timeout => 60 );
sleep 30;
$msg->send;
print "\nEmail notification of Connect
irect transfer sent...\n";
print "\n\n*******Waiting for VIRGIN MOBILE file processing to
complete*******\n\n";
sleep 50;
# Rename the current process to done
print "File is writable\n" if -w "$dirVM/$FILE";
my $FILEDONE = $FILE . $doneExt;
print "filedone=$FILEDONE\n";
rename "$dirVM/$FILE", "$dirVM/$FILEDONE" or die "Cannot rename
'$dirVM/$FILE' to '$dirVM/$FILEDONE' $!";
print "\nFile successfully renamed: $FILEDONE\n" or errorexit(
14, "Could not rename $FILE" );
}
continue {
print "\n\n*******Waiting for VIRGIN MOBILE Connect
irect
file*******\n\n";
sleep 10;
}
}
#
# Begin Subroutines
#
# Sub file_transfer_complete
#
# monitor a file for size changes over a brief period
#
# parm1 - file name
# parm2 - delay in seconds (optional)
#
sub file_transfer_complete {
my $filename = shift;
my $waitTime = shift || 20;
my $sizefirst = -s $filename; # initial file size
sleep $waitTime; # wait a while
my $sizeDelta = -s $filename; #file size after wait
if ( $sizeDelta == $sizefirst ) {
print "transfer complete $filename 1: $sizefirst\t2: $sizeDelta";
return 1;
}
else {
print "transfer incomplete $filename 1: $sizefirst\t2: $sizeDelta";
return 0;
}
}
# Sub errorexit print error message to the log and return an error code
#
sub errorexit {
my $returncode = shift;
my $message = shift;
print $LOGFH "\n### ERROR $returncode ### $message";
exit $returncode;
}
__END__
John