From b005a303b3381a30e44ec71f0f08234721f1be2e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Ask=20Bj=C3=B8rn=20Hansen?= <ask@develooper.com>
Date: Fri, 5 Mar 2004 09:12:20 +0000
Subject: [PATCH] spamd_socket support -- thanks to John Peacock

git-svn-id: https://svn.perl.org/qpsmtpd/trunk@213 958fd67b-6ff1-0310-b445-bb7760255be9
---
 Changes              |  3 +++
 plugins/spamassassin | 29 ++++++++++++++++++++++++++---
 2 files changed, 29 insertions(+), 3 deletions(-)

diff --git a/Changes b/Changes
index df540b0..47cf591 100644
--- a/Changes
+++ b/Changes
@@ -1,5 +1,8 @@
 0.27 
 
+  Support for unix sockets in the spamassassin plugin (requires SA
+  2.60 or higher).  Thanks to John Peacock!
+
   Modified the dnsbl plugin to better support both A and TXT records and 
   support all of the RBLSMTPD functionality. (Thanks to Mark Powell)
 
diff --git a/plugins/spamassassin b/plugins/spamassassin
index 3680df3..f218dad 100644
--- a/plugins/spamassassin
+++ b/plugins/spamassassin
@@ -44,12 +44,22 @@ might want to make another plugin that does this on a per user basis.
 
 The default is to never munge the subject based on the SpamAssassin score.
 
+=item spamd_socket [/path/to/socket]
+
+Beginning with Mail::SpamAssassin 2.60, it is possible to use Unix 
+domain sockets for spamd.  This is faster and more secure than using
+a TCP connection.
+
 =back
 
-With both options the configuration line will look like the following
+With both of the first options the configuration line will look like the following
 
  spamasssasin  reject_threshold 18  munge_subject_threshold 8
 
+=head1 TODO
+
+Make the "subject munge string" configurable
+
 =cut
 
 
@@ -88,8 +98,18 @@ sub check_spam {
   my $paddr   = sockaddr_in($port, $iaddr);
 
   my $proto   = getprotobyname('tcp');
-  socket(SPAMD, PF_INET, SOCK_STREAM, $proto)
-    or $self->log(1, "Could not open socket: $!") and return (DECLINED);
+  if ( $self->{_args}->{spamd_socket} =~ /^([\w\/.]+)$/ ) { # connect to Unix Domain Socket
+    my $spamd_socket = $1;
+    
+    socket(SPAMD, PF_UNIX, SOCK_STREAM, 0)
+      or $self->log(1, "Could not open socket: $!") and return (DECLINED);
+
+    $paddr = sockaddr_un($spamd_socket); 
+  }
+  else {
+    socket(SPAMD, PF_INET, SOCK_STREAM, $proto)
+      or $self->log(1, "Could not open socket: $!") and return (DECLINED);
+  }
 
   connect(SPAMD, $paddr) 
     or $self->log(1, "Could not connect to spamassassin daemon: $!") and return DECLINED;
@@ -102,6 +122,9 @@ sub check_spam {
   print SPAMD "SYMBOLS SPAMC/1.0" . CRLF;
   # or CHECK or REPORT or SYMBOLS
 
+  print SPAMD "X-Envelope-From: ", $transaction->sender->format, CRLF
+    or warn "Could not print to spamd: $!";
+
   print SPAMD join CRLF, split /\n/, $transaction->header->as_string
     or warn "Could not print to spamd: $!";