You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@spamassassin.apache.org by fe...@apache.org on 2004/11/13 03:01:37 UTC
svn commit: rev 57552 - in spamassassin/trunk: . lib/Mail/SpamAssassin lib/Mail/SpamAssassin/Plugin
Author: felicity
Date: Fri Nov 12 18:01:35 2004
New Revision: 57552
Modified:
spamassassin/trunk/lib/Mail/SpamAssassin/Plugin.pm
spamassassin/trunk/lib/Mail/SpamAssassin/Plugin/Razor2.pm
spamassassin/trunk/lib/Mail/SpamAssassin/Reporter.pm
spamassassin/trunk/spamassassin.raw
Log:
bug 3778: plugins will be called during report and revoke operations. bug 3643: finish converting Razor2 to a plugin. also added in plugin call to cache/log/etc the razor result, moving towards _RBL_ esque implementation via extra plugin. changed report and revoke to return 1 for success and 0 for failure -- like every other function. fixed spamcop-report debug output.
Modified: spamassassin/trunk/lib/Mail/SpamAssassin/Plugin.pm
==============================================================================
--- spamassassin/trunk/lib/Mail/SpamAssassin/Plugin.pm (original)
+++ spamassassin/trunk/lib/Mail/SpamAssassin/Plugin.pm Fri Nov 12 18:01:35 2004
@@ -468,6 +468,46 @@
=back
+=item $plugin->plugin_report ( { options ... } )
+
+Called if the message is to be reported as spam.
+
+=over 4
+
+=item report
+
+Reference to the Reporter object
+
+=item text
+
+Reference to a markup removed copy of the message in scalar format
+
+=item msg
+
+Reference to the original message object
+
+=back
+
+=item $plugin->plugin_revoke ( { options ... } )
+
+Called if the message is to be reported as ham (revokes a spam report).
+
+=over 4
+
+=item revoke
+
+Reference to the Reporter object
+
+=item text
+
+Reference to a markup removed copy of the message in scalar format
+
+=item msg
+
+Reference to the original message object
+
+=back
+
=item $plugin->finish ()
Called when the C<Mail::SpamAssassin> object is destroyed.
Modified: spamassassin/trunk/lib/Mail/SpamAssassin/Plugin/Razor2.pm
==============================================================================
--- spamassassin/trunk/lib/Mail/SpamAssassin/Plugin/Razor2.pm (original)
+++ spamassassin/trunk/lib/Mail/SpamAssassin/Plugin/Razor2.pm Fri Nov 12 18:01:35 2004
@@ -51,8 +51,8 @@
}
else {
if (eval { require Razor2::Client::Agent; }) {
- dbg("razor2: razor2 is available");
$self->{razor2_available} = 1;
+ dbg("razor2: razor2 is available, version " . $Razor2::Client::Version::VERSION . "\n");
}
else {
dbg("razor2: razor2 is not available");
@@ -112,25 +112,28 @@
$conf->{parser}->register_commands(\@cmds);
}
-sub razor2_lookup {
- my ($self, $permsgstatus, $fulltext) = @_;
- my $timeout=$self->{main}->{conf}->{razor_timeout};
+# This is to reset the alarm before die() - spamd can die of a stray alarm!
+sub adie {
+ my $msg = shift;
+ alarm 0;
+ die $msg;
+}
- # Set the score for the ranged checks
- $self->{razor2_cf_score} = 0;
- return $self->{razor2_result} if ( defined $self->{razor2_result} );
- $self->{razor2_result} = 0;
+sub razor2_access {
+ my ($self, $fulltext, $type) = @_;
+ my $timeout=$self->{main}->{conf}->{razor_timeout};
+ my $return = 0;
+ my @results = ();
- return unless $self->{main}->{conf}->{use_razor2};
- return unless $self->{razor2_available};
-
# razor also debugs to stdout. argh. fix it to stderr...
if ($Mail::SpamAssassin::DEBUG) {
open (OLDOUT, ">&STDOUT");
open (STDOUT, ">&STDERR");
}
- $permsgstatus->enter_helper_run_mode();
+ my $debug = $type eq 'check' ? 'razor2' : 'reporter';
+
+ Mail::SpamAssassin::PerMsgStatus::enter_helper_run_mode($self);
eval {
local ($^W) = 0; # argh, warnings in Razor
@@ -139,24 +142,29 @@
alarm $timeout;
# everything's in the module!
- my $rc = Razor2::Client::Agent->new('razor-check');
+ my $rc = Razor2::Client::Agent->new("razor-$type");
if ($rc) {
- my %opt = (
+ $rc->{opt} = {
debug => ($Mail::SpamAssassin::DEBUG &&
- $Mail::SpamAssassin::facilities{razor2}),
+ ($Mail::SpamAssassin::facilities{all} ||
+ $Mail::SpamAssassin::facilities{razor2})),
foreground => 1,
config => $self->{main}->{conf}->{razor_config}
- );
- $rc->{opt} = \%opt;
- $rc->do_conf() or die "razor2: " . $rc->errstr;
+ };
+ $rc->do_conf() or adie "$debug: " . $rc->errstr;
- my $tmptext = $$fulltext;
- my @msg = (\$tmptext);
+ # Razor2 requires authentication for reporting
+ my $ident;
+ if ($type ne 'check') {
+ $ident = $rc->get_ident
+ or adie("reporter: razor2: $type requires authentication");
+ }
+ my @msg = ($fulltext);
my $objects = $rc->prepare_objects( \@msg )
- or die "razor2: error in prepare_objects";
- $rc->get_server_info() or die $rc->errprefix("razor2: spamassassin");
+ or adie "$debug: error in prepare_objects";
+ $rc->get_server_info() or adie $rc->errprefix("$debug: spamassassin");
# let's reset the alarm since get_server_info() calls
# nextserver() which calls discover() which very likely will
@@ -164,23 +172,34 @@
alarm $timeout;
my $sigs = $rc->compute_sigs($objects)
- or die "razor2: error in compute_sigs";
+ or adie "$debug: error in compute_sigs";
#
# if mail isn't whitelisted, check it out
+ # see 'man razor-whitelist'
#
- if ( ! $rc->local_check( $objects->[0] ) ) {
- if (!$rc->connect()) {
- # provide a better error message when servers are unavailable,
- # than "Bad file descriptor Died".
- die "razor2: could not connect to any servers\n";
+ if ( $type ne 'check' || ! $rc->local_check($objects->[0]) ) {
+ # provide a better error message when servers are unavailable,
+ # than "Bad file descriptor Died".
+ $rc->connect() or adie "$debug: could not connect to any servers\n";
+
+ # Talk to the Razor server and do work
+ if ($type eq 'check') {
+ $rc->check($objects) or adie $rc->errprefix("$debug: spamassassin");
+ }
+ else {
+ $rc->authenticate($ident) or adie($rc->errprefix("$debug: spamassassin"));
+ $rc->report($objects) or adie($rc->errprefix("$debug: spamassassin"));
}
- $rc->check($objects) or die $rc->errprefix("razor2: spamassassin");
- $rc->disconnect() or die $rc->errprefix("razor2: spamassassin");
+
+ $rc->disconnect() or adie $rc->errprefix("$debug: spamassassin");
# if we got here, we're done doing remote stuff, abort the alert
alarm 0;
+ # Razor 2.14 says that if we get here, we did ok.
+ $return = 1;
+
# figure out if we have a log file we need to close...
if (ref($rc->{logref}) && exists $rc->{logref}->{fd}) {
# the fd can be stdout or stderr, so we need to find out if it is
@@ -197,55 +216,53 @@
close $rc->{logref}->{fd} if ($untie);
}
- dbg("razor2: using results from Razor version " .
- $Razor2::Client::Version::VERSION . "\n");
-
- # so $objects->[0] is the first (only) message, and ->{spam} is a general yes/no
- $self->{razor2_result} = $objects->[0]->{spam} || 0;
-
- # great for debugging, but leave this off!
- #use Data::Dumper;
- #print Dumper($objects),"\n";
-
- # ->{p} is for each part of the message
- # so go through each part, taking the highest cf we find
- # of any part that isn't contested (ct). This helps avoid false
- # positives. equals logic_method 4.
- #
- # razor-agents < 2.14 have a different object format, so we now support both.
- # $objects->[0]->{resp} vs $objects->[0]->{p}->[part #]->{resp}
- my $part = 0;
- my $arrayref = $objects->[0]->{p} || $objects;
- if ( defined $arrayref ) {
- foreach my $cf ( @{$arrayref} ) {
- if ( exists $cf->{resp} ) {
- for (my $response=0;$response<@{$cf->{resp}};$response++) {
- my $tmp = $cf->{resp}->[$response];
- my $tmpcf = $tmp->{cf} || 0; # Part confidence
- my $tmpct = $tmp->{ct} || 0; # Part contested?
- my $engine = $cf->{sent}->[$response]->{e};
- dbg("razor2: found razor2 part: part=$part engine=$engine ct=$tmpct cf=$tmpcf");
- $self->{razor2_cf_score} = $tmpcf if ( !$tmpct && $tmpcf > $self->{razor2_cf_score} );
+ if ($type eq 'check') {
+ # so $objects->[0] is the first (only) message, and ->{spam} is a general yes/no
+ push(@results, { result => $objects->[0]->{spam} });
+
+ # great for debugging, but leave this off!
+ #use Data::Dumper;
+ #print Dumper($objects),"\n";
+
+ # ->{p} is for each part of the message
+ # so go through each part, taking the highest cf we find
+ # of any part that isn't contested (ct). This helps avoid false
+ # positives. equals logic_method 4.
+ #
+ # razor-agents < 2.14 have a different object format, so we now support both.
+ # $objects->[0]->{resp} vs $objects->[0]->{p}->[part #]->{resp}
+ my $part = 0;
+ my $arrayref = $objects->[0]->{p} || $objects;
+ if ( defined $arrayref ) {
+ foreach my $cf ( @{$arrayref} ) {
+ if ( exists $cf->{resp} ) {
+ for (my $response=0;$response<@{$cf->{resp}};$response++) {
+ my $tmp = $cf->{resp}->[$response];
+ my $tmpcf = $tmp->{cf} || 0; # Part confidence
+ my $tmpct = $tmp->{ct} || 0; # Part contested?
+ my $engine = $cf->{sent}->[$response]->{e};
+
+ push(@results,
+ { part => $part, engine => $engine, contested => $tmpct, confidence => $tmpcf });
+ }
}
+ else {
+ push(@results, { part => $part, noreponse => 1 });
+ }
+ $part++;
}
- else {
- my $text = "part=$part noresponse";
- $text .= " skipme=1" if ( $cf->{skipme} );
- dbg("razor2: found razor2 part: $text");
- }
- $part++;
}
- }
- else {
- # If we have some new $objects format that isn't close to
- # the current razor-agents 2.x version, we won't FP but we
- # should alert in debug.
- dbg("razor2: it looks like the internal Razor object has changed format!");
- }
- }
+ else {
+ # If we have some new $objects format that isn't close to
+ # the current razor-agents 2.x version, we won't FP but we
+ # should alert in debug.
+ dbg("$debug: it looks like the internal Razor object has changed format!");
+ }
+ }
+ }
}
else {
- warn "razor2: undefined Razor2::Client::Agent\n";
+ warn "$debug: undefined Razor2::Client::Agent\n";
}
alarm 0;
@@ -255,21 +272,23 @@
if ($@) {
if ( $@ =~ /alarm/ ) {
- dbg("razor2: check timed out after $timeout seconds");
- } elsif ($@ =~ /(?:could not connect|network is unreachable)/) {
- # make this a dbg(); SpamAssassin will still continue,
- # but without Razor checking. otherwise there may be
- # DSNs and errors in syslog etc., yuck
- dbg("razor2: check could not connect to any servers");
- } else {
- warn("razor2: check skipped: $! $@");
- }
+ dbg("$debug: razor2 $type timed out after $timeout seconds");
+ } elsif ($@ =~ /(?:could not connect|network is unreachable)/) {
+ # make this a dbg(); SpamAssassin will still continue,
+ # but without Razor checking. otherwise there may be
+ # DSNs and errors in syslog etc., yuck
+ dbg("$debug: razor2 $type could not connect to any servers");
+ } elsif ($@ =~ /timeout/i) {
+ dbg("$debug: razor2 $type timed out connecting to razor servers");
+ } else {
+ warn("$debug: razor2 $type failed: $! $@");
}
+ }
# work around serious brain damage in Razor2 (constant seed)
srand;
- $permsgstatus->leave_helper_run_mode();
+ Mail::SpamAssassin::PerMsgStatus::leave_helper_run_mode($self);
# razor also debugs to stdout. argh. fix it to stderr...
if ($Mail::SpamAssassin::DEBUG) {
@@ -277,24 +296,89 @@
close OLDOUT;
}
- dbg("razor2: results: spam? " . $self->{razor2_result} .
- " highest cf score: " . $self->{razor2_cf_score} . "\n");
+ return wantarray ? ($return, @results) : $return;
+}
+
+sub plugin_report {
+ my($self, $options) = @_;
- if ($self->{razor2_result} > 0) {
- return 1;
+ return unless $self->{razor2_available};
+ return if $self->{main}->{local_tests_only};
+ return unless $self->{main}->{conf}->{use_razor2};
+ return if $options->{report}->{options}->{dont_report_to_razor};
+
+ if ($self->razor2_access($options->{text}, 'report')) {
+ $options->{report}->{report_available} = 1;
+ dbg ('reporter: spam reported to Razor.');
+ $options->{report}->{report_return} = 1;
+ }
+ else {
+ dbg ('reporter: could not report spam to Razor.');
}
- return 0;
}
-sub check_razor2 {
- my ($self, $permsgstatus) = @_;
+sub plugin_revoke {
+ my($self, $options) = @_;
+ return unless $self->{razor2_available};
+ return if $self->{main}->{local_tests_only};
return unless $self->{main}->{conf}->{use_razor2};
+ return if $options->{revoke}->{options}->{dont_report_to_razor};
+
+ if ($self->razor2_access($options->{text}, 'revoke')) {
+ $options->{revoke}->{revoke_available} = 1;
+ dbg('reporter: spam revoked from Razor');
+ $options->{revoke}->{revoke_return} = 1;
+ }
+ else {
+ dbg('reporter: could not revoke spam from Razor');
+ }
+}
+
+sub check_razor2 {
+ my ($self, $permsgstatus, $full) = @_;
+
+ return $permsgstatus->{razor2_result} if (defined $permsgstatus->{razor2_result});
+ $permsgstatus->{razor2_result} = 0;
+ $permsgstatus->{razor2_cf_score} = 0;
+
return unless $self->{razor2_available};
- return $self->{razor2_result} if (defined $self->{razor2_result});
+ return unless $self->{main}->{conf}->{use_razor2};
+
+ my $return;
+ my @results = ();
- my $full = $permsgstatus->{msg}->get_pristine();
- return $self->razor2_lookup ($permsgstatus, \$full);
+ # TODO: check for cache header, set results appropriately
+
+ # do it this way to make it easier to get out the results later from the
+ # netcache plugin
+ ($return, @results) = $self->razor2_access($full, 'check');
+ $self->{main}->call_plugins ('process_razor_result', @results);
+
+ foreach my $result (@results) {
+ if (exists $result->{result}) {
+ $permsgstatus->{razor2_result} = $result->{result} if $result->{result};
+ }
+ elsif ($result->{noresponse}) {
+ dbg('razor2: part=' . $result->{part} . ' noresponse');
+ }
+ else {
+ dbg('razor2: part=' . $result->{part} .
+ ' engine=' . $result->{engine} .
+ ' contested=' . $result->{contested} .
+ ' confidence=' . $result->{confidence});
+
+ next if $result->{contested};
+ if ($result->{confidence} > $permsgstatus->{razor2_cf_score}) {
+ $permsgstatus->{razor2_cf_score} = $result->{confidence};
+ }
+ }
+ }
+
+ dbg("razor2: results: spam? " . $permsgstatus->{razor2_result} .
+ " highest cf score: " . $permsgstatus->{razor2_cf_score} . "\n");
+
+ return $permsgstatus->{razor2_result};
}
# Check the cf value of a given message and return if it's within the
@@ -304,20 +388,21 @@
# If Razor2 isn't available, or the general test is disabled, don't
# continue.
- return 0 unless $self->{main}->{conf}->{use_razor2};
return unless $self->{razor2_available};
- return 0 unless $self->{main}->{conf}->{scores}->{'RAZOR2_CHECK'};
+ return unless $self->{main}->{conf}->{use_razor2};
+ return unless $self->{main}->{conf}->{scores}->{'RAZOR2_CHECK'};
# If Razor2 hasn't been checked yet, go ahead and run it.
- if (!defined $self->{razor2_result}) {
- $self->check_razor2($permsgstatus);
+ unless (defined $permsgstatus->{razor2_result}) {
+ $self->check_razor2($permsgstatus, $body);
}
- if ($self->{razor2_cf_score} >= $min && $self->{razor2_cf_score} <= $max) {
- $permsgstatus->test_log(sprintf ("cf: %3d", $self->{razor2_cf_score}));
+ if ($permsgstatus->{razor2_cf_score} >= $min && $permsgstatus->{razor2_cf_score} <= $max) {
+ $permsgstatus->test_log(sprintf ("cf: %3d", $permsgstatus->{razor2_cf_score}));
return 1;
}
- return 0;
+
+ return;
}
sub dbg { Mail::SpamAssassin::dbg(@_); }
Modified: spamassassin/trunk/lib/Mail/SpamAssassin/Reporter.pm
==============================================================================
--- spamassassin/trunk/lib/Mail/SpamAssassin/Reporter.pm (original)
+++ spamassassin/trunk/lib/Mail/SpamAssassin/Reporter.pm Fri Nov 12 18:01:35 2004
@@ -44,10 +44,9 @@
'main' => $main,
'msg' => $msg,
'options' => $options,
+ 'conf' => $main->{conf},
};
- $self->{conf} = $self->{main}->{conf};
-
bless ($self, $class);
$self;
}
@@ -56,16 +55,16 @@
sub report {
my ($self) = @_;
- my $return = 1;
- my $available = 0;
+ $self->{report_return} = 1;
+ $self->{report_available} = 0;
my $text = $self->{main}->remove_spamassassin_markup ($self->{msg});
if (!$self->{options}->{dont_report_to_dcc} && $self->is_dcc_available()) {
if ($self->dcc_report($text)) {
- $available = 1;
+ $self->{report_available} = 1;
dbg("reporter: spam reported to DCC");
- $return = 0;
+ $self->{report_return} = 0;
}
else {
dbg("reporter: could not report spam to DCC");
@@ -73,82 +72,53 @@
}
if (!$self->{options}->{dont_report_to_pyzor} && $self->is_pyzor_available()) {
if ($self->pyzor_report($text)) {
- $available = 1;
+ $self->{report_available} = 1;
dbg("reporter: spam reported to Pyzor");
- $return = 0;
+ $self->{report_return} = 0;
}
else {
dbg("reporter: could not report spam to Pyzor");
}
}
- if (!$self->{options}->{dont_report_to_razor} && $self->is_razor_available()) {
- if ($self->razor_report($text)) {
- $available = 1;
- dbg("reporter: spam reported to Razor");
- $return = 0;
- }
- else {
- dbg("reporter: could not report spam to Razor");
- }
- }
if (!$self->{options}->{dont_report_to_spamcop} && $self->is_spamcop_available()) {
if ($self->spamcop_report($text)) {
- $available = 1;
+ $self->{report_available} = 1;
dbg("reporter: spam reported to SpamCop");
- $return = 0;
+ $self->{report_return} = 0;
}
else {
- dbg("reporter: could not report spam to reporter.");
+ dbg("reporter: could not report spam to SpamCop.");
}
}
+ $self->{main}->call_plugins ("plugin_report", { report => $self, text => \$text, msg => $self->{msg} });
+
$self->delete_fulltext_tmpfile();
- if ($available == 0) {
+ if ($self->{report_available} == 0) {
warn "reporter: no network reporting methods available, so couldn't report\n";
}
- return $return;
+ return $self->{report_return};
}
###########################################################################
sub revoke {
my ($self) = @_;
- my $return = 1;
+ $self->{revoke_return} = 0;
+ $self->{revoke_available} = 0;
my $text = $self->{main}->remove_spamassassin_markup($self->{msg});
- if (!$self->{main}->{local_tests_only}
- && !$self->{options}->{dont_report_to_razor}
- && $self->is_razor_available()) # we only work with Razor2
- {
- if ($self->razor_revoke($text)) {
- dbg("reporter: spam revoked from Razor");
- $return = 0;
- }
- else {
- dbg("reporter: could not revoke spam from Razor");
- }
- }
-
- # This is where you would revoke from DCC and Pyzor but I was unable
- # to find where they supported revoke
+ $self->{main}->call_plugins ("plugin_revoke", { revoke => $self, text => \$text, msg => $self->{msg} });
- return $return;
+ return $self->{revoke_return};
}
###########################################################################
# non-public methods.
-# This is to reset the alarm before die() - spamd can die of a stray alarm!
-
-sub adie {
- my $msg = shift;
- alarm 0;
- die $msg;
-}
-
# Close an fh piped to a process, possibly exiting if the process returned nonzero.
# thanks to nix /at/ esperi.demon.co.uk for this.
sub close_pipe_fh {
@@ -168,113 +138,6 @@
}
}
-sub razor_report {
- my ($self, $fulltext, $revoke) = @_;
- my $timeout=$self->{conf}->{razor_timeout} || 10;
- my $response;
-
- # If we passed in a true value for $revoke then we must be revoking
- my $type = (defined($revoke) && $revoke) ? 'revoke' : 'report';
-
- # razor also debugs to stdout. argh. fix it to stderr...
- if ($Mail::SpamAssassin::DEBUG) {
- open (OLDOUT, ">&STDOUT");
- open (STDOUT, ">&STDERR");
- }
-
- $self->enter_helper_run_mode();
-
- # Use Razor2 if it's available
- eval { require Razor2::Client::Agent; };
- if ( !$@ ) {
- eval {
- local ($^W) = 0; # argh, warnings in Razor
-
- local $SIG{ALRM} = sub { die "alarm\n" };
- alarm $timeout;
-
- # everything's in the module!
- my $rc = Razor2::Client::Agent->new("razor-$type");
-
- if ($rc) {
- my %opt = (
- debug => $Mail::SpamAssassin::DEBUG,
- foreground => 1,
- config => $self->{conf}->{razor_config}
- );
- $rc->{opt} = \%opt;
- $rc->do_conf() or adie("reporter: razor2: " . $rc->errstr);
-
- # Razor2 requires authentication for reporting
- my $ident = $rc->get_ident
- or adie("reporter: razor2: $type requires authentication");
-
- my @msg = (\$fulltext);
- my $objects = $rc->prepare_objects( \@msg )
- or adie("reporter: razor2: error in prepare_objects");
- $rc->get_server_info() or adie $rc->errprefix("reporter: razor2");
-
- # let's reset the alarm since get_server_info() calls
- # nextserver() which calls discover() which very likely will
- # reset the alarm for us ... how polite. :(
- alarm $timeout;
-
- my $sigs = $rc->compute_sigs($objects)
- or adie("reporter: razor2: error in compute_sigs");
-
- $rc->connect() or adie($rc->errprefix("reporter: razor2"));
- $rc->authenticate($ident) or adie($rc->errprefix("reporter: razor2"));
- $rc->report($objects) or adie($rc->errprefix("reporter: razor2"));
- $rc->disconnect() or adie($rc->errprefix("reporter: razor2"));
- $response = 1; # Razor 2.14 says that if we get here, we did ok.
- }
- else {
- warn "reporter: undefined Razor2::Client::Agent\n";
- }
-
- alarm 0;
- dbg("reporter: razor2 spam $type, response is \"$response\".");
- };
-
- alarm 0;
-
- if ($@) {
- if ( $@ =~ /alarm/ ) {
- dbg("reporter: razor2 $type timed out after $timeout secs.");
- } elsif ($@ =~ /could not connect/) {
- dbg("reporter: razor2 $type could not connect to any servers");
- } elsif ($@ =~ /timeout/i) {
- dbg("reporter: razor2 $type timed out connecting to razor servers");
- } else {
- warn "reporter: razor2 $type failed: $! $@";
- }
- undef $response;
- }
- }
-
- # work around serious brain damage in Razor2 (constant seed)
- srand;
-
- $self->leave_helper_run_mode();
-
- if ($Mail::SpamAssassin::DEBUG) {
- open (STDOUT, ">&OLDOUT");
- close OLDOUT;
- }
-
- if (defined($response) && $response+0) {
- return 1;
- } else {
- return 0;
- }
-}
-
-sub razor_revoke {
- my ($self, $fulltext) = @_;
-
- return $self->razor_report($fulltext, 1);
-}
-
sub dcc_report {
my ($self, $fulltext) = @_;
my $timeout=$self->{conf}->{dcc_timeout};
@@ -504,9 +367,6 @@
}
sub is_pyzor_available {
Mail::SpamAssassin::PerMsgStatus::is_pyzor_available(@_);
-}
-sub is_razor_available {
- Mail::SpamAssassin::PerMsgStatus::is_razor2_available(@_);
}
sub is_spamcop_available {
my ($self) = @_;
Modified: spamassassin/trunk/spamassassin.raw
==============================================================================
--- spamassassin/trunk/spamassassin.raw (original)
+++ spamassassin/trunk/spamassassin.raw Fri Nov 12 18:01:35 2004
@@ -405,11 +405,11 @@
$mail->finish();
my $failed;
- if ( $opt{'report'} && $spamtest->report_as_spam($new_mail) ) {
+ if ( $opt{'report'} && !$spamtest->report_as_spam($new_mail) ) {
$failed = 'report';
}
- if ( $opt{'revoke'} && $spamtest->revoke_as_spam($new_mail) ) {
+ if ( $opt{'revoke'} && !$spamtest->revoke_as_spam($new_mail) ) {
$failed = 'revoke';
}