procmail
[Top] [All Lists]

Re: rules seem to fail after reaching the 16th of 34 rules without a match

1999-10-23 14:52:35
David Gikandi <myprocmail(_at_)yahoo(_dot_)com> writes:
I have 34 rules on my procmailrc file. They work great
as long as the word(s) being searched for in the
incoming mail match within the first 16 rules or so.
But if the incoming mail has words that would have
matched an rule after that, procmail always responds
to the incoming email with the file that is supposed
to be sent out for rule 16. Here is what I mean:

Here is what rule 16 on my procmail file looks like:

:0 HB
* .*(time +out|time-out|timeout|i +did +not +get|i
+didnt +get|i +didnt +get|file +missing|files
+missing|receiv|reciev|missing|missed|i +only +get|i
+only +got|everything +but|Didnt +get|havent
+got|Didnt +get|havent +got)
* !.*768sdfds
| (formail -rtk ; cat
/usr/apache/htdocs/search/mailtemplates/Missingouts.txt
) | $SENDMAIL -oi -t
...

First off, because there's no anchor before it, the ".*" at the beginning
of the recipe does nothing except slow procmail down.

Secondly, the regexp is very redundant.  For example, there's no point
in looking for a match on "files +missing" if "missing" by itself will
be a match.  Some of those could use work boundary anchors to prevent
accidental matching on other words (e.g., "dismissed").  Hmm, it looks
like the following is close to minimal and possibly closer to what you
intended:

        * \<((time( +|-)?out|\
              did( +no|n'?)t +get|\
              miss(ing|ed)|\
              havent +got|\
              everything +but|\
              i +only +g[oe]t)\>|\
             rec(ei|ie)v)

Next, that recipe includes a possible match on the partial word "receiv".
It so happens that *every message* your get should include at least one
"Received:" header.  Since procmail's regexps are case insensitive by
default and the above recipe is matching against the header, it will
always match.  You should probably mean to match against only the Subject:
header field or the body.  That can be done most easily with two recipes:

        :0
        * ^Subject:.*\
          \<((time( +|-)?out|\
              did( +no|n'?)t +get|\
              miss(ing|ed)|\
              havent +got|\
              everything +but|\
              i +only +g[oe]t)\>|\
             rec(ei|ie)v)
        * ! ^Subject:.*768sdfds
        |(formail -rtk; \
          cat /usr/apache/htdocs/search/mailtemplates/Missingouts.txt \
         ) | $SENDMAIL $SENDMAILFLAGS -t

        :0 B
        * \<((time( +|-)?out|\
              did( +no|n'?)t +get|\
              miss(ing|ed)|\
              havent +got|\
              everything +but|\
              i +only +g[oe]t)\>|\
             rec(ei|ie)v)
        * ! 768sdfds
        |(formail -rtk; \
          cat /usr/apache/htdocs/search/mailtemplates/Missingouts.txt \
         ) | $SENDMAIL $SENDMAILFLAGS -t


HOWEVER, that brings up the question of whether the exclusion of messages
that contain "768sdfds" should only be those where that non-word occurs
in the same part (Subject: vs body) as the catch phrase.  The above
recipes can easily be tweaked to match using the "HB ??" syntax.


On a more general note, it's helpful in these sorts of things to turn
on verbose logging and look at what shows up in the logfile.  To turn
on verbose logging, put the line

        VERBOSE=on

above the recipe in question.  Procmail will then log all sorts of
information about what's it's doing to the logfile set through the
LOGFILE variable.  If you don't currently set a logfile and are having
procmail problems, run, don't walk, to you computer and put the line

        LOGFILE = $HOME/procmail.log

at the top of the rcfile.


Philip Guenther

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