Why not adopt me?
NAME
Mail::Audit - Library for creating easy mail filters
SYNOPSIS
use Mail::Audit; # or use Mail::Audit qw(...plugins...);
my $mail = Mail::Audit->new( emergency => "~/emergency_mbox");
$mail->pipe("listgate p5p") if $mail->from =~ /perl5-porters/;
$mail->accept("perl") if $mail->from =~ /perl/;
$mail->reject("We do not accept spam") if $mail->rblcheck();
$mail->ignore if $mail->subject =~ /boring/i;
$mail->noexit(1);
$mail->accept("~/Mail/Archive/%Y%m%d");
$mail->noexit(0);
$mail->accept()
DESCRIPTION
procmail is nasty. It has a tortuous and complicated recipe format, and I don't like it. I wanted something flexible whereby I could filter my mail using Perl tests.
Mail::Audit was inspired by Tom Christiansen's audit_mail and deliverlib programs. It allows a piece of email to be logged, examined, accepted into a mailbox, filtered, resent elsewhere, rejected, replied to, and so on. It's designed to allow you to easily create filter programs to stick in a .forward file or similar.
Mail::Audit groks MIME; when appropriate, it subclasses MIME::Entity. Read the MIME::Tools man page for details.
CONSTRUCTOR
- new
-
my $mail = Mail::Audit->new(%option)
The constructor reads a mail message from
STDIN
(or, if thedata
option is set, from an array reference or \*GLOBref) and creates aMail::Audit
object from it.Other options include the
accept
,reject
orpipe
keys, which specify subroutine references to override the methods with those names.You are encouraged to specify an
emergency
argument and check for the appearance of messages in that mailbox on a regular basis. If for any reason anaccept()
is unsuccessful, the message will be saved to theemergency
mailbox instead. If noemergency
mailbox is defined, messages will be deferred back to the MTA, where they will show up in your mailq.You may also specify
log => $logfile
to write a debugging log. If you don't specify a log file, logs will be written to ~/mail-audit.log. You can set the verbosity of the log with theloglevel
key. A higher loglevel will result in more lines being logged. The default level is 3. To get all internally generated logs, log at level 5. To get none, log at -1.Usually, the delivery methods
accept
,pipe
, andresend
are final; Mail::Audit will terminate when they are done. If you specifynoexit => 1
,Mail::Audit
will not exit after completing the above actions, but continue running your script.The
reject
delivery method is always final;noexit
has no effect.If you just want to print the message to STDOUT, $mail->print().
Percent (%) signs seen in arguments to
accept
andpipe
do not undergostrftime
interpolation by default. If you want this, use theinterpolate_strftime
option. You can override the "global" interpolate_strftime option by passing an overriding option toaccept
andpipe
.By default, MIME messages are automatically recognized and parsed. This is potentially expensive; if you don't want MIME parsing, use the
nomime
option.You can pass further MIME options in the
mimeoptions
variable: for example, if you want to output_to_core (man MIME::Parser) setmimeoptions => {output_to_core=>1}
.
DELIVERY METHODS
- accept
-
$mail->accept(\%option, @locations);
You can choose to accept the mail into a mailbox by calling the
accept
method; with no argument, this accepts to /var/spool/mail/you. The mailbox is opened append-write, then lockedLOCK_EX
, the mail written and then the mailbox unlocked and closed. If Mail::Audit sees that you have a maildir style system, where /var/spool/mail/you is a directory, it'll deliver in maildir style. If the path you specify does not exist, Mail::Audit will assume mbox, unless it ends in /, which means maildir.If multiple maildirs are given, Mail::Audit will use hardlinks to deliver to them, so that multiple hardlinks point to the same underlying file. (If the maildirs turn out to be on multiple filesystems, you get multiple files.)
If you don't want the "new/cur/tmp" structure of a classical maildir, set the one_for_all option, and you'll still get the unique filenames.
accept( dir1, dir2, ..., { one_for_all => 1 });
If you want "%" signs to be expanded according to
strftime(3)
, you can passaccept
the optioninterpolate_strftime
:accept( file1, file2, ..., { interpolate_strftime => 1 });
"interpolate_strftime" is not enabled by default for two reasons: backward compatibility (though nobody I know has a % in any mail folder name) and username interpolation: many people like to save messages by their correspondent's username, and that username may contain a % sign. If you are one of these people, you should
$username =~ s/%/%%/g;
If your arguments contain "/",
accept
will create arbitarily deep subdirectories accordingly. Untaint your input by saying$username =~ s,/,-,g;
By default,
accept
is final; Mail::Audit will terminate after successfully accepting the message. If you want to keep going, setnoexit
.accept
will return the filename(s) that it saved to.my @pathnames = accept(file1, file2, ..., { noexit => 1 }); my ($pathname) = accept(file1);
If for any reason
accept
is unable to write the message (eg. you're over quota), Mail::Audit will attempt delivery to theemergency
mailbox. Ifaccept
was called with multiple destinations, theemergency
action will only be taken if the message couldn't be delivered to any of the desired destinations. By default theemergency
mailbox is set to the system mailbox. If we were unable to save to the emergency mailbox, the message will be deferred back into the MTA's queue. This happens whether or notnoexit
is set, so if you observe that some of youraccept
s somehow aren't getting run, check your mailq.If this isn't how you want local delivery to happen, you'll need to override this method.
- reject
-
$mail->reject($reason);
This rejects the email; it will be bounced back to the sender as undeliverable. If a reason is given, this will be included in the bounce.
This is a final delivery method. The
noexit
option has no effect here. - resend
-
$mail->resend($address, \%option)
Reinjects the email in its entirety to another address, using SMTP.
This is a final delivery method. Set
noexit
if you want to keep going.Other options are all optional, and include host, port, and debug; see "smtpsend" in Mail::Internet
At this time this method is not overrideable by an argument to
new
. - pipe
-
$mail->pipe($program)
This opens a pipe to an external program and feeds the mail to it.
This is a final delivery method. Set
noexit
if you want to keep going. Ifnoexit
is set, the exit status of the pipe is returned. - ignore
-
$mail->ignore;
This merely ignores the email, dropping it into the bit bucket for eternity.
This is a final delivery method. Set
noexit
if you want to keep going. (Calling ignore withnoexit
set is pretty pointless.) - reply
-
$mail->reply(%option);
Sends an autoreply to the sender of the message. Return value: the recipient address of the reply.
Recognized content-related options are: from, subject, cc, bcc, body. The "To" field defaults to the incoming message's "Reply-To" and "From" fields.
body
should be a single multiline string.Set the option
EVEN_IF_FROM_DAEMON
to send a reply even if the original message was from some sort of automated agent. What that set, only X-Loop will stop loops.If you use this method, use KillDups to keep track of who you've autoreplied to, so you don't autoreply more than once.
use Mail::Audit qw(KillDups); $mail->reply(body=>"I am on vacation") if not $self->killdups($mail->from);
reply
is not considered a final delivery method, so execution will continue after completion.
HEADER MANAGEMENT METHODS
- get_header
- get
-
my $header = $mail->get($header);
Retrieves the named header from the mail message.
- add_header
- put_header
-
$mail->add_header($header => $value);
Inserts a new header into the mail message with the given value.
put_header
is an alias for this method. - replace_header
-
$mail->replace_header($header => $value);
Removes the old header, adds a new one.
- delete_header
-
$mail->delete_header($header);
Guess.
MISCELLANEOUS METHODS
- log
-
$mail->log($priority => $message);
This method logs the given message if
$priority
is greater than the loglevel given during construction. - tidy
-
$mail->tidy;
Tidies up the email as per Mail::Internet. If the message is a MIME message, nothing happens.
- noexit
-
$mail->noexit($bool);
This method sets the value of
noexit
. Ifnoexit
is true, final delivery methods will not be considered final.
ATTRIBUTE METHODS
The following attributes correspond to fields in the mail:
from
to
subject
cc
bcc
received
body
Returns a reference to an array of lines in the body of the email.
header
Returns the header as a single string.
is_mime
Am I a MIME message? If so, MIME::Entity methods apply. Otherwise, Mail::Internet methods apply.
from_mailer
Am I from a mailer-daemon? See procmailrc. This method returns the part of the header that matched. This method's implementation of the pattern is not identical to procmail's.
from_daemon
Am I from any sort of daemon? See procmailrc. This method returns the part of the header that matched. This method's implementation of the pattern is not identical to procmail's.
LICENSE
The usual. This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
BUGS
Numerous and sometimes nasty. RJBS is working to eradicate them all.
http://rt.cpan.org/NoAuth/Bugs.html?Dist=Mail-Audit
PERL EMAIL PROJECT
This module is maintained by the Perl Email Project, and is considered superseded by Email::Filter.
http://emailproject.perl.org/wiki/Mail::Audit
CAVEATS
If your mailbox file in /var/spool/mail/ doesn't already exist, you may need to use your standard system MDA to create it. After it's been created, Mail::Audit should be able to append to it. Mail::Audit may not be able to create /var/spool/mail because programs run from .forward don't inherit the special permissions needed to create files in that directory.
AUTHORS
Simon Cozens <simon@cpan.org> wrote versions 1 and 2.
Meng Weng Wong <mengwong@pobox.com> turned a petite demure v2.0 into a raging bloated v2.1, adding MIME support, emergency recovery, filename interpolation, and autoreply features.
Ricardo SIGNES <rjbs@cpan.org> took over after Meng and tried to tame the beast, refactoring, documenting, and testing. Thanks to Listbox.com for sponsoring maintenance of this module !