sub check_reputation()

in lib/Mail/SpamAssassin/Plugin/TxRep.pm [1480:1623]


sub check_reputation {
###########################################################################
  my ($self, $storage, $pms, $key, $id, $ip, $signedby, $msgscore) = @_;

  my $delta  = 0;
  my $weight = ($key eq 'MSG_ID') ? 1 : $self->{conf}->{'txrep_weight_'.lc($key)};

#  {
#    #Bug 7164, trying to find out reason for these: _WARN: Use of uninitialized value $msgscore in addition (+) at /usr/share/perl5/vendor_perl/Mail/SpamAssassin/Plugin/TxRep.pm line 1415.
#    no warnings;
#
#    unless (defined $msgscore) {
#      #Output some params and the calling function so we can identify more about this bug
#      dbg("TxRep: MsgScore Undefined (bug 7164) - check_reputation Parameters: self: $self storage: $storage pms: $pms, key: $key, id: $id, ip: $ip, signedby: $signedby, msgscore: $msgscore");
#      dbg("TxRep: MsgScore Undefined (bug 7164) - weight: $weight");
#
#      my ($package, $filename, $line) = caller();
#
#      chomp($package);
#      chomp($filename);
#      chomp($line);
#
#      dbg("TxRep: MsgScore Undefined (bug 7164) - Caller Info: Package: $package - Filename: $filename - Line: $line");
#
#      #Define $msgscore as a triage to hide warnings while we find the root cause
#      #$msgscore = 0;
#    }
#  }


  if (defined $weight && $weight) {
    my $meanrep;
    my $timer = $self->{main}->time_method('check_txrep_'.lc($key));

    if (defined $storage) {
        $self->{checker} = $self->{$storage};
    }
    my $found  = $self->get_sender($id, $ip, $signedby);
    my $tag_id = (defined $storage)? uc($key.'_'.substr($storage,0,1)) : uc($key);
    # TEMPLATE TAGS should match [A-Z] in their name
    # and "_" must be avoided
    $tag_id =~ s/_//g;
    if (defined $found && ($self->count() > 0)) {
        $meanrep = $self->total() / $self->count();
    }
    if ($self->{learning} && defined $msgscore) {
        if (defined $meanrep) {
            # $msgscore<=>0 gives the sign of $msgscore
            $msgscore += ($msgscore<=>0) * abs($meanrep);
        }
        dbg("TxRep: reputation: %s, count: %d, learning: %s, $tag_id: %s",
            defined $meanrep? sprintf("%.3f",$meanrep) : 'none',
            $self->count()      || 0,
            $self->{learning}   || '',
            $id                 || 'none'
        );
    } else {
        $self->{totalweight} += $weight;
        if ($key eq 'MSG_ID' && ($self->count() > 0)) {
            $delta = $self->total() / $self->count();
	    $pms->set_tag('TXREP'.$tag_id,              sprintf("%2.1f", $delta));
        } elsif (defined $self->total()) {
            #Bug 7164 - $msgscore undefined
            # in some cases we can have negative number
            # even if both total and $msgscore are positive numbers
            my $deltacheck;
            my $skipmsgscore = 0;
            if(defined $msgscore) {
              $deltacheck = ($self->total() + $msgscore) / (1 + $self->count()) - $msgscore;
              if(($self->total() > 0) && ($msgscore > 0) && ($deltacheck < 0)) {
                $skipmsgscore = 1;
              } elsif(($self->total() < 0) && ($msgscore < 0) && ($deltacheck > 0)) {
                $skipmsgscore = 1;
              }
            }
            if($skipmsgscore) {
              dbg("TxRep: skipping msg score $msgscore when calculating delta");
            }
            if (defined $msgscore and not $skipmsgscore) {
              $delta = $deltacheck;
            } else {
              $delta = ($self->total()) / (1 + $self->count());
            }

            $pms->set_tag('TXREP'.$tag_id,             sprintf("%2.1f", $delta));
            if (defined $meanrep) {
                $pms->set_tag('TXREP'.$tag_id.'MEAN', sprintf("%2.1f", $meanrep));
            }
            $pms->set_tag('TXREP'.$tag_id.'COUNT',    sprintf("%2.1f", $self->count()));
            $pms->set_tag('TXREP'.$tag_id.'PRESCORE', sprintf("%2.1f", $pms->{score}));
        } else {
            $pms->set_tag('TXREP'.$tag_id.'UNKNOWN', 1);
        }
        dbg("TxRep: reputation: %s, count: %d, weight: %.1f, delta: %.3f, $tag_id: %s",
            defined $meanrep? sprintf("%.3f",$meanrep) : 'none',
            $self->count()      || 0,
            $weight             || 0,
            $delta              || 0,
            $id                 || 'none'
        );

        if ($self->{conf}->{txrep_report_details}
            && defined $id && defined $meanrep && $tag_id ne "MSGID") {

            my $log = sprintf("%s: %s",
                              $tag_id,
                              (defined $ip) ? $id."|".$self->ip_to_awl_key($ip) : $id
                );

            if ($self->{conf}->{txrep_report_details} == 2) {
                $log .= sprintf(", rep: %.2f, count: %d",
                                $meanrep,
                                $self->count() || 0
                    );
            }

            $pms->test_log($log, "TXREP");
            # dbg ("TxRep: test_log: $log");
        }

    }
    $timer = $self->{main}->time_method('update_txrep_'.lc($key));
    if (defined $msgscore) {
        if ($self->{forgetting}) {              # forgetting a message score
            $self->remove_score($msgscore);     # remove the given score and decrement the count
            if ($key eq 'MSG_ID') {             # remove the message ID score completely
                $self->{checker}->remove_entry($self->{entry});
            }
        } else {
            $self->add_score($msgscore);        # add the score and increment the count
            if ($self->{learning} && $key eq 'MSG_ID' && $self->count() eq 1) {
                $self->add_score($msgscore);    # increasing the count by 1 at a learned score (count=2)
            }                                   # it can be distinguished from a scanned score (count=1)
        }
    } elsif (defined $found && $self->{forgetting} && $key eq 'MSG_ID') {
        $self->{checker}->remove_entry($self->{entry}); #forgetting the message ID
    }
  }
  if (!defined $storage) {
    $self->{checker} = $self->{default_storage};
  }

  return ($weight || 0) * ($delta || 0);
}