in reply to Code Issue after Upgrading the perl from 5.14.4 to 5.22.3

Thank you Madtoperl, Stevieb & Anonymous Monk for your response

Posting complete code

#!/usr/bin/perl # $Header: # Use a pragma that restricts use of unsafe constructs, such as symbol +ic # references, barewords, and undeclared variables. # This pragma is part of the standard Perl library. use strict; # Use a module that allows English-like words to be used in place of # Perl's special variables aka punctuation variables. # This module is part of the standard Perl library. use English; # Use a module for file copying. # This module is part of the standard Perl library. use File::Copy qw(cp mv); # Use a module for parsing file specifications into useful pieces. # This module is part of the standard Perl library. use File::Basename; # Use a module provides basic email functionality. # This module was downloaded from CPAN. #use Net::SMTP; use POSIX qw(strftime); my %CONFIG_PARAMS; #set -x # declare a few useful subroutines, this allows us to use them like bu +iltin functions sub Println($); sub Translate(%); my $error_flag = 'n'; my $st = strftime('%H%M', localtime); #Println ($st); my $sd = strftime('%Y%m%d', localtime); #Println ($sd); my $debug = 1; our $LOGS; my $inout = shift @ARGV; unless ( $inout eq '-i' or $inout eq '-o' ) { Println("Usage : $0 -i|-o"); exit 1; } if ( $inout eq '-i' ) { $CONFIG_PARAMS{"INBOUND"}="true"; } else { $CONFIG_PARAMS{"INBOUND"}="false"; } unless (open FILE , "< $0.conf") { Println ("ERROR : Could not open $0.conf configuration file"); exit 1; } # parse the config file while (<FILE>) { # remove leading spaces $_ =~ s/^\s+//g; # remove trailing spaces $_ =~ s/\s+$//g; # ignore comments next if $_ =~ /^#/; my @params = split /=/ , $_; $CONFIG_PARAMS{$params[0]}=$params[1]; } my $date = strftime '%Y%m%d', localtime; my $logdir = $CONFIG_PARAMS{'LOG_DIR'}; $logdir = $logdir . "/" if $logdir !~ /\/$/; my $log = $logdir . $date . '.log'; open LOGS , ">> $log" or die "ERROR : Couldn't open $log for writing/a +ppending. $!\n"; my $AI_QUEUEID = $ENV{'OT_QUEUEID'}; my $OT_DIR = $ENV{'OT_DIR'}; unless (Translate(\%CONFIG_PARAMS)) { Println "Translation was not successful, check logs for more detail +s"; exit 1; } close LOGS; # Translate inbound/outbound files sub Translate(%) { local $ARG; my $CONFIG_PARAMS = shift @ARG; my $attach; my $aicommand; my $dir; if ($CONFIG_PARAMS->{'INBOUND'} eq 'true') { $dir = $CONFIG_PARAMS->{'INBOUND_IN_DIR'}; Println "Inbound dir set to $dir" if $debug; } else { $dir = $CONFIG_PARAMS->{'OUTBOUND_IN_DIR'}; Println "Outbound dir set to $dir" if $debug; } unless (opendir DIR , $dir) { Println "ERROR : Couldn't open dir $dir , " . "$!"; return; } my @files = readdir(DIR); if (scalar @files - 2 == 0) { Println "ERROR : No files exist in $dir , no translation perform +ed"; return 1; } Println "Total files found " . scalar @files - 2 if $debug; # archive date time stamp my $archdts = strftime('%Y%m%d%H%M%S', localtime); if ($CONFIG_PARAMS->{'INBOUND'} eq 'true') { Println "Processing inbound files" if $debug; # cat file name my $catfile = "$dir/in.$$"; # cat all the inbound files #system ("cat $dir/* | grep -v directory >> $catfile"); # inbound attachment $attach = "OTRecogn.att"; my @sessionnumbers = (); foreach my $file (@files) { $file = $dir ."/". $file; next if $file =~ /^\./ or -d $file; my $tempfile = $file . 'tmp'; unless (cp $file , $tempfile) { Println "ERROR : Could not copy $file to $tempfile, $!"; return; } $aicommand = qq{"$ENV{'OT_DIR'}/bin/inittrans" -cs $ENV{'OT +_QUEUEID'} -at $attach -DINPUT_FILE=$file}; Println "Translating file $catfile"; my $sessionnumber = callAI($aicommand , \%CONFIG_PARAMS); push @sessionnumbers, $sessionnumber; if ($sessionnumber != 0) { my $originalname = basename $file; #$file = $dir ."/". $file; my $arch_dir = $CONFIG_PARAMS->{'INBOUND_ARCH_DIR'}; Println "Inbound Archive dir set to $arch_dir" if $debug; my $arch_filename = $arch_dir . "/" . $originalname . "." +. $sessionnumber; unless (cp $tempfile , $arch_filename) { Println "ERROR : Could not copy $file to $arch_filena +me, $!"; return; } Println "Archived file $file to $arch_filename"; unlink $tempfile; } } } else { # Process each outbound file OUTBOUND: foreach my $file (@files) { my $filename = $file; next if $file =~ /^\./ or -d $file; $file = $dir ."/". $file; Println "Processing outbound file $file" if $debug; # delete sig files if ($file =~ /\.sig/) { Println "Deleting sig file $file" if $debug; unlink $file; next; } if ($file !~ /$CONFIG_PARAMS->{'OUTCRIT'}/) { Println "Skipping $file, doesn't match $CONFIG_PARAMS->{'OUTCR +IT'}"; next OUTBOUND; } # main attach for outbound $attach = "OTEnvelp.att"; # archive directory for outbound files my $arch_dir = $CONFIG_PARAMS->{'OUTBOUND_ARCH_DIR'}; Println "Outbound Archive dir set to $arch_dir" if $debug; # is this an 856 # if ( $file =~ /$CONFIG_PARAMS->{'SORT'}/ ) { # yes it is so call the sort attachment # $attach = "WALMRTo856sorts.att"; # Println "Attachment set to $attach"; #} # is this an 810 MMG ## if ( $file =~ /$CONFIG_PARAMS->{'MSORT'}/ ) { ## ## # yes it is so call the sort attachment ## $attach = "MMGUPCo810sorts.att"; ## Println "Attachment set to $attach"; ## ## } ## ## # is this an 810 WALMRT ## if ( $file =~ /$CONFIG_PARAMS->{'WSORT'}/ ) { ## ## # yes it is so call the sort attachment ## $attach = "WALMRTUPCo810sorts.att"; ## Println "Attachment set to $attach"; ## ## } ## ## # is this an 810 FRDMYR ## if ( $file =~ /$CONFIG_PARAMS->{'WSORT'}/ ) { ## ## # yes it is so call the sort attachment ## $attach = "FRDMYRUPCo810sorts.att"; ## Println "Attachment set to $attach"; ## ## } my $mapattach; # grab the map attach from the conf file while (my ($key , $value) = each(%CONFIG_PARAMS)) { if ($file =~ /$key/) { $mapattach = $value; } } # is there a map attach for this file? unless (defined $mapattach) { #Println "Could not find the map attachment for $file, please c +heck the configuration file and try again"; Println "WARN : Ignoring $file, not found in the config file"; next OUTBOUND; } # set the trace level my $tracelevel = 0; # set trace level to 0 if debug $tracelevel = 0 if $debug; my $cpfile = $file . ".cp"; unless (cp $file , $cpfile) { Println "ERROR : Could not copy $file to $file . '.cp'"; return; } # construct aicommand $aicommand = qq{"$ENV{'OT_DIR'}/bin/inittrans" -cs $ENV{'OT_QUEUE +ID'} -at $attach -DINPUT_FILE=$cpfile -DMESSAGE=$mapattach -DBYPASS=O +TINOByp.att}; # call the translator my $sessionnumber = callAI($aicommand , \%CONFIG_PARAMS); my $arch_filename = $arch_dir . "/" . $filename; if ($sessionnumber != 0) { # archive file to the archive directory $arch_filename = $arch_filename . "." . $sessionnumber; unless (cp $file , $arch_filename) { Println "ERROR : Could not archive $file to $arch_filename, + $!"; return; } # delete the file, no longer needed unlink $file; # delete the temp file, if AI is not deleting this file, speci +ally for the 856 unlink $cpfile if -e $cpfile; } } # OUTBOUND : foreach closedir DIR; } if ($error_flag eq 'y') { Println("E-mailing Exception Report"); my $scrip_call = 'C:/AI_EDI/AIScripts/ExceptionReport.sh'; ##$CONFIG_P +ARAMS->{'SCRIPT_DIR'} . '/ExceptionReport.sh ' . $sd . ' ' .$st; system($scrip_call); } #if ( $inout eq '-i' ){ # # # #Println("E-mailing Inbound Document Report"); ##my $scrip_call = 'C:/AI_EDI/AIScripts/InboundDocumentReport.sh' ($s +d) #; ##$CONFIG_PARAMS->{'SCRIPT_DIR'} . '/InboundDocumentReport.sh +' .' ($sd)' . .'($st)'; #my $scrip_call = 'C:/AI_EDI/AIScripts/btInboundDocumentReport.sh' . +' '. $sd . ' ' .$st; #Println ($scrip_call); #system($scrip_call); # #} if ( $inout eq '-o' ){ Println("E-mailing Outbound Document Report"); #my $scrip_call = 'C:/AI_EDI/AIScripts/btOutboundDocumentReport.sh' .' + '. $sd . ' ' .$st;; ##$CONFIG_PARAMS->{'SCRIPT_DIR'} . '/OutboundDoc +umentReport.sh '; # . $sd . ' ' .$st; #system($scrip_call); } # return successfully return 1; } sub callAI() { local $ARG; my $aicommand = shift @ARG; my $CONFIG_PARAMS = shift @ARG; my $tracelevel = 0; $tracelevel = 0 if $debug; $aicommand = $aicommand . " -tl " . $tracelevel . " -I"; Println ($aicommand) if $debug; my @output = (); chomp(@output = qx($aicommand 2>&1)); if ($debug) { for my $out (@output) { Println($out); } } my $sessionnumber; LINE: for my $line ( @output ) { if ( $line =~ /Session# (\w{1,9}) completed successfully./ ) { # the process completed without any apparent errors $sessionnumber = $1; last LINE; } # end of if $line =~ ... if ( $line =~ /Cannot connect with server|Connection lost with +Server|Invalid command arguments/i ) { Println "ERROR : $line"; return; } } my @applfiles = FindSessionFiles($ENV{'OT_DIR'} . '/' . $CONFIG_PA +RAMS->{'APPL'} . '/' , $sessionnumber); my @commfiles = FindSessionFiles($ENV{'OT_DIR'} . '/' . $CONFIG_PA +RAMS->{'COMM'} . '/', $sessionnumber); my @excpfiles = FindSessionFiles($ENV{'OT_DIR'} . '/' . $CONFIG_PA +RAMS->{'EXCP'} . '/', $sessionnumber); my @logsfiles = FindSessionFiles($ENV{'OT_DIR'} . '/' . $CONFIG_PA +RAMS->{'LOGS'} . '/', $sessionnumber); if (scalar @applfiles > 0) { for my $afile (@applfiles) { sleep 1; my $inboundout = $CONFIG_PARAMS->{'INBOUND_OUT_DIR'}; my $newfile = $afile; $newfile = basename $newfile; ### $newfile =~ s/\.$sessionnumber//g; unless (cp $afile , "$inboundout/$newfile") { Println ("ERROR : Unable to copy $afile to $CONFIG_PARA +MS->{'INBOUND_OUT_DIR'}, $!"); return; } } } if (scalar @commfiles > 0) { COMM: for my $afile (@commfiles) { sleep 1; # special wrap 80 processing for outbound files if ($afile =~ /$CONFIG_PARAMS->{'WRAP'}/) { open (COMMFILE , "< $afile"); open (COMMFILETMP , "> $afile.tmp"); my $delim = "\n"; while (<COMMFILE>) { my $line = $_; $line =~ s/\r|\n//g; while ( length $line > 80 ) { print COMMFILETMP substr( $line, 0, 80 ) . $delim; $line = substr( $line, 80, length $line ); } print COMMFILETMP $line . $delim; } close COMMFILETMP; close COMMFILE; unless (cp $afile . '.tmp' , $afile) { Println ("ERROR : Unable to move $afile . '.tmp' to $a +file"); return; } } unless (cp $afile , $CONFIG_PARAMS->{'OUTBOUND_OUT_DIR'}) { Println ("ERROR : Unable to copy $afile to $CONFIG_PARAMS +->{'OUTBOUND_OUT_DIR'}"); return; } } } if (scalar @excpfiles > 0 ) { Println ("ERROR : Session number $sessionnumber had errors, plea +se check AI logs for more detailed information"); # Send email here. $error_flag = 'y'; Println (@output); } return $sessionnumber; } sub FindSessionFiles ($$) { # protect the current value of $ARG ($_) local $ARG; # get the directory path my $dir = shift @ARG; # get the session number my $sessionnumber = shift @ARG; my $caller = (caller 1) [3]; # open a directory handle unless ( opendir DIR, $dir ) { # failure Println "ERROR : Unable to open AI directory $dir \n"; return; } # end of unless opendir DIR, $dir # get all the entries in the directory my @entries = readdir DIR; # close the directory handle, no longer needed closedir DIR; # get the files @entries = grep /$sessionnumber/, @entries; # prepend the directory @entries = map $dir . $ARG, @entries; # return the array return @entries; } # end of sub FindSessionFiles ($$) # print with a new line sub Println($) { my $leader = strftime('%Y/%m/%d %H:%M:%S', localtime) . ' [' . sprin +tf('%6s', $PID) . '] '; print $leader . $_[0] . "\n"; print LOGS $leader . $_[0] . "\n"; }

