Module Internals and Writing your Own
Check plugins/skeleton for a bare structure of a plugin.
All plugin functions are called inside an eval, so if your plugin dies (or calls &main::fatal, see below), the current rule is effectively skipped for this invocation, and the mail gets passed on to the next rule.
The mail must flow!
The plugins get loaded with a "require" once when mimicry starts up, immediately calling the description function the output of which is written to the syslog.
As of 0.3.1 plugins are called as true class instances, thus the init function was renamed to new. Certain function internals have changed accordingly.
Each rule gets its own instance of the plugin class, passing the value of the 'param' given in the mimicry.conf file to the plugin classes new function.
If your plugin is used in a rule with the 'collect' usage mode, the functions are called in the order:
- description()
- new($param)
- feed( @ids ) at least once, can be called arbitarily often
- process( $self, $old_tree, $node, $new_tree )
- reset()
- feed( @ids )
- process( $self, $old_tree, $node, $new_tree )
- reset()
- feed( @ids ) ...
If your plugin won't handle 'collect' usage, the feed function won't be called.
The "process" Function
This is the function that actually does something. You are given four
parameters:
- $self
- $old_tree (the tree structure of the original mail)
- $node ( the node number of the part in old_tree you are to process -
unless you are handeling a 'collect' usage. In that case $node will
be empty and you will have to rely on the data you were handed by
the feed function call(s)! )
- $new_tree (where the processed mail part(s) are to added)
$old_tree and $new_tree are refs to hashes. $node is a ref to a scalar.
The Mail Tree Structure
Both the $old_tree and $new_tree hashrefs contain the following internal structure:
$tree->{$$node}->{'entity'} # the MIME::Entity we're working on/have worked on $tree->{$$node}->{'parent'} # node id of our parent $tree->{$$node}->{'children'} # array of node ids of our immediate children $tree->{$$node}->{'type_path'} # mimetype path from the top entity to the
# current node $tree->{$$node}->{'filename'} # if defined contains the recommended filename $tree->{$$node}->{'id'} # contains the current node id as a value ( so
# $$node == $tree->{$$node}->{'id'} )
In addition you can set the following field in the old_tree after you're done
processing the node and don't want other plugins to process the same mime part
after you're done with it:
$tree->{$$node}-{'skip'} # always set to 1. Automatically causes the entire
# subtree, that $node is the root of, to be skipped.
Helper Functions
&main::log( $min_loglevel_required, $message ); Will write $message to syslog if the current loglevel is at least $min_loglevel_required.
&main::warn( $message )
Always writes "Warning: $message" to the syslog.
&main::error( $message )
Always writes "Error: $message" to the syslog.
&main::fatal( $message )
Always writes "FATAL: $message" to the syslog and calls die.
&main::get_tempfile;
Returns the filename of a newly created tempfile. This will be automatically
deleted after the current mail is passed on to the next mailserver.
&main::add_entity_to_tree( $tree_ref, $entity, $parent_node_id ) Adds the given MIME::Entity instances $entity to the tree referenced by $tree_ref, making $tree_ref->{$parent_node_id}->{'entity'} the parent entity of $entity.
