You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@spamassassin.apache.org by km...@apache.org on 2014/02/11 18:26:52 UTC

svn commit: r1567225 [8/15] - in /spamassassin/site/full/3.4.x: ./ doc/

Added: spamassassin/site/full/3.4.x/doc/Mail_SpamAssassin_Plugin.html
URL: http://svn.apache.org/viewvc/spamassassin/site/full/3.4.x/doc/Mail_SpamAssassin_Plugin.html?rev=1567225&view=auto
==============================================================================
--- spamassassin/site/full/3.4.x/doc/Mail_SpamAssassin_Plugin.html (added)
+++ spamassassin/site/full/3.4.x/doc/Mail_SpamAssassin_Plugin.html Tue Feb 11 17:26:49 2014
@@ -0,0 +1,1288 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<title>Mail::SpamAssassin::Plugin - SpamAssassin plugin base class</title>
+<link rev="made" href="mailto:root@twm2005-dev.thoughtworthy.com" />
+</head>
+
+<body style="background-color: white">
+
+<p><a name="__index__"></a></p>
+<!-- INDEX BEGIN -->
+
+<ul>
+
+	<li><a href="#name">NAME</a></li>
+	<li><a href="#synopsis">SYNOPSIS</a></li>
+	<ul>
+
+		<li><a href="#spamassassin_configuration_">SpamAssassin configuration:</a></li>
+		<li><a href="#perl_code_">Perl code:</a></li>
+	</ul>
+
+	<li><a href="#description">DESCRIPTION</a></li>
+	<li><a href="#interface">INTERFACE</a></li>
+	<li><a href="#methods">METHODS</a></li>
+	<li><a href="#helper_apis">HELPER APIS</a></li>
+	<li><a href="#logging">LOGGING</a></li>
+	<li><a href="#registering_eval_rules">REGISTERING EVAL RULES</a></li>
+	<li><a href="#standard_arguments_for_rule_types">STANDARD ARGUMENTS FOR RULE TYPES</a></li>
+	<li><a href="#backward_compatibility">BACKWARD COMPATIBILITY</a></li>
+	<li><a href="#see_also">SEE ALSO</a></li>
+</ul>
+<!-- INDEX END -->
+
+<hr />
+<p>
+</p>
+<h1><a name="name">NAME</a></h1>
+<p>Mail::SpamAssassin::Plugin - SpamAssassin plugin base class</p>
+<p>
+</p>
+<hr />
+<h1><a name="synopsis">SYNOPSIS</a></h1>
+<p>
+</p>
+<h2><a name="spamassassin_configuration_">SpamAssassin configuration:</a></h2>
+<pre>
+  loadplugin MyPlugin /path/to/myplugin.pm</pre>
+<p>
+</p>
+<h2><a name="perl_code_">Perl code:</a></h2>
+<pre>
+  package MyPlugin;</pre>
+<pre>
+  use Mail::SpamAssassin::Plugin;
+  our @ISA = qw(Mail::SpamAssassin::Plugin);</pre>
+<pre>
+  sub new {
+    my ($class, $mailsa) = @_;
+    
+    # the usual perlobj boilerplate to create a subclass object
+    $class = ref($class) || $class;
+    my $self = $class-&gt;SUPER::new($mailsa);
+    bless ($self, $class);
+   
+    # then register an eval rule, if desired...
+    $self-&gt;register_eval_rule (&quot;check_for_foo&quot;);</pre>
+<pre>
+    # and return the new plugin object
+    return $self;
+  }</pre>
+<pre>
+  ...methods...</pre>
+<pre>
+  1;</pre>
+<p>
+</p>
+<hr />
+<h1><a name="description">DESCRIPTION</a></h1>
+<p>This is the base class for SpamAssassin plugins; all plugins must be objects
+that implement this class.</p>
+<p>This class provides no-op stub methods for all the callbacks that a plugin
+can receive.  It is expected that your plugin will override one or more
+of these stubs to perform its actions.</p>
+<p>SpamAssassin implements a plugin chain; each callback event is passed to each
+of the registered plugin objects in turn.  Any plugin can call
+<a href="#item_inhibit_further_callbacks"><code>$self-&gt;inhibit_further_callbacks()</code></a> to block delivery of that event to
+later plugins in the chain.  This is useful if the plugin has handled the
+event, and there will be no need for later plugins to handle it as well.</p>
+<p>If you're looking to write a simple eval rule, skip straight to 
+<a href="#item_register_eval_rule"><code>register_eval_rule()</code></a>, below.</p>
+<p>
+</p>
+<hr />
+<h1><a name="interface">INTERFACE</a></h1>
+<p>In all the plugin APIs below, <code>options</code> refers to a reference to a hash
+containing name-value pairs.   This is used to ensure future-compatibility, in
+that we can add new options in future without affecting objects built to an
+earlier version of the API.</p>
+<p>For example, here would be how to print out the <a href="#item_line"><code>line</code></a> item in a
+<a href="#item_parse_config"><code>parse_config()</code></a> method:</p>
+<pre>
+  sub parse_config {
+    my ($self, $opts) = @_;
+    print &quot;MyPlugin: parse_config got &quot;.$opts-&gt;{line}.&quot;\n&quot;;
+  }</pre>
+<p>
+</p>
+<hr />
+<h1><a name="methods">METHODS</a></h1>
+<p>The following methods can be overridden by subclasses to handle events.</p>
+<dl>
+<dt><strong><a name="item_new">$plugin = MyPluginClass-&gt;new ($mailsaobject)</a></strong><br />
+</dt>
+<dd>
+Constructor.  Plugins that need to register themselves will need to
+define their own; the default super-class constructor will work fine
+for plugins that just override a method.
+</dd>
+<dd>
+<p>Note that subclasses must provide the <code>$mailsaobject</code> to the
+superclass constructor, like so:</p>
+</dd>
+<dd>
+<pre>
+  my $self = $class-&gt;SUPER::new($mailsaobject);</pre>
+</dd>
+<dd>
+<p>Lifecycle note: plugins that will need to store per-scan state should not store
+that on the Plugin object; instead this should be stored on the PerMsgStatus
+object, see <a href="#item_check_start"><code>check_start()</code></a> below.  It is also likewise recommended that
+configuration settings be stored on the Conf object; see <a href="#item_parse_config"><code>parse_config()</code></a>.</p>
+</dd>
+<p></p>
+<dt><strong><a name="item_parse_config">$plugin-&gt;parse_config ( { options ... } )</a></strong><br />
+</dt>
+<dd>
+Parse a configuration line that hasn't already been handled.  <code>options</code>
+is a reference to a hash containing these options:
+</dd>
+<dl>
+<dt><strong><a name="item_line">line</a></strong><br />
+</dt>
+<dd>
+The line of configuration text to parse.   This has leading and trailing
+whitespace, and comments, removed.
+</dd>
+<p></p>
+<dt><strong><a name="item_key">key</a></strong><br />
+</dt>
+<dd>
+The configuration key; ie. the first ``word'' on the line.
+</dd>
+<p></p>
+<dt><strong><a name="item_value">value</a></strong><br />
+</dt>
+<dd>
+The configuration value; everything after the first ``word'' and
+any whitespace after that.
+</dd>
+<p></p>
+<dt><strong><a name="item_conf">conf</a></strong><br />
+</dt>
+<dd>
+The <code>Mail::SpamAssassin::Conf</code> object on which the configuration
+data should be stored.
+</dd>
+<p></p>
+<dt><strong><a name="item_user_config">user_config</a></strong><br />
+</dt>
+<dd>
+A boolean: <code>1</code> if reading a user's configuration, <code>0</code> if reading the
+system-wide configuration files.
+</dd>
+<p></p></dl>
+<p>If the configuration line was a setting that is handled by this plugin, the
+method implementation should call <a href="#item_inhibit_further_callbacks"><code>$self-&gt;inhibit_further_callbacks()</code></a>.</p>
+<p>If the setting is not handled by this plugin, the method should return <code>0</code> so
+that a later plugin may handle it, or so that SpamAssassin can output a warning
+message to the user if no plugin understands it.</p>
+<p>Lifecycle note: it is suggested that configuration be stored on the
+<code>Mail::SpamAssassin::Conf</code> object in use, instead of the plugin object itself.
+That can be found as <code>$plugin-&gt;{main}-&gt;{conf}</code>, or as ``conf'' in the
+<code>$options</code> hash reference above.   By storing it on <a href="#item_conf"><code>conf</code></a>, this allows
+per-user and system-wide configuration precedence to be dealt with correctly.</p>
+<dt><strong><a name="item_finish_parsing_start">$plugin-&gt;finish_parsing_start ( { options ... } )</a></strong><br />
+</dt>
+<dd>
+Signals that the system-wide configuration has been completely read,
+but internal data structures are not yet created. It is possible to
+use this hook to dynamically change the configuration already read in
+or add new config options.
+</dd>
+<dd>
+<p><code>options</code> is a reference to a hash containing these options:</p>
+</dd>
+<dl>
+<dt><strong>conf</strong><br />
+</dt>
+<dd>
+The <code>Mail::SpamAssassin::Conf</code> object on which the configuration
+data should be stored.
+</dd>
+<p></p></dl>
+<p>Note: there are no guarantees that the internal data structures of
+SpamAssassin will not change from release to release.  In particular to
+this plugin hook, if you modify the rules data structures in a
+third-party plugin, all bets are off until such time that an API is
+present for modifying that configuration data.</p>
+<dt><strong><a name="item_finish_parsing_end">$plugin-&gt;finish_parsing_end ( { options ... } )</a></strong><br />
+</dt>
+<dd>
+Signals that the system-wide configuration parsing has just finished, and
+SpamAssassin is nearly ready to check messages.
+</dd>
+<dd>
+<p><code>options</code> is a reference to a hash containing these options:</p>
+</dd>
+<dl>
+<dt><strong>conf</strong><br />
+</dt>
+<dd>
+The <code>Mail::SpamAssassin::Conf</code> object on which the configuration
+data should be stored.
+</dd>
+<p></p></dl>
+<p>Note: there are no guarantees that the internal data structures of
+SpamAssassin will not change from release to release.  In particular to
+this plugin hook, if you modify the rules data structures in a
+third-party plugin, all bets are off until such time that an API is
+present for modifying that configuration data.</p>
+<dt><strong><a name="item_user_conf_parsing_start">$plugin-&gt;user_conf_parsing_start ( { options ... } )</a></strong><br />
+</dt>
+<dd>
+Signals that the per-user configuration has been completely read, but
+not converted to internal data structures. It is possible to use this
+hook to dynamically change the configuration already read in or add
+new config options.
+</dd>
+<dd>
+<p>If <code>allow_user_rules</code> is enabled in the configuration, it is possible
+that additional rules have been added since the <a href="#item_finish_parsing_start"><code>finish_parsing_start</code></a>
+plugin hook invocation was called.</p>
+</dd>
+<dl>
+<dt><strong>conf</strong><br />
+</dt>
+<dd>
+The <code>Mail::SpamAssassin::Conf</code> object on which the configuration
+data should be stored.
+</dd>
+<p></p></dl>
+<p>Note: there are no guarantees that the internal data structures of
+SpamAssassin will not change from release to release.  In particular to
+this plugin hook, if you modify the rules data structures in a
+third-party plugin, all bets are off until such time that an API is
+present for modifying that configuration data.</p>
+<dt><strong><a name="item_user_conf_parsing_end">$plugin-&gt;user_conf_parsing_end ( { options ... } )</a></strong><br />
+</dt>
+<dd>
+Signals that the per-user configuration parsing has just finished, and
+SpamAssassin is nearly ready to check messages.   If <code>allow_user_rules</code> is
+enabled in the configuration, it is possible that additional rules have been
+added since the <a href="#item_finish_parsing_end"><code>finish_parsing_end</code></a> plugin hook invocation was called.
+</dd>
+<dd>
+<p><code>options</code> is a reference to a hash containing these options:</p>
+</dd>
+<dl>
+<dt><strong>conf</strong><br />
+</dt>
+<dd>
+The <code>Mail::SpamAssassin::Conf</code> object on which the configuration
+data should be stored.
+</dd>
+<p></p></dl>
+<p>Note: there are no guarantees that the internal data structures of
+SpamAssassin will not change from release to release.  In particular to
+this plugin hook, if you modify the rules data structures in a
+third-party plugin, all bets are off until such time that an API is
+present for modifying that configuration data.</p>
+<dt><strong><a name="item_signal_user_changed">$plugin-&gt;signal_user_changed ( { options ... } )</a></strong><br />
+</dt>
+<dd>
+Signals that the current user has changed for a new one.
+</dd>
+<dl>
+<dt><strong><a name="item_username">username</a></strong><br />
+</dt>
+<dd>
+The new user's username.
+</dd>
+<p></p>
+<dt><strong><a name="item_user_dir">user_dir</a></strong><br />
+</dt>
+<dd>
+The new user's home directory. (equivalent to <code>~</code>.)
+</dd>
+<p></p>
+<dt><strong><a name="item_userstate_dir">userstate_dir</a></strong><br />
+</dt>
+<dd>
+The new user's storage directory. (equivalent to <code>~/.spamassassin</code>.)
+</dd>
+<p></p></dl>
+<dt><strong><a name="item_services_authorized_for_username">$plugin-&gt;services_authorized_for_username ( { options ... } )</a></strong><br />
+</dt>
+<dd>
+Validates that a given username is authorized to use certain services.
+</dd>
+<dd>
+<p>In order to authorize a user, the plugin should first check that it can
+handle any of the services passed into the method and then set the value
+for each allowed service to true (or any non-negative value).</p>
+</dd>
+<dd>
+<p>The current supported services are: bayessql</p>
+</dd>
+<dl>
+<dt><strong>username</strong><br />
+</dt>
+<dd>
+A username
+</dd>
+<p></p>
+<dt><strong><a name="item_services">services</a></strong><br />
+</dt>
+<dd>
+Reference to a hash containing the services you want to check.
+</dd>
+<dd>
+<p>{</p>
+</dd>
+<dd>
+<pre>
+  'bayessql' =&gt; 0</pre>
+</dd>
+<dd>
+<p>}</p>
+</dd>
+<p></p>
+<dt><strong>conf</strong><br />
+</dt>
+<dd>
+The <code>Mail::SpamAssassin::Conf</code> object on which the configuration
+data should be stored.
+</dd>
+<p></p></dl>
+<dt><strong><a name="item_compile_now_start">$plugin-&gt;compile_now_start ( { options ... } )</a></strong><br />
+</dt>
+<dd>
+This is called at the beginning of Mail::SpamAssassin::compile_now() so
+plugins can do any necessary initialization for multi-process
+SpamAssassin (such as spamd or mass-check -j).
+</dd>
+<dl>
+<dt><strong><a name="item_use_user_prefs">use_user_prefs</a></strong><br />
+</dt>
+<dd>
+The value of $use_user_prefs option in compile_now().
+</dd>
+<p></p>
+<dt><strong><a name="item_keep_userstate">keep_userstate</a></strong><br />
+</dt>
+<dd>
+The value of $keep_userstate option in compile_now().
+</dd>
+<p></p></dl>
+<dt><strong><a name="item_compile_now_finish">$plugin-&gt;compile_now_finish ( { options ... } )</a></strong><br />
+</dt>
+<dd>
+This is called at the end of Mail::SpamAssassin::compile_now() so
+plugins can do any necessary initialization for multi-process
+SpamAssassin (such as spamd or mass-check -j).
+</dd>
+<dl>
+<dt><strong>use_user_prefs</strong><br />
+</dt>
+<dd>
+The value of $use_user_prefs option in compile_now().
+</dd>
+<p></p>
+<dt><strong>keep_userstate</strong><br />
+</dt>
+<dd>
+The value of $keep_userstate option in compile_now().
+</dd>
+<p></p></dl>
+<dt><strong><a name="item_check_start">$plugin-&gt;check_start ( { options ... } )</a></strong><br />
+</dt>
+<dd>
+Signals that a message check operation is starting.
+</dd>
+<dl>
+<dt><strong><a name="item_permsgstatus">permsgstatus</a></strong><br />
+</dt>
+<dd>
+The <code>Mail::SpamAssassin::PerMsgStatus</code> context object for this scan.
+</dd>
+<dd>
+<p>Lifecycle note: it is recommended that rules that need to track test state on a
+per-scan basis should store that state on this object, not on the plugin object
+itself, since the plugin object will be shared between all active scanners.</p>
+</dd>
+<dd>
+<p>The message being scanned is accessible through the
+<code>$permsgstatus-&gt;get_message()</code> API; there are a number of other public
+APIs on that object, too.  See <code>Mail::SpamAssassin::PerMsgStatus</code> perldoc.</p>
+</dd>
+<p></p></dl>
+<dt><strong><a name="item_check_main">$plugin-&gt;check_main ( { options ... } )</a></strong><br />
+</dt>
+<dd>
+Signals that a message should be checked.  Note that implementations of
+this hook should return <code>1</code>.
+</dd>
+<dl>
+<dt><strong>permsgstatus</strong><br />
+</dt>
+<dd>
+The <code>Mail::SpamAssassin::PerMsgStatus</code> context object for this scan.
+</dd>
+<p></p></dl>
+<dt><strong><a name="item_check_tick">$plugin-&gt;check_tick ( { options ... } )</a></strong><br />
+</dt>
+<dd>
+Called periodically during a message check operation.  A callback set for
+this method is a good place to run through an event loop dealing with
+network events triggered in a <code>parse_metadata</code> method, for example.
+</dd>
+<dl>
+<dt><strong>permsgstatus</strong><br />
+</dt>
+<dd>
+The <code>Mail::SpamAssassin::PerMsgStatus</code> context object for this scan.
+</dd>
+<p></p></dl>
+<dt><strong><a name="item_check_post_dnsbl">$plugin-&gt;check_post_dnsbl ( { options ... } )</a></strong><br />
+</dt>
+<dd>
+Called after the DNSBL results have been harvested.  This is a good
+place to harvest your own asynchronously-started network lookups.
+</dd>
+<dl>
+<dt><strong>permsgstatus</strong><br />
+</dt>
+<dd>
+The <code>Mail::SpamAssassin::PerMsgStatus</code> context object for this scan.
+</dd>
+<p></p></dl>
+<dt><strong><a name="item_check_post_learn">$plugin-&gt;check_post_learn ( { options ... } )</a></strong><br />
+</dt>
+<dd>
+Called after auto-learning may (or may not) have taken place.  If you
+wish to perform additional learning, whether or not auto-learning
+happens, this is the place to do it.
+</dd>
+<dl>
+<dt><strong>permsgstatus</strong><br />
+</dt>
+<dd>
+The <code>Mail::SpamAssassin::PerMsgStatus</code> context object for this scan.
+</dd>
+<p></p></dl>
+<dt><strong><a name="item_check_end">$plugin-&gt;check_end ( { options ... } )</a></strong><br />
+</dt>
+<dd>
+Signals that a message check operation has just finished, and the
+results are about to be returned to the caller.
+</dd>
+<dl>
+<dt><strong>permsgstatus</strong><br />
+</dt>
+<dd>
+The <code>Mail::SpamAssassin::PerMsgStatus</code> context object for this scan.
+The current score, names of rules that hit, etc. can be retrieved
+using the public APIs on this object.
+</dd>
+<p></p></dl>
+<dt><strong><a name="item_finish_tests">$plugin-&gt;finish_tests ( { options ... } )</a></strong><br />
+</dt>
+<dd>
+Called via <code>Mail::SpamAssassin::finish</code>.  This should clear up any tests that
+a plugin has added to the namespace.
+</dd>
+<dd>
+<p>In certain circumstances, plugins may find it useful to compile
+perl functions from the ruleset, on the fly.  It is important to
+remove these once the <code>Mail::SpamAssassin</code> object is deleted,
+however, and this API allows this.</p>
+</dd>
+<dd>
+<p>Each plugin is responsible for its own generated perl functions.</p>
+</dd>
+<dl>
+<dt><strong>conf</strong><br />
+</dt>
+<dd>
+The <code>Mail::SpamAssassin::Conf</code> object on which the configuration
+data should be stored.
+</dd>
+<p></p></dl>
+<p>See also the <a href="#item_register_generated_rule_method"><code>register_generated_rule_method</code></a> helper API, below.</p>
+<dt><strong><a name="item_extract_metadata">$plugin-&gt;extract_metadata ( { options ... } )</a></strong><br />
+</dt>
+<dd>
+Signals that a message is being mined for metadata.  Some plugins may wish
+to add their own metadata as well.
+</dd>
+<dl>
+<dt><strong><a name="item_msg">msg</a></strong><br />
+</dt>
+<dd>
+The <code>Mail::SpamAssassin::Message</code> object for this message.
+</dd>
+<p></p>
+<dt><strong>permsgstatus</strong><br />
+</dt>
+<dd>
+The <code>Mail::SpamAssassin::PerMsgStatus</code> context object for this scan.
+</dd>
+<p></p></dl>
+<dt><strong><a name="item_parsed_metadata">$plugin-&gt;parsed_metadata ( { options ... } )</a></strong><br />
+</dt>
+<dd>
+Signals that a message's metadata has been parsed, and can now be
+accessed by the plugin.
+</dd>
+<dl>
+<dt><strong>permsgstatus</strong><br />
+</dt>
+<dd>
+The <code>Mail::SpamAssassin::PerMsgStatus</code> context object for this scan.
+</dd>
+<p></p></dl>
+<dt><strong><a name="item_start_rules">$plugin-&gt;start_rules ( { options ... } )</a></strong><br />
+</dt>
+<dd>
+Called before testing a set of rules of a given type and priority.
+</dd>
+<dl>
+<dt><strong>permsgstatus</strong><br />
+</dt>
+<dd>
+The <code>Mail::SpamAssassin::PerMsgStatus</code> context object for this scan.
+</dd>
+<p></p>
+<dt><strong><a name="item_ruletype">ruletype</a></strong><br />
+</dt>
+<dd>
+The type of the rules about to be performed.
+</dd>
+<p></p>
+<dt><strong><a name="item_priority">priority</a></strong><br />
+</dt>
+<dd>
+The priority level of the rules about to be performed.
+</dd>
+<p></p></dl>
+<dt><strong><a name="item_hit_rule">$plugin-&gt;hit_rule ( { options ... } )</a></strong><br />
+</dt>
+<dd>
+Called when a rule fires.
+</dd>
+<dl>
+<dt><strong>permsgstatus</strong><br />
+</dt>
+<dd>
+The <code>Mail::SpamAssassin::PerMsgStatus</code> context object for this scan.
+</dd>
+<p></p>
+<dt><strong>ruletype</strong><br />
+</dt>
+<dd>
+The type of the rule that fired.
+</dd>
+<p></p>
+<dt><strong><a name="item_rulename">rulename</a></strong><br />
+</dt>
+<dd>
+The name of the rule that fired.
+</dd>
+<p></p>
+<dt><strong><a name="item_score">score</a></strong><br />
+</dt>
+<dd>
+The rule's score in the active scoreset.
+</dd>
+<p></p></dl>
+<dt><strong><a name="item_ran_rule">$plugin-&gt;ran_rule ( { options ... } )</a></strong><br />
+</dt>
+<dd>
+Called after a rule has been tested, whether or not it fired.  When the
+rule fires, the hit_rule callback is always called before this.
+</dd>
+<dl>
+<dt><strong>permsgstatus</strong><br />
+</dt>
+<dd>
+The <code>Mail::SpamAssassin::PerMsgStatus</code> context object for this scan.
+</dd>
+<p></p>
+<dt><strong>ruletype</strong><br />
+</dt>
+<dd>
+The type of the rule that was tested.
+</dd>
+<p></p>
+<dt><strong>rulename</strong><br />
+</dt>
+<dd>
+The name of the rule that was tested.
+</dd>
+<p></p></dl>
+<dt><strong><a name="item_autolearn_discriminator">$plugin-&gt;autolearn_discriminator ( { options ... } )</a></strong><br />
+</dt>
+<dd>
+Control whether a just-scanned message should be learned as either
+spam or ham.   This method should return one of <code>1</code> to learn
+the message as spam, <code>0</code> to learn as ham, or <code>undef</code> to not
+learn from the message at all.
+</dd>
+<dl>
+<dt><strong>permsgstatus</strong><br />
+</dt>
+<dd>
+The <code>Mail::SpamAssassin::PerMsgStatus</code> context object for this scan.
+</dd>
+<p></p></dl>
+<dt><strong><a name="item_autolearn">$plugin-&gt;autolearn ( { options ... } )</a></strong><br />
+</dt>
+<dd>
+Signals that a message is about to be auto-learned as either ham or spam.
+</dd>
+<dl>
+<dt><strong>permsgstatus</strong><br />
+</dt>
+<dd>
+The <code>Mail::SpamAssassin::PerMsgStatus</code> context object for this scan.
+</dd>
+<p></p>
+<dt><strong><a name="item_isspam">isspam</a></strong><br />
+</dt>
+<dd>
+<code>1</code> if the message is spam, <code>0</code> if ham.
+</dd>
+<p></p></dl>
+<dt><strong><a name="item_per_msg_finish">$plugin-&gt;per_msg_finish ( { options ... } )</a></strong><br />
+</dt>
+<dd>
+Signals that a <code>Mail::SpamAssassin::PerMsgStatus</code> object is being
+destroyed, and any per-scan context held on that object by this
+plugin should be destroyed as well.
+</dd>
+<dd>
+<p>Normally, any member variables on the <code>PerMsgStatus</code> object will be cleaned up
+automatically -- but if your plugin has made a circular reference on that
+object, this is the place to break them so that garbage collection can operate
+correctly.</p>
+</dd>
+<dl>
+<dt><strong>permsgstatus</strong><br />
+</dt>
+<dd>
+The <code>Mail::SpamAssassin::PerMsgStatus</code> context object for this scan.
+</dd>
+<p></p></dl>
+<dt><strong><a name="item_have_shortcircuited">$plugin-&gt;have_shortcircuited ( { options ... } )</a></strong><br />
+</dt>
+<dd>
+Has the current scan operation 'short-circuited'?  In other words, can
+further scanning be skipped, since the message is already definitively
+classified as either spam or ham?
+</dd>
+<dd>
+<p>Plugins should return <code>0</code> to indicate that scanning should continue,
+or <code>1</code> to indicate that short-circuiting has taken effect.</p>
+</dd>
+<dl>
+<dt><strong>permsgstatus</strong><br />
+</dt>
+<dd>
+The <code>Mail::SpamAssassin::PerMsgStatus</code> context object for this scan.
+</dd>
+<p></p></dl>
+<dt><strong><a name="item_bayes_learn">$plugin-&gt;bayes_learn ( { options ... } )</a></strong><br />
+</dt>
+<dd>
+Called at the end of a bayes learn operation.
+</dd>
+<dd>
+<p>This phase is the best place to map the raw (original) token value
+to the SHA1 hashed value.</p>
+</dd>
+<dl>
+<dt><strong><a name="item_toksref">toksref</a></strong><br />
+</dt>
+<dd>
+Reference to hash returned by call to tokenize.  The hash takes the
+format of:
+</dd>
+<dd>
+<pre>
+  {
+    'SHA1 Hash Value' =&gt; 'raw (original) value',
+    ...
+  }</pre>
+</dd>
+<dd>
+<p>NOTE: This data structure has changed since it was originally introduced
+in version 3.0.0.  The values are no longer perl anonymous hashes, they
+are a single string containing the raw token value.  You can test for
+backward compatibility by checking to see if the value for a key is a
+reference to a perl HASH, for instance:</p>
+</dd>
+<dd>
+<p>if (ref($toksref-&gt;{$sometokenkey}) eq 'HASH') {...</p>
+</dd>
+<dd>
+<p>If it is, then you are using the old interface, otherwise you are using
+the current interface.</p>
+</dd>
+<p></p>
+<dt><strong>isspam</strong><br />
+</dt>
+<dd>
+Boolean value stating what flavor of message the tokens represent, if
+true then message was specified as spam, false is nonspam.  Note, when
+function is scan then isspam value is not valid.
+</dd>
+<p></p>
+<dt><strong><a name="item_msgid">msgid</a></strong><br />
+</dt>
+<dd>
+Generated message id of the message just learned.
+</dd>
+<p></p>
+<dt><strong><a name="item_msgatime">msgatime</a></strong><br />
+</dt>
+<dd>
+Received date of the current message or current time if received date
+could not be determined.  In addition, if the receive date is more than
+24 hrs into the future it will be reset to current datetime.
+</dd>
+<p></p></dl>
+<dt><strong><a name="item_bayes_forget">$plugin-&gt;bayes_forget ( { options ... } )</a></strong><br />
+</dt>
+<dd>
+Called at the end of a bayes forget operation.
+</dd>
+<dl>
+<dt><strong>toksref</strong><br />
+</dt>
+<dd>
+Reference to hash returned by call to tokenize.  See bayes_learn
+documentation for additional information on the format.
+</dd>
+<p></p>
+<dt><strong>isspam</strong><br />
+</dt>
+<dd>
+Boolean value stating what flavor of message the tokens represent, if
+true then message was specified as spam, false is nonspam.  Note, when
+function is scan then isspam value is not valid.
+</dd>
+<p></p>
+<dt><strong>msgid</strong><br />
+</dt>
+<dd>
+Generated message id of the message just forgotten.
+</dd>
+<p></p></dl>
+<dt><strong><a name="item_bayes_scan">$plugin-&gt;bayes_scan ( { options ... } )</a></strong><br />
+</dt>
+<dd>
+Called at the end of a bayes scan operation.  NOTE: Will not be
+called in case of error or if the message is otherwise skipped.
+</dd>
+<dl>
+<dt><strong>toksref</strong><br />
+</dt>
+<dd>
+Reference to hash returned by call to tokenize.  See bayes_learn
+documentation for additional information on the format.
+</dd>
+<p></p>
+<dt><strong><a name="item_probsref">probsref</a></strong><br />
+</dt>
+<dd>
+Reference to hash of calculated probabilities for tokens found in
+the database.
+</dd>
+<dd>
+<pre>
+  {
+    'SHA1 Hash Value' =&gt; {
+            'prob' =&gt; 'calculated probability',
+            'spam_count' =&gt; 'Total number of spam msgs w/ token',
+            'ham_count' =&gt; 'Total number of ham msgs w/ token',
+            'atime' =&gt; 'Atime value for token in database'
+          }
+  }</pre>
+</dd>
+<p></p>
+<dt><strong>score</strong><br />
+</dt>
+<dd>
+Score calculated for this particular message.
+</dd>
+<p></p>
+<dt><strong>msgatime</strong><br />
+</dt>
+<dd>
+Calculated atime of the message just learned, note it may have been adjusted
+if it was determined to be too far into the future.
+</dd>
+<p></p>
+<dt><strong><a name="item_significant_tokens">significant_tokens</a></strong><br />
+</dt>
+<dd>
+Array ref of the tokens found to be significant in determining the score for
+this message.
+</dd>
+<p></p></dl>
+<dt><strong><a name="item_plugin_report">$plugin-&gt;plugin_report ( { options ... } )</a></strong><br />
+</dt>
+<dd>
+Called if the message is to be reported as spam.  If the reporting system is
+available, the variable <code>$options-&gt;{report}-&gt;report_available}</code> should
+be set to <code>1</code>; if the reporting system successfully reported the message, the
+variable <code>$options-&gt;{report}-&gt;report_return}</code> should be set to <code>1</code>.
+</dd>
+<dl>
+<dt><strong><a name="item_report">report</a></strong><br />
+</dt>
+<dd>
+Reference to the Reporter object (<code>$options-&gt;{report}</code> in the
+paragraph above.)
+</dd>
+<p></p>
+<dt><strong><a name="item_text">text</a></strong><br />
+</dt>
+<dd>
+Reference to a markup removed copy of the message in scalar string format.
+</dd>
+<p></p>
+<dt><strong>msg</strong><br />
+</dt>
+<dd>
+Reference to the original message object.
+</dd>
+<p></p></dl>
+<dt><strong><a name="item_plugin_revoke">$plugin-&gt;plugin_revoke ( { options ... } )</a></strong><br />
+</dt>
+<dd>
+Called if the message is to be reported as ham (revokes a spam report). If the
+reporting system is available, the variable
+<code>$options-&gt;{revoke}-&gt;revoke_available}</code> should be set to <code>1</code>; if the
+reporting system successfully revoked the message, the variable
+<code>$options-&gt;{revoke}-&gt;revoke_return}</code> should be set to <code>1</code>.
+</dd>
+<dl>
+<dt><strong><a name="item_revoke">revoke</a></strong><br />
+</dt>
+<dd>
+Reference to the Reporter object (<code>$options-&gt;{revoke}</code> in the
+paragraph above.)
+</dd>
+<p></p>
+<dt><strong>text</strong><br />
+</dt>
+<dd>
+Reference to a markup removed copy of the message in scalar string format.
+</dd>
+<p></p>
+<dt><strong>msg</strong><br />
+</dt>
+<dd>
+Reference to the original message object.
+</dd>
+<p></p></dl>
+<dt><strong><a name="item_whitelist_address">$plugin-&gt;whitelist_address( { options ... } )</a></strong><br />
+</dt>
+<dd>
+Called when a request is made to add an address to a
+persistent address list.
+</dd>
+<dl>
+<dt><strong><a name="item_address">address</a></strong><br />
+</dt>
+<dd>
+Address you wish to add.
+</dd>
+<p></p>
+<dt><strong><a name="item_cli_p">cli_p</a></strong><br />
+</dt>
+<dd>
+Indicate if the call is being made from a command line interface.
+</dd>
+<p></p></dl>
+<dt><strong><a name="item_blacklist_address">$plugin-&gt;blacklist_address( { options ... } )</a></strong><br />
+</dt>
+<dd>
+Called when a request is made to add an address to a
+persistent address list.
+</dd>
+<dl>
+<dt><strong>address</strong><br />
+</dt>
+<dd>
+Address you wish to add.
+</dd>
+<p></p>
+<dt><strong>cli_p</strong><br />
+</dt>
+<dd>
+Indicate if the call is being made from a command line interface.
+</dd>
+<p></p></dl>
+<dt><strong><a name="item_remove_address">$plugin-&gt;remove_address( { options ... } )</a></strong><br />
+</dt>
+<dd>
+Called when a request is made to remove an address to a
+persistent address list.
+</dd>
+<dl>
+<dt><strong>address</strong><br />
+</dt>
+<dd>
+Address you wish to remove.
+</dd>
+<p></p>
+<dt><strong>cli_p</strong><br />
+</dt>
+<dd>
+Indicate if the call is being made from a command line interface.
+</dd>
+<p></p></dl>
+<dt><strong><a name="item_spamd_child_init">$plugin-&gt;spamd_child_init ()</a></strong><br />
+</dt>
+<dd>
+Called in each new child process when it starts up under spamd.
+</dd>
+<p></p>
+<dt><strong><a name="item_log_scan_result">$plugin-&gt;log_scan_result ( { options ... } )</a></strong><br />
+</dt>
+<dd>
+Called when spamd has completed scanning a message.  Currently,
+only spamd calls this API.
+</dd>
+<dl>
+<dt><strong><a name="item_result">result</a></strong><br />
+</dt>
+<dd>
+The <code>'result: ...'</code> line for this scan.  Format is as described
+at <strong><a href="http://wiki.apache.org/spamassassin/SpamdSyslogFormat">http://wiki.apache.org/spamassassin/SpamdSyslogFormat</a></strong>.
+</dd>
+<p></p></dl>
+<dt><strong><a name="item_spamd_child_post_connection_close">$plugin-&gt;spamd_child_post_connection_close ()</a></strong><br />
+</dt>
+<dd>
+Called when child returns from handling a connection.
+</dd>
+<dd>
+<p>If there was an accept failure, the child will die and this code will
+not be called.</p>
+</dd>
+<p></p>
+<dt><strong><a name="item_finish">$plugin-&gt;finish ()</a></strong><br />
+</dt>
+<dd>
+Called when the <code>Mail::SpamAssassin</code> object is destroyed.
+</dd>
+<p></p>
+<dt><strong><a name="item_learner_new">$plugin-&gt;learner_new ()</a></strong><br />
+</dt>
+<dd>
+Used to support human-trained probabilistic classifiers like the BAYES_* ruleset.
+Called when a new <code>Mail::SpamAssassin::Bayes</code> object has been created; typically
+when a new user's scan is about to start.
+</dd>
+<p></p>
+<dt><strong><a name="item_learn_message">$plugin-&gt;learn_message ()</a></strong><br />
+</dt>
+<dd>
+Train the classifier with a training message.
+</dd>
+<dl>
+<dt><strong>isspam</strong><br />
+</dt>
+<dd>
+1 if the message is spam, 0 if it's non-spam.
+</dd>
+<p></p>
+<dt><strong>msg</strong><br />
+</dt>
+<dd>
+The message's <code>Mail::SpamAssassin::Message</code> object.
+</dd>
+<p></p>
+<dt><strong><a name="item_id">id</a></strong><br />
+</dt>
+<dd>
+An optional message-identification string, used internally to tag the message.
+If it is <code>undef</code>, one will be generated.  It should be unique to that message.
+</dd>
+<p></p></dl>
+<dt><strong><a name="item_forget_message">$plugin-&gt;forget_message ()</a></strong><br />
+</dt>
+<dd>
+Tell the classifier to 'forget' its training about a specific message.
+</dd>
+<dl>
+<dt><strong>msg</strong><br />
+</dt>
+<dd>
+The message's <code>Mail::SpamAssassin::Message</code> object.
+</dd>
+<p></p>
+<dt><strong>id</strong><br />
+</dt>
+<dd>
+An optional message-identification string, used internally to tag the message.
+If it is <code>undef</code>, one will be generated.  It should be unique to that message.
+</dd>
+<p></p></dl>
+<dt><strong><a name="item_learner_sync">$plugin-&gt;learner_sync ()</a></strong><br />
+</dt>
+<dd>
+Tell the classifier to 'sync' any pending changes against the current 
+user's training database.  This is called by <code>sa-learn --sync</code>.
+</dd>
+<dd>
+<p>If you do not need to implement these for your classifier, create an
+implementation that just contains <code>return 1</code>.</p>
+</dd>
+<p></p>
+<dt><strong><a name="item_learner_expire_old_training">$plugin-&gt;learner_expire_old_training ()</a></strong><br />
+</dt>
+<dd>
+Tell the classifier to perform infrequent, time-consuming cleanup of
+the current user's training database.  This is called by <code>sa-learn
+--force-expire</code>.
+</dd>
+<dd>
+<p>If you do not need to implement these for your classifier, create an
+implementation that just contains <code>return 1</code>.</p>
+</dd>
+<p></p>
+<dt><strong><a name="item_learner_is_scan_available">$plugin-&gt;learner_is_scan_available ()</a></strong><br />
+</dt>
+<dd>
+Should return 1 if it is possible to use the current user's training data for
+a message-scan operation, or 0 otherwise.
+</dd>
+<p></p>
+<dt><strong><a name="item_learner_dump_database">$plugin-&gt;learner_dump_database ()</a></strong><br />
+</dt>
+<dd>
+Dump information about the current user's training data to <code>stdout</code>.
+This is called by <code>sa-learn --dump</code>.
+</dd>
+<dl>
+<dt><strong><a name="item_magic">magic</a></strong><br />
+</dt>
+<dd>
+Set to 1 if ``magic'' name-value metadata should be dumped.
+</dd>
+<p></p>
+<dt><strong><a name="item_toks">toks</a></strong><br />
+</dt>
+<dd>
+Set to 1 if the database of tokens should be dumped.
+</dd>
+<p></p>
+<dt><strong><a name="item_regex">regex</a></strong><br />
+</dt>
+<dd>
+Either <code>undef</code> to dump all tokens, or a value which specifies a regular expression
+subset of the tokens to dump.
+</dd>
+<p></p></dl>
+<dt><strong><a name="item_learner_close">$plugin-&gt;learner_close ()</a></strong><br />
+</dt>
+<dd>
+Close any open databases.
+</dd>
+<dl>
+<dt><strong><a name="item_quiet">quiet</a></strong><br />
+</dt>
+<dd>
+Set to 1 if warning messages should be suppressed.
+</dd>
+<p></p></dl>
+</dl>
+<p>
+</p>
+<hr />
+<h1><a name="helper_apis">HELPER APIS</a></h1>
+<p>These methods provide an API for plugins to register themselves
+to receive specific events, or control the callback chain behaviour.</p>
+<dl>
+<dt><strong><a name="item_register_eval_rule">$plugin-&gt;register_eval_rule ($nameofevalsub)</a></strong><br />
+</dt>
+<dd>
+Plugins that implement an eval test will need to call this, so that
+SpamAssassin calls into the object when that eval test is encountered.
+See the <strong>REGISTERING EVAL RULES</strong> section for full details.
+</dd>
+<p></p>
+<dt><strong><a name="item_register_generated_rule_method">$plugin-&gt;register_generated_rule_method ($nameofsub)</a></strong><br />
+</dt>
+<dd>
+In certain circumstances, plugins may find it useful to compile
+perl functions from the ruleset, on the fly.  It is important to
+remove these once the <code>Mail::SpamAssassin</code> object is deleted,
+however, and this API allows this.
+</dd>
+<dd>
+<p>Once the method <code>$nameofsub</code> has been generated, call this API
+with the name of the method (including full package scope).
+This indicates that it's a temporary piece of generated code,
+built from the SpamAssassin ruleset, and when 
+<a href="#item_finish"><code>Mail::SpamAssassin::finish()</code></a> is called, the method will
+be destroyed.</p>
+</dd>
+<dd>
+<p>This API was added in SpamAssassin 3.2.0.</p>
+</dd>
+<p></p>
+<dt><strong><a name="item_register_method_priority">$plugin-&gt;register_method_priority($methodname, $priority)</a></strong><br />
+</dt>
+<dd>
+Indicate that the method named <code>$methodname</code> on the current object
+has a callback priority of <code>$priority</code>.
+</dd>
+<dd>
+<p>This is used by the plugin handler to determine the relative order of
+callbacks; plugins with lower-numbered priorities are called before plugins
+with higher-numbered priorities.  Each method can have a different priority
+value.  The default value is <code>0</code>.  The ordering of callbacks to methods with
+equal priority is undefined.</p>
+</dd>
+<dd>
+<p>Typically, you only need to worry about this if you need to ensure your
+plugin's method is called before another plugin's implementation of that
+method.  It should be called from your plugin's constructor.</p>
+</dd>
+<dd>
+<p>This API was added in SpamAssassin 3.2.0.</p>
+</dd>
+<p></p>
+<dt><strong><a name="item_inhibit_further_callbacks">$plugin-&gt;<code>inhibit_further_callbacks()</code></a></strong><br />
+</dt>
+<dd>
+Tells the plugin handler to inhibit calling into other plugins in the plugin
+chain for the current callback.  Frequently used when parsing configuration
+settings using <a href="#item_parse_config"><code>parse_config()</code></a>.
+</dd>
+<p></p></dl>
+<p>
+</p>
+<hr />
+<h1><a name="logging">LOGGING</a></h1>
+<dl>
+<dt><strong><a name="item_dbg">Mail::SpamAssassin::Plugin::dbg($message)</a></strong><br />
+</dt>
+<dd>
+Output a debugging message <code>$message</code>, if the SpamAssassin object is running
+with debugging turned on.
+</dd>
+<dd>
+<p><em>NOTE:</em> This function is not available in the package namespace
+of general plugins and can't be called via $self-&gt;dbg().  If a
+plugin wishes to output debug information, it should call
+<a href="#item_dbg"><code>Mail::SpamAssassin::Plugin::dbg($msg)</code></a>.</p>
+</dd>
+<p></p>
+<dt><strong><a name="item_info">Mail::SpamAssassin::Plugin::info($message)</a></strong><br />
+</dt>
+<dd>
+Output an informational message <code>$message</code>, if the SpamAssassin object
+is running with informational messages turned on.
+</dd>
+<dd>
+<p><em>NOTE:</em> This function is not available in the package namespace
+of general plugins and can't be called via $self-&gt;info().  If a
+plugin wishes to output debug information, it should call
+<a href="#item_info"><code>Mail::SpamAssassin::Plugin::info($msg)</code></a>.</p>
+</dd>
+<dd>
+<p>In general, it is better for plugins to use the <code>Mail::SpamAssassin::Logger</code>
+module to import <a href="#item_dbg"><code>dbg</code></a> and <a href="#item_info"><code>info</code></a> directly, like so:</p>
+</dd>
+<dd>
+<pre>
+  use Mail::SpamAssassin::Logger;
+  dbg(&quot;some message&quot;);
+  info(&quot;some other message&quot;);</pre>
+</dd>
+<p></p></dl>
+<p>
+</p>
+<hr />
+<h1><a name="registering_eval_rules">REGISTERING EVAL RULES</a></h1>
+<p>Plugins that implement an eval test must register the methods that can be
+called from rules in the configuration files, in the plugin class' constructor.</p>
+<p>For example,</p>
+<pre>
+  $plugin-&gt;register_eval_rule ('check_for_foo')</pre>
+<p>will cause <code>$plugin-&gt;check_for_foo()</code> to be called for this
+SpamAssassin rule:</p>
+<pre>
+  header   FOO_RULE     eval:check_for_foo()</pre>
+<p>Note that eval rules are passed the following arguments:</p>
+<dl>
+<dt><strong><a name="item__2d_the_plugin_object_itself">- The plugin object itself</a></strong><br />
+</dt>
+<dt><strong><a name="item__2d_the_mail_3a_3aspamassassin_3a_3apermsgstatus_o">- The <code>Mail::SpamAssassin::PerMsgStatus</code> object calling the rule</a></strong><br />
+</dt>
+<dt><strong><a name="item__2d_standard_arguments_for_the_rule_type_in_use">- standard arguments for the rule type in use</a></strong><br />
+</dt>
+<dt><strong><a name="item__2d_any_and_all_arguments_as_specified_in_the_conf">- any and all arguments as specified in the configuration file</a></strong><br />
+</dt>
+</dl>
+<p>In other words, the eval test method should look something like this:</p>
+<pre>
+  sub check_for_foo {
+    my ($self, $permsgstatus, ...arguments...) = @_;
+    ...code returning 0 or 1
+  }</pre>
+<p>Note that the headers can be accessed using the <code>get()</code> method on the
+<code>Mail::SpamAssassin::PerMsgStatus</code> object, and the body by
+<code>get_decoded_stripped_body_text_array()</code> and other similar methods.
+Similarly, the <code>Mail::SpamAssassin::Conf</code> object holding the current
+configuration may be accessed through <code>$permsgstatus-&gt;{main}-&gt;{conf}</code>.</p>
+<p>The eval rule should return <code>1</code> for a hit, or <code>0</code> if the rule
+is not hit.</p>
+<p>State for a single message being scanned should be stored on the <code>$permsgstatus</code>
+object, not on the <code>$self</code> object, since <code>$self</code> persists between scan
+operations.  See the 'lifecycle note' on the <a href="#item_check_start"><code>check_start()</code></a> method above.</p>
+<p>
+</p>
+<hr />
+<h1><a name="standard_arguments_for_rule_types">STANDARD ARGUMENTS FOR RULE TYPES</a></h1>
+<p>Plugins will be called with the same arguments as a standard EvalTest.
+Different rule types receive different information by default:</p>
+<dl>
+<dt><strong><a name="item__2d_header_tests_3a_no_extra_arguments">- header tests: no extra arguments</a></strong><br />
+</dt>
+<dt><strong><a name="item__2d_body_tests_3a_fully_rendered_message_as_array_">- body tests: fully rendered message as array reference</a></strong><br />
+</dt>
+<dt><strong><a name="item__2d_rawbody_tests_3a_fully_decoded_message_as_arra">- rawbody tests: fully decoded message as array reference</a></strong><br />
+</dt>
+<dt><strong><a name="item__2d_full_tests_3a_pristine_message_as_scalar_refer">- full tests: pristine message as scalar reference</a></strong><br />
+</dt>
+</dl>
+<p>The configuration file arguments will be passed in after the standard
+arguments.</p>
+<p>
+</p>
+<hr />
+<h1><a name="backward_compatibility">BACKWARD COMPATIBILITY</a></h1>
+<p>Note that if you write a plugin and need to determine if a particular
+helper method is supported on <code>Mail::SpamAssassin::Plugin</code>, you
+can do this:</p>
+<pre>
+    if ($self-&gt;can(&quot;name_of_method&quot;)) {
+      eval {
+        $self-&gt;name_of_method();        # etc.
+      }
+    } else {
+      # take fallback action
+    }</pre>
+<p>The same applies for the public APIs on objects of other types, such as
+<code>Mail::SpamAssassin::PerMsgStatus</code>.</p>
+<p>
+</p>
+<hr />
+<h1><a name="see_also">SEE ALSO</a></h1>
+<p><code>Mail::SpamAssassin</code></p>
+<p><code>Mail::SpamAssassin::PerMsgStatus</code></p>
+<p><a href="http://wiki.apache.org/spamassassin/PluginWritingTips">http://wiki.apache.org/spamassassin/PluginWritingTips</a></p>
+<p><a href="http://issues.apache.org/SpamAssassin/show_bug.cgi?id=2163">http://issues.apache.org/SpamAssassin/show_bug.cgi?id=2163</a></p>
+
+</body>
+
+</html>

