procmail
[Top] [All Lists]

RE: Spamd before delivery

2007-07-25 12:16:19
Skip Brott wrote on Wednesday, July 25, 2007 3:24 PM:

Here is what I have now:

Skip, I'm staring and staring at this and I find it
so boggling that I just don't know where to start
to help you.  Please forgive me.  I'm not trying to
be a smart-ass.  But . . .

I think I will start just really small, with this
one recipe in what you offered:

:0c
* !^FROM_DAEMON
* ^X-Spam-Flag: YES
* !^X-Loop: spam
| echo "`formail -x X-Spam-Status: | \
    awk -F 'score=' '{print $2}' | \
    cut --delimiter=' ' -f1`" >> /var/log/spam

That action line kind of astonished me for several reasons.

Let me start by saying that the pipe obviates the need for
the echo and backticks.  So your action works out just the
same like this:

 | formail -x X-Spam-Status: | \
   awk -F 'score=' '{print $2}' | \
   cut --delimiter=' ' -f1 >> /var/log/spam

By the way, my cut doesn't support that GNU-style flag.
I used "-d ' '" to test.  But let's go on.

Before I say more about the action, let's look at the
recipe flags.  You're only operating on the header,
yet you're piping the entire message to the action.  I'll
bet you have some error messages in your logs here and there,
too, for when the pipe closed too soon on long messages.
Anyway, use the "h" flag on this recipe.

Okay, let's think some more about that action.  I'd urge
you to slow down and think about it some.  You're using
the formail binary to extract the headerfield info from
(the top line of what is probably a multi-line headerfield of)
X-Spam-Status.  Then you're piping to awk.  Then you're piping
*that* to cut.  Then you're just saving the score in your file.
That's a lo-o-o-o-o-o-o-o-o-o-o-t of extra work!  Not to mention
the echo you had originally that I took out already.

One could use any individual of the compound-piped shell tools
you used to extract that score.  I'll show you how, just for
grins.  But even one is too much.

Let's start with one you didn't use: sed. Here's the header from some
message
I have lying around in my spam folder:

 6:31pm [~/Mail] 610[1]> formail -x 'X-Spam-Status: Yes,' < .myspam/$lastf
 Yes, score=9.449 tagged_above=-999 required=5
        tests=[FROM_LOCAL_NOVOWEL=2.331, HELO_DYNAMIC_DHCP=2.664,
        URIBL_JP_SURBL=3.36, URIBL_SBL=1.094]

Okay:

 | formail -x X-Spam-Status | sed 's/[^0-9]*//; s/ .*//;q'

would work to extract the number.

Now let's try awk.  But let's make it much easier on ourselves by
using the -c flag to formail, so we don't have multi-line output
for the X-Spam-Status headerfield:

 | formail -c -x X-Spam-Status | awk -F"[ =]" '{print $4}'

Okay, next let's use just cut:
 | formail -c -x X-Spam-Status | cut -c13-18

I cheated.  If the count is over 10 we lose the last (thousanths)
decimal digit.  Oh, well, who cares?

Of course, as I said above, you don't need any of this at all.  Not
even formail.  Not even echo.  Pure procmail.

 :0 c h
 * ^X-Spam-Flag: YES
 * !^FROM_DAEMON
 * !^X-Loop: spam
 * ^X-Spam-Score:[^0-9]+\/[^ ]+
 {
   OLDLOGFILE = ${LOGFILE:-/dev/null}
   OLDVERBOSE = $VERBOSE
   VERBOSE = off
   LOGFILE = /var/log/spam
   LOG = "$MATCH
 " LOGFILE = $OLDLOGFILE
   VERBOSE = $OLDVERBOSE
 }

Note that I also moved the ^FROM_DAEMON down one in the
condition list for added efficiency.

After you work through that, we can get into the rest of
your request.

Dallman
____________________________________________________________
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>