procmail
[Top] [All Lists]

Re: Resending mail from one mailbox to multiple accounts

2001-04-10 13:23:56
At 21:44 2001-04-10 -0400, Intuitive Design Archive did say:

        We have a company that we had to dump over 2000 messages for into
one mailbox. Now I they have setup their own server and we are looking for
a way to have the massages reset back to the new email server:

Presumably then, this is ONE domain? This is important when considering how you must approach the solution below...

formail -s procmail ./redirect.rc < test.mailbox

Righto.

There are issues of course - BCC's (where the recipient address doesn't appear in the message) and multiple in-domain recipients (TO: bob and sue, CC: joe).

:0
*^TO_$USER(_at_)$DOMAIN
! $USER(_at_)$DOMAIN

where $USER and $DOMAIN are the variables gotten from the email
messages. Any idea how to capture and reuse that info. Thanks Alot in
advance for all your help.

The problem with this is that I doubt the ^TO_ regexp is going to catch much of anything in a way that you're going to be able to directly manipulate if you want to catch it as a MATCH to subsequently parse. (unlike matching something within ^To: or ^Cc:, which aren't macro regexps like ^TO_). You're not really asking for anything SPECIFIC, and MATCH matches to EOL. If you check the ^TO_ regexp, you'll see that it looks for a match within various headers which don't exclusively contain a mail address. You WILL need to provide some address anchor for it to search for.


Now, the first thing to keep in mind is that while developing/testing your rule you should have it dump messages into a series of files (one for each recipient), rather than forwarding them - this way, failed tests don't send a flurry of email at someone (and someone to whom perhaps they shouldn't have been sent!). When you figure you've got it right THEN change it to forward. During testing, since you'll be writing to a file, you'll want to add the ':' (lock) flag (though I think with the formail invocation, this isn't strictly necessary, it is still proper practice).

As for the domain - is it really a bunch of different ones? That seems like it'd be a problem, since you're not really matching against anything specific (and if you need to match the userid and domain as separate tokens, you'll probably need to extract them together and pass them through a sed script or something). I'm really guessing that your company now has their own server for their (one) real domain, and you're now processing the mail for it that. If there really are multiple domains, simply duplicate your recipe for each domain. You could have a primary rcfile with each domain being defined, and then an includerc with the core of the script, but unless your core script gets complex, it isn't worth the effort to do it that way -- most certainly not if it is for a one-off task.

Perhaps there is a finite number of addresses? This could make the one-off filtering that much easier.

You'll need to use the MATCH syntax, as described in the manpages, in order to extract addressee information to re-use for delivery.

The following should serve as a starting point for redelivery of your messages, with the caveat that BCCs that don't have any identifying address in the message and messages with multiple local recipients will pose problems. The BCC problem isn't something you can easily address after the fact -- if the message doesn't identify who it was to be delivered to, you can't pull this information out of the air. Multiple local recipients could either be handled by a filter which first uses a msgid cache (provided all messages even HAVE messageids) to dump duplicates, then parses all the TO: and CC: addresses on the remaining messages and delivers a copy of that message to each addressee on that list (which is WITHIN your domain - it'd be buttheaded to deliver messages to addresses OUTSIDE of your domains, and as a listadmin on several other lists, I can say that this will NOT endear you to anybody).

Here goes (please not the disclaimer document in my .sig):

#--------
# enable verbose logging - check your logfile for the results of the test
LOGFILE=./testing.log
VERBOSE=on

# define a default mailbox -- anything you don't specifcally deliver yourself
# (forward or to a file basically), will be dumped here.  These messages you
# can revisit to develop further filtering rules for (you'd then move this
# file to another file, and pipe it into the formail invocation).
DEFAULT=./unfiltered.mbx

# If X-Envelope-To header is present (assumes your server is set up to add it)
# then use it -- this should concisely define who the recipient of THIS
# message was.  If you manage the mailserver where the messages were queued
# up originally, you might consider changing your MTA config to add the
# header (a topic which is an MTA issue, not a procmail one).
# *** Note that under certain circumstances, this may be the LOCAL username
# where the mailbox is hosted, or if mailed FROM the localhost, may not
# include the domain portion.  You might use a regexp similar to the one
# used in the next recipe, then manually deal with non-domain mail later.

:0:
* ^X-Envelope-To:[      ]*\/[^  ]+
{
# with the verbose logging, this assignment will appear in the logfile. # no doubt this sed invocation is less than optimal - anyone is welcome
        # to tidy it up - we're just removing the optional brackets.
        USERADDR=`echo $MATCH | sed -e s/\<// -e s/\>//`

        # insert your forward rule here.  This currently just dumps it
        # in a file
        :0:
        mailbox.$USERADDR
}

# Here, you're stuck with dealing with messages to different people, possibly
# with some messages being addressed to more than one local recipient.  This
# rule will attempt to determine who the apparent recipient is (within your
# domain), and emit a logfile entry to that effect.
# Run the script once and then pour over the logfile for "UNKNOWN!" entries.

:0
* ^TO_\/.*@([^\.]*\.|)yourdomain\.tld\>?
{
# with the verbose logging, this assignment will appear in the logfile. # no doubt this sed invocation is less than optimal - anyone is welcome
        # to tidy it up - we're just removing the optional brackets.
        USERADDR=`echo $MATCH | sed -e s/\<// -e s/\>//`

        # insert your forward rule here.  This currently just dumps it
        # in a file
        :0:
        mailbox.$USERADDR
}

# If the message reaches this point, we didn't find a candidate address.
# It'll fall off to deliver to default, and you can manually examine that
# file for further action.  These should be BCC's with no apparent local
# recipient.  Many may probably be spams.

#--------

Of course, you could take the filtered mailboxes and draw up a script to those individually to their respective users (say if you end up manually migrating some messages to certain mailboxes).

If the remote mailserver is *nix based, you might try moving the mailbox to the mail spool for the user on this host, then from the remote server, using fetchmail and procmail to bring the mail there and filter it that way (or FTP the mailbox file over and redeliver it locally).

---
 Sean B. Straw / Professional Software Engineering

 Procmail disclaimer: <http://www.professional.org/procmail/disclaimer.html>
 Please DO NOT carbon me on list replies.  I'll get my copy from the list.

_______________________________________________
procmail mailing list
procmail(_at_)lists(_dot_)RWTH-Aachen(_dot_)DE
http://MailMan.RWTH-Aachen.DE/mailman/listinfo/procmail

<Prev in Thread] Current Thread [Next in Thread>