Config file for your reference

# Inbound File Dir INBOUND_IN_DIR=C:/AI_EDI/inbound/BBB-TGT # Inbound Output Dir INBOUND_OUT_DIR=C:/AI_EDI/inbound/out # Inbound Archive Dir INBOUND_ARCH_DIR=C:/AI_EDI/Inbound/BBB-TGT/EDI-Inbound-Archive # Outbound In Dir OUTBOUND_IN_DIR=C:/AI_EDI/outbound/in # Outbound Archive Dir OUTBOUND_ARCH_DIR=C:/AI_EDI/outbound/BBBTGT/Inputarchive # Outbound Out Dir OUTBOUND_OUT_DIR=C:/AI_EDI/outbound/out/ # Tmp dir TMP_DIR=C:/AI_EDI/tmp # Daily Log Dir LOG_DIR=C:/AI_EDI/logs # Daily Log Dir SCRIPT_DIR = C:/AI_EDI/AIScripts # Outbound configuration, file name = map attach name TGTASN=TGTo856FFEDI.att ECPOAO=GIBo855FFEDI.att DSVINV=GIBo846FFEDI.att INO=GIBSONo810FFEDI.att DSVRMA=GIBo180FFEDI.att DSVASN=GIBSONo856FFEDI.att DSNO=GIBSONo856FFEDI.att EPOCAC=GIBo865FFEDIC.att TGT865=GIBo865FFEDIS.att ECPOAC=GIBo855CSFFEDI.att # Do not process any outbound files that do not match this criteria "| +" is an OR condition OUTCRIT=DSVASN|DSNO|ECPOAO|EPOCAC|EPOCAO|DSVINV|INO|DSVRMA|TGT865|TGTA +SN|ECPOAO| # AI related parameters APPL=appl COMM=comm EXCP=excp LOGS=logs # Wrap 80 bytes, outbound specific only WRAP=CITGRP

