Procmail is a program available on all ACMS machines which allows you to automatically process your email as it arrives into your account. You can sort, delete, forward, and store messages depending on their sender, their subject, or other characteristics. For example, you could have Procmail direct all messages from your friend at UC Berkeley into a folder called "berkeley". You could then read the messages in this folder at your leisure.
To use Procmail you need to create a set of "recipes," or instructions, for Procmail to follow each time you receive a message. These "recipes" reside in a file called ".procmailrc" in your home directory. You can use a Unix editor, such as vi or pico, to create this file. See the vi or vim help articles for assistance in using vi.
The following two sections, "Examples of common uses," and "A more complex example," lead you through the creation of several recipes that you might want to copy or modify for your own use. Please read the fourth section, "Resolving problems with procmail, " if you have any trouble with your new Procmail recipe set.
PROCMAIL: EXAMPLES OF COMMON USES Procmail is a versatile program and can be put to a number of uses. Some common applications include: * Saving letters from a particular person to an Elm folder * Saving letters with a particular subject to a Pine folder * Deleting messages from a particular person * Forwarding messages to different addresses based on the sender. Each of these examples may be used as-is, without modification, or you may change them to suit your particular needs. Please see the "man procmail" manual entry for more specific information on Procmail's capabilities and functions. In particular, many of these rules can be used at the same time simply by including them all in the same .procmailrc file. For each of the following samples you must create a file called '.procmailrc' in your Unix home directory. See the articles available under 'help editor' for basic help on creating this file. Saving letters from a particular person to a folder The following '.procmailrc' file will save messages coming from anybody with "peter" in their email address, including "email@example.com," "firstname.lastname@example.org," and others. The messages will be saved into an Elm folder called 'peter.folder'. This folder is accessible under Elm through the "c)hange folder" command at the main menu, or from Pine using its 'Folder Index' command. Please note that the first rule in this file doesn't really have anything to do with mail from Peter. It's there to ensure that you don't lose mail in the event of an error in your .procmailrc file; every message will be copied to a folder called "backup" before anything else is done with it. Once you're satisfied that everything is working properly, you can remove the section so that your disk quota isn't used up by copies of old messages. Place the following into your .procmailrc file: # Remove these three lines when you're sure this works :0 c: Mail/backup.folder :0: * ^From.*peter Mail/peter.folder You can, of course, substitute your own folder name for "peter.folder" above, and you can also use another email name instead of "peter". Deleting messages from a particular person It's sometimes necessary to mechanically ignore messages sent from one person or account. Here's how you can do it with Procmail. Please note that this will only throw away these messages. If you're receiving threatening or harassing messages from somebody, please contact email@example.com so that more direct action can be taken. Put the following into a .procmailrc file: # Remove these three lines when you're sure this works :0 c: Mail/backup.folder :0 * ^From.*firstname.lastname@example.org /dev/null Here, the only thing for you to customize is the e-mail address of the person you wish to ignore. You should be as specific as possible when writing out this e-mail address, since you probably don't want to randomly delete messages simply because they're from someone with "peter" in their login name. The '/dev/null' folder listed here isn't really a folder; it's more like the system's trash can. You can use it anywhere you'd list a folder name, but remember that messages put into this folder are DESTROYED! Forwarding messages to different addresses based on the sender. This is the most complicated example so far. Sometimes you have more than one email account, but you don't want to forward ALL your mail from the other accounts into your main one (for instructions on this, see the 'help forward' article). Here's an example which only forwards e-mail from the CSE department to a separate address: # Remove these three lines when you're sure this works :0 c: Mail/backup.folder :0 * ^From.*cse-announce ! email@example.com Note that you can use a "* ^Subject:" line instead of the ^From line above if you want to forward messages with a certain subject to another account. Also note the "!" exclamation point at the beginning of the line which signifies that the mail should be forwarded to the following address.
PROCMAIL: A MORE COMPLEX EXAMPLE As was mentioned in the previous article, it's possible to combine a number of rules into one '.procmailrc' recipe file. The following .procmailrc file incorporates most of the ideas you learned previously into a single recipe file. Note the second rule which contains two criteria which must be satisfied before the mail is forwarded to another e-mail address. # Once again, remove these lines when you're satisfied # that everything is working properly. :0 c: Mail/backup.folder # This rule will forward all mail from peter with the # word 'compilers' in the subject to the e-mail address # 'firstname.lastname@example.org' :0 * ^From.*peter * ^Subject:.*compilers ! email@example.com # Save all mail from 'cse-dept' to an Elm folder. :0: * ^From.*cse-dept Mail/deptmail.folder # Save any mail with 'scuba' in the Subject: to an Elm # folder. Note that if for some reason you received # mail from the 'cse-dept' about 'scuba', the message would # have be saved to the first folder rather than this one. :0: * ^Subject:.*scuba Mail/scuba.folder
PATH=/bin:/usr/bin:/software/common/bin MAILDIR=$HOME/mailroom #you'd better make sure it exists LOGFILE=$MAILDIR/procmail.log #recommended # Vacation work-alike (3/6/98) Accurso # # This is an annotated and slightly modified version of the # vacation work-alike example given in "man procmailex". # The use of ^TO is the significant modification. # See also "man procmailrc". # # First we must decide whether to send an auto reply. # All the egrep conditions (* lines) must be satisfied. # If so, headers (h) of the current message are fed to # formail which checks the vacation.cache to find out # if the sender has already received an auto reply. # We will lock vacation.lock while processing this # recipe to avoid clashes when updating the cache. # # This recipe waits (W) for a return from formail. # Without the (c) procmail would stop processing # after completing this recipe because it is # a delivery recipe, it delivers headers to formail. # # The conditions ^TO and ^FROM_DAEMON are more than # meet the eye. # # ^TOzz1demo is satisfied if zz1demo # appears in any recipient header To: Cc: Bc:. # This avoids sending auto replies to messages that # were addressed to an alias or maillist, but not # explicitly to zz1demo. # # !^FROM_DAEMON makes sure we do not auto reply to # messages from any of a wide variety of daemons. # # "!^X-Loop: firstname.lastname@example.org" avoids replying # to our own auto reply, notice below that this X-Loop # header is inserted into the auto replies we send out. SHELL=/bin/sh # for other shells, this might need adjustment :0 Whc: vacation.lock * ^TOzz1demo * !^FROM_DAEMON * !^X-Loop: email@example.com | formail -rD 8192 vacation.cache # Due to (e) recipe below is executed if the preceding one # returns an error status. In this case it is not really # and error, it is just the signal from formail to go # ahead with the auto reply. Notice that if in the # preceding recipe the egrep conditions are not met # and that causes the formail cache check to be # skipped, procmail is [somehow] clever enough to skip # this recipe. # # The headers (h) of the current message are fed to the # formail in this recipe in order to construct the # headers for the auto reply. # # The (c) in this recipe causes the whole # current message to be processed after this recipe. # Typically that means it will be processed with no # further recipies and that is how you get a copy in your # mailbox. There is no need for a lock while executing # this recipe so none is used. :0 ehc # if the name was not in the cache | (formail -rA"Precedence: junk" \ -A"X-Loop: firstname.lastname@example.org" ; \ echo "I received your mail, but I will be away"; \ echo "from the office until Monday Dec 15th."; \ echo " ";\ echo "If this is an urgent matter, please call my office XXX-XXXX ";\ echo " ";\ cat $HOME/.sig \ ) | $SENDMAIL -oi -t
# This procmailrc will automatically reject and bounce mail from # certain addresses. NOTE: DO NOT USE THIS FOR SPAM! Only use it for # folks that you know have a valid return address. # # This file can be dropped into your home directory as '.procmailrc', or # inserted into your existing '.procmailrc', with or without the # comments. # -zz1sn 2/18/98 # # The :0 is the start of a rule. Note, blank lines in a rule are NOT # happy. Don't insert any blank lines between the :0 and the line with # $SENDMAIL, or the rule won't work. Also, don't put any comments # within the rule, either. # # The *^From:.*example.*nuisance # line indicates the string you want to match. If the From # header in the e-mails you want to match looks something like # From: Block Head <email@example.com> # you can use a rule like: *^From:.*llarry.*ancientgames # or perhaps something like *^From:.*Block Head # (Remember, case is important - capitals are different from lowercase!) # # You want to be as specific as possible, but general enough to # catch the person's e-mails. The '*^From: bit ensures that the # rule only matches on the 'From:' header, and the '.*' sequence # is a wildcard (match 0 or more occurrences of any character). # # Replace 'example.*nuisance' with your expression; otherwise, this # rule won't do a thing. # # If you want to reject mail from more than one source you can # repeat the whole rule (from the :0 line to the SENDMAIL line) # as many times as necessary in your .procmailrc file. Put # a blank line between rules. # # This rule bounces the mail. First, it pipes through a series of # commands that generate a new e-mail. 'formail' takes the old e-mail # and generates a response; we replace the 'From:' line with # 'firstname.lastname@example.org' (which silently discards all mail) to prevent # mail loops caused by ricocheting bounces. # # We then pipe the result through $SENDMAIL -oi -t, which tells # sendmail to ignore dots as end-of-file markers, and to grab the # sender/recipient info from the message body. # # Note syntax; anything that should be in the message needs to go in # an 'echo' statement inside the parentheses. It should be # double-quoted, and should not contain funny characters (*, $, etc.). # The ' \' (space-backslash) needs to be at the end of each line # except the last to indicate that technically the entire rule belongs # on one line. # :0 *^From:.*example.*nuisance |( formail -rI"From: Responses will be automatically discarded <email@example.com>"; \ echo "Your mail has been administratively rejected."; \ echo "It was NOT received." \ ) | $SENDMAIL -oi -t
# This procmailrc will automatically reject and discard mail from # certain addresses. # # This file can be dropped into your home directory as '.procmailrc', or # inserted into your existing '.procmailrc', with or without the # comments. # -zz1sn 3/09/98 # # The :0 is the start of a rule. Note, blank lines in a rule are NOT # happy. Don't insert any blank lines between the :0 and the line with # $SENDMAIL, or the rule won't work. Also, don't put any comments # within the rule, either. # # The *^From:.*example.*nuisance # line indicates the string you want to match. If the From # header in the e-mails you want to match looks something like # From: Block Head <firstname.lastname@example.org> # you can use a rule like: *^From:.*llarry.*ancientgames # or perhaps something like *^From:.*Block Head # (Remember, case is important - capitals are different from lowercase!) # # You want to be as specific as possible, but general enough to # catch the person's e-mails. The '*^From: bit ensures that the # rule only matches on the 'From:' header, and the '.*' sequence # is a wildcard (match 0 or more occurrences of any character). # # Replace 'example.*nuisance' with your expression; otherwise, this # rule won't do a thing. # # This rule silently discards all mail containing the matched From: # address. If you want to discard mail from more than one address, # duplicate the entire 3-line rule, from :0 to /dev/null (changing the # wildcard expression appropriately) # # :0 *^From:.*example.*nuisance /dev/null
RESOLVING PROBLEMS WITH PROCMAIL If you're having problems with Procmail, you might want to see a Zebra in person: Zebra hours and locations. The full documentation for Procmail is available online under the Unix "man" command. Look under the "man procmail" command for an introduction to the available documentation.