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; }

Reply via email to