I've attached the scripts and sample patches. The local one has some extra functionality - it looks in user's home dir to see what mode to operate in for that user. Full Blocking into separate folder, Just Marking, or Disabled.
I don't remember if qmail-rspawn needs patch or not, if it does, it's essentially the same as the qmail-lspawn.c patch. To work this with vpopmail would be just minor changes I think. -- Nathan On Sun, Jan 05, 2003 at 02:02:42PM -0600, Neulinger, Nathan wrote: > On Sun, 2003-01-05 at 12:39, Remo Mattei wrote: > > Does anyone have an howto for spamassassin with vpopmail. > > > > Thanks, > > > > Remo > > I haven't set it on on my vpopmail setup yet, but everywhere else I put > a wrapper around qmail-local and/or qmail-remote. (Depending on nature > of server.) If server is acting solely as a relay-filter, I'll only do > qmail-remote. If it's acting as a mailbox-spool host, I'll do > qmail-local only. > > All you really need are a couple of tiny patches to qmail to allow > specifying qmail-local and qmail-remote paths in the environment. > > I can send you the wrapper scripts and patches if you want, but there > isn't really much to them. > > -- Nathan > > ------------------------------------------------------------ > Nathan Neulinger EMail: [EMAIL PROTECTED] > University of Missouri - Rolla Phone: (573) 341-4841 > Computing Services Fax: (573) 341-4216 > > -- Nathan ------------------------------------------------------------ Nathan Neulinger EMail: [EMAIL PROTECTED] University of Missouri - Rolla Phone: (573) 341-4841 Computing Services Fax: (573) 341-4216
#!/usr/local/bin/perl $cmd = $0; $cmd =~ s|.*/||gio; open(LOG, "|/usr/bin/logger -t $cmd"); select(LOG); $| = 1; select(STDOUT); print LOG "[$$] IN: ", join(" # ", @ARGV), "\n"; @args = @ARGV; $is_spam = 0; # Apr 16 08:50:22 mailsrv qmail-local-wrapper: /products/qmail-server/local/qmail-local-wrapper # # -- # rollalib # /products/qmail-spool/rollalib # rollalib # # # rollanet.org # [EMAIL PROTECTED] # ./Maildir/ # 1 2 3 4 5 6 7 8 9 # Split out args - dependent on lspawn exact calling convention, should be more intelligent eventually # qmail-local [ -nN ] user homedir local dash ext domain sender defaultdelivery ($opts, $user, $homedir, $local, $dash, $ext, $domain, $sender, $defaultdelivery) = @ARGV; # # Temporary for testing # #if ( $user ne "tnneul3" ) #{ # print "Testing. Temporarily deferring deliveries.\n"; # exit(111); #} # # If spam blocking is not enabled for this user, immediately spawn real qmail-local with # current args. Otherwise perform spam checking. # # Block trigger $luser = lc $user; $blocktrigger = "/products/qmail-spool/$luser/SPAMBLOCK"; $marktrigger = "/products/qmail-spool/$luser/SPAMMARK"; if ( ! -e $blocktrigger && ! -e $marktrigger ) { print LOG "[$$] trigger does not exists, passing to qmail-local directly\n"; close(LOG); exec("/products/qmail-server/bin/qmail-local", @ARGV); } # # Temporarily disable scanning if trigger file exists # if ( -e "/products/qmail-server/local/block-scanning" ) { print "Temporarily disabling spam scanning for $user.\n"; exit(111); } # # Create temporary file, and write message to it for spamc to process # umask(077); $tmpbase = "/tmp/spamc.$$." . time . "." . "$user"; $tmpfile = $tmpbase . ".tmp"; $outfile = $tmpbase . ".out"; open(OUT, ">$tmpfile"); while ( sysread(STDIN, $data, 50000) ) { syswrite(OUT, $data); } close(OUT); # # Rewind file descriptor for sending to qmail-local # seek(STDIN, 0, 0); # # Perform spam checking # $CHILD_PID = fork; if ( $CHILD_PID == 0 ) { close(STDOUT); open(STDOUT, ">$outfile"); open(STDIN, "<$tmpfile"); unlink($tmpfile); exec("/usr/local/bin/spamc", "-d", "spamd.rollanet.org", "-f"); exit(0); # just in case } $SIG{ALRM} = "handle_timeout"; alarm(60); wait; alarm(0); # # Process the output file to determine if it was marked as spam # open(IN, $outfile); while ( $line = <IN> ) { last if ( $line eq "\n" ); last if ( $line eq "\r" ); last if ( $line eq "\r\n" ); if ( index($line, "X-Spam-Flag: YES") == 0 ) { $is_spam = 1; last; } } close(IN); # # In case it didn't get unlinked earlier # unlink($tmpfile); # # If spam, redirect to the junk mailbox # if ( $is_spam && -e $blocktrigger && $defaultdelivery eq "./Maildir/") { print LOG "[$$] delivering to Maildir-Junk for $user\n"; $defaultdelivery = "./Maildir-Junk/"; } else { print LOG "[$$] delivering to Maildir for $user\n"; } # Figure out new args @args = ($opts, $user, $homedir, $local, $dash, $ext, $domain, $sender, $defaultdelivery); # Actually execute qmail-local # 0 if the delivery is completely successful; nonzero if any delivery instruction failed. Exit code 111 indicates temporary failure. # # Open rewritten message for delivery # close(LOG); close(STDIN); open(STDIN, $outfile); unlink($outfile); exec("/products/qmail-server/bin/qmail-local", @args); sub handle_timeout { if ( $CHILD_PID != 0 ) { kill 9, $CHILD_PID; } print LOG "[$$] OUT: Timeout communicating with spamd. Exiting.\n"; print "Timeout communicating with spamd.\n"; unlink($tmpfile); unlink($outfile); exit(111); }
#!/umr/bin/perl $cmd = $0; $cmd =~ s|.*/||gio; open(LOG, "|/usr/bin/logger -t $cmd"); select(LOG); $| = 1; select(STDOUT); print LOG "[$$] IN: ", join(" # ", @ARGV), "\n"; @args = @ARGV; $is_spam = 0; # apparently, qmail-rspawn.c never delivers to multiple recips simultaneous, so it's # safe to assume here that only a single recip will be specified # in any case, worst case scenario is that wrong prefs are applied ($host,$sender,$recip) = @ARGV; # # Create temporary file, and write message to it for spamc to process # umask(077); $tmpbase = "/tmp/spamc.$$." . time . "." . "$host"; $tmpfile = $tmpbase . ".tmp"; $outfile = $tmpbase . ".out"; open(OUT, ">$tmpfile"); while ( sysread(STDIN, $data, 50000) ) { syswrite(OUT, $data); } close(OUT); # # As a note here - since we are not customizing behavior based on spam status, we # could probably just "| spamc | qmail-remote" without all the extra file creation. # However, this does give us the opportunity to handle timeouts easier. # # # Perform spam checking # $CHILD_PID = fork; if ( $CHILD_PID == 0 ) { close(STDOUT); open(STDOUT, ">$outfile"); open(STDIN, "<$tmpfile"); unlink($tmpfile); exec("/local/spamassassin/redhat71/bin/spamc", "-d", "localhost", "-f", "-u", $recip); exit(0); # just in case } $SIG{ALRM} = "handle_timeout"; alarm(180); wait; alarm(0); # # Open rewritten message for delivery # close(LOG); close(STDIN); open(STDIN, $outfile); unlink($outfile); exec("/local/qmail-server/bin/qmail-remote", @ARGV); sub handle_timeout { if ( $CHILD_PID != 0 ) { kill 9, $CHILD_PID; } print LOG "[$$] OUT: Timeout communicating with spamd. Exiting.\n"; print "Timeout communicating with spamd.\n"; unlink($tmpfile); unlink($outfile); exit(111); }
Also need to add env.a str.a to qmail-lspawn target in makefile. --- qmail-lspawn.c.orig Tue Apr 16 08:27:29 2002 +++ qmail-lspawn.c Tue Apr 16 08:29:35 2002 @@ -13,6 +13,7 @@ #include "auto_qmail.h" #include "auto_uids.h" #include "qlx.h" +#include "env.h" char *aliasempty; @@ -191,7 +192,10 @@ x = nughde.s; xlen = nughde.len; - args[0] = "bin/qmail-local"; + args[0] = env_get("QMAILLOCAL") + if ( !args[0] ) { + args[0] = "bin/qmail-local"; + } args[1] = "--"; args[2] = x; n = byte_chr(x,xlen,0); if (n++ == xlen) _exit(QLX_USAGE); x += n; xlen -= n;
>From >[EMAIL PROTECTED] >Mon Jan 25 21:40:06 1999 X-VM-v5-Data: ([nil nil nil nil nil nil nil nil nil] [nil nil nil nil nil nil nil nil nil nil nil nil "^From:" nil nil nil nil nil nil nil nil] nil) Return-Path: <[EMAIL PROTECTED]> Delivered-To: [EMAIL PROTECTED] Received: (qmail 17256 invoked from network); 25 Jan 1999 21:40:03 -0000 Received: from ns.crynwr.com (192.203.178.14) by desk.crynwr.com with SMTP; 25 Jan 1999 21:40:03 -0000 Received: (qmail 246 invoked by uid 500); 25 Jan 1999 21:38:36 -0000 Delivered-To: [EMAIL PROTECTED] Received: (qmail 241 invoked by uid 0); 25 Jan 1999 21:38:34 -0000 Received: from muncher.math.uic.edu (131.193.178.181) by pdam.crynwr.com with SMTP; 25 Jan 1999 21:38:34 -0000 Received: (qmail 27129 invoked by uid 1002); 25 Jan 1999 21:37:13 -0000 Mailing-List: contact [EMAIL PROTECTED]; run by ezmlm Precedence: bulk Delivered-To: mailing list [EMAIL PROTECTED] Received: (qmail 7464 invoked from network); 25 Jan 1999 21:37:13 -0000 Received: from hal.qcc.sk.ca (198.169.27.1) by muncher.math.uic.edu with SMTP; 25 Jan 1999 21:37:13 -0000 Received: (qmail 9995 invoked from network); 25 Jan 1999 21:37:22 -0000 Received: from mikhail.qcc.sk.ca (198.169.27.34) by hal.qcc.sk.ca with QMQP; 25 Jan 1999 21:37:22 -0000 Message-ID: <[EMAIL PROTECTED]> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii X-Mailer: Mutt 0.91.1 From: Bruce Guenter <[EMAIL PROTECTED]> To: [EMAIL PROTECTED] Subject: QMAILQUEUE patch for qmail-1.03 Date: Mon, 25 Jan 1999 15:37:21 -0600 Greetings. Appended is a patch to qmail-1.03 that causes any program that would run qmail-queue to look for an environment variable QMAILQUEUE. If it is present, it is used in place of the string "bin/qmail-queue" when running qmail-queue. This could be used, for example, to add a program into the qmail-smtpd->qmail-queue pipeline that could do filtering, rewrite broken headers, etc. (this is my planned usage for it). This has undergone virtually no testing, but it looks so simple that it almost has to be correct. No warranties, etc. Note that the chdir to /var/qmail is always done before exec'ing the program. Does this look like a reasonable thing to do? -- Bruce Guenter, QCC Communications Corp. EMail: [EMAIL PROTECTED] Phone: (306)249-0220 WWW: http://www.qcc.sk.ca/~bguenter/ diff -u qmail-1.03-orig/Makefile qmail-1.03/Makefile --- qmail-1.03-orig/Makefile Mon Jun 15 04:53:16 1998 +++ qmail-1.03/Makefile Tue Jan 19 10:52:24 1999 @@ -1483,12 +1483,12 @@ trigger.o fmtqfn.o quote.o now.o readsubdir.o qmail.o date822fmt.o \ datetime.a case.a ndelay.a getln.a wait.a seek.a fd.a sig.a open.a \ lock.a stralloc.a alloc.a substdio.a error.a str.a fs.a auto_qmail.o \ -auto_split.o +auto_split.o env.a ./load qmail-send qsutil.o control.o constmap.o newfield.o \ prioq.o trigger.o fmtqfn.o quote.o now.o readsubdir.o \ qmail.o date822fmt.o datetime.a case.a ndelay.a getln.a \ wait.a seek.a fd.a sig.a open.a lock.a stralloc.a alloc.a \ - substdio.a error.a str.a fs.a auto_qmail.o auto_split.o + substdio.a error.a str.a fs.a auto_qmail.o auto_split.o env.a qmail-send.0: \ qmail-send.8 diff -u qmail-1.03-orig/qmail.c qmail-1.03/qmail.c --- qmail-1.03-orig/qmail.c Mon Jun 15 04:53:16 1998 +++ qmail-1.03/qmail.c Tue Jan 19 09:57:36 1999 @@ -6,14 +6,25 @@ #include "fd.h" #include "qmail.h" #include "auto_qmail.h" +#include "env.h" -static char *binqqargs[2] = { "bin/qmail-queue", 0 } ; +static char *binqqargs[2] = { 0, 0 } ; + +static void setup_qqargs() +{ + if(!binqqargs[0]) + binqqargs[0] = env_get("QMAILQUEUE"); + if(!binqqargs[0]) + binqqargs[0] = "bin/qmail-queue"; +} int qmail_open(qq) struct qmail *qq; { int pim[2]; int pie[2]; + + setup_qqargs(); if (pipe(pim) == -1) return -1; if (pipe(pie) == -1) { close(pim[0]); close(pim[1]); return -1; }