[EXIM] gadget to parse log file and generate bounce message

Top Page
Delete this message
Reply to this message
Author: mark david mcCreary
Date:  
To: exim-users
Subject: [EXIM] gadget to parse log file and generate bounce message
These steps can process exim log files, and generate a bounce message
back to mailing lists, thus clearing the bad address off the list.

Bounce message come in a couple of flavors. First of all, it could
bounce before the message even got there. They just reply with an
SMTP code of 5xx, such as 550 - User Unknown. Juno.com does it this
way.

Or they could accept the message, and then later on realize that the
user is unknown, and email back a bounce message. Aol.com does it
like this.

This gadget will help remove bad addresses from juno.com, and similiar
mail hosts. Since there is no bounce message, the information must be
gotten from the exim log (typically called exim_mainlog).

This works ok with the Smartlist Mailing List Manager.


4 Steps

1) Use Eximstats to generate error only report, and mail to special
procmail recipe.

    Put this in your crontab file


        54 23 * * * root /usr/local/exim/bin/eximstats -nt -h0 -q0
-nr -t0 /var/log/exim/exim_mainlog 2>&1 | /bin/mail -s 'exim errors' bouncer




    It generates a report like this


          1 Joe@??? <jokes@???>: unrouteable mail
domain "aol.net"


which means that the error occured 1 time, joe@??? was the mailing
list subscriber, and jokes was the mailing list.

2) Procmail recipe massages headers, and passes body of message to
Perl program. Handle email sent to bouncer address.


    #   The mail-list.com front-end for Smartlist Mailing Lists
    #
    #   Copyright (c) 1998 Internet Tools, Inc.
    #
    #    This program is free software; you can redistribute it
and/or modify
    #    it under the terms of the GNU General Public License as
published by
    #    the Free Software Foundation; either version 2 of the
License, or
    #    (at your option) any later version.
    #
    #
    #   Bounce Error Routine
    #
    #   Reads report of errors generated by Eximstats and creates and sends
    #   bounce message back to appropriate list
    #
    #   Calls Perl program bouncer.pl to accomplish the bulk of the work


    PATH=.:/home/ftp/discuss/.bin:/bin:/usr/bin:/usr/local/bin:/usr/sbin:$PATH    SHE
LL=/bin/sh


    VERBOSE=yes
    LOGABSTRACT=all
    LOGFILE=$HOME/procmailog
    COMSAT=no


    DOMAIN=domain.com           # the common domain for all the lists
    SUBDOMAIN=`hostname`        # the fully qualified hostname


    #  save a copy of all incoming files to an existing directory
called backup
    #
    :0 c
    backup


    SENDER  = `formail -rtzx To:`
    SUBJECT = `formail -zxSubject:`
    TODAY   = `date "+%Y-%m-%d %T"`



    :0 hwic: log.lock
    |  echo -e $TODAY "\t" $SENDER "\t" $SUBJECT >> log-bouncer



    #  filter the email message
    #  set up the headers for the perl program


    :0 fh
    | formail -I"Subject: Bounce from Bouncer" \
              -I"From: mailer-daemon@localhost"


    #
    #  pass email message to perl program
    #  which will send out 1 email message for each error line in the
body of the message
    #


    :0 w
    | bouncer.pl



3) Perl program parses report, grabbing bad email addresses, and
sending in a bounce message.

    #!/usr/bin/perl -w
    #
    #   The mail-list.com front-end for Smartlist Mailing Lists
    #
    #   Copyright (c) 1998 Internet Tools, Inc.
    #
    #    This program is free software; you can redistribute it
and/or modify
    #    it under the terms of the GNU General Public License as
published by
    #    the Free Software Foundation; either version 2 of the
License, or
    #    (at your option) any later version.
    #


    #
    #
    #  This program will generate bounce messages, and send them to the
    #  appropriate list-request address.
    #
    #  This program is invoked by a Procmail recipe.  The body of the email
    #  message is an error report produced by Eximstats.
    #
    #  The error report has a specific format of error messages, which
looks like
    #
    #        1 u2pino@??? <chistes@???>
    #
    #  From which the first email address is the bad address, and the
second
    #  address is the list address.  Which can easily be transformed into
    #  the list-request address.
    #
    #  This program uses the Perl Module  Mail::Internet to send each
message.
    #
    #
    #


    use Mail::Internet;


    chop(my $Date = `date "+%Y-%m-%d %T"`);


    my $error_ind = '    \d ';         #  all error lines start
with this sequence
    my $bounce_body = '     550 ';  #  550 is SMTP error code for user
unknown
    open(LOG,">>/tmp/bouncer.log") || die(" Could not open bouncer.log
$!");


    $ENV{'SMTPHOSTS'} = 'localhost';


    my $mesg = new Mail::Internet \*STDIN;


    # look at mail headers, and grab the data


    my $from = $mesg->head->get('From'); chop($from);
    my $subject = $mesg->head->get('Subject'); chop($subject);


    # tidy up the body


    my $body = $mesg->body();
    map {chop($_)} @$body;


    # @commands is an array of each line in the message body.


    my @commands = @$body;


    @$body = ();


    my $command;
    foreach $command (@commands) {


        next if $command =~ m/^\s*$/;            # skip
blank lines


        unless ($command =~ m/^$error_ind/) {
            next;
        }


        @tokens = split(/\s+/, $command);        # put each word
into a seperate array cell


        my $bad_address = $tokens[2];            # bad
address that caused the list problems


        my $list_address = $tokens[3];          # list address that
had problems


        $list_address =~ s/<//;                    #
strip < symbol from address
        $list_address =~ s/>//;                    #
strip > symbol from address
        $list_address =~ s/://;                    #
strip colon symbol from address
        $list_address =~ s/\@/-request\@/;        # add request onto
user name


        unless ($bad_address =~ m/\@/) {
            next;
        }


        unless ($list_address =~ m/\@/) {
            next;
        }


        # make the body of the message a simple bounce message that
smartlist can handle


        my $message_body = $bounce_body . "<" . $bad_address . ">"
. "\n";


        my $new_mesg = new Mail::Internet(
            [ ],
            'Body' => [$message_body]
            );


        # this is who the mail is directed to via SMTP;


        $ENV{MAILADDRESS} = $from;


        # these are the addresses placed in the header block of the
message.


        $new_mesg->head()->add('From', $from);
        $new_mesg->head()->add('To', $list_address);
        $new_mesg->head()->add('Subject', $subject);


    #    $new_mesg->print_header(\*LOG);
    #    $new_mesg->print_body(\*LOG);


        print LOG  "$Date\t$list_address\t$bad_address\n";


        my @recips =  $new_mesg->smtpsend;


        unless (@recips > 0) {
                   print LOG "Failed to deliver
($from,$list_address,$message_body) \n";
            next;
        }


        }



4) Mailing list software unsubscribes bad address.



Assumes

You have Procmail installed. Preferably the latest version.

Your exim configuration file receives incoming mail for localhost ip
address. For example,

    local_domains = "@:domain.com:[127.0.0.1]"


You have Eximstats, which is a Perl program to report on the exim
mainlog, that comes with Exim as standard equipment.

You have the Perl Mailtools modules installed. This module takes care
of sending via SMTP interchange a mail message to the list request
address.

I will be happy to take corrections, updates, or additions via private
email (mdm@???).

mark



mark david mcCreary
Internet Tools, Inc.            1436 West Gray #438
mdm@???          Houston, Texas 77019
http://www.internet-tools.com   713.627.9600




--
*** Exim information can be found at http://www.exim.org/ ***