procmail - autonomous mail processor [ ] ...
[ ]

DESCRIPTION
For a quick start, see at the end. should be invoked automatically over the file mechanism as soon as mail arrives. Alternatively, when installed by a system administrator, it can be invoked from within the mailer immediately. When invoked, it first sets some environment variables to default values, reads the mail message from stdin until an EOF, separates the body from the header, and then, if no command line arguments are present, it starts to look for a file named in your home directory. According to the processing recipes in this file, the mail message that just arrived gets distributed into the right folder (and more). If running suid root or with root priviliges, procmail will be able to perform as a functionally enhanced, backwards compatible mail delivery agent.

  Defaults
Your (the recipient's) defaults &|<>~;?*[]= -c /usr/spool/mail/$USER $HOME $ORGMAIL msg. /bin/smail .lock $DEFAULT$LOCKEXT
(only if in explicit delivery mode and no rcfile is found)

  Environment
Before you get lost in the multitude of environment variables, keep in mind that all of them have reasonable defaults. Current directory while procmail is executing (that means that all paths are relative to $MAILDIR). Default file (if not told otherwise, procmail will dump mail in this mailbox). Filename prefix that is used when delivering to a directory (not used when delivering to an MH directory). All incoming messages will be logged here with their `From ' and `Subject:' lines in the header, and an additional line specifying what folder it finally went to and how long (in bytes) the message was. This file will also contain any error or diagnostic messages from procmail (normally none :-) or any other programs started by procmail. If this file is not specified it defaults to You can turn on by prepending a `:' to the desired pathname. Anything assigned to this variable will be echoed in $LOGFILE. Usually the system mailbox (ORiGinal MAILbox). If, for some obscure reason (like `filesystem full') the mail could not be delivered, then this mailbox will be the last resort. If procmail fails to save the mail in here (deep, deep trouble :-), then the mail will bounce back to the sender. Global semaphore file. If this file already exists, procmail will wait until it has gone before proceeding, and will create it itself (cleaning it up when ready, of course). If more than one are specified, then the previous one will be removed before trying to create the new one. Default extension that is appended to a destination file to determine what local to use (only if turned on, on a per-recipe basis). Number of seconds procmail will sleep before retrying on a (if it already existed); if not specified, it defaults to 8 seconds. Number of seconds that have to have passed since a was last modified/created before procmail decides that this must be an erroneously leftover lockfile that can be removed by force now. If zero, then no timeout will be used and procmail will wait forever until the lockfile is removed; if not specified, it defaults to 3600 seconds. This variable is useful to prevent indefinite hangups of Number of seconds that have to have passed before procmail decides that some child it started must be hanging. The offending program will receive a TERMINATE signal from procmail, and processing of the rcfile will continue. If zero, then no timeout will be used and procmail will wait forever until the child has terminated; if not specified, it defaults to 3540 seconds. If this is not the of the machine, processing of the current will immediately cease. If other rcfiles were specified on the command line, processing will continue with the next one. If all rcfiles are exhausted, the program will terminate, but will not generate an error (i.e. to the mailer it will seem that the mail has been delivered). Only the first 8 characters of the HOST are significant. The name says it all (if it doesn't, then forget about this one :-). It is taken as an number. If not specified, it defaults to 077. If any of the characters in SHELLMETAS appears in the line specifying a filter or program, the line will be fed to $SHELL instead of being executed directly. Any invocation of $SHELL will be like:
"$SHELL" "$SHELLFLAGS" "$*"; If you're not using the facility don't worry about this one. It specifies the program being called to forward any mail.
It gets invoked as: "$SENDMAIL" "$@"; Number of retries that are to be made if any `process table full', `file table full', `out of memory' or `out of swap space' error should occur. If this number is negative, then procmail will retry indefinitely; if not specified, it defaults to two times. The retries occur with a $SUSPEND second interval. The idea behind this is, that if the has been exhausted or the is full, usually several other programs will either detect this and abort or crash 8-), and thereby freeing valuable for procmail. Number of seconds that procmail will pause if it has to wait for something that is currently unavailable (memory, fork, etc.); if not specified, it will default to 16 seconds. See also: Length of the internal line buffers, cannot be set smaller than 128. All lines read from the rcfile the mail itself, which can have arbitrary line lengths, or could be a binary file for that matter) should not exceed $LINEBUF characters before and after expansion. If not specified, it defaults to 2048. If set (to a dummy value) procmail will pretend (to the mail agent) the mail has been delivered. If mail cannot be delivered after meeting this assignment, the mail will be lost (i.e. it will not bounce).

  Signals
Terminate prematurely and requeue the mail. Terminate prematurely and bounce the mail. Terminate prematurely and bounce the mail. Terminate prematurely and silently lose the mail. Force a timeout (see

OPTIONS
Procmail will print its version number and exit. Preserve any old environment. Normally procmail clears the environment upon startup. However, in any case: any default values will override any preexisting environment variables, i.e. procmail will not pay any attention to any predefined environment variables, it will happily overwrite them with his own defaults. Make procmail fail softly, i.e. if procmail cannot deliver the mail to any of the destinations you gave, the mail will not bounce, but will return to the mailqueue. Another delivery-attempt will be made at some time in the future. This turns on explicit delivery mode, delivery will be to the local user This, of course, only is possible if procmail has root priviliges. For security reasons procmail will refuse to accept more arguments when using this mode, procmail will setuid to the intended recipient and will read the recipient's .procmailrc file (if present, if not, delivery is like ordinary mail).

ARGUMENTS
Any arguments containing an '=' are considered to be environment variable assignments, they will be evaluated after the default values have been assigned and before the first rcfile is opened. Any other arguments are presumed to be rcfile paths (absolute or relative to $HOME); procmail will start with the first one it finds on the command line. The following ones will only be parsed if the preceding ones have a not matching HOST-directive entry, or in case they should not exist. If no rcfiles are specified, it looks for If not even that can be found processing will continue according to the default settings of the environment variables and the ones specified on the command line.

RCFILE FORMAT
Environment variable and can be freely intermixed in the rcfile. If any environment variable has a special meaning to procmail, it will be used appropiately the moment it is parsed. (i.e. you can change the current directory whenever you want by specifying a new switch lockfiles by specifying a new (usually one won't need this particular application though), change the umask at any time, etc., the possibilities are endless :-). The assignments and substitutions of these environment variables are handled exactly like in (that includes all possible quotes and escapes), with the added bonus that blanks around the '=' sign are ignored and that, if an environment variable appears without a trailing '=', it will be removed from the environment.

  Comments
A word beginning with # and all the following characters up to a NEWLINE are ignored.

  Recipes
A line starting with ':' marks the beginning of a recipe. It has the following format: : The is optional (defaults to 1) and specifies the number of conditionals following this line. Conditionals are complete lines that are passed on to the internal egrep except for leading blanks. If a conditional starts with an '!', the condition is inverted. If you really want the conditional to start with an '!', precede the '!' by a '\'. These conditionals are compatible to the normal egrep regular expressions. Conditionals are anded; if is zero, then the condition is always true and no conditionals are expected next. can be any of the following: Egrep the header (default). Egrep the body. Tell the internal egrep to distinguish between upper and lower case (defaults to ignoring case). This recipe will depend on the last preceding recipe without the `A' or `a' flag. This allows you to chain actions that depend on a common condition. The number of conditionals that are expected to follow default to none. Has the same meaning as the `A' flag, but will depend on the completion of the immediately preceding recipe as well. Feed the header to the pipe (default). Feed the body to the pipe (default). Consider the pipe as a filter (ignored if a file). Continue processing rcfile even if this recipe matches (not needed if 'f' specified). Wait for the filter or program to finish and check its exitcode (normally ignored); if the filter is unsuccessful, then the text will not have been filtered. This flag is also recommended if you specified any on this recipe. Ignore any write errors on this recipe (i.e. usually due to an early closed pipe).

  Local lockfile
If you put a second ':' on the first recipe line, then procmail will use a (for this recipe only). You optionally can specify the locallockfile to use; if you don't however, procmail will use the filename specified as the destination (or the filename following the first '>>') and will append $LOCKEXT to it.

  Recipe destination
The next line can start with the following characters: Forwards to all the specified mail addresses. Starts the specified program, possibly in $SHELL if any of the characters $SHELLMETAS are found. Anything else will be taken as a mailbox name (either a filename or a directory, absolute or relative to the current directory (see $MAILDIR)). If it is a filename (or nonexistent), the mail will be appended to it. If it is a directory, the mail will be delivered to a newly created, guaranteed to be unique, file named $MSGPREFIX* in the specified directory. If the directory name ends in "/.", then this directory is presumed to be an MH folder; i.e. procmail will use the lowest number it finds available.

EXAMPLES
Some example recipes are listed below:
Sort out all mail to mailling list scuba-dive. : ^TOscuba scubafile Forward all mail from peter about compilers to william (and keep a copy of it here in petcompil). :2 bc ^From.*peter ^Subject:.*compilers ! william@somewhere.edu :A petcompil Add the headers of all messages that didn't come from the postmaster to your private header collection (for statistics or mail debugging); and use the lockfile `headc.lock'. In order to make sure the lockfile is not removed until the pipe has finished, you have to specify option 'w'; otherwise the lockfile would be removed as soon as the pipe has accepted the mail. :hwc: !From +(postmaster|Mailer) | uncompress headc.Z; cat >>headc; compress headc

CAVEATS
If you don't explicitly tell procmail to wait (recipe option 'w') for a program to finish, it won't wait and will terminate early (not knowing if the program returns success). That also means that any locallockfile on this recipe might get removed the program has terminated. Continued lines in a recipe that are to be executed are concatenated being parsed, hence backslash-newline combinations in them are removed regardless. Don't put comments on the condition lines (the regular expressions) in a recipe, these lines are fed to the internal egrep (Except for any whitespace, `!' or `\', it will be stripped. Precede it by a `\' if you want it to be taken literally too.) Watch out for deadlocks when doing unhealthy things like forwarding mail to your own account. Deadlocks can be broken by proper use of Any default values that procmail has for some environment variables will override the ones that were already defined. If you really want to override the defaults, you either have to put them in the or in the command line as arguments.

FILES
to get the recipient's USER, HOME and SHELL variable defaults system mailbox default rcfile lockfile for the system mailbox (automatically used if no rcfile is found, not used by procmail otherwise unless you explicitly tell it to) default mail forwarder temporary `unique' zero-length files created by procmail

SEE ALSO

DIAGNOSTICS
Bad substitution of "x" Not a valid environment variable name specified. Couldn't unlock "x" Lockfile was already gone, or write permission to the directory were the lockfile is has been denied. Error while writing to "x" Nonexistent subdirectory, no write permission, pipe died or disk full. Exceeded LINEBUF Buffer overflow detected, LINEBUF was too small, memory might be corrupted. Failed forking "x" Process table is full (and NORESRETRY has been exhausted). Failed to execute "x" Program not in path, or not executable. Forced unlock denied on "x" No write permission in the directory where resides, or more than one procmail trying to force a lock at exactly the same time. Forcing lock on "x" Specified is going to be removed by force because of a timeout (see also: Lock failure on "x" Can only occur if you specify some real weird (and illegal) lockfilenames or if the could not be created because of insufficient permissions or noexistent subdirectories. Mail bounced Procmail hasn't been able to deliver the mail correctly. Mail lost Procmail could not bounce or requeue the mail anymore. Mail requeued Procmail could not deliver the mail, another delivery attempt will be done some time in the future. Out of memory The system is out of swap space (and NORESRETY has been exhausted). Processing continued The unrecognised options on the command line are ignored, proceeding as usual. Program failure of "x" Program that was started by procmail didn't return EX_OK (=0). Skipped: "x" Couldn't do anything with "x" in the rcfile (syntax error), ignoring it. Terminating prematurely whilst waiting for ... Procmail received a signal while it was waiting for ... Timeout, terminating "x" Timeout has occurred on program/filter "x". Truncating "x" and retrying lock "x" does not seem to be a valid filename or the file is not empty. Rescue of unfiltered data succeeded/failed A filter returned unsuccessfully, procmail tried to get back the original text. Unexpected EOL Missing closing quote, or trying to escape EOF.

EXTENDED DIAGNOSTICS
Assigning "x" Environment variable assignment Executing "x" Starting program "x" HOST mismatched "x" This host was called "x", HOST contained something else Locking "x" Creating lockfile "x" Match on "x" Conditional matched No match on "x" Conditional didn't match, recipe skipped Opening "x" Opening file "x" for appending Rcfile: "x" Rcfile changed to "x" Unlocking "x" Removing lockfile "x" again

WARNINGS
You should create a shell script that uses before invoking your mail shell on any mailbox file other than the system mailbox (unless of course, your mail shell uses the same lockfiles (local or global) you specified in your rcfile). In the unlikely event that you absolutely need to kill procmail before it has finished, first try and use the regular kill command (i.e. kill -9, see the subsection for suggestions), otherwise some might not get removed. Beware when using the option, if procmail repeatedly is unable to deliver the mail (e.g. due to an incorrect rcfile), the system mailqueue could fill up. This could aggravate both the local postmaster and other users. For security reasons, procmail will unset the IFS environment variable upon startup, even if the environment is supposed to be preserved.

BUGS
The only substitutions of environment variables that can be handled by procmail itself are of the type $name, ${name}, $$ and $-; whereas $- will be substituted by the name of the last folder delivered to. If the standard is case sensitive, and some users have login names with uppercase letters in them, procmail will be unable to deliver mail to them, unless started with their uid. After a lockfile is removed by force, a suspension of $SUSPEND seconds is taken into account, in order to prevent the inadvertent immediate removal of any newly created lockfile by another program. A line buffer of length $LINEBUF is used when processing the any expansions to fit within this limit; if they don't, behaviour is undefined. Procmail uses the regular TERMINATE signal to terminate any runaway filter, but it does not check if the filter responds to that signal and it only sends it to the filter itself, not to any of the filter's children. If the global lockfile has a path, and the current directory is not the same as when the global lockfile was created, then the global lockfile will not be removed if procmail exits at that point (remedy: use paths to specify global lockfiles). Some braindamaged mailers want lines that start with `From ' to be escaped, procmail only escapes those that could really be dangerous; to support those other mailers you should consider using as a filter for all your mail.

MISCELLANEOUS
Whitespace is ignored in the rcfile, except on the lines that are fed to the internal egrep where only leading whitespace is ignored; i.e. you can indent everything. If the regular expression starts with `^TO' it will be substituted by `^(To|Cc|Apparently-To):.*', which should catch all destination specifications. Any lines in the body of the message that look like postmarks are prepended with `>' (disarms bogus mailheaders). The regular expression that is used to search for these postmarks is: "\n\nFrom +[^\t\n ]+ +[^\t\n ]" Should the uid procmail is running under, have no corresponding /etc/passwd entry, then HOME will default to /tmp, USER will default to #uid. If /usr/spool/mail/$USER is a bogus mailbox (i.e. does not belong to the recipient, is unwritable, is a symbolic link or is a hard link), procmail will upon startup try to rename it into a file starting with `BOGUS.' and ending in an inode-sequence-code. If this turns out to be impossible, will have initial value. When delivering to directories (or to MH folders) you need to use lockfiles to prevent several concurrently running procmail programs from messing up. Delivering to MH folders is slightly more time consuming than delivering to normal directories or mailboxes, because procmail has to search for the first available number (instead of having the filename immediately available). On general failure procmail will return EX_CANTCREAT, unless option is specified, in which case it will return EX_TEMPFAIL. Procmail performs the locking in an NFS-secure way.

NOTES
For complicated processing you can even consider calling recursively.
If procmail is installed globally as the default mail delivery agent (ask your system administrator), you have to make sure it is invoked when your mail arrives. In this case your $HOME/.forward (beware, it to be world readable) file should contain (include the single and double quotes, be an path):
"|IFS=' ';exec /usr/local/bin/procmail #YOUR_LOGIN_NAME"

  A sample small .procmailrc:
PATH=/bin:/usr/bin:/usr/local/bin
MAILDIR=$HOME/Mail      #you'd better make sure it exists
DEFAULT=$MAILDIR/mbox
LOGFILE=$MAILDIR/from
LOCKFILE=$HOME/.lockmail
:
^From.*berg
from_me
:
^Subject:.*Flame
/dev/null

AUTHOR
Stephen R. van den Berg at RWTH-Aachen, Germany berg@messua.informatik.rwth-aachen.de berg@physik.tu-muenchen.de