procmail
[Top] [All Lists]

Re: Folding E-mail Headers

2006-04-20 21:35:31
On 4/20/06, Craig <craig(_at_)0604(_dot_)zuym(_dot_)com> wrote:

Sorry, I'm more confused than I was before!

Let's start back at the beginning: "fold" requires either a file name
as a command-line argument, or a stream of text on standard input. 
The first problem you ran into was because you tried to give "fold" a
long string of text as a command-line argument; worse, you failed to
quote the string of text, so it was divided into separate arguments at
spaces, and fold tried to interpret each of the words in the string as
a separate file name.  These are pretty basic shell programming
mistakes, and if you want to write procmail recipes beyond the very
simplest you should probably start by getting some background in using
the shell, because a lot of the syntax rules used by procmail are
borrowed from the shell language.

The next most basic problem that you're having is that you don't
understand the format of internet message headers.  A header that's
folded onto multiple lines must have every line after the first one
begin with a whitespace character (usually tab, but space is OK too). 
So it is not sufficient to do what "fold" does to the long string; you
must also insert that leading space on every line that is output by
"fold".  Not doing so is why, when you used Gerald's suggestion, you
ended up with the second and succeeding lines inserted into the
message body instead.

Assuming you have the header content in a variable, e.g.

X_MY_CONTENT = "Long string of text here"

(note, the field name is not there yet)

You first need to fold it, which can be done by

  echo "$X_MY_CONTENT" | fold -s -w60

(note, that's shell syntax, NOT yet procmailrc sytax; I'm building up
to the solution)

I used 60 instead of 78 because in my approach the field name and
colon are going to be added to the first line after folding, so it
needs a little extra room.

Next you need to insert a space or tab at the beginning of every line.
 That sort of thing is usually done by using "sed", the stream editor:

  echo "$X_MY_CONTENT" | fold -s -w60 | sed "s/^/ /"

There the caret means beginning of (every) line, and the s/// syntax
means "substitute".

To capture the result of that shell command in procmail, you put the
whole thing in backquotes, that is, accents grave or
left-single-quotes, like so:

X_MY_FOLDED = `echo "$X_MY_CONTENT" | fold -s -w60 | sed "s/^/ /"`

(that IS procmailrc syntax; it's also shell syntax, if you remove the
spaces from around the equals sign)

Now we can put it together with the field name:

X_MY_HEADER = "X-My-Header:$X_MY_FOLDED"

(note you don't need a space after the colon, because sed has already
inserted a space on every line including the first line)

Finally, you're ready for your procmailrc recipe, which looks exactly
like what Ruud wrote:

:0 fhw
|formail -i"$X_MY_HEADER"

It doesn't matter whether there is a space after the -i or not, but
it's sort of conventional to omit it.  However, you do need the
quotation marks to prevent $X_MY_HEADER from being split up on spaces
again.

Does that clear things up?

Incidentally, if you have the "fmt" command, you may be able to use it
instead of fold+sed, like so:

X_MY_FOLDED = `echo "$X_MY_CONTENT" | fmt -t -w60`

However, the behavior of the -t option of fmt is less predictable than
I like; if $X_MY_CONTENT already begins with a space, the above will
do the wrong thing.


____________________________________________________________
procmail mailing list   Procmail homepage: http://www.procmail.org/
procmail(_at_)lists(_dot_)RWTH-Aachen(_dot_)DE
http://MailMan.RWTH-Aachen.DE/mailman/listinfo/procmail

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