Squirrel Logo


Johan Vromans
Software & Tools

Procmail-like facility for creating easy mail filters

procmail is a great mail filter program, but it has weird recipe format. It's pattern matching capabilities are basic and often insufficient. I wanted something flexible whereby I could filter my mail using the power of Perl.

I've been considering to write a procmail replacement in Perl for a while, but it was Simon Cozen's Mail::Audit module, and his article in The Perl Journal #18, that set it off.

I first started using Simon's great module, and then decided to write my own since I liked certain things to be done differently. And I couldn't wait for his updates. Currently, Simon and I are in the process of considering to port my enhancements to his code as well.

Mail::Procmail allows a piece of email to be logged, examined, delivered into a mailbox, filtered, resent elsewhere, rejected, and so on. It is designed to allow you to easily create filter programs to stick in a .forward or F.procmailrc file, or similar.

For example, a simple filter that copies incoming mail regarding a specific subject to a separate mailbox, while also sending it to a friend:

#!/usr/bin/perl -w
use strict;
use Mail::Procmail;
pm_init(logfile=>'stderr', loglevel=>3);
if ( pm_gethdr("subject") =~ /interesting topic/i ) {
  pm_resend("my_friend@somewhere.com", continue => 1);
# Default delivery.

As can be deduced from the pm_init() call, logging will be done to standard error. If a suitable message comes along, the following information will be logged:

2000/08/08 21:23:55 Mail from John Doe 
2000/08/08 21:23:55 To: jvromans@squirrel.nl
2000/08/08 21:23:55 Subject: This is an interesting topic
2000/08/08 21:23:55 resend[6]: my_friend@somewhere.com
2000/08/08 21:23:55 deliver[7]: /home/jv/Mail/interesting

The number between [ ] shows the line number in your program that caused the delivery. This makes it easy to find out what rule triggered the delivery.

If the message did not have the interesting subject, the log would show:

2000/08/08 21:26:14 Mail from John Doe 
2000/08/08 21:26:14 To: jvromans@squirrel.nl
2000/08/08 21:26:14 Subject: This is a boring topic
2000/08/08 21:26:14 deliver[19]: /var/spool/mail/jv

All headers, and the body, of the message are at your disposal, so you can use all the powers of perl pattern matching for your email filtering.

Delivery routines

Most delivery routines will exit the program with status DELIVERED unless the attribute "continue=>1" is passed.

  • pm_deliver(filename[,attributes])
    Deliver to the file. The file is locked during delivery to prevent data corruption.
  • pm_resend(address[,attributes])
    Remail to the specifield address.
  • pm_pipe_to(command[,attributes])
    Pipe the message to the command. A lockfile attribute can be used to prevent multiple deliveries using the same command at the same time. Pipe write errors are silently ignored.
  • pm_command(command[,attributes])
    Execute a system command for its side-effects.
  • pm_ignore(reason)
    Treat as delivered but do noting but logging the reason.
  • pm_reject(reason)
    The program will exit with status REJECTEDto signal the mail delivery system that the message was rejected.
  • pm_log(level,message)
    Add a message to the log. A timestamp will be prepended.



GPL or Artistic, whatever you prefer.


Mail::Procmail is inspired by Simon Cozen's Mail::Audit, that was inspired by Tom Christiansen's audit_mail and deliverlib programs.

Current version
CPAN sites. The MetaCPAN search engine will find it for you.

© Copyright 2003-2018 Johan Vromans. All Rights Reserved.
software/sw_procmail.html last modified 14:14:34 14-May-2004