teja402000 has asked for the wisdom of the Perl Monks concerning the following question:

Hi guys, We are using perl module net::pop3 :sslwrapper for downloading and reading our mails from gmail ( googleapps ) The problem we are facing is earlier we didnt had a secure mail server i.e we were not using ssl/tls . so our script was working fine. but nw what we have noticed is its skipping alternate mails and reading. PFA perl script. it reads 1,3,5,7 and skips 2,4,6

use strict ; # All variables must be declared before use use Cwd ; # Perl module to get current working directory use Getopt::EvaP ; use IPC::SysV qw(IPC_PRIVATE S_IRWXU S_IRWXU S_IROTH S_IRGRP IPC_CREAT + IPC_NOWAIT) ; use IPC::Semaphore ; use Mail::Sender ; #use Net::POP3 ; # Post Office Protocol 3(POP3) Client Perl mo +dule SS use Net::POP3::SSLWrapper ; # SSFIX use sigtrap qw(die normal-signals USR1) ; use XML::Simple ; $|=1 ; sub TRUE { 1 } ; sub FALSE { 0 } ; my $childCount ; # Tells the number of threads to be started fo +r mail processing my $configFile ; # The config file which stores the configurati +on information my %configparams ; my $children ; # Maximum number of instances of promote1mail. +pl my %cmdarg ; my $exit ; # Flag set to stop promoter my @PDT ; my @MM ; my $mode ; # Mode in which the promoter is running my $verbose ; # Flag used to decide whether to display infor +mation messages # List of functions starting from main and the rest sorted in alph +abetical order sub main; # Main routine sub checkmail ; # Log in as promoter on to pop3 server + and # Check if there are new promotion req +uests. sub checkcounter() ; # Gets the number of promote1mail.pl # that can be initiated sub exithandler ; # Traps the usr1 signal which is the # indication not to read any new mails sub getUnreadRequest($$$) ; # Reads the mail from promoter's mail +box # and creates a temporary file with co +ntents # of the mail sub initialise ; # open files and initialise variables sub readConfigFile() ; # Reads the PromoterConfig.xml file to + set the # values of the variables used in the +program sub rebuildref ; # Rebuild's reference file from log fi +le sub startchild($) ; # Starts the child process to process +mail read sub timestamp() ; # To get current time in YYYY-MM-DD da +y hh-mm-ss # format sub updateref($) ; # Updates the reference file after pro +cessing # each mail sub validateArgv; # Validates the commandline parameters + specified @PDT = split /\n/, <<end_of_PDT ; PDT promoter.pl childcount, cc: string configfile, cf: string="/utilities/promoter/data/PromoterConfi +g.xml" mode, m: key regular,restricted,test, keyend=regular verbose, v: switch, keyend=0 PDTEND no_file_list end_of_PDT @MM = split /\n/, <<end_of_MM ; promoter.pl Mail interface of promoter. Program controls the number of instances. .verbose Flag indicates if messages are to be displayed .childcount The number of mails to be process simultaneously .configfile File with the configuration details for the instance .mode Mode of operation of promoter end_of_MM # Main function which calls other functions. # INPUT : # OUTPUT : sub main{ initialise() ; checkmail() ; } # Functions to initialise constant lists and variables used. # INPUT : None # OUTPUT : None sub initialise { # Get the commandline arguments for which values are # supplied validateArgv() ; # Read the PromoterConfig.xml file to set the values of # the variables used. readConfigFile() ; if ( $verbose ) { print "\nCommand line arguments :\n" ; print "\tConfigFile = $configFile\n" ; print "\tChildCount = $childCount\n" if defined ( $childCount +) ; print "\tMode = $mode\n" ; print "\tStart Reference Number = $configparams{'STARTREFNUMBE +R'}\n" ; print "\nConfiguration parameters' values :\n" ; foreach ( keys %configparams ) { print "\t$_ = $configparams{$_}\n" ; } } # Check the value of childcount to ensure it is defined and is + less than # the max child count specified in config file. if ( (! defined $childCount) || ($childCount > $configparams{'MAXC +HILDCOUNT'}) ) { $configparams{'CHILDCOUNT'} = $configparams{'DEFAULTCHILDCOUNT +'} ; } else { $configparams{'CHILDCOUNT'} = $childCount ; } # Create a semaphore and set its value to the child count spec +ified $children = new IPC::Semaphore($configparams{'SEMAPHOREKEY'}, 1, S +_IRWXU | S_IRWXU | S_IROTH | S_IRGRP | IPC_CREAT) or die "Unable to c +reate semaphore \n" ; $children->setval(0, $configparams{'CHILDCOUNT'}) ; $SIG{'INT'} = \&exithandler ; $SIG{'TERM'} = \&exithandler ; $SIG{'HUP'} = 'IGNORE' ; } # Function which will be running as email listener always # INPUT : None # OUTPUT : None sub checkmail{ my $to_read=0 ; # Number of new promotion requests to be read my $num_Messages; # Message count returned by pop3 server on logi +n my $previousRead ; # The value from lastread.txt is read in to thi +s variable # in memory. my $pop3 ; # POP3 client object while (1){ my $checkmail = checkcounter() ; if ( $checkmail && ! $exit ){ # This program runs for ever as email listener print "Checking mail ". timestamp()."\n" ; # Create new pop3 object pop3s { print "INSIDE pops"."\n" ; $pop3 = Net::POP3->new($configparams{'POP3SVRIP'}, Port => +"995") ; #$pop3 = Net::POP3->new($configparams{'POP3SVRIP'},Port=>" +110",) ; # Check if object creation was successful or not # If not wait for 2 minutes and try again if(!defined($pop3)){ print "Pop3 server $configparams{'POP3SVRIP'} is not r +eachable.\n" ; print "will try again after 2 minutes\n" ; sleep 120 ; next ; } # Login with the promotion request user on to # pop3 server and get the new messages to be read $num_Messages = $pop3->login($configparams{'PROMOTERMAILID +'}, $configparams{'PROMOTERMAILPWD'}) ; # my $msgs = $pop3->list; #my $countmsg=0 ; #while (my ($id, $data) = each %$msgs) { #$countmsg +=$countmsg + 1 ; #print "gmail mail no == > $id " ; # } #print "Total tejas $countmsg ". "\n" ; print "INSIDE login"."\n" ; # Get the message number of the last read promotion re +quest # from the reference file in to variable open (REF,"$configparams{'DATADIR'}/$configparams{'LASTREA +DMAILNOFILE'}") || die "Cannot open file $configparams{'DATADIR'}/$co +nfigparams{'LASTREADMAILNOFILE'}\n" ; $previousRead = <REF> ; print "INSIDE mess no"."\n" ; close(REF) ; ###################### To read total number of messages in inbox ##### +######################### # open (REF,"$configparams{'DATADIR'}/$configparams{'GMAILR +EFFILE'}") || die "Cannot open file $configparams{'DATADIR'}/$configp +arams{'GMAILREFFILE'}\n" ; # my $lastmailcount = <REF> ; # print "INSIDE gmail count no"."\n" ; # close(REF) ; ###################################################################### +######################### # Check if the reference file is empty # If yes there is some problem so get the # message number of last processed mail from pop3.log # and rebuild the reference file if ( !$previousRead ) { # Call the Function to rebuild $previousRead = rebuildref() ; } die "Unable to rebuild the mail reference number\n" if ($p +reviousRead !~ /^\d+$/) ; # If login fails wait for 2 minutes and try to login +again # else check if there were any unread mails and proce +ss them if ( !defined($num_Messages) ) { # If the login failed close the connection. $pop3->close ; print "Failed to establish connection with server\n" ; # Wait for 120 seconds before checking # for new promotion requests sleep(120) ; } else { $to_read=0 ; print " Previous read count $previousRead " ; print " value of num_Messages before add $num_Messages + "."\n" ; #my $newlastmailcount = $num_Messages + $lastmailcount + ; #SSFIX #updategmailcount($newlastmailcount) ; #SSFIX #$num_Messages += $configparams{'STARTREFNUMBER'} + $l +astmailcount ; #my $msg_numbers = $pop3->list ; ##SSFIX #print "Total Gmail count $msg_numbers " ; $num_Messages += $configparams{'STARTREFNUMBER'} ; print "value of num_Messages after add $num_Messages " +."\n" ; # If num_messages returned by server is greater th +an # previous read message number there are some new # promotion requests to be handled so read them # and process them one by one if ( $num_Messages > $previousRead ) { # Get the number of new messages # (i.e) difference between previous read and # number returned from server $to_read= 1 ; # Clear pending requests list before again get +ting new # promotion requests getUnreadRequest($to_read,$previousRead,$pop3) ; print "INSIDE read message"."\n" ; # Close the connection to POP3 server # after getting all the new mails # in to memory $pop3->quit() ; # Now start processing each mail # in the pending requests list my $msgnum=$previousRead + 1 ; my $ncnt = $children->getval(0) ; $children->op(0, -1, 0) ; startchild($msgnum) ; $ncnt = $children->getval(0) ; } else { # If there were no pending request just wait f +or # a few seconds before again checking for # new promotion requests if ( $to_read == 0){ $pop3->quit ; print "No New Messages\n" if $verbose ; sleep $configparams{'MAILCHECKINTERVAL'} ; } } } } } else { print "Max child processes already running \n" ; sleep 15 ; } } } # Function which will clean up when exit command is received # i.e. INT, TERM signal is received # INPUT : None # OUTPUT : None sub exithandler { $exit = 1 ; print "\nReceived exit command\n" ; print "\nWaiting for all children to complete....\n" ; while (1) { my $children = checkcounter() ; if ( $children == $configparams{'MAXCHILDCOUNT'} ){ $children->remove if ( defined $children ) ; exit 0 ; } sleep 10 ; } } # Function to get the current time in YYYY-MM-DD at HH:MM:SS format # INPUT : None # OUTPUT : current time in YYYY-MM-DD at HH:MM:SS format sub timestamp() { my @weekdays = qw( Sun Mon Tue Wed Thu Fri Sat ) ; my ( $sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localt +ime ; $year += 1900 ; $mon += 1 ; my $timeStamp = sprintf "on %04d-%02d-%02d %3s at %02d:%02d:%02d" +, $year, $mon, $mday, $weekdays[$wday], $hour, $min, $s +ec ; return $timeStamp ; } # Function to get the new request in to memory for processing. # INPUT : Number of new messages, Last processed message number # OUTPUT : File containing the contents of mail sub getUnreadRequest($$$){ my $count = 0 ; my $unread = $_[0] ; my $previousRead = $_[1] ; my $pop3 = $_[2] ; my $mesg_to_be_read ; # Message number of pending promotion reques +t # Make the list containing the reference numbers # of requests processed null # Get all the requests in to memory as # the connection with the server timesout # before processing all of them and # some of them may be left off while ( $unread > 0 ) { $count++ ; $mesg_to_be_read = ($previousRead - $configparams{'STARTREFNUM +BER'}) + $count ; my $msg = $pop3->get($mesg_to_be_read) ; my $mailid += $mesg_to_be_read + $configparams{'STARTREFNUMBER +'} ; open (MAIL,">$configparams{'TEMPDIR'}"."/$mailid.mail") || die + ("Cannot open $mailid.mail file\n") ; print STDERR "START\n"; print MAIL @$msg if ( defined $msg ); close MAIL ; updateref($mailid) ; $unread-- ; } } # Funtion to update the reference file after processing each new mail # INPUT : Message reference number # OUTPUT : None sub updateref($) { my $mesgNumRead=$_[0] ; open (REF,">$configparams{'DATADIR'}/$configparams{'LASTREADMAILNO +FILE'}") || die "Cannot open file $configparams{'DATADIR'}/$configpar +ams{'LASTREADMAILNOFILE'}\n" ; print REF $mesgNumRead ; close REF ; } ############################################ gmail count file update # +#################### #sub updategmailcount($) { # # my $mesgNumRead=$_[0] ; # # open (REF,">$configparams{'DATADIR'}/$configparams{'GMAILREFFILE' +}") || die "Cannot open file $configparams{'DATADIR'}/$configparams{' +GMAILREFFILE'}\n" ; # print REF $mesgNumRead ; # close REF ; #} ###################################################################### +##################### # Function which rebuilds the lastread.txt reference file from pop3.lo +g file # INPUT : None # OUTPUT : None sub rebuildref { my $line ; my $lastprocessed ; print "Rebuilding $configparams{'DATADIR'}/$configparams{'LASTREAD +MAILNOFILE'} from $configparams{'LOGSDIR'}/pop3.log\n" ; open (REBUILD, "tail -n 15 $configparams{'LOGSDIR'}/pop3.log|") || + die "Cannot open file $configparams{'LOGSDIR'}/pop3.log\n" ; # Sample line from pop3.log file # 29 Aug 2003 14:15 406 sravanthi Fw: SPR 20300 # | | | | # | | | | # | | | Subject of the mail sent # | | Person who sent the mail # | Refernce number of the mail # Date and time when mail is received # We require last line in the log file for rebuilding # lastread.txt. As it will be a very big file reading entire # file in to memory will cause problem. So, we read the last # 15 lines and find the mail reference number. while (<REBUILD>) { chomp ; if (/^\s*\d{2}\s+\w{3}\s+\d{4}\s+\d{2}:\d{2}\s+(\d+)\s+.*$/) { $lastprocessed = $1 if ((!defined $lastprocessed) || ($1 > + $lastprocessed)) ; } } close REBUILD ; return ($lastprocessed) ; } # Function to determine command line arguments and read them into vari +ables # Input : None # Output : None sub validateArgv { &EvaP(\@PDT, \@MM, \%cmdarg) ; $childCount = $cmdarg{'childcount'} ; $configFile = $cmdarg{'configfile'} ; $mode = $cmdarg{'mode'} ; $verbose = $cmdarg{'verbose'} ; $verbose = 1 if ( $mode eq "test" ) ; # Get the login name of the user who is running the script my $login = getlogin || (getpwuid($<))[0] ; # If promoter is started in either regular or restricted # mode, then the user has to be 'promoter'. if ( $mode ne "test" ) { if ( $login ne "promoter") { print "Promoter cannot be run in \'$mode\' mode as \'$logi +n\'. Terminating....\n" ; exit ; } } } # Function to read the Config file and set the variables and paths use +d in the program # Input : None # Output : None sub readConfigFile() { if ( -r "$configFile" ) { my $promoterconfig = XMLin("$configFile",keyattr=>'CONFIG',sup +pressempty=>'') ; foreach my $key ( keys %{$promoterconfig} ) { $configparams{$key} = $promoterconfig->{$key} ; } } else { print "Unable to open $configFile file \n" if $verbose ; exit ; } } # Function to start the instance of the promote1mail.pl # INPUT : None # OUTPUT : None sub startchild($) { my $msgnum = $_[0] ; print "Starting Child process for $msgnum mail ". timestamp()."\n" + ; my $cmd = "perl $configparams{'EXECDIR'}/promote1mail.pl -mode $mo +de -mailid $msgnum -configfile $configFile -ppid $$ -debug" ; $cmd .= " -debug" if ( $verbose || ($mode eq "test") ) ; system("$cmd > $configparams{'TEMPDIR'}/$msgnum 2>&1 &") ; my $retVal = $?>>8 ; print "Executed : \"$cmd > $configparams{'TEMPDIR'}/$msgnum &\" Re +turn value : [$retVal]\n" if ($retVal != 0) ; } # Function to get the number of instances of promote1mail.pl promoter +can run # INPUT : None # OUTPUT : How many child process can be started sub checkcounter(){ my $ncnt = $children->getval(0) ; return $ncnt ; } # Function to do the cleanup job. # Input : None. # Output : None. # sub cleanup() { print STDERR "\n\nCleaning up the promoter environment...." ; # Remove all the flag files from the /utilities/promoter/tmp d +irectory. my $cmd = "rm -f $configparams{'TEMPDIR'}/*.flag" ; system ("$cmd >/dev/null") ; # Remove the Semaphore. $children->remove if ( defined $children ) ; print STDERR "\n\nPromoter environment cleaned.\n\n" ; } END { cleanup() ; } &main ;

Replies are listed 'Best First'.
Re: Perl net::pop3:sslwrapper
by roboticus (Chancellor) on May 23, 2012 at 10:09 UTC

    teja402000:

    When you present people with a huge wall of code, people will often skip right over your node, as it's not fun to read a billion lines of code. You should spend a little effort to reduce the program to a short example that demonstrates the problem. If you do, you'll often find the answer in the process.

    Having said that, I gave the code a brief glance. This is just a guess, but I'm thinking that next statement (line 155) is exiting from the subroutine and skipping to the next EMail. If you instead wrap it with a loop and retry the connection, it may work more to your liking.

    ...roboticus

    When your only tool is a hammer, all problems look like your thumb.

      Hi Roboticus , Ya i should have kept it short and sweet , my apologies. Wrap it up in a loop means ?

        teja402000:

        Actually, now that I look again, it is wrapped up in a loop. The code is a bit much to digest as it is, so I don't see where the error is. I originally didn't see the while (1) you have up there, so I thought the next was throwing you to the next EMail message, thus skipping EMails when you have login faults.

        ...roboticus

        When your only tool is a hammer, all problems look like your thumb.