More Newbie Help
Matthias Andree
matthias.andree at gmx.de
Thu Jul 10 13:43:30 CEST 2003
"Clark, Aaron" <aclark at Calence.com> writes:
> Okay I'm almost there. I have a filtermail.sh script that Postfix calls when
> it receives a message and pass it through bogofilter. I then have the script
> grep for X-Bogosity:yes and redirect it using Postfix's sendmail to a SPAM
> mailbox. However after it redirects the SPAM the original message is sent to
> the deferred queue with Temporary Failure. I would assume this would hurt
> performance as all SPAM messages get placed in this queue and retry
> delivery.
>
> Anyone have any thoughts on this?
Yes, I do. My suggestions below may look strange, "remove the file, then
send it", but it is safe because of the "exec <msg.$$" trick:
1. "exec <msg.$$" opens the file for reading, assigns file descriptor #0.
2. "rm -f msg.$$" removes the file name, but the contents remain
available because the file is still open.
(At this time, the next process could safely write to msg.$$ without
changing the file we have still open, unless we decided to use msg.$$
by its name, which we do not.)
3. "exec $POSTFIX..." REPLACES the shell script by $POSTFIX
(/usr/sbin/sendmail), and will inherit all open
files, including the file descriptor #0. Only
after this $POSTFIX program terminates, will the
operating system let go of the file contents of
msg.$$ and reclaim the disk space.
It is IMPORTANT that in this step there is NO INPUT REDIRECTION.
> #!/bin/sh
>
> FILTER=/usr/bin/bogofilter
> FILTER_DIR=/var/spool/filter
> POSTFIX=/usr/sbin/sendmail
> # BOGOFITLER_DIR=/var/spool/mail
^^ Interchanged letters T and L in the BOGOFILTER word.
> EGREP=/bin/egrep
>
> # Exit codes from <sysexits.h>
> EX_TEMPFAIL=75
> EX_UNAVAILABLE=69
>
> cd $FILTER_DIR || \
> { echo $FILTER_DIR does not exist; exit $EX_TEMPFAIL; }
>
> # Clean up when done or when aborting.
> trap "rm -f inp.$$ msg.$$; exit $EX_TEMPFAIL" 0 1 2 3 15
This means: "when done, clean up and exit $EX_TEMPFAIL".
> # bogofilter returns: 0 for spam; 1 for non-spam; 2 for I/O or other errors.
> rm -f inp.$$ || exit $EX_TEMPFAIL
> cat > inp.$$ || exit $EX_TEMPFAIL
> $FILTER -p -e < inp.$$ > msg.$$ || exit $EX_TEMPFAIL
You don't use inp.$$ ever again, so make this:
trap "rm -f msg.$$; exit $EX_TEMPFAIL" 0 1 2 3 15
rm -f msg.$$ || exit $EX_TEMPFAIL
$FILTER -p -e >msg.$$ || exit $EX_TEMPFAIL
> if $EGREP -q "^X-Bogosity: Yes" < msg.$$
> then
> $POSTFIX spam at kalence.org < msg.$$
Try:
exec <msg.$$
rm -f msg.$$
exec $POSTFIX spam at kalence.org
> rm -f inp.$$
Remove the rm -f line.
> else
> exec $POSTFIX "$@" < msg.$$
This will leave msg.$$ behind. Use as above,
exec <msg.$$
rm -f msg.$$
exec $POSTFIX "$@"
> fi
>
> exit 0
This should be exit $EX_TEMPFAIL for in-depth robustness against failure
or accidental changes of the script.
--
Matthias Andree
More information about the Bogofilter
mailing list