X-Git-Url: http://www.git.stargrave.org/?a=blobdiff_plain;f=lib%2FPublicInbox%2FSpamcheck%2FSpamc.pm;h=d2b6429c46e44e8f660c354458ef5cd0fa885603;hb=af0b0fb7a454470a32c452119d0392e0dedb3fe1;hp=a76e920f0210221a6345528c2c8fd8998033789f;hpb=3d41aa23f35501ca92aab8aa42980fa73f7fa74f;p=public-inbox.git diff --git a/lib/PublicInbox/Spamcheck/Spamc.pm b/lib/PublicInbox/Spamcheck/Spamc.pm index a76e920f..d2b6429c 100644 --- a/lib/PublicInbox/Spamcheck/Spamc.pm +++ b/lib/PublicInbox/Spamcheck/Spamc.pm @@ -1,11 +1,13 @@ -# Copyright (C) 2016-2018 all contributors +# Copyright (C) 2016-2021 all contributors # License: AGPL-3.0+ + +# Default spam filter class for wrapping spamc(1) package PublicInbox::Spamcheck::Spamc; use strict; use warnings; use PublicInbox::Spawn qw(popen_rd spawn); use IO::Handle; -use Fcntl qw(:DEFAULT SEEK_SET); +use Fcntl qw(SEEK_SET); sub new { my ($class) = @_; @@ -19,24 +21,13 @@ sub new { sub spamcheck { my ($self, $msg, $out) = @_; - my $tmp; - my $fd = _msg_to_fd($self, $msg, \$tmp); - my $rdr = { 0 => $fd }; + my $rdr = { 0 => _msg_to_fh($self, $msg) }; my ($fh, $pid) = popen_rd($self->{checkcmd}, undef, $rdr); - defined $pid or die "failed to popen_rd spamc: $!\n"; - my $r; unless (ref $out) { my $buf = ''; $out = \$buf; } -again: - do { - $r = sysread($fh, $$out, 65536, length($$out)); - } while (defined($r) && $r != 0); - unless (defined $r) { - goto again if $!{EINTR}; - die "read failed: $!"; - } + $$out = do { local $/; <$fh> }; close $fh or die "close failed: $!"; waitpid($pid, 0); ($? || $$out eq '') ? 0 : 1; @@ -55,10 +46,9 @@ sub spamlearn { sub _learn { my ($self, $msg, $rdr, $field) = @_; $rdr ||= {}; + $rdr->{0} = _msg_to_fh($self, $msg); $rdr->{1} ||= $self->_devnull; $rdr->{2} ||= $self->_devnull; - my $tmp; - $rdr->{0} = _msg_to_fd($self, $msg, \$tmp); my $pid = spawn($self->{$field}, undef, $rdr); waitpid($pid, 0); !$?; @@ -66,20 +56,18 @@ sub _learn { sub _devnull { my ($self) = @_; - my $fd = $self->{-devnullfd}; - return $fd if defined $fd; - open my $fh, '+>', '/dev/null' or + $self->{-devnull} //= do { + open my $fh, '+>', '/dev/null' or die "failed to open /dev/null: $!"; - $self->{-devnull} = $fh; - $self->{-devnullfd} = fileno($fh); + $fh + } } -sub _msg_to_fd { - my ($self, $msg, $tmpref) = @_; - my $fd; +sub _msg_to_fh { + my ($self, $msg) = @_; if (my $ref = ref($msg)) { - my $fileno = eval { fileno($msg) }; - return $fileno if defined $fileno; + my $fd = eval { fileno($msg) }; + return $msg if defined($fd) && $fd >= 0; open(my $tmpfh, '+>', undef) or die "failed to open: $!"; $tmpfh->autoflush(1); @@ -87,9 +75,8 @@ sub _msg_to_fd { print $tmpfh $$msg or die "failed to print: $!"; sysseek($tmpfh, 0, SEEK_SET) or die "sysseek(fh) failed: $!"; - $$tmpref = $tmpfh; - return fileno($tmpfh); + return $tmpfh; } $msg; }