procmail
[Top] [All Lists]

Re: Message split in Two

1998-11-19 12:12:04
"Matthew G. Saroff" <msaroff(_at_)sparc-119(_dot_)re-ro(_dot_)com> writes:
      I just got a message sent to me.  It was a forward of another
message.  I have procmail set up to forward mail to me, and at this
account, I got it as two messages.
      On my home account, the headers and the headers of the fowarded
message look like:

From owner-staff(_at_)arisia(_dot_)org  Thu Nov 19 01:32:55 1998
Return-Path: owner-staff(_at_)arisia(_dot_)org
...

From Eristocracy(_at_)merrymeet(_dot_)com Wed Nov 18 20:49:22 1998
X-Sender: jon(_at_)merrymeet(_dot_)com
...

      On my forwarded account, and on my procmail backup mailbox (it
keeps a copy of the most recent 50 messages, the headers look like this:

From owner-staff(_at_)arisia(_dot_)org  Thu Nov 19 01:32:55 1998
Return-Path: owner-staff(_at_)arisia(_dot_)org
...

From Eristocracy(_at_)merrymeet(_dot_)com Wed Nov 18 20:49:22 1998
X-Sender: jon(_at_)merrymeet(_dot_)com
...

      I see where the > has been deleted from the 2nd from line, and I
am assuming that this is what caused the split.

The pertinant recipe (for the backup file, the forwarding is just using !)
is:
# This appends the last maxgbackup files to the fallback folder
# It prevents mail from being lost through incorrect recipes
:0Wc:$HOME/incoming/fall.lock
| cat - $BACKGFILE | formail -${maxgbackup}s > $TEMPGFILE ; \
 mv -f $TEMPGFILE $BACKGFILE


Okay, when procmail received the message, the "From " line in the body
did not start with a '>'.  A traditional style mailbox file uses "From "
lines to delineate the start of each message.  Therefore, when writing
a message to such a folder, procmail hides "From " lines by preceding
them with a '>'.  This is why the message in your backup mailbox looked
that way.

However, altering the content of a message is a Bad Thing to do if you
don't have to.  Procmail therefore only escaped "From " lines when
writing to a simple file folder.  When feeding a message into a pipe it
doesn't do the escaping -- you can always do the escaping 'by hand' in
the pipe action if you need it, but it would be impossible to undo it
if procmail always did it and you didn't want it to.

So, when the message if fed to 'cat' in the action, it gets
concatenated with the other messages in the file and the fact that it's
a single message is lost.  The solution is to escape the "From " lines
yourself before feeding the message into cat.  When invoked with no
arguments formail will do "From " escaping:

        :0Wc:$HOME/incoming/fall.lock
        | formail | cat - $BACKGFILE | formail -${maxgbackup}s > $TEMPGFILE ; \
                mv -f $TEMPGFILE $BACKGFILE

Actually, that can be improved.  Rather than feed the new message
through cat, we'll just send it to the second formail before cat is
even invoked, thus saving some number of reads and writes.  Also, don't
do the move if the second formail fails for some reason:

        :0Wc:$HOME/incoming/fall.lock
        | { formail; cat $BACKGFILE; } | \
          formail -${maxgbackup}s > $TEMPGFILE && \
                mv -f $TEMPGFILE $BACKGFILE

Explanation: the
        { command; command; command; }
syntax tells to invoke the given commands in the order given, but
sharing the same input/output descriptors, so that the pipe from that
group gets all of their output, not just the output from one of them.
The '&&' tells the shell to only invoke the following command if the
preceding one completed successfully.  The previous command in this
case is the entire pipe, and the return code of a pipe is the return
code of its last command, in this case, the second formail.


Philip Guenther

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