Quick Navigator

Search Site

Unix VPS
A - Starter
B - Basic
C - Preferred
D - Commercial
MPS - Dedicated
Previous VPSs
* Sign Up! *

Contact Us
Online Help
Domain Status
Man Pages

Virtual Servers

Topology Map

Server Agreement
Year 2038

USA Flag



Man Pages

Manual Reference Pages  -  MAIL::PROCMAILRC (3)

.ds Aq ’


Mail::Procmailrc - An interface to Procmail recipe files



  use Mail::Procmailrc;

  ## create a new procmailrc object and initialize it
  $pmrc = new Mail::Procmailrc("$HOME/.procmail/rc.spam");

  ## add a new variable
  $pmrc->push( new Mail::Procmailrc::Variable(["FOO=bar"]) );

  ## add a new recipe
  $recipe =<<_RECIPE_;
  ## this will catch evil email messages
  * 1^0 xxx
  * 1^0 evil things
  * 1^0 porn and other wickedness
  * 1^0 all kinds of cursing
  * 1^0 lewdness, filth, etc\.

  ## add this new recipe to our procmail rc file
  $pmrc->push( new Mail::Procmailrc::Recipe($recipe) );

  ## add another condition to our recipe (we shoulda left a scalar
  ## handle lying around, but this illustrates something useful)
  for my $obj ( @{$pmrc->rc} ) {
      ## find the recipe we just added by its info string
      next unless $obj->stringify =~ /^\#\# this will catch evil email messages/m;

      ## we want to block emails about censorship, too ;o)
      push @{$obj->conditions}, * 1^0 censor(ship|ing)?

  ## write this object to disk


<B>Mail::ProcmailrcB> can parse <B>procmailB> recipe files and store the contents in an object which can be later manipulated and saved (see CAVEATS and BUGS/TODO for limitations and special conditions).

You may also start with a fresh, empty <B>Mail::ProcmailrcB> object, populate it with recipes and/or variables and write it to file.

Recipes and variables are written to the file in the order they’re parsed and added. If you want to re-order the recipes you may do so by getting a handle on the variable or recipe list and ordering them yourself.

The <B>Mail::ProcmailrcB> object is primarily a list of <B>procmailB> component objects (see below). When <B>Mail::ProcmailrcB> parses a <B>procmailB> rc file, it decides which lines are variable assignments, which lines are comments, and which lines are recipes. It preserves the order in which it encounters these <B>procmailB> components and stores them as a list of objects in the main <B>Mail::ProcmailrcB> object.
<B>newB> Creates a new Mail::Procmailrc object.


    ## 1. in memory object
    my $pmrc = new Mail::Procmailrc;

    ## 2. parses /etc/procmailrc
    my $pmrc = new Mail::Procmailrc("/etc/procmailrc");

    ## 3. parses /etc/procmailrc, makes backup
    my $pmrc = new Mail::Procmailrc("/etc/procmailrc");
    $pmrc->flush;   ## create a backup

    $pmrc->file("/etc/procmailrc");  ## future flushes will go here

    ## 4. alternative syntax: filename specified in hashref
    my $pmrc = new Mail::Procmailrc( { file => /etc/procmailrc } );

    ## 5. alternative syntax: scalar
    my $rc =<<_FOO_;
    * 1^0 this is not spam
    my $pmrc = new Mail::Procmailrc( { data => $rc } );

    ## 6. alternative syntax: array reference
    my $rc =<<_RCFILE_;
    my @rc = map { "$_\n" } split(/\n/, $rcfile);
    $pmrc = new Mail::Procmailrc( { data => \@rc } );

<B>readB> Sets the object’s file attribute and parses the given file. If the file is not readable, returns undef. Normally not invoked directly.


    ## set $pmrc->file and parse
    unless( $pmrc->read(/etc/procmailrc) ) {
        die "Could not parse /etc/procmailrc!\n";

<B>parseB> Takes an array or string reference and populates the object with it.


    my $chunk =<<_RECIPE_;
    ## begin foo section
    ## process the mail via foo
    |/usr/local/bin/foo -c /etc/mail/foo.conf
    ## end spamassassin vinstall (do not remove these comments)

    ## make a new in-memory procmailrc file
    my $new_pmrc = new Mail::Procmailrc;

    ## add this new procmailrc file to our existing procmailrc file

Alternatively, you can pass an array reference to <B>parseB>:

    $new_pmrc->parse([split("\n", $chunk)]);

<B>rcB> Returns a list reference. Each item in the list is either a Variable, Literal, or Recipe object. Items are returned in the order they were originally parsed. You may assign to <B>rcB> and rewrite the <B>Mail::ProcmailrcB> object thereby.


    ## remove foo section from recipe file
    my @tmp_rc = ();
    my $foo_section = 0;
    for my $pm_obj ( @{$pmrc->rc} ) {
        if( $pm_obj->stringify =~ /^\#\# begin foo recipes/m ) {
            $foo_section = 1;
        elsif( $pm_obj->stringify =~ /^\#\# end foo recipes/m ) {
            $foo_section = 0;
        elsif( $foo_section ) {
        push @tmp_rc, $rc_obj;

<B>recipesB> Returns a listref of recipes in this object.
<B>variablesB> Returns a listref of variables in this object.
<B>literalsB> Returns a listref of literals in this object.
<B>pushB> Pushes the dat(a|um) onto this object’s internal object list. If the object being pushed is another Mail::Procmailrc object, that object’s <B>rcB> method is invoked first and the results are pushed.


    my $rc_objs = $old_pmrc->rc;
    $pmrc->push( @$rc_objs );

<B>deleteB> Deletes an object from the main Mail::Procmailrc object:

    for my $obj ( @{$pmrc->rc} ) {
        next unless $obj->isa(Mail::Procmailrc::Recipe);

        ## I lost all my enemies when I switched to the Perl Artistic License...
        next unless $obj->info->[0] =~ /^\#\# block email from enemies/;

<B>fileB> Returns the path where this object will write when <B>flushB> is invoked. If <B>fileB> is given an argument, the object’s internal file attribute is set to this path.
<B>flushB> Writes the procmail object to disk in the file specified by the <B>fileB> attribute. If the <B>fileB> attribute is not set, <B>flushB> writes to STDOUT. If a filename is given as an argument, it is set as the objects <B>fileB> attribute.


    ## 1. flushes to whatever $pmrc->file is set to (STDOUT if file is unset)

    ## 2. flushes to a specific file; future flushes will also go here

<B>stringifyB> Returns the object in string representation.
<B>dumpB> Like <B>stringifyB> but with nicer formatting (indentation, newlines, etc.). Suitable for inclusion in procmail rc files.

Mail::Procmailrc::Variable Objects

<B>Mail::Procmailrc::VariableB> objects are easy to create and use. Normally, the <B>VariableB> constructor is invoked by <B>Mail::ProcmailrcB> during parsing. If you are creating or modifying an existing <B>procmailB> rc file, you might do something like this:

    my $var = new Mail::Procmailrc::Variable(["VERBOSE=off"]);

or you might wish to do it another way:

    my $var = new Mail::Procmailrc::Variable;

You may get a handle on all <B>VariableB> objects in an rc file with the <B>variablesB> method:

    ## change to verbose mode
    for my $var ( @{$pmrc->variables} ) {
        next unless $var->lval eq VERBOSE;

    Mail::Procmailrc::Variable Methods

<B>variable([$string])B> $string, if present, is split on the first ’=’. The left half is assigned to <B>lvalB> and the right half to <B>rvalB>. If $string is false, <B>lvalB> and <B>rvalB> are concatenated with ’=’ and returned as a single string.
<B>lval([$val])B> Returns the current lvalue of the variable assignment, optionally setting it if $val is present.
<B>rval([$val])B> Returns the current rvalue of the variable assignment, optionally setting it if $val is present.
<B>stringifyB> Returns the output of <B>variableB>. Provides a consistent interface to all Mail::Procmailrc::* subclasses.
<B>dumpB> Returns the output of <B>stringifyB> with a trailing newline. Suitable for inserting into a <B>procmailB> rc file.
<B>defaults([\%defaults [, B>$elem<B>]])B> Returns some internal object settings, currently not very useful or interesting except when parsing deeply nested recipes. Included here for completeness.
<B>init(\@data)B> Normally invoked by the constructor (<B>newB>), but may be used to re-initialize an object.

Mail::Procmailrc::Literal Objects

<B>Mail::Procmailrc::LiteralB> objects are even easier to create and use than <B>VariableB> objects. A <B>Mail::Procmailrc::LiteralB> is simply a string with a few methods wrapped around it for convenient printing.

You may get a handle on all <B>LiteralB> objects in an rc file with the <B>literalsB> method:

    ## change a comment in the rc file
    for my $lit ( @{$pmrc->literals} ) {
        next unless $lit->literal =~ /## spam follows/i;
        $lit->literal(## this is a nice spam recipe);

Here is how to create a new literal:

   ## create a new literal
   my $lit = new Mail::Procmailrc::Literal(## this file is for filtering spam);

   ## same as above
   my $lit = new Mail::Procmailrc::Literal;
   $lit->literal(## this file is for filtering spam);

   ## print it

    Mail::Procmailrc::Literal Methods

<B>literal([$string])B> Get or set the literal object contents.
<B>dumpB> Dump the contents of the object with a trailing newline.

Mail::Procmailrc::Recipe Objects

A recipe object is made up of a flags object, zero or more literal (comments or vertical whitespace) objects, zero or more condition objects, and an action object. A <B>Mail::Procmailrc::RecipeB> object is made of four parts:
o flags (required)
o info/comment (optional)
o conditions (optional)
o action (required)
Normally, the <B>RecipeB> object is created automatically during parsing. However, if you are constructing a new rc file or want to modify an existing procmailrc file, you will need to know a little about the <B>RecipeB> object.

To create a recipe object from a string, you may do something like this:

    $recipe =<<_RECIPE_;
    ## block indecent emails
    * 1^0 people talking dirty
    * 1^0 dirty persian poetry
    * 1^0 dirty pictures
    * 1^0 xxx

    $recipe_obj = new Mail::Procmailrc::Recipe($recipe);

or the more obtuse (if you happen to already have an array or reference):

    $recipe_obj = new Mail::Procmailrc::Recipe([split("\n", $recipe)]);

The entire recipe in $recipe is now contained in the $recipe_obj. You could also piece together an object part by part:

    $recipe_obj = new Mail::Procmailrc::Recipe;
    $recipe_obj->info([q(## block indecent emails)]);
    $recipe_obj->conditions([q(* 1^0 people talking dirty),
                             q(* 1^0 dirty persian poetry),
                             q(* 1^0 dirty pictures),
                             q(* 1^0 xxx),]);

You can get a handle on all recipes in an rc file with the <B>recipesB> method:

    my $conditions;
    for my $recipe ( @{$pmrc->recipes} ) {
        next unless $recipe->info->[0] =~ /^\s*\#\# this recipe is for spam/io;
        $conditions = $recipe->conditions;
    push @$conditions, * 1^0 this is not SPAM;  ## add another condition
    $pmrc->flush;  ## write out to file

Important Note about info

The <B>infoB> method of the <B>RecipeB> object is really just a procmail comment (or <B>literalB> elsewhere in this document), but because it appears between the <B>flagsB> line (e.g., ’:0fw’) and the conditions (e.g., * 1^0 foo), it becomes part of the recipe itself. This is terribly convenient usage because it allows you to index your recipes and find them later.


The eg directory in the <B>Mail::ProcmailrcB> distribution contains at least one useful program illustrating the several uses of this module. Other examples may appear here in future releases as well as the eg directory of the distribution.


Parsing is lossy in two senses. Some formatting and stray lines may be lost. Also, array references fed to constructors will not be returned intact (i.e., data will be shifted out of them).


Please let the author/maintainer know if you find any bugs (providing a regression test would also be helpful; see the testing format in the ’t’ directory).
o We can’t parse old-style counting syntax (before v2.90, 1993/07/01):


Thanks to <> (8 Oct 2002) for finding this bug.

o We don’t use any advisory locking on the <B>procmailB> rc files. This wouldn’t be hard to fix, but I’m not sure it is needed.
o We suck in the entire procmailrc file into memory. This could be done more efficiently with a typeglob and reading the file line by line.
o Comments on the flags line (e.g., :0B ## parse body) or on an assignment line (e.g., VAR=FOO ## make FOO be known) are quietly dropped when the rc file is parsed and they are not replaced when the file is rewritten. If you want to keep comments around, put them on a separate line.
o We don’t recursively parse file INCLUDE directives. This could be construed as a safety feature. The INCLUDE directives will show up, however, as <B>VariableB> objects, so you could provide the recursion pretty easily yourself.


5 Feb 2003 Erwin Lansing ( for 5.00503 patch and doc typo. Danke!


Copyright 2002 Scott Wiersdorf.

This library is free software; you can redistribute it and/or modify it under the terms of the Perl Artistic License.


Scott Wiersdorf <>


procmail, procmailrc(5), procmailex(5), procmailsc(5)
Search for    or go to Top of page |  Section 3 |  Main Index

perl v5.20.3 PROCMAILRC (3) 2005-06-09

Powered by GSP Visit the GSP FreeBSD Man Page Interface.
Output converted with manServer 1.07.