about summary refs log tree commit homepage
path: root/public-inbox-mda
diff options
context:
space:
mode:
authorEric Wong <normalperson@yhbt.net>2014-01-09 23:13:37 +0000
committerEric Wong <e@80x24.org>2014-01-09 22:37:54 +0000
commit3e96cf129ba5fc2834b691314c504aa363fd5cf4 (patch)
treedd5c42532049bc5dd2a420126edb9f07e9a5b9a0 /public-inbox-mda
downloadpublic-inbox-3e96cf129ba5fc2834b691314c504aa363fd5cf4.tar.gz
Diffstat (limited to 'public-inbox-mda')
-rwxr-xr-xpublic-inbox-mda51
1 files changed, 51 insertions, 0 deletions
diff --git a/public-inbox-mda b/public-inbox-mda
new file mode 100755
index 00000000..4e971d92
--- /dev/null
+++ b/public-inbox-mda
@@ -0,0 +1,51 @@
+#!/usr/bin/perl -w
+# Copyright (C) 2013, Eric Wong <normalperson@yhbt.net> and all contributors
+# License: AGPLv3 or later (https://www.gnu.org/licenses/agpl-3.0.txt)
+use strict;
+use warnings;
+use Email::Filter;
+use PublicInbox::Filter;
+use IPC::Run qw(run);
+my $usage = "public-inbox-mda main_repo fail_repo < rfc2822_message";
+my $filter = Email::Filter->new(emergency => "~/emergency.mbox");
+my $main_repo = shift @ARGV or die "Usage: $usage\n";
+my $fail_repo = shift @ARGV or die "Usage: $usage\n";
+
+my $filtered;
+if (do_spamc($filter->simple, \$filtered)) {
+        # update our message with SA headers (in case our filter rejects it)
+        my $simple = Email::Simple->new($filtered);
+        $filtered = undef;
+        $filter->simple($simple);
+
+        if (PublicInbox::Filter->run($simple)) {
+                # run spamc again on the HTML-free message
+                if (do_spamc($simple, \$filtered)) {
+                        $filter->simple(Email::Simple->new($filtered));
+                        $filter->pipe("ssoma-mda", $main_repo);
+                } else {
+                        $filter->pipe("ssoma-mda", $fail_repo);
+                }
+        } else {
+                # PublicInbox::Filter nuked everything, oops :x
+                $filter->pipe("ssoma-mda", $fail_repo);
+        }
+} else {
+        # if SA thinks it's spam or there's an error:
+        # don't bother with our own filtering
+        $filter->pipe("ssoma-mda", $fail_repo);
+}
+die "Email::Filter failed to exit\n";
+
+# we depend on "report_safe 0" in /etc/spamassassin/*.cf with --headers
+# not using Email::Filter->pipe here since we want the stdout of
+# the command even on failure (spamc will set $? on error).
+sub do_spamc {
+        my ($simple, $out) = @_;
+        eval {
+                my $orig = $simple->as_string;
+                run([qw/spamc -E --headers/], \$orig, $out);
+        };
+
+        return ($@ || $? || !defined($$out) || length($$out) == 0) ? 0 : 1;
+}