Milter(3pm) | User Contributed Perl Documentation | Milter(3pm) |
Sendmail::Milter - Interface to sendmail's Mail Filter API
use Sendmail::Milter; my %my_milter_callbacks = ( 'connect' => \&my_connect_callback, 'helo' => \&my_helo_callback, 'envfrom' => \&my_envfrom_callback, 'envrcpt' => \&my_envrcpt_callback, 'header' => \&my_header_callback, 'eoh' => \&my_eoh_callback, 'body' => \&my_body_callback, 'eom' => \&my_eom_callback, 'abort' => \&my_abort_callback, 'close' => \&my_close_callback, ); sub my_connect_callback; sub my_helo_callback; sub my_envfrom_callback; sub my_envrcpt_callback; sub my_header_callback; sub my_eoh_callback; sub my_body_callback; sub my_eom_callback; sub my_abort_callback; sub my_close_callback; BEGIN: { # Get myfilter's connection information # from /etc/mail/sendmail.cf Sendmail::Milter::auto_setconn("myfilter"); Sendmail::Milter::register("myfilter", \%my_milter_callbacks, SMFI_CURR_ACTS); Sendmail::Milter::main(); # Never reaches here, callbacks are called from Milter. }
Sendmail::Milter is a Perl extension to sendmail's Mail Filter API (Milter).
Note: You need to have a Perl 5.6 or later interpreter built with -Dusethreads.
Portions of this document come from comments in the libmilter/mfapi.h header file.
Note: No functions are exported. You must call these functions explicitly from the Sendmail::Milter package.
connect helo envfrom envrcpt header eoh body eom abort close
The values for these keys indicate the callback routine that is associated with each Milter callback. The values must be either function names, code references or closures.
This function returns nonzero upon success, the undefined value otherwise.
%Sendmail::Milter::DEFAULT_CALLBACKS is a hash with default function names for all of the Milter callbacks. The default callback function names are:
connect_callback, helo_callback, envfrom_callback, envrcpt_callback, header_callback, eoh_callback, body_callback, eom_callback, abort_callback, close_callback.
See the section Writing Milter Callbacks for more information on writing the callbacks themselves.
For more information on capability flags, see the section Capability Flags in the @EXPORT section.
MAX_INTERPRETERS sets the limit on the maximum number of interpreters that Sendmail::Milter is allowed to create. These interpreters will only be created as the need arises and are not all created at startup. The default value is 0. (No maximum limit)
MAX_REQUESTS sets the limit on the maximum number of requests an interpreter will process before being recycled. The default value is 0. (Don't recycle interpreters)
This function returns nonzero on success (if a kill was signaled or something), the undefined value otherwise.
Note: You should have at least registered a callback and set the connection information string before calling this function.
This function returns nonzero upon success, the undefined value otherwise.
Note: This connection information isn't useful for implementing a Milter that resides on a machine that is remote to the machine running sendmail. In those cases, you will want to set the connection information manually with setconn.
This function returns nonzero upon success, the undefined value otherwise.
SENDMAIL_CF_FILENAME defaults to "/etc/mail/sendmail.cf" if not specified.
This function returns the connection information string for NAME, or undef on failure.
SENDMAIL_CF_FILENAME defaults to "/etc/mail/sendmail.cf" if not specified.
This function returns nonzero upon success, the undefined value otherwise.
This function returns nonzero upon success, the undefined value otherwise.
Writing Milter callbacks is pretty easy when you're doing simple text processing.
But remember one thing: Each Milter callback could quite possibly run in a different instance of the Perl interpreter.
Sendmail::Milter launches multiple persistent Perl interpreters to increase performance (so it doesn't have to startup and shutdown the interpreters constantly). Thus, you can't rely on setting external package variables, global variables, or even running other modules which rely on such things. This will continue to be true while interpreter thread support in Perl is experimental. For more information, see perlfork. Most of that information applies here.
Remember to return one of the SMFIS_* result codes from the callback routine. Remember there can be multiple message body chunks. And remember that only eom_callback is allowed to manipulate the headers, recipients, message body, etc.
See the @EXPORT section for information on the SMFIS_* result codes.
Here is an example of a connect_callback routine:
# External modules are OK, but note the caveats above. use Socket; sub connect_callback { my $ctx = shift; # The Milter context object. my $hostname = shift; # The connection's host name. my $sockaddr_in = shift; my ($port, $iaddr) = sockaddr_in($sockaddr_in); print "Hostname is: " . $hostname . "\n"; # Cool, a printable IP address. print "IP Address is: " . inet_ntoa($iaddr) . "\n"; return SMFIS_CONTINUE; # Returning a value is important! }
Note: The $ctx Milter context object is not a true Perl object. It's really a blessed reference to an opaque C structure. Only use the Milter context functions (described in a later section) with this object. (Don't touch it, it's evil.)
These interfaces closely mirror their Milter callback counterparts, however there are some differences that take advantage of Perl's syntactic sugar.
Note: Each callback receives a Milter context object as the first argument. This context object is used in making Milter Context function calls. See Milter Context Functions for more details.
This callback should return one of the SMFIS_* result codes.
This callback should return one of the SMFIS_* result codes.
This callback should return one of the SMFIS_* result codes.
This callback should return one of the SMFIS_* result codes.
This callback should return one of the SMFIS_* result codes.
This callback should return one of the SMFIS_* result codes.
This callback should return one of the SMFIS_* result codes.
This callback should return one of the SMFIS_* result codes.
This callback should return one of the SMFIS_* result codes.
This callback should return one of the SMFIS_* result codes.
These routines are object methods that are part of the Sendmail::Milter::Context pseudo-package for use by Sendmail::Milter callback functions. Any attempts to use them without a properly blessed Milter context object will fail miserably. Please see restrictions on when these routines may be called.
Context routines available to all Milter callback functions:
These functions are available to all types of Milter callback functions. It is worth noting that passing connection-private data by reference is probably more efficient than passing by value.
This function returns nonzero upon success, the undefined value otherwise.
This function returns a scalar containing $ctx's private data.
This function returns the value of the symbol name SYMNAME.
This function returns nonzero upon success, the undefined value otherwise.
Context routines available only to the eom_callback function:
The eom_callback Milter callback is called at the end of a message (essentially, after the final DATA dot). This routine can call some special routines to modify the envelope, header, or body of the message before the message is enqueued. These routines must not be called from any vendor routine other than eom_callback.
This function returns nonzero upon success, the undefined value otherwise.
This function returns nonzero upon success, the undefined value otherwise.
This function returns nonzero upon success, the undefined value otherwise.
This function returns nonzero upon success, the undefined value otherwise.
This function returns nonzero upon success, the undefined value otherwise.
Sendmail::Milter exports the following constants:
These are the possible result codes that may be returned by the Milter callback functions. If you do not specify a return value, Sendmail::Milter will send a default result code of SMFIS_CONTINUE back to Milter.
These are possible capability flags for what a mail filter can do. Normally, you should specify each capability explicitly as needed.
These provide sets of capability flags that indicate all of the capabilities in a particular version of Milter. SMFI_CURR_ACTS is set to the capabilities in the current version of Milter.
use Sendmail::Milter; my %my_milter_callbacks = ( 'eoh' => \&my_eoh_callback, 'body' => \&my_body_callback, 'eom' => \&my_eom_callback, 'abort' => \&my_abort_callback, ); sub my_eoh_callback { my $ctx = shift; my $body = ""; $ctx->setpriv(\$body); return SMFIS_CONTINUE; } sub my_body_callback { my $ctx = shift; my $body_chunk = shift; my $body_ref = $ctx->getpriv(); ${$body_ref} .= $body_chunk; # This is crucial, the reference to the body may have # changed. $ctx->setpriv($body_ref); return SMFIS_CONTINUE; } sub my_eom_callback { my $ctx = shift; my $body_ref = $ctx->getpriv(); # Note: This doesn't support messages with MIME data. ${$body_ref} .= "---> Append me to this message body!\n"; $ctx->replacebody(${$body_ref}); $ctx->setpriv(undef); return SMFIS_ACCEPT; } sub my_abort_callback { my $ctx = shift; $ctx->setpriv(undef); return SMFIS_CONTINUE; } # The following code does not necessarily need to be in a # BEGIN block. It just looks funny without it. :) BEGIN: { Sendmail::Milter::auto_setconn("myfilter"); Sendmail::Milter::register("myfilter", \%my_milter_callbacks, SMFI_CURR_ACTS); Sendmail::Milter::main(); # Never reaches here, callbacks are called from Milter. }
See the test.pl sample test case for more callback examples.
Charles Ying, cying@cpan.org.
Copyright (c) 2000-2001 Charles Ying. All rights reserved. This program is free software; you can redistribute it and/or modify it under the same terms as sendmail itself.
The interpreter pools portion (found in the intpools.c, intpools.h, and test.pl files) of this code is also available under the same terms as perl itself.
perl(1), sendmail(8).
2024-10-15 | perl v5.40.0 |