What is it?

A Perl Extensible Mail Filter



This software is essentially free, but please read my payment spiel
Please read the full license


Grab the perl script and the example filter.
If you have multiple email addresses, then I also recommend that you install forge_pipe, this is a good replacement for sendmail that allows you to specify your outbound email address.


  1. Install pemf somewhere (preferably on the same NFS server as the mail) and make it readable/executable
  2. Install the example filter as in the same directory as pemf or in your home directory and make it readable
  3. I also recommend that you install forge_pipe in a normal place in your path and do:
       % chown root:root forge_pipe
       % chmod +s forge_pipe
  4. Edit the as desired
  5. Make any directories you'll need that you don't have, such as ~/Mail and possibly ~/Mail/INBOUND
  6. If desired, save an email and try running it through the filter with:
       % pemf < test_email
  7. Make a gobally readable .forward file (probably in your home directory, check with your sysadmin) containing:
       "|/path/to/pemf -l"


I can't help you with how to get your mail program to use the filter if the .forward file doesn't work, talk to your sysadmin or RTFM.

The is what you customize to tailor the behavior of the script, through subroutines that 'pemf' will call if found. It's generally commented, here's a few extra notes:

Many of the subs are given ($home,$user) as arguments, these are the home directory and the user's login.

You only need to set/modify inbox() and save_mail() if the defaults don't work (they probably will). If your sendmail is in an unusual place you can create a sub sendmail() that returns the path to sendmail.

If you want to control where your logfile goes, change logfile(). If you don't want logging, don't use the '-l' option in your .forward file.

To save inbound your inbound mail, adjust save_inbound() and save_inbound_lines().

If you use the spam checking utilities, you'll want to adjust some of: is_spam_to(), is_spam_from(), is_spam_subject(), is_spam_hdr(), never_spam_from()

If you use auto_respond_mail (see below), then you should set my_name(), auto_respond_from() and respond_key()


Check if a message is spam based upon settings
Send a response to a message, like "reply" in your email reader.
Returns the body of the message in an array. This is less efficient, especially with larger messages, so avoid it if possible.
Change any headers (in the header_list) that match $re to $str
Finally, this is where the message is handled. If $box is 0 or undef, then it will use your default inbox. If $box is a path or a mailbox in your saved mail directory, it will save it there. $box can also be a forwarding email address or a '|command' (though consider the security implications!). Normally send_to will exit when done, unless $no_quit is specified, so that you can do further processing of the email.

The actual filter itself is mail_filter(). It's called with a $msg data structure, this is a hash reference:

Hash of all headers (lower case)
An array reference to the original headers, in order
Boolean. Set if you don't want to save this email, regardless of save_inbound() settings
Boolean. Set if you want to clean quoted_printable email. This is the email with all the = escapes throughout the message and at the end of lines. If you have a text email reader (like 'elm') then this probably aggravates you. See the example filter for an easy check.
It will likely make some checks and decide how to call send_to().


  1. Perl, which kicks ass
  2. sendmail or some equivalent that allows mail filters

Revision History:



You bet.