#!/usr/bin/perl -w # Copyright (C) 2013, Eric Wong 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; }