Replies are listed 'Best First'.
Re^2: Code Issue after Upgrading the perl from 5.14.4 to 5.22.3
by poj (Abbot) on Feb 10, 2017 at 20:06 UTC

    Check out this config line

    # Do not process any outbound files that do not match this criteria "|" is an OR condition
    OUTCRIT=DSVASN|DSNO|ECPOAO|EPOCAC|EPOCAO|DSVINV|INO|DSVRMA|TGT865|TGTASN|ECPOAO|
    

    ECPOAO appears twice but more important is the trailing | which makes the regex accepts any value of $file so none are skipped here.

    241:     if ($file !~ /$CONFIG_PARAMS->{'OUTCRIT'}/) {
    242:         Println "Skipping $file, doesn't match $CONFIG_PARAMS->{'OUTCR
    +IT'}";
    243:         next OUTBOUND;
    244:     }
    

    Note also ECPOAC=GIBo855CSFFEDI.att but ECPOAC does not appear in criteria

    EPOCAO in criteria does no have assoc .att file

    poj

      hi poj

      I have corrected the config file and executed the script still the issue, if you notice the output for first run the script has picked the file and for the next run it failed, though the file is still available to process.

      Output

      $ ./aicallerbt -o 2017/02/11 07:44:19 [ 956] Outbound dir set to C:/AI_EDI/outbound/in 2017/02/11 07:44:19 [ 956] Total files found 1 2017/02/11 07:44:19 [ 956] Processing outbound file C:/AI_EDI/outbou +nd/in/TGTASN1234 2017/02/11 07:44:19 [ 956] Outbound Archive dir set to C:/AI_EDI/out +bound/BBBTGT/Inputarchive 2017/02/11 07:44:19 [ 956] WARN : Ignoring C:/AI_EDI/outbound/in/TGT +ASN1234, not found in the config file 2017/02/11 07:44:19 [ 956] E-mailing Outbound Document Report $ ./aicallerbt -o 2017/02/11 07:44:21 [ 5280] Outbound dir set to C:/AI_EDI/outbound/in 2017/02/11 07:44:21 [ 5280] Total files found 1 2017/02/11 07:44:21 [ 5280] Processing outbound file C:/AI_EDI/outbou +nd/in/TGTASN1234 2017/02/11 07:44:21 [ 5280] Outbound Archive dir set to C:/AI_EDI/out +bound/BBBTGT/Inputarchive 2017/02/11 07:44:21 [ 5280] "/bin/inittrans" -cs -at OTEnvelp.att -D +INPUT_FILE=C:/AI_EDI/outbound/in/TGTASN1234.cp -DMESSAGE=TGTo856FFEDI +.att -DBYPASS=OTINOByp.att -tl 0 -I 2017/02/11 07:44:21 [ 5280] sh: /bin/inittrans: No such file or direc +tory 2017/02/11 07:44:21 [ 5280] ERROR : Unable to open AI directory /appl +/

      ignore Error messaage, my only criteria is $mapattch value

        Your next step is to inspect what is in %CONFIG_FILE when you encounter that condition.

        Use the following code:

        if ($file =~ /$key/) { $mapattach = $value; use Data::Dumper; print Dumper \%CONFIG_FILE; }

        Also output whenever you get a match on /$key/:

        if ($file =~ /$key/) { $mapattach = $value; use Data::Dumper; print Dumper \%CONFIG_FILE; print "'$file' matches /$key/, setting value '$value'\n"; }

        Maybe there are two keys in %CONFIG_FILE that match the filename and the second one overwrites the first match in some cases? You are aware that hash keys are not ordered in Perl?

        OK, took some finding but this might be the problem. The blank lines in your config file are creating a blank key entry in the %CONFIG_PARAMS hash i.e. "" => undef. When you loop through the keys at some point the match becomes

        if ($file =~ //) { $mapattach = undef; }

        Because the order is random it depend which keys follow as to whether it gets corrected. The fix is to add a line to skip the blanks lines in here

        # parse the config file while (<FILE>) { # remove leading spaces $_ =~ s/^\s+//g; # remove trailing spaces $_ =~ s/\s+$//g; # ignore comments next if $_ =~ /^#/; # ignore blanks next unless /\S/; my @params = split /=/ , $_; $CONFIG_PARAMS{$params[0]}=$params[1]; }

        A better way would be use a regex to extract the key from the filename and match directly like this.

        my $mapattach; # add () inside // to capture match if ($file !~ /($CONFIG_PARAMS->{'OUTCRIT'})/) { Println "Skipping $file, doesn't match $CONFIG_PARAMS->{'OUTCRIT'}"; next OUTBOUND; } else { $mapattach = $CONFIG_PARAMS->{$1}; }
        poj