# This is a Courier maildroprc, hand-rolled by 02 Sep 2003. # # The objective here is to provide a reasonably simple way to inject # spam-filtering into the mail delivery in such a way that it is easily # changeable on a per-user basis, especially when users are configured # in a mysql table. # # How to specify a delivery instruction that invokes maildrop assuming # this is installed as /etc/courier/maildroprc: # # |maildrop -d user hamdelivery spamdelivery # # where 'user' is the actual (physical system) username that corresponds # with this mail, irrespective of whether it is a virtual mailbox or not. # (It seems mandatory to specify that, in order to be able to pass other # arguments on the cmdline. We determine the "actual" recipient from an # environment variable.) # # The other two args are each a whitespace-delimited list of delivery # instructions (wholly enclosed in quotes if there are several in the arg): # - components beginning with | are piped to the given command; # - components containing @ are delivered to the given email address; # - otherwise construed as path to a maildir/mailbox. # # The message is delivered to the first (hamdelivery) if it is deemed # non-spam, or else to the second (spamdelivery) if it smells like spam. # Either may be null, in which case the default delivery instruction # (typically ./Maildir) is used). # Import some useful stuff from the environment import USER import RECIPIENT # The following is just for temporary diagnostics #xfilter "/usr/local/courier/bin/reformail -A'X-Test: user $USER recip $RECIPIENT and log $LOGNAME'" # Run the message through the spam filter exception { xfilter "/usr/local/bin/spamc -u $USER -t 15" } # Choose list of delivery instructions depending on spammyness if (/^X-Spam-Status: *Yes/:h) { # It's spam; was a spam delivery box specified in second arg? if ("x$2" eq "x") DELIVERLIST = $1 # No, so deliver same as non-spam. else DELIVERLIST = $2 # Yup, so deliver where specified. } else DELIVERLIST = $1 # Not spammy, so deliver as in first arg. # See if delivery instructions are null in which case deliver to default if ("x$DELIVERLIST" eq "x") to $DEFAULT # (that will have effect of ending execution, if true) # Parse out the list of delivery instructions. A = " $DELIVERLIST" while ($A =~ /.*![:space:]+!.+$/) { REST = $MATCH D = $MATCH3 if ($D =~ /^\|!.*/) { echo "Piping to $MATCH2" cc "|$MATCH2" # pipe to command } else if ($D =~ /@/) { echo "Forwarding to $D" cc "!$D" # forward to email address } else { echo "Delivering into $D" cc $D # write to maildir/box } A = $REST } # Deliberately exit so as to suppress fall-through to default delivery exit # the end.