procmail
[Top] [All Lists]

Re: Valid Flags before nested block {}

1997-12-14 00:40:22
end
dattier(_at_)wwa(_dot_)com (David W. Tamkin) writes (in early November):
...
A, a, E, and e [recipe flags] are mutually exclusive and no more than
one should ever appear on a single recipe.

Actually, this is not true.  e does not work with E or a (and procmail
gives a warning if you try), and A is redundant if a is given, but at
least some of the other combination make sense and work.  See below.


A = try this recipe if the conditions succeeded on the most recent recipe at
   that nesting level that did not itself have an A nor an a

a = same as A, but moreover the action must have succeeded on the most
   recently tried recipe at that nesting level

e = same as A, but moreover the action must have failed on the most recently
   tried recipe at that nesting level; within the A universe, e is the op-
   posite of a

Not quite; 'e' only looks backwards past 'E' recipes that were skipped
because of their 'E'.  It doesn't care whether a previous recipe had an
'A' or 'a' flag:

e = try this recipe if the conditions matched but the action failed on
    the most recently tried (not skipped) recipe at this nesting level.

Thus:
        # match, but action fails
        :0
        /etc/hosts/foo

        # no match
        :0 A
        * -1^0
        /dev/null

        # this is skipped because the last tried recipe didn't match
        :0e
        { whatever }


E = try this recipe if the conditions have failed on the most recent recipe
   at that nesting level that did not have an E and on since then every 
   recipe at that level that did have an E; essentially opposite of A

Or to rephrase:

E = try this recipe unless the last tried recipe matched.

...
How they interact with one another when used consecutively has not been
fully tested to my knowledge.  Consider this:

:0
* conditons
non-delivering action1
:0a
action2
:0e
action3

Is action3 done if action2 failed or if action1 failed (or perhaps in
both situations)?

Action 3 is only done if action2 failed.

                  If the answer is action2, does this work to get action3
done if action1 failed?  I think it does, but does it also run action3 if
the conditions didn't match on the first recipe?

Yes, and yes.

:0
* conditions
non-delivering action1
:0a
action2
:0E
action3

If that's not what you want, combine some flags:

        :0
        * conditions
        non-delivering action1
        :0 Ae
        action3
        :0 a
        action2

If the conditions match, action1 will be executed.  action3 will then
execute if action1 failed, otherwise action2 will be executed [if action1
succeeded].

I know what this structure does because I use it:

  :0
  * conditions
  non-delivering action1
  :0A
  action2
  :0E
  non-delivering action3
  :0A
  action4

If the conditions match, action1 and action2 are performed and action4 is
not (of course action3 is not either), even if action2 is non-delivering; if
they fail, action3 and action4 are performed.  The A on the fourth recipe
refers back to the third and no farther.  But I don't know about this:

  :0
  * conditions
  non-delivering action1
  :0A
  * more conditions
  action2
  :0E
  non-delivering action3
  :0A
  action4

Now, suppose the conditions on the first recipe match but those on the second
recipe do not match.  Would the third recipe (and thus the fourth one) be
attempted?

Yes.  The last tried recipe didn't match, therefore the E flag will be
triggered.

I would expect so.  If that isn't what you want, you can prevent it this way:

[solution involving a nested recipe]


For those who are interested, I'll note that there are only 3 combinations
of the a, A, e, and E flags that aren't either illegal or redundant.  They
are 'Ae', 'aE', and 'AE'.  I've shown a use for 'Ae' up above.  Here's an
example of 'AE':

        :0
        * condition1
        non-delivering action1
        :0 A
        * condition2
        non-delivering action2
        :0 AE
        action3

action3 will only be executed if condition1 matched but condition2
didn't match.  Without the A flag, action3 would be executed if either
of them failed.  This can also be done with a instead of A with
analogous results.

Procmail's "flow-control" flags may not be particularly easy to
describe in straight terms (and this can all be made more complicated
by throwing in a more varied mix of delivering vs non-delivering
recipes), but I've found that it usually does what I expect it to do,
and when it doesn't or I'm in doubt or I want to be particularly clear,
I can always fallback to doing it explicitly via nesting blocks.  Pick
your poison...

Philip Guenther

<Prev in Thread] Current Thread [Next in Thread>
  • Re: Valid Flags before nested block {}, Philip Guenther <=