Added: spamassassin/site/full/3.4.x/doc/Mail_SpamAssassin_Plugin.txt
URL: http://svn.apache.org/viewvc/spamassassin/site/full/3.4.x/doc/Mail_SpamAssassin_Plugin.txt?rev=1567225&view=auto
==============================================================================
--- spamassassin/site/full/3.4.x/doc/Mail_SpamAssassin_Plugin.txt (added)
+++ spamassassin/site/full/3.4.x/doc/Mail_SpamAssassin_Plugin.txt Tue Feb 11 17:26:49 2014
@@ -0,0 +1,838 @@
+NAME
+    Mail::SpamAssassin::Plugin - SpamAssassin plugin base class
+
+SYNOPSIS
+  SpamAssassin configuration:
+      loadplugin MyPlugin /path/to/myplugin.pm
+
+  Perl code:
+      package MyPlugin;
+
+      use Mail::SpamAssassin::Plugin;
+      our @ISA = qw(Mail::SpamAssassin::Plugin);
+
+      sub new {
+        my ($class, $mailsa) = @_;
+    
+        # the usual perlobj boilerplate to create a subclass object
+        $class = ref($class) || $class;
+        my $self = $class->SUPER::new($mailsa);
+        bless ($self, $class);
+   
+        # then register an eval rule, if desired...
+        $self->register_eval_rule ("check_for_foo");
+
+        # and return the new plugin object
+        return $self;
+      }
+
+      ...methods...
+
+      1;
+
+DESCRIPTION
+    This is the base class for SpamAssassin plugins; all plugins must be
+    objects that implement this class.
+
+    This class provides no-op stub methods for all the callbacks that a
+    plugin can receive. It is expected that your plugin will override one or
+    more of these stubs to perform its actions.
+
+    SpamAssassin implements a plugin chain; each callback event is passed to
+    each of the registered plugin objects in turn. Any plugin can call
+    "$self->inhibit_further_callbacks()" to block delivery of that event to
+    later plugins in the chain. This is useful if the plugin has handled the
+    event, and there will be no need for later plugins to handle it as well.
+
+    If you're looking to write a simple eval rule, skip straight to
+    "register_eval_rule()", below.
+
+INTERFACE
+    In all the plugin APIs below, "options" refers to a reference to a hash
+    containing name-value pairs. This is used to ensure
+    future-compatibility, in that we can add new options in future without
+    affecting objects built to an earlier version of the API.
+
+    For example, here would be how to print out the "line" item in a
+    "parse_config()" method:
+
+      sub parse_config {
+        my ($self, $opts) = @_;
+        print "MyPlugin: parse_config got ".$opts->{line}."\n";
+      }
+
+METHODS
+    The following methods can be overridden by subclasses to handle events.
+
+    $plugin = MyPluginClass->new ($mailsaobject)
+        Constructor. Plugins that need to register themselves will need to
+        define their own; the default super-class constructor will work fine
+        for plugins that just override a method.
+
+        Note that subclasses must provide the $mailsaobject to the
+        superclass constructor, like so:
+
+          my $self = $class->SUPER::new($mailsaobject);
+
+        Lifecycle note: plugins that will need to store per-scan state
+        should not store that on the Plugin object; instead this should be
+        stored on the PerMsgStatus object, see "check_start()" below. It is
+        also likewise recommended that configuration settings be stored on
+        the Conf object; see "parse_config()".
+
+    $plugin->parse_config ( { options ... } )
+        Parse a configuration line that hasn't already been handled.
+        "options" is a reference to a hash containing these options:
+
+        line
+            The line of configuration text to parse. This has leading and
+            trailing whitespace, and comments, removed.
+
+        key The configuration key; ie. the first "word" on the line.
+
+        value
+            The configuration value; everything after the first "word" and
+            any whitespace after that.
+
+        conf
+            The "Mail::SpamAssassin::Conf" object on which the configuration
+            data should be stored.
+
+        user_config
+            A boolean: 1 if reading a user's configuration, 0 if reading the
+            system-wide configuration files.
+
+        If the configuration line was a setting that is handled by this
+        plugin, the method implementation should call
+        "$self->inhibit_further_callbacks()".
+
+        If the setting is not handled by this plugin, the method should
+        return 0 so that a later plugin may handle it, or so that
+        SpamAssassin can output a warning message to the user if no plugin
+        understands it.
+
+        Lifecycle note: it is suggested that configuration be stored on the
+        "Mail::SpamAssassin::Conf" object in use, instead of the plugin
+        object itself. That can be found as "$plugin->{main}->{conf}", or as
+        "conf" in the $options hash reference above. By storing it on
+        "conf", this allows per-user and system-wide configuration
+        precedence to be dealt with correctly.
+
+    $plugin->finish_parsing_start ( { options ... } )
+        Signals that the system-wide configuration has been completely read,
+        but internal data structures are not yet created. It is possible to
+        use this hook to dynamically change the configuration already read
+        in or add new config options.
+
+        "options" is a reference to a hash containing these options:
+
+        conf
+            The "Mail::SpamAssassin::Conf" object on which the configuration
+            data should be stored.
+
+        Note: there are no guarantees that the internal data structures of
+        SpamAssassin will not change from release to release. In particular
+        to this plugin hook, if you modify the rules data structures in a
+        third-party plugin, all bets are off until such time that an API is
+        present for modifying that configuration data.
+
+    $plugin->finish_parsing_end ( { options ... } )
+        Signals that the system-wide configuration parsing has just
+        finished, and SpamAssassin is nearly ready to check messages.
+
+        "options" is a reference to a hash containing these options:
+
+        conf
+            The "Mail::SpamAssassin::Conf" object on which the configuration
+            data should be stored.
+
+        Note: there are no guarantees that the internal data structures of
+        SpamAssassin will not change from release to release. In particular
+        to this plugin hook, if you modify the rules data structures in a
+        third-party plugin, all bets are off until such time that an API is
+        present for modifying that configuration data.
+
+    $plugin->user_conf_parsing_start ( { options ... } )
+        Signals that the per-user configuration has been completely read,
+        but not converted to internal data structures. It is possible to use
+        this hook to dynamically change the configuration already read in or
+        add new config options.
+
+        If "allow_user_rules" is enabled in the configuration, it is
+        possible that additional rules have been added since the
+        "finish_parsing_start" plugin hook invocation was called.
+
+        conf
+            The "Mail::SpamAssassin::Conf" object on which the configuration
+            data should be stored.
+
+        Note: there are no guarantees that the internal data structures of
+        SpamAssassin will not change from release to release. In particular
+        to this plugin hook, if you modify the rules data structures in a
+        third-party plugin, all bets are off until such time that an API is
+        present for modifying that configuration data.
+
+    $plugin->user_conf_parsing_end ( { options ... } )
+        Signals that the per-user configuration parsing has just finished,
+        and SpamAssassin is nearly ready to check messages. If
+        "allow_user_rules" is enabled in the configuration, it is possible
+        that additional rules have been added since the "finish_parsing_end"
+        plugin hook invocation was called.
+
+        "options" is a reference to a hash containing these options:
+
+        conf
+            The "Mail::SpamAssassin::Conf" object on which the configuration
+            data should be stored.
+
+        Note: there are no guarantees that the internal data structures of
+        SpamAssassin will not change from release to release. In particular
+        to this plugin hook, if you modify the rules data structures in a
+        third-party plugin, all bets are off until such time that an API is
+        present for modifying that configuration data.
+
+    $plugin->signal_user_changed ( { options ... } )
+        Signals that the current user has changed for a new one.
+
+        username
+            The new user's username.
+
+        user_dir
+            The new user's home directory. (equivalent to "~".)
+
+        userstate_dir
+            The new user's storage directory. (equivalent to
+            "~/.spamassassin".)
+
+    $plugin->services_authorized_for_username ( { options ... } )
+        Validates that a given username is authorized to use certain
+        services.
+
+        In order to authorize a user, the plugin should first check that it
+        can handle any of the services passed into the method and then set
+        the value for each allowed service to true (or any non-negative
+        value).
+
+        The current supported services are: bayessql
+
+        username
+            A username
+
+        services
+            Reference to a hash containing the services you want to check.
+
+            {
+
+              'bayessql' => 0
+
+            }
+
+        conf
+            The "Mail::SpamAssassin::Conf" object on which the configuration
+            data should be stored.
+
+    $plugin->compile_now_start ( { options ... } )
+        This is called at the beginning of Mail::SpamAssassin::compile_now()
+        so plugins can do any necessary initialization for multi-process
+        SpamAssassin (such as spamd or mass-check -j).
+
+        use_user_prefs
+            The value of $use_user_prefs option in compile_now().
+
+        keep_userstate
+            The value of $keep_userstate option in compile_now().
+
+    $plugin->compile_now_finish ( { options ... } )
+        This is called at the end of Mail::SpamAssassin::compile_now() so
+        plugins can do any necessary initialization for multi-process
+        SpamAssassin (such as spamd or mass-check -j).
+
+        use_user_prefs
+            The value of $use_user_prefs option in compile_now().
+
+        keep_userstate
+            The value of $keep_userstate option in compile_now().
+
+    $plugin->check_start ( { options ... } )
+        Signals that a message check operation is starting.
+
+        permsgstatus
+            The "Mail::SpamAssassin::PerMsgStatus" context object for this
+            scan.
+
+            Lifecycle note: it is recommended that rules that need to track
+            test state on a per-scan basis should store that state on this
+            object, not on the plugin object itself, since the plugin object
+            will be shared between all active scanners.
+
+            The message being scanned is accessible through the
+            "$permsgstatus->get_message()" API; there are a number of other
+            public APIs on that object, too. See
+            "Mail::SpamAssassin::PerMsgStatus" perldoc.
+
+    $plugin->check_main ( { options ... } )
+        Signals that a message should be checked. Note that implementations
+        of this hook should return 1.
+
+        permsgstatus
+            The "Mail::SpamAssassin::PerMsgStatus" context object for this
+            scan.
+
+    $plugin->check_tick ( { options ... } )
+        Called periodically during a message check operation. A callback set
+        for this method is a good place to run through an event loop dealing
+        with network events triggered in a "parse_metadata" method, for
+        example.
+
+        permsgstatus
+            The "Mail::SpamAssassin::PerMsgStatus" context object for this
+            scan.
+
+    $plugin->check_post_dnsbl ( { options ... } )
+        Called after the DNSBL results have been harvested. This is a good
+        place to harvest your own asynchronously-started network lookups.
+
+        permsgstatus
+            The "Mail::SpamAssassin::PerMsgStatus" context object for this
+            scan.
+
+    $plugin->check_post_learn ( { options ... } )
+        Called after auto-learning may (or may not) have taken place. If you
+        wish to perform additional learning, whether or not auto-learning
+        happens, this is the place to do it.
+
+        permsgstatus
+            The "Mail::SpamAssassin::PerMsgStatus" context object for this
+            scan.
+
+    $plugin->check_end ( { options ... } )
+        Signals that a message check operation has just finished, and the
+        results are about to be returned to the caller.
+
+        permsgstatus
+            The "Mail::SpamAssassin::PerMsgStatus" context object for this
+            scan. The current score, names of rules that hit, etc. can be
+            retrieved using the public APIs on this object.
+
+    $plugin->finish_tests ( { options ... } )
+        Called via "Mail::SpamAssassin::finish". This should clear up any
+        tests that a plugin has added to the namespace.
+
+        In certain circumstances, plugins may find it useful to compile perl
+        functions from the ruleset, on the fly. It is important to remove
+        these once the "Mail::SpamAssassin" object is deleted, however, and
+        this API allows this.
+
+        Each plugin is responsible for its own generated perl functions.
+
+        conf
+            The "Mail::SpamAssassin::Conf" object on which the configuration
+            data should be stored.
+
+        See also the "register_generated_rule_method" helper API, below.
+
+    $plugin->extract_metadata ( { options ... } )
+        Signals that a message is being mined for metadata. Some plugins may
+        wish to add their own metadata as well.
+
+        msg The "Mail::SpamAssassin::Message" object for this message.
+
+        permsgstatus
+            The "Mail::SpamAssassin::PerMsgStatus" context object for this
+            scan.
+
+    $plugin->parsed_metadata ( { options ... } )
+        Signals that a message's metadata has been parsed, and can now be
+        accessed by the plugin.
+
+        permsgstatus
+            The "Mail::SpamAssassin::PerMsgStatus" context object for this
+            scan.
+
+    $plugin->start_rules ( { options ... } )
+        Called before testing a set of rules of a given type and priority.
+
+        permsgstatus
+            The "Mail::SpamAssassin::PerMsgStatus" context object for this
+            scan.
+
+        ruletype
+            The type of the rules about to be performed.
+
+        priority
+            The priority level of the rules about to be performed.
+
+    $plugin->hit_rule ( { options ... } )
+        Called when a rule fires.
+
+        permsgstatus
+            The "Mail::SpamAssassin::PerMsgStatus" context object for this
+            scan.
+
+        ruletype
+            The type of the rule that fired.
+
+        rulename
+            The name of the rule that fired.
+
+        score
+            The rule's score in the active scoreset.
+
+    $plugin->ran_rule ( { options ... } )
+        Called after a rule has been tested, whether or not it fired. When
+        the rule fires, the hit_rule callback is always called before this.
+
+        permsgstatus
+            The "Mail::SpamAssassin::PerMsgStatus" context object for this
+            scan.
+
+        ruletype
+            The type of the rule that was tested.
+
+        rulename
+            The name of the rule that was tested.
+
+    $plugin->autolearn_discriminator ( { options ... } )
+        Control whether a just-scanned message should be learned as either
+        spam or ham. This method should return one of 1 to learn the message
+        as spam, 0 to learn as ham, or "undef" to not learn from the message
+        at all.
+
+        permsgstatus
+            The "Mail::SpamAssassin::PerMsgStatus" context object for this
+            scan.
+
+    $plugin->autolearn ( { options ... } )
+        Signals that a message is about to be auto-learned as either ham or
+        spam.
+
+        permsgstatus
+            The "Mail::SpamAssassin::PerMsgStatus" context object for this
+            scan.
+
+        isspam
+            1 if the message is spam, 0 if ham.
+
+    $plugin->per_msg_finish ( { options ... } )
+        Signals that a "Mail::SpamAssassin::PerMsgStatus" object is being
+        destroyed, and any per-scan context held on that object by this
+        plugin should be destroyed as well.
+
+        Normally, any member variables on the "PerMsgStatus" object will be
+        cleaned up automatically -- but if your plugin has made a circular
+        reference on that object, this is the place to break them so that
+        garbage collection can operate correctly.
+
+        permsgstatus
+            The "Mail::SpamAssassin::PerMsgStatus" context object for this
+            scan.
+
+    $plugin->have_shortcircuited ( { options ... } )
+        Has the current scan operation 'short-circuited'? In other words,
+        can further scanning be skipped, since the message is already
+        definitively classified as either spam or ham?
+
+        Plugins should return 0 to indicate that scanning should continue,
+        or 1 to indicate that short-circuiting has taken effect.
+
+        permsgstatus
+            The "Mail::SpamAssassin::PerMsgStatus" context object for this
+            scan.
+
+    $plugin->bayes_learn ( { options ... } )
+        Called at the end of a bayes learn operation.
+
+        This phase is the best place to map the raw (original) token value
+        to the SHA1 hashed value.
+
+        toksref
+            Reference to hash returned by call to tokenize. The hash takes
+            the format of:
+
+              {
+                'SHA1 Hash Value' => 'raw (original) value',
+                ...
+              }
+
+            NOTE: This data structure has changed since it was originally
+            introduced in version 3.0.0. The values are no longer perl
+            anonymous hashes, they are a single string containing the raw
+            token value. You can test for backward compatibility by checking
+            to see if the value for a key is a reference to a perl HASH, for
+            instance:
+
+            if (ref($toksref->{$sometokenkey}) eq 'HASH') {...
+
+            If it is, then you are using the old interface, otherwise you
+            are using the current interface.
+
+        isspam
+            Boolean value stating what flavor of message the tokens
+            represent, if true then message was specified as spam, false is
+            nonspam. Note, when function is scan then isspam value is not
+            valid.
+
+        msgid
+            Generated message id of the message just learned.
+
+        msgatime
+            Received date of the current message or current time if received
+            date could not be determined. In addition, if the receive date
+            is more than 24 hrs into the future it will be reset to current
+            datetime.
+
+    $plugin->bayes_forget ( { options ... } )
+        Called at the end of a bayes forget operation.
+
+        toksref
+            Reference to hash returned by call to tokenize. See bayes_learn
+            documentation for additional information on the format.
+
+        isspam
+            Boolean value stating what flavor of message the tokens
+            represent, if true then message was specified as spam, false is
+            nonspam. Note, when function is scan then isspam value is not
+            valid.
+
+        msgid
+            Generated message id of the message just forgotten.
+
+    $plugin->bayes_scan ( { options ... } )
+        Called at the end of a bayes scan operation. NOTE: Will not be
+        called in case of error or if the message is otherwise skipped.
+
+        toksref
+            Reference to hash returned by call to tokenize. See bayes_learn
+            documentation for additional information on the format.
+
+        probsref
+            Reference to hash of calculated probabilities for tokens found
+            in the database.
+
+              {
+                'SHA1 Hash Value' => {
+                        'prob' => 'calculated probability',
+                        'spam_count' => 'Total number of spam msgs w/ token',
+                        'ham_count' => 'Total number of ham msgs w/ token',
+                        'atime' => 'Atime value for token in database'
+                      }
+              }
+
+        score
+            Score calculated for this particular message.
+
+        msgatime
+            Calculated atime of the message just learned, note it may have
+            been adjusted if it was determined to be too far into the
+            future.
+
+        significant_tokens
+            Array ref of the tokens found to be significant in determining
+            the score for this message.
+
+    $plugin->plugin_report ( { options ... } )
+        Called if the message is to be reported as spam. If the reporting
+        system is available, the variable
+        "$options->{report}->report_available}" should be set to 1; if the
+        reporting system successfully reported the message, the variable
+        "$options->{report}->report_return}" should be set to 1.
+
+        report
+            Reference to the Reporter object ("$options->{report}" in the
+            paragraph above.)
+
+        text
+            Reference to a markup removed copy of the message in scalar
+            string format.
+
+        msg Reference to the original message object.
+
+    $plugin->plugin_revoke ( { options ... } )
+        Called if the message is to be reported as ham (revokes a spam
+        report). If the reporting system is available, the variable
+        "$options->{revoke}->revoke_available}" should be set to 1; if the
+        reporting system successfully revoked the message, the variable
+        "$options->{revoke}->revoke_return}" should be set to 1.
+
+        revoke
+            Reference to the Reporter object ("$options->{revoke}" in the
+            paragraph above.)
+
+        text
+            Reference to a markup removed copy of the message in scalar
+            string format.
+
+        msg Reference to the original message object.
+
+    $plugin->whitelist_address( { options ... } )
+        Called when a request is made to add an address to a persistent
+        address list.
+
+        address
+            Address you wish to add.
+
+        cli_p
+            Indicate if the call is being made from a command line
+            interface.
+
+    $plugin->blacklist_address( { options ... } )
+        Called when a request is made to add an address to a persistent
+        address list.
+
+        address
+            Address you wish to add.
+
+        cli_p
+            Indicate if the call is being made from a command line
+            interface.
+
+    $plugin->remove_address( { options ... } )
+        Called when a request is made to remove an address to a persistent
+        address list.
+
+        address
+            Address you wish to remove.
+
+        cli_p
+            Indicate if the call is being made from a command line
+            interface.
+
+    $plugin->spamd_child_init ()
+        Called in each new child process when it starts up under spamd.
+
+    $plugin->log_scan_result ( { options ... } )
+        Called when spamd has completed scanning a message. Currently, only
+        spamd calls this API.
+
+        result
+            The 'result: ...' line for this scan. Format is as described at
+            http://wiki.apache.org/spamassassin/SpamdSyslogFormat.
+
+    $plugin->spamd_child_post_connection_close ()
+        Called when child returns from handling a connection.
+
+        If there was an accept failure, the child will die and this code
+        will not be called.
+
+    $plugin->finish ()
+        Called when the "Mail::SpamAssassin" object is destroyed.
+
+    $plugin->learner_new ()
+        Used to support human-trained probabilistic classifiers like the
+        BAYES_* ruleset. Called when a new "Mail::SpamAssassin::Bayes"
+        object has been created; typically when a new user's scan is about
+        to start.
+
+    $plugin->learn_message ()
+        Train the classifier with a training message.
+
+        isspam
+            1 if the message is spam, 0 if it's non-spam.
+
+        msg The message's "Mail::SpamAssassin::Message" object.
+
+        id  An optional message-identification string, used internally to
+            tag the message. If it is "undef", one will be generated. It
+            should be unique to that message.
+
+    $plugin->forget_message ()
+        Tell the classifier to 'forget' its training about a specific
+        message.
+
+        msg The message's "Mail::SpamAssassin::Message" object.
+
+        id  An optional message-identification string, used internally to
+            tag the message. If it is "undef", one will be generated. It
+            should be unique to that message.
+
+    $plugin->learner_sync ()
+        Tell the classifier to 'sync' any pending changes against the
+        current user's training database. This is called by "sa-learn
+        --sync".
+
+        If you do not need to implement these for your classifier, create an
+        implementation that just contains "return 1".
+
+    $plugin->learner_expire_old_training ()
+        Tell the classifier to perform infrequent, time-consuming cleanup of
+        the current user's training database. This is called by "sa-learn
+        --force-expire".
+
+        If you do not need to implement these for your classifier, create an
+        implementation that just contains "return 1".
+
+    $plugin->learner_is_scan_available ()
+        Should return 1 if it is possible to use the current user's training
+        data for a message-scan operation, or 0 otherwise.
+
+    $plugin->learner_dump_database ()
+        Dump information about the current user's training data to "stdout".
+        This is called by "sa-learn --dump".
+
+        magic
+            Set to 1 if "magic" name-value metadata should be dumped.
+
+        toks
+            Set to 1 if the database of tokens should be dumped.
+
+        regex
+            Either "undef" to dump all tokens, or a value which specifies a
+            regular expression subset of the tokens to dump.
+
+    $plugin->learner_close ()
+        Close any open databases.
+
+        quiet
+            Set to 1 if warning messages should be suppressed.
+
+HELPER APIS
+    These methods provide an API for plugins to register themselves to
+    receive specific events, or control the callback chain behaviour.
+
+    $plugin->register_eval_rule ($nameofevalsub)
+        Plugins that implement an eval test will need to call this, so that
+        SpamAssassin calls into the object when that eval test is
+        encountered. See the REGISTERING EVAL RULES section for full
+        details.
+
+    $plugin->register_generated_rule_method ($nameofsub)
+        In certain circumstances, plugins may find it useful to compile perl
+        functions from the ruleset, on the fly. It is important to remove
+        these once the "Mail::SpamAssassin" object is deleted, however, and
+        this API allows this.
+
+        Once the method $nameofsub has been generated, call this API with
+        the name of the method (including full package scope). This
+        indicates that it's a temporary piece of generated code, built from
+        the SpamAssassin ruleset, and when "Mail::SpamAssassin::finish()" is
+        called, the method will be destroyed.
+
+        This API was added in SpamAssassin 3.2.0.
+
+    $plugin->register_method_priority($methodname, $priority)
+        Indicate that the method named $methodname on the current object has
+        a callback priority of $priority.
+
+        This is used by the plugin handler to determine the relative order
+        of callbacks; plugins with lower-numbered priorities are called
+        before plugins with higher-numbered priorities. Each method can have
+        a different priority value. The default value is 0. The ordering of
+        callbacks to methods with equal priority is undefined.
+
+        Typically, you only need to worry about this if you need to ensure
+        your plugin's method is called before another plugin's
+        implementation of that method. It should be called from your
+        plugin's constructor.
+
+        This API was added in SpamAssassin 3.2.0.
+
+    $plugin->inhibit_further_callbacks()
+        Tells the plugin handler to inhibit calling into other plugins in
+        the plugin chain for the current callback. Frequently used when
+        parsing configuration settings using "parse_config()".
+
+LOGGING
+    Mail::SpamAssassin::Plugin::dbg($message)
+        Output a debugging message $message, if the SpamAssassin object is
+        running with debugging turned on.
+
+        *NOTE:* This function is not available in the package namespace of
+        general plugins and can't be called via $self->dbg(). If a plugin
+        wishes to output debug information, it should call
+        "Mail::SpamAssassin::Plugin::dbg($msg)".
+
+    Mail::SpamAssassin::Plugin::info($message)
+        Output an informational message $message, if the SpamAssassin object
+        is running with informational messages turned on.
+
+        *NOTE:* This function is not available in the package namespace of
+        general plugins and can't be called via $self->info(). If a plugin
+        wishes to output debug information, it should call
+        "Mail::SpamAssassin::Plugin::info($msg)".
+
+        In general, it is better for plugins to use the
+        "Mail::SpamAssassin::Logger" module to import "dbg" and "info"
+        directly, like so:
+
+          use Mail::SpamAssassin::Logger;
+          dbg("some message");
+          info("some other message");
+
+REGISTERING EVAL RULES
+    Plugins that implement an eval test must register the methods that can
+    be called from rules in the configuration files, in the plugin class'
+    constructor.
+
+    For example,
+
+      $plugin->register_eval_rule ('check_for_foo')
+
+    will cause "$plugin->check_for_foo()" to be called for this SpamAssassin
+    rule:
+
+      header   FOO_RULE     eval:check_for_foo()
+
+    Note that eval rules are passed the following arguments:
+
+    - The plugin object itself
+    - The "Mail::SpamAssassin::PerMsgStatus" object calling the rule
+    - standard arguments for the rule type in use
+    - any and all arguments as specified in the configuration file
+
+    In other words, the eval test method should look something like this:
+
+      sub check_for_foo {
+        my ($self, $permsgstatus, ...arguments...) = @_;
+        ...code returning 0 or 1
+      }
+
+    Note that the headers can be accessed using the "get()" method on the
+    "Mail::SpamAssassin::PerMsgStatus" object, and the body by
+    "get_decoded_stripped_body_text_array()" and other similar methods.
+    Similarly, the "Mail::SpamAssassin::Conf" object holding the current
+    configuration may be accessed through "$permsgstatus->{main}->{conf}".
+
+    The eval rule should return 1 for a hit, or 0 if the rule is not hit.
+
+    State for a single message being scanned should be stored on the
+    $permsgstatus object, not on the $self object, since $self persists
+    between scan operations. See the 'lifecycle note' on the "check_start()"
+    method above.
+
+STANDARD ARGUMENTS FOR RULE TYPES
+    Plugins will be called with the same arguments as a standard EvalTest.
+    Different rule types receive different information by default:
+
+    - header tests: no extra arguments
+    - body tests: fully rendered message as array reference
+    - rawbody tests: fully decoded message as array reference
+    - full tests: pristine message as scalar reference
+
+    The configuration file arguments will be passed in after the standard
+    arguments.
+
+BACKWARD COMPATIBILITY
+    Note that if you write a plugin and need to determine if a particular
+    helper method is supported on "Mail::SpamAssassin::Plugin", you can do
+    this:
+
+        if ($self->can("name_of_method")) {
+          eval {
+            $self->name_of_method();        # etc.
+          }
+        } else {
+          # take fallback action
+        }
+
+    The same applies for the public APIs on objects of other types, such as
+    "Mail::SpamAssassin::PerMsgStatus".
+
+SEE ALSO
+    "Mail::SpamAssassin"
+
+    "Mail::SpamAssassin::PerMsgStatus"
+
+    http://wiki.apache.org/spamassassin/PluginWritingTips
+
+    http://issues.apache.org/SpamAssassin/show_bug.cgi?id=2163
+

Added: spamassassin/site/full/3.4.x/doc/Mail_SpamAssassin_PluginHandler.html
URL: http://svn.apache.org/viewvc/spamassassin/site/full/3.4.x/doc/Mail_SpamAssassin_PluginHandler.html?rev=1567225&view=auto
==============================================================================
--- spamassassin/site/full/3.4.x/doc/Mail_SpamAssassin_PluginHandler.html (added)
+++ spamassassin/site/full/3.4.x/doc/Mail_SpamAssassin_PluginHandler.html Tue Feb 11 17:26:49 2014
@@ -0,0 +1,27 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<title>Mail::SpamAssassin::PluginHandler - SpamAssassin plugin handler</title>
+<link rev="made" href="mailto:root@twm2005-dev.thoughtworthy.com" />
+</head>
+
+<body style="background-color: white">
+
+<p><a name="__index__"></a></p>
+<!-- INDEX BEGIN -->
+
+<ul>
+
+	<li><a href="#name">NAME</a></li>
+</ul>
+<!-- INDEX END -->
+
+<hr />
+<p>
+</p>
+<h1><a name="name">NAME</a></h1>
+<p>Mail::SpamAssassin::PluginHandler - SpamAssassin plugin handler</p>
+
+</body>
+
+</html>

Added: spamassassin/site/full/3.4.x/doc/Mail_SpamAssassin_PluginHandler.txt
URL: http://svn.apache.org/viewvc/spamassassin/site/full/3.4.x/doc/Mail_SpamAssassin_PluginHandler.txt?rev=1567225&view=auto
==============================================================================
--- spamassassin/site/full/3.4.x/doc/Mail_SpamAssassin_PluginHandler.txt (added)
+++ spamassassin/site/full/3.4.x/doc/Mail_SpamAssassin_PluginHandler.txt Tue Feb 11 17:26:49 2014
@@ -0,0 +1,3 @@
+NAME
+    Mail::SpamAssassin::PluginHandler - SpamAssassin plugin handler
+

Added: spamassassin/site/full/3.4.x/doc/Mail_SpamAssassin_Plugin_ASN.html
URL: http://svn.apache.org/viewvc/spamassassin/site/full/3.4.x/doc/Mail_SpamAssassin_Plugin_ASN.html?rev=1567225&view=auto
==============================================================================
--- spamassassin/site/full/3.4.x/doc/Mail_SpamAssassin_Plugin_ASN.html (added)
+++ spamassassin/site/full/3.4.x/doc/Mail_SpamAssassin_Plugin_ASN.html Tue Feb 11 17:26:49 2014
@@ -0,0 +1,160 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<title>Mail::SpamAssassin::Plugin::ASN - SpamAssassin plugin to look up the
+Autonomous System Number of the connecting IP address.</title>
+<link rev="made" href="mailto:root@twm2005-dev.thoughtworthy.com" />
+</head>
+
+<body style="background-color: white">
+
+<p><a name="__index__"></a></p>
+<!-- INDEX BEGIN -->
+
+<ul>
+
+	<li><a href="#name">NAME</a></li>
+	<li><a href="#synopsis">SYNOPSIS</a></li>
+	<li><a href="#description">DESCRIPTION</a></li>
+	<li><a href="#template_tags">TEMPLATE TAGS</a></li>
+	<li><a href="#configuration">CONFIGURATION</a></li>
+	<li><a href="#see_also">SEE ALSO</a></li>
+	<li><a href="#status">STATUS</a></li>
+	<li><a href="#administrator_settings">ADMINISTRATOR SETTINGS</a></li>
+</ul>
+<!-- INDEX END -->
+
+<hr />
+<p>
+</p>
+<h1><a name="name">NAME</a></h1>
+<p>Mail::SpamAssassin::Plugin::ASN - SpamAssassin plugin to look up the
+Autonomous System Number (ASN) of the connecting IP address.</p>
+<p>
+</p>
+<hr />
+<h1><a name="synopsis">SYNOPSIS</a></h1>
+<pre>
+ loadplugin Mail::SpamAssassin::Plugin::ASN</pre>
+<pre>
+ asn_lookup asn.routeviews.org _ASN_ _ASNCIDR_</pre>
+<pre>
+ add_header all ASN _ASN_ _ASNCIDR_</pre>
+<p>
+</p>
+<hr />
+<h1><a name="description">DESCRIPTION</a></h1>
+<p>This plugin uses DNS lookups to the services of an external DNS zone such
+as at <code>http://www.routeviews.org/</code> to do the actual work. Please make
+sure that your use of the plugin does not overload their infrastructure -
+this generally means that <strong>you should not use this plugin in a
+high-volume environment</strong> or that you should use a local mirror of the
+zone (see <code>ftp://ftp.routeviews.org/dnszones/</code>).  Other similar zones
+may also be used.</p>
+<p>
+</p>
+<hr />
+<h1><a name="template_tags">TEMPLATE TAGS</a></h1>
+<p>This plugin allows you to create template tags containing the connecting
+IP's AS number and route info for that AS number.</p>
+<p>The default config will add a header field that looks like this:</p>
+<pre>
+ X-Spam-ASN: AS24940 213.239.192.0/18</pre>
+<p>where ``24940'' is the ASN and ``213.239.192.0/18'' is the route
+announced by that ASN where the connecting IP address came from.
+If the AS announces multiple networks (more/less specific), they will
+all be added to the <code>_ASNCIDR_</code> tag, separated by spaces, eg:</p>
+<pre>
+ X-Spam-ASN: AS1680 89.138.0.0/15 89.139.0.0/16</pre>
+<p>Note that the literal ``AS'' before the ASN in the _ASN_ tag is configurable
+through the <em>asn_prefix</em> directive and may be set to an empty string.</p>
+<p>
+</p>
+<hr />
+<h1><a name="configuration">CONFIGURATION</a></h1>
+<p>The standard ruleset contains a configuration that will add a header field
+containing ASN data to scanned messages.  The bayes tokenizer will use the
+added header field for bayes calculations, and thus affect which BAYES_* rule
+will trigger for a particular message.</p>
+<p><strong>Note</strong> that in most cases you should not score on the ASN data directly.
+Bayes learning will probably trigger on the _ASNCIDR_ tag, but probably not
+very well on the _ASN_ tag alone.</p>
+<p>
+</p>
+<hr />
+<h1><a name="see_also">SEE ALSO</a></h1>
+<p><a href="http://www.routeviews.org/">http://www.routeviews.org/</a> - all data regarding routing, ASNs, etc....</p>
+<p><a href="http://issues.apache.org/SpamAssassin/show_bug.cgi?id=4770">http://issues.apache.org/SpamAssassin/show_bug.cgi?id=4770</a> -
+SpamAssassin Issue #4770 concerning this plugin</p>
+<p>
+</p>
+<hr />
+<h1><a name="status">STATUS</a></h1>
+<p>No in-depth analysis of the usefulness of bayes tokenization of ASN data has
+been performed.</p>
+<p>
+</p>
+<hr />
+<h1><a name="administrator_settings">ADMINISTRATOR SETTINGS</a></h1>
+<dl>
+<dt><strong><a name="item_asn_lookup_asn_2dzone_2eexample_2ecom__5b__asntag_">asn_lookup asn-zone.example.com [ _ASNTAG_ _ASNCIDRTAG_ ]</a></strong><br />
+</dt>
+<dd>
+Use this to lookup the ASN info in the specified zone for the first external
+IP address and add the AS number to the first specified tag and routing info
+to the second specified tag.
+</dd>
+<dd>
+<p>If no tags are specified the AS number will be added to the _ASN_ tag and the
+routing info will be added to the _ASNCIDR_ tag.  You must specify either none
+or both of the tag names.  Tag names must start and end with an underscore.</p>
+</dd>
+<dd>
+<p>If two or more <em>asn_lookup</em>s use the same set of template tags, the results of
+their lookups will be appended to each other in the template tag values in no
+particular order.  Duplicate results will be omitted when combining results.
+In a similar fashion, you can also use the same template tag for both the AS
+number tag and the routing info tag.</p>
+</dd>
+<dd>
+<p>Examples:</p>
+</dd>
+<dd>
+<pre>
+  asn_lookup asn.routeviews.org</pre>
+</dd>
+<dd>
+<pre>
+  asn_lookup asn.routeviews.org _ASN_ _ASNCIDR_
+  asn_lookup myview.example.com _MYASN_ _MYASNCIDR_</pre>
+</dd>
+<dd>
+<pre>
+  asn_lookup asn.routeviews.org _COMBINEDASN_ _COMBINEDASNCIDR_
+  asn_lookup myview.example.com _COMBINEDASN_ _COMBINEDASNCIDR_</pre>
+</dd>
+<dd>
+<pre>
+  asn_lookup in1tag.example.net _ASNDATA_ _ASNDATA_</pre>
+</dd>
+<p></p></dl>
+<dl>
+<dt><strong><a name="item_clear_asn_lookups">clear_asn_lookups</a></strong><br />
+</dt>
+</dl>
+<p>Removes any previously declared <em>asn_lookup</em> entries from a list of queries.</p>
+<dl>
+<dt><strong><a name="item_asn_prefix__27prefix_string_27__28default_3a__27as">asn_prefix 'prefix_string'       (default: 'AS')</a></strong><br />
+</dt>
+<dd>
+The string specified in the argument is prepended to each ASN when storing
+it as a tag. This prefix is rather redundant, but its default value 'AS'
+is kept for backward compatibility with versions of SpamAssassin earlier
+than 3.4.0. A sensible setting is an empty string. The argument may be (but
+need not be) enclosed in single or double quotes for clarity.
+</dd>
+<p></p></dl>
+
+</body>
+
+</html>