mourningdove/bin/incoming-mail-inject.pl

105 lines
3.1 KiB
Perl
Raw Normal View History

2026-05-24 01:03:05 +00:00
#!/usr/bin/perl
# This code was forked from the LiveJournal project owned and operated
# by Live Journal, Inc. The code has been modified and expanded by
# Dreamwidth Studios, LLC. These files were originally licensed under
# the terms of the license supplied by Live Journal, Inc, which can
# currently be found at:
#
# http://code.livejournal.org/trac/livejournal/browser/trunk/LICENSE-LiveJournal.txt
#
# In accordance with the original license, this code and all its
# modifications are provided under the GNU General Public License.
# A copy of that license can be found in the LICENSE file included as
# part of this distribution.
use strict;
use v5.10;
BEGIN {
require "$ENV{LJHOME}/cgi-bin/ljlib.pl";
}
use Log::Log4perl;
my $log = Log::Log4perl->get_logger(__PACKAGE__);
use Digest::MD5 qw/ md5_hex /;
use DW::Task::IncomingEmail;
my $tempfail = sub {
my $msg = shift;
warn "Failure: $msg\n" if $msg;
# makes postfix do temporary failure:
exit 75;
};
# below this size, we put in database directly. if over,
# we put in mogile.
sub IN_MEMORY_THRES () {
return $ENV{T_MAILINJECT_THRES_SIZE}
|| 768 * 1024;
}
my $msg = ''; # in-memory message
my $len = 0; # length of message
eval {
my ( $buf, $rv );
while ( $rv = sysread STDIN, $buf, 1024 * 64 ) {
$len += $rv;
$msg .= $buf;
}
$tempfail->("Error reading: $!")
unless defined $rv;
if ( should_ignore($msg) ) {
$log->info("Received probable spam message of $len bytes, dropping");
exit 0;
}
$log->info("Received email of $len bytes, saving for handling");
};
$tempfail->($@) if $@;
if ( $len > IN_MEMORY_THRES ) {
my $md5 = md5_hex($msg);
DW::BlobStore->store( temp => "ie:$md5", \$msg );
$log->info("Storing email in blobstore at key: ie:$md5");
# Overwrite $msg so that the incoming-email worker knows that this
# is a key it should look up in the storage system
$msg = "ie:$md5";
}
my $h = DW::TaskQueue->dispatch( DW::Task::IncomingEmail->new($msg) );
exit 0 if $h;
exit 75; # temporary error
# it pays to get rid of as many bounces and gibberish now, before we
# have to put it in the database, mogile, allocate ids, run workers,
# move disks around, etc.. so these are just quick & dirty checks.
sub should_ignore {
my $msg = shift;
return 0 unless $msg;
return 1 if $msg =~ /^Return-Path:\s+<>/im;
my ($subject) = $msg =~ /^Subject: (.+)/im;
if ($subject) {
return 1
if $subject =~ /auto.?(response|reply)/i
|| $subject =~
/^(Undelive|Mail System Error - |ScanMail Message: |\+\s*SPAM|Norton AntiVirus)/i
|| $subject =~ /^(Mail Delivery Problem|Mail delivery failed)/i
|| $subject =~ /^failure notice$/i
|| $subject =~ /\[BOUNCED SPAM\]/i
|| $subject =~ /^Symantec AVF /i
|| $subject =~ /Attachment block message/i
|| $subject =~ /Use this patch immediately/i
|| $subject =~ /^don\'t be late! ([\w\-]{1,15})$/i
|| $subject =~ /^your account ([\w\-]{1,15})$/i
|| $subject =~ /Message Undeliverable/i;
}
return 0;
}