You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@spamassassin.apache.org by Justin Mason <jm...@jmason.org> on 2006/01/04 02:06:31 UTC
Re: defining new rule types
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
"John Myers" writes:
> Justin Mason wrote:
> > Agreed that adding new rule types is *doable*, if not exactly intuitive.
> >
> >I've done it in the URIBL code, by simply adding eval rules on the fly,
> >and that seems to work OK. It'd be nice to have a more intuitive method,
> >though.
> >
> I just call PerMsgStatus::got_pattern_hit() from the plugin's
> parsed_metadata(). I suppose I'm missing the syntax checks and other
> minor things done by Conf::Parser::add_test().
>
> >>The one area that could
> >>use work is in providing the default score.
> >
> >how so? do you mean having a score of != 1.0, by default?
> >
> It appears that since my new type of rules never appear in
> $conf->{tests}, they never get assigned a default score.
aha. OK, the eval-rules trick works to avoid that issue. What you do
is...
1. Define the subroutine to parse the configuration settings for that new
rule type:
my @cmds = ();
push (@cmds, {
setting => 'mimeheader',
code => sub {
my ($self, $key, $value, $line) = @_;
[... parse the line of text]
[... see next step]
}
});
$conf->{parser}->register_commands(\@cmds);
2. In that config-parse callback, define and register an eval rule
*on the fly*, once the rule is parsed:
my $evalfn = "_mimeheader_eval_$rulename";
$evalfn =~ s/[^a-zA-Z0-9_]/_/gs;
$self->{parser}->add_test($rulename, $evalfn."()",
$Mail::SpamAssassin::Conf::TYPE_BODY_EVALS);
my $evalcode = '
sub Mail::SpamAssassin::Plugin::MIMEHeader::'.$evalfn.' {
$_[0]->eval_hook_called($_[1], q{'.$rulename.'});
}
';
eval $evalcode;
if ($@) {
warn "mimeheader: plugin error: $@";
return $Mail::SpamAssassin::Conf::INVALID_VALUE;
}
$pluginobj->register_eval_rule($evalfn);
($Mail::SpamAssassin::Conf::TYPE_BODY_EVALS was chosen above, simply
because it's an eval type in an area of the message *similar* to what the
new rule type covers -- the body.)
3. In the plugin, define an eval_hook_called() method to deal with
implementing what the code does.
sub eval_hook_called {
my ($pobj, $scanner, $rulename) = @_;
my $rule = $scanner->{conf}->{mimeheader_tests}->{$rulename};
[... do stuff]
return $match ? 1 : 0;
}
Calling got_hit(), getting the right scores, etc. can then be left
to PerMsgStatus, as with a bundled rule.
This is based on lib/Mail/SpamAssassin/Plugin/MIMEHeader.pm ; take a look
at that for more.
> I do happen to need some of my newly defined tests to have a default
> score of 0. For example, suppose there are two lines in the .cf file
> using a new rule type "foo":
>
> foo BAR baz
> foo BAR quux
>
> If a message matches either condition "baz" or "quux" (or both) then it
> will fire the test BAR, which should have a default score of 1. In
> order to record the specific condition that caused BAR to be triggered,
> it will also fire FOO_baz if "foo" was matched and/or fire FOO_quux if
> "quux" was matched. These latter tests are not intended to be weighted,
> so should be assigned a default score of 0. It may be worthwhile to
> define a new prefix, e.g. "I_" for such informational tests.
sounds like a meta subrule: __FOO_baz. Or am I missing something?
- --j.
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.1 (GNU/Linux)
Comment: Exmh CVS
iD8DBQFDux+XMJF5cimLx9ARAkg+AJ9yIhrAbFhb7IwbFnZeopF00B2yYQCeOtoE
UxRdAB0xv+SqJYfcuFbSruE=
=SUbh
-----END PGP SIGNATURE-----
Re: defining new rule types
Posted by John Myers <jg...@proofpoint.com>.
Justin Mason wrote:
> 2. In that config-parse callback, define and register an eval rule
>
>*on the fly*, once the rule is parsed:
>
>
This isn't appropriate for my rule types. I don't want to iterate over
each possible rule definition, I want to do lookups in hash tables.
>sounds like a meta subrule: __FOO_baz. Or am I missing something?
>
>
Unlike subrules, I want the hit to be included in the list returned by
PerMsgStatus::get_names_of_tests_hit(). The whole purpose of FOO_baz is
to be visible, making diagnosis easier.