]> Sergey Matveev's repositories - public-inbox.git/blob - public-inbox-mda
initial commit
[public-inbox.git] / public-inbox-mda
1 #!/usr/bin/perl -w
2 # Copyright (C) 2013, Eric Wong <normalperson@yhbt.net> and all contributors
3 # License: AGPLv3 or later (https://www.gnu.org/licenses/agpl-3.0.txt)
4 use strict;
5 use warnings;
6 use Email::Filter;
7 use PublicInbox::Filter;
8 use IPC::Run qw(run);
9 my $usage = "public-inbox-mda main_repo fail_repo < rfc2822_message";
10 my $filter = Email::Filter->new(emergency => "~/emergency.mbox");
11 my $main_repo = shift @ARGV or die "Usage: $usage\n";
12 my $fail_repo = shift @ARGV or die "Usage: $usage\n";
13
14 my $filtered;
15 if (do_spamc($filter->simple, \$filtered)) {
16         # update our message with SA headers (in case our filter rejects it)
17         my $simple = Email::Simple->new($filtered);
18         $filtered = undef;
19         $filter->simple($simple);
20
21         if (PublicInbox::Filter->run($simple)) {
22                 # run spamc again on the HTML-free message
23                 if (do_spamc($simple, \$filtered)) {
24                         $filter->simple(Email::Simple->new($filtered));
25                         $filter->pipe("ssoma-mda", $main_repo);
26                 } else {
27                         $filter->pipe("ssoma-mda", $fail_repo);
28                 }
29         } else {
30                 # PublicInbox::Filter nuked everything, oops :x
31                 $filter->pipe("ssoma-mda", $fail_repo);
32         }
33 } else {
34         # if SA thinks it's spam or there's an error:
35         # don't bother with our own filtering
36         $filter->pipe("ssoma-mda", $fail_repo);
37 }
38 die "Email::Filter failed to exit\n";
39
40 # we depend on "report_safe 0" in /etc/spamassassin/*.cf with --headers
41 # not using Email::Filter->pipe here since we want the stdout of
42 # the command even on failure (spamc will set $? on error).
43 sub do_spamc {
44         my ($simple, $out) = @_;
45         eval {
46                 my $orig = $simple->as_string;
47                 run([qw/spamc -E --headers/], \$orig, $out);
48         };
49
50         return ($@ || $? || !defined($$out) || length($$out) == 0) ? 0 : 1;
51 }