X-Git-Url: http://www.git.stargrave.org/?a=blobdiff_plain;f=public-inbox-mda;h=50805da2e6ecc99b679cc69dacfea1caa6e37e21;hb=e022d3377fd2c50fd9931bf96394728958a90bf3;hp=72f1eac4b41f04b6f51eb2bd01bb1b4fc347c323;hpb=bf4630c098ad7159ba36dea6cfe77c4cf6806ffe;p=public-inbox.git diff --git a/public-inbox-mda b/public-inbox-mda index 72f1eac4..50805da2 100755 --- a/public-inbox-mda +++ b/public-inbox-mda @@ -3,51 +3,69 @@ # License: AGPLv3 or later (https://www.gnu.org/licenses/agpl-3.0.txt) use strict; use warnings; +my $usage = 'public-inbox-mda < rfc2822_message'; + use Email::Filter; +use Email::MIME; use Email::Address; -use PublicInbox::Filter; +use File::Path::Expand qw/expand_filename/; 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 $max = 1024 * 500; # same as spamc - -my $filtered; -if (length($filter->simple->as_string) <= $max - && PublicInbox->recipient_specified($filter) - && do_spamc($filter->simple, \$filtered)) { +use PublicInbox::MDA; +use PublicInbox::Filter; +use PublicInbox::Config; + +# n.b: hopefully we can setup the emergency path without bailing due to +# user error, we really want to setup the emergency destination ASAP +# in case there's bugs in our code or user error. +my $emergency = $ENV{PI_EMERGENCY} || '~/.public-inbox/emergency/'; +$emergency = expand_filename($emergency); + +# this reads the message from stdin +my $filter = Email::Filter->new(emergency => $emergency); +my $config = PublicInbox::Config->new; + +my $recipient = $ENV{ORIGINAL_RECIPIENT}; +defined $recipient or die "ORIGINAL_RECIPIENT not defined in ENV\n"; +my $dst = $config->lookup($recipient); +defined $dst or exit(1); +my $main_repo = $dst->{mainrepo} or exit(1); +my $filtered; # string dest + +if (PublicInbox::MDA->precheck($filter, $recipient) && + do_spamc($filter->simple, \$filtered)) { # update our message with SA headers (in case our filter rejects it) - my $simple = Email::Simple->new($filtered); + my $msg = Email::Simple->new($filtered); $filtered = undef; - $filter->simple($simple); + $filter->simple($msg); - if (PublicInbox::Filter->run($simple)) { + if (PublicInbox::Filter->run($msg)) { # 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); + if (do_spamc($msg, \$filtered)) { + $msg = Email::MIME->new($filtered); + PublicInbox::MDA->set_list_headers($msg, $dst); + $filter->simple($msg); + + my ($name, $email, $date) = + PublicInbox::MDA->author_info($msg); + local $ENV{GIT_AUTHOR_NAME} = $name; + local $ENV{GIT_AUTHOR_EMAIL} = $email; + local $ENV{GIT_AUTHOR_DATE} = $date; + local $ENV{GIT_COMMITTER_EMAIL} = $recipient; + local $ENV{GIT_COMMITTER_NAME} = $dst->{listname}; + + $filter->pipe(PublicInbox::MDA->cmd, $main_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"; +exit 0; # goes to emergency # 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) = @_; + my ($msg, $out) = @_; eval { - my $orig = $simple->as_string; + my $orig = $msg->as_string; run([qw/spamc -E --headers/], \$orig, $out); };