#167086 procmail: deliveredness is not documented satisfactorily

Package:
procmail
Source:
procmail
Description:
Versatile e-mail processor
Submitter:
Francesco Potorti`
Date:
2005-07-18 04:00:06 UTC
Severity:
wishlist
#167086#5
Date:
2002-10-30 11:44:17 UTC
From:
To:
This is a documentation bug that has bugged me for a long time, until
eventually I have tried to read very carefully the man pages and
documentation, examples and network faqs, and have decided to write
this.

Please note that not only would I like to find an answer to my
questions, to some but not all of which I know the response, but mainly
I would like to stimulate the maintainers to complete and clarify the
manual, by writing or clarifying the necessary information, and by
adding ad hoc examples.

The problem is that I cannot determine whether a given recipe is
delivering or not.  From the procmailrc man page:
----------------
  There  are two kinds of recipes: delivering and non-delivering recipes.
  [...]
  Delivering recipes are those that cause header and/or body of the  mail
  to  be:  written  into  a file, absorbed by a program or forwarded to a
  mailaddress.

  Non-delivering recipes are: those that cause the output of a program or
  filter  to  be  captured back by procmail or those that start a nesting
  block.
----------------

Once one understands what "delivering recipe" means, the two definitions
above are not sufficient.  That is, they are definitions of the meaning
of the word, but they say little about whether a given action is
delivering.  For example, it is clear that a file action is a delivery
one, and that a mail action is a delivery one.  The big problem is that
IT IS NOT CLEAR WHETHER A PIPE ACTION IS A DELIVERING ONE.

For example, in the following recipe, taken from the procmailex man
page:

              :0 h                            # alternate method
              KEYWORDS=| formail -xKeywords:

it is not clear whether the pipe action is delivering or not.  Is the
header of the mail "absorbed" into the program or "captured back" by
procmail?  How can I tell?

Same doubt for the following, again from procmailex:

              :0 Bb
              * ^^%!
              | lpr

From this in procmailex I deduce that pipe actions are delivering:

  to  weed  out  duplicate mails.  Simply put the following recipe at the
  top of your rcfile, and no duplicate mail will get past it.

	 :0 Wh: msgid.lock
	 | formail -D 8192 msgid.cache

But then, again in procmailex, I read that the two following are
equivalent:

	 FROM=`formail -rt -xTo:`

	 :0 h
	 FROM=| formail -rt -xTo:

Since the first one is obviously non delivering, I understand that the
second one is non-delivering too.  So pipes are non delivering.  Or not?
Does it make a difference if their output is captured in a variable?


On the same line, it is not clear what the "f" flag means.  The manual
says:

  f    Consider the pipe as a filter.

I suppose that this means: make the following pipe action into a
non-delivering action, and continue processing using the output of the
program.  This is consistent with my experience using procmail, but it
is not written anywhere.

If this interpretation was correct, it would also imply that pipe
actions are normally delivering, and you must use "f" to make them non
delivering and capture their output.

Nor it is clear what the "w" flag means.  The manual says:

  w    Wait  for  the  filter or program to finish and check its exitcode
       (normally ignored); if the filter is unsuccessful, then  the  text
       will not have been filtered.

First, it  makes a  distinction between  a filter and  a program  in the
first half of  the sentence.  What is a filter?  Is  a program where the
"f" flag is used?  Is it something else?

Second, it only speaks about a filter (no program any more) in the
second part of the sentence.

Third, it says that procmail understands that the text is not filtered
with a bad exit code.  What then?  What does procmail do when the text
has not been filtered?

Next, if I put a "wc" flag on a pipe action captured into a variable,
procmail says that it ignores the extraneous "c".  Does this mean that
"w" implies "c" in this case?  If yes, it is not written anywhere.  And
moreover, why ever is the "w" tolerated?  Shouldn't it be redundant?

The "i" flag is even more obscure:

  i    Ignore any write errors on this recipe (i.e., usually  due  to  an
       early closed pipe).

What means that procmail ignores the error?  What then?  Is the output
so far ignored or not?  Is the recipe delivering or not?  What if the
errorr is not ignored?

About the variable=| construct, is it delivering or not?

#167086#10
Date:
2002-10-30 19:18:43 UTC
From:
To:
Hello.

I've received the following report from the debian bug system:


Package: procmail
Version: 3.22-4
Severity: wishlist

This is a documentation bug that has bugged me for a long time, until
eventually I have tried to read very carefully the man pages and
documentation, examples and network faqs, and have decided to write
this.

Please note that not only would I like to find an answer to my
questions, to some but not all of which I know the response, but mainly
I would like to stimulate the maintainers to complete and clarify the
manual, by writing or clarifying the necessary information, and by
adding ad hoc examples.

The problem is that I cannot determine whether a given recipe is
delivering or not.  From the procmailrc man page:
----------------
  There  are two kinds of recipes: delivering and non-delivering recipes.
  [...]
  Delivering recipes are those that cause header and/or body of the  mail
  to  be:  written  into  a file, absorbed by a program or forwarded to a
  mailaddress.

  Non-delivering recipes are: those that cause the output of a program or
  filter  to  be  captured back by procmail or those that start a nesting
  block.
----------------

Once one understands what "delivering recipe" means, the two definitions
above are not sufficient.  That is, they are definitions of the meaning
of the word, but they say little about whether a given action is
delivering.  For example, it is clear that a file action is a delivery
one, and that a mail action is a delivery one.  The big problem is that
IT IS NOT CLEAR WHETHER A PIPE ACTION IS A DELIVERING ONE.

For example, in the following recipe, taken from the procmailex man
page:

              :0 h                            # alternate method
              KEYWORDS=| formail -xKeywords:

it is not clear whether the pipe action is delivering or not.  Is the
header of the mail "absorbed" into the program or "captured back" by
procmail?  How can I tell?

Same doubt for the following, again from procmailex:

              :0 Bb
              * ^^%!
              | lpr
  top of your rcfile, and no duplicate mail will get past it.

	 :0 Wh: msgid.lock
	 | formail -D 8192 msgid.cache

But then, again in procmailex, I read that the two following are
equivalent:

	 FROM=`formail -rt -xTo:`

	 :0 h
	 FROM=| formail -rt -xTo:

Since the first one is obviously non delivering, I understand that the
second one is non-delivering too.  So pipes are non delivering.  Or not?
Does it make a difference if their output is captured in a variable?


On the same line, it is not clear what the "f" flag means.  The manual
says:

  f    Consider the pipe as a filter.

I suppose that this means: make the following pipe action into a
non-delivering action, and continue processing using the output of the
program.  This is consistent with my experience using procmail, but it
is not written anywhere.

If this interpretation was correct, it would also imply that pipe
actions are normally delivering, and you must use "f" to make them non
delivering and capture their output.

Nor it is clear what the "w" flag means.  The manual says:

  w    Wait  for  the  filter or program to finish and check its exitcode
       (normally ignored); if the filter is unsuccessful, then  the  text
       will not have been filtered.

First, it  makes a  distinction between  a filter and  a program  in the
first half of  the sentence.  What is a filter?  Is  a program where the
"f" flag is used?  Is it something else?

Second, it only speaks about a filter (no program any more) in the
second part of the sentence.

Third, it says that procmail understands that the text is not filtered
with a bad exit code.  What then?  What does procmail do when the text
has not been filtered?

Next, if I put a "wc" flag on a pipe action captured into a variable,
procmail says that it ignores the extraneous "c".  Does this mean that
"w" implies "c" in this case?  If yes, it is not written anywhere.  And
moreover, why ever is the "w" tolerated?  Shouldn't it be redundant?

The "i" flag is even more obscure:

  i    Ignore any write errors on this recipe (i.e., usually  due  to  an
       early closed pipe).

What means that procmail ignores the error?  What then?  Is the output
so far ignored or not?  Is the recipe delivering or not?  What if the
errorr is not ignored?

About the variable=| construct, is it delivering or not?

#167086#11
Date:
2002-10-31 06:55:03 UTC
From:
To:
Santiago Vila <sanvila@unex.es> forwarded:
...

Part of the problem is that what is clear and complete to us is not
the same as what is clear and complete to someone who hasn't used it
for years.  Your comments are helpful in pinpointing the areas that are
particularly unclear.  Feel free to suggest particular textual changes
once you feel you have a grasp on the semantics of procmail.

It depends on whether the program's output is being captured by procmail.
If yes, then the non-delivering description applies.  If not, then the
delivering description applies.

procmailrc(5) says:
   Recipe action line
       The action line can start with the following characters:
...
       |      Starts the specified program, possibly in $SHELL if
              any of the characters $SHELLMETAS are spotted.  You
              can optionally prepend this pipe symbol with  vari-
              able=, which will cause stdout of the program to be
              captured in the environment variable (procmail will
              not terminate processing the rcfile at this point).

That action has prepended the '|' with KEYWORDS=, so procmail is
capturing the output and the recipe is not delivering.  Indeed, that
paragraph explictly mentions that procmail will not terminate, so the
recipe cannot be delivering.

Is the output being captured?  No, so it's a delivering recipe.


...

Yes.  That's part of what the "captured back by procmail" part of the
definition of a non-delivering recipe is referring to.  The other part
is of course filtering recipes.

I agree that sentence needs to say more.

That seems to confuse the purpose of the 'f' flag.  If you want to use a
program to modify a message header, body, or both, continuing processing
with the modified results, you use the 'f' flag.  If you just want to
feed a message to a program without terminating processing, you use the
'c' flag to effectively feed a copy of the message to the program.
Using the 'f' flag where you wanted the effect of the 'c' flag will
generally result in the rest of the rcfile seeing a message that consists
of just a newline.
a filter.

That's because in a non-filtering program action, the message isn't
being modified.  That clause just tells you that if the filter fails,
procmail will retain the original version of the message instead of
using the (presumably incomplete) output of the filter.

No, the 'c' is extraneous because it's a variable capture recipe.
The description of the 'c' flag explictly says that it only makes sense
on delivering recipes and on a nesting block recipe.  You should have
gotten that warning whether or not you included a 'w' flag on it.

By default, if a program in a '|' action fails to read all its input
such that procmail gets an error writing to the pipe, procmail will
consider the action to have failed.  Procmail will not terminate but
go on to the next recipe.  Whether an action has suceeded or failed is
testable using the 'a' or 'e' flag on the succeeding recipe.

The 'i' flag simply tells procmail to ignore whether it got any write
errors when determining whether the action succeeded or failed.  It has
no effect on whether the recipe is delivering.


Philip Guenther
Procmail Maintainer

#167086#16
Date:
2002-10-31 09:47:16 UTC
From:
To:
This clarifies the definition a little.  But it is still part of the
definition.  What I need is, for each possible action, knowing whether
that is a delivering action or not.  In the listing of actions in
procmailrc, the first thing to be written should be: "Name: a delivering
action" or "Name: a not-delivering action".

Yes, I came to understand what you are explaining, after reading many
times the documentation and examples, and after some experiments.  And
after all that, I also understood that's logic and well though out.  The
fact is, this is a central point, and should always be clearly stated.
The implications you mention are not obvious at all.  That paragraph
should read like this:

   |      Pipe: a program delivering action.  Starts the specified
	  program, possibly in $SHELL if any of the characters
	  $SHELLMETAS are spotted.  The standard input of the program is
	  fed with the body or the headers of the mail message being
	  processed, depending on the flags used for the recipe.  If
	  procmail detects an error while writing on the pipe (usually a
	  broken pipe), the action is ignored and procmail continues
	  with the next recipe.

   VAR=|  Var-pipe: a program non-delivering action.  The behaviour is
	  the same as with the previous action, but the standard output
	  of the program is captured in the environment variable, and
	  procmail continues processing a copy of the message.

In the procmailex example sited above, there should be a line saying:

  Since this is a non-delivering action, procmail continues processing a
  copy of the message.

Yes, but this is not written explicitely anywhere, it must be deducted
as a consequence of many different sparse observations.  Instead, a line
should be added right after the example (this is true of all examples)
saying:

  This is a delivering recipe.  Procmail feeds the message to the
  program, then stopsprocessing, without waiting for it to complete.

Something like that:

    f    Filter: applies exclusively to pipe actions.  It turns a pipe
	 action into a filter action, a program non-delivering action
	 after which procmail continues processing a modified copy of
	 the message, instead of the original copy as usual.  The
	 modified part is the header or body, depending on other flags
	 used in the action.

Okay, I'll try to rewrite this:

    w    Wait: applies exclusively to filter actions (see filter flag).
	 Do not process the output of the filter program as soon as it
	 is produced.  Rather, wait for the filter program to finish,
	 and use its output only if the exit code is successful.  If it
	 is not, discard the output, write an error message on standard
	 error and continue processing a copy of the original message.

    i    Ignore: applies only to program actions.  Errors detected by
         procmail while writing on the pipe (usually a broken pipe) are
         completely ignored.