procmail
[Top] [All Lists]

Re: Header insertion from message body...

1999-12-03 12:43:56

I got two suggestions for solving my problem, David Tomkin suggested I
get new web mail service, and Era Eriksson suggested I use perl. Both
would be much more reasonable solutions to my problem, but having
admitted to being stumped in public I felt it necessary to figure out a
better solution. 

I managed to construct a better version using sed, expr, formail and
procmail's recursive INCLUDERC feature. I include it here in case it is
useful to someone else. 

:0
* [ Check for specially tagged messages from my web account... ]
{
  # Figure out the line number that the body of the message starts 
  # on...
  #   Find the line number of the empty line delineating the end of 
  #   the header
  :0 c
  HEADEREND=| /usr/bin/sed -n -e '1,/^$/{/^$/=;}' -e '/^$/q'

  #   And add one...
  BODYSTART=`expr $HEADEREND + 1`

  # Deal with secondary headers one at a time...
  INCLUDERC=redir.loop

  # Forward the redirected mail on, if it has been modified
  # appropriately...
  :0 D
  * ! [ To: field unchanged ]
  * ! [ To: field empty ]
  | $SENDMAIL -t
 
  # Otherwise bounce it...
  EXITCODE=65
  HOST=drop.mail.that.gets.to.here.and.bounce
}

The file redir.loop:

# This is just a variable assignment, so don't count this one as 
# delivery. b flag pipes only the body, the sed command picks out 
# just the first line and stores it in $FIELD.
:0 bc
FIELD=|/usr/bin/sed '1 q'

# If $FIELD looks like a header, then...
:0
* FIELD ?? ^[-a-zA-Z0-9]+:
{
        # Remove the first line of the body...
        :0 f
        | /usr/bin/sed "$BODYSTART d"

        # Insert the header with formail. Quote to aviod problems 
        # with special charaters. Use of -i rather than -I ensures that
        # number of lines in the header goes up by one, whether the
        # field was present previously or not. 
        :0 f
        | formail -i "$FIELD"

        # The body now starts one line further down...
        BODYSTART=`expr $BODYSTART + 1`

        # Iterate...
        INCLUDERC=redir.loop
}

As it stands, this expects the first line of the body of the email to be
the first "secondary" header line. It stops processing lines as soon as
it hits a line in the body that doen't look like a header. Dealing with
extra blank lines above and below the secondary header is left as an
exercise to the reader. 

However, I'm still left with my original challenge. It seems like it
should be possible to do this without iteration. I can extract the
secondary header into a variable in a single recipe, eliminate the
secondary header with a sed or two, but I can't transform this into a
suitable set of arguements for a single invocation of formail. The
problem boils down to this:

VERBOSE=YES
LOGABSTRACT=NO
A=`echo \"a b c\" d \"e f\"`
:0 c
| echo $A

:0
| echo "$A"

HOST=dummy

Excerpt from verbose logging:

procmail: Executing "echo,"a,b,c",d,"e,f""
procmail: Assigning "A="a b c" d "e f""
procmail: Executing "echo,"a,b,c",d,"e,f""
procmail: Executing "echo,"a b c" d "e f""

What I need is:

procmail: Executing "echo,a b c,d,e f"

Any ideas?

Thanks,

nathan

-- 
---------------------------------------------------------------------
                                 as ci   Field of Operations Research
Nathan Edwards                  imapofa            Cornell University
nedwards(_at_)orie(_dot_)cornell(_dot_)edu       ustrali               Ithaca 
NY 14853
www.orie.cornell.edu/~nedwards       a                      
---------------------------------------------------------------------

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