slocal - MH receive-mail hooks
slocal $HOME/.maildelivery [-form formfile] [switches for
postproc] address... [-help]
/usr/lib/mh/rcvpack file [-help]
/usr/lib/mh/rcvtty [command...] [-help]
A receive-mail hook is a program that is run whenever you
receive a mail message. You do not invoke the hook yourself;
it is invoked on your behalf by sendmail, when you
include the following line in your file in your home
"| /usr/lib/mh/slocal -user username"
The file, which is an ordinary ASCII file, controls how
local delivery is performed. This file is read by slocal.
The format of each line in the file is:
field pattern action result string
These components are explained below: The name of a field
that is to be searched for a pattern. This is any field
in the headers of the message that might be present. In
addition, the following special fields are also defined:
source: the out-of-band sender information
addr: the address that was used to cause delivery
to the recipient
default: this matches only if the message has not
been delivered yet
*: this always matches The sequence of characters
to match in the specified field. Matching is caseinsensitive
but not Regular Expression-based. The
action to take to deliver the message. This is one
of the following: Append the message to the file
named by string using the standard maildrop delivery
process. If the message can be appended to the
file, then this action succeeds. When writing to
the file, a new field is added: This field indicates
the date and time at which the message was
appended to the file. Pipe the message as the
standard input to the command named by string. The
Bourne shell, sh(1), is used to interpret the
string. Prior to giving the string to the shell, it
is expanded with the following built-in variables:
$(sender): the return address for the message
$(address): the address that was used to cause
delivery to the recipient
$(size): the size of the message in bytes
$(reply-to): either the Reply-To: or From: field of
$(info): miscellaneous out-of-band information
When a process is invoked, its environment is as
follows: the user/group id's are set to recipient's
id's; the working directory is the recipient's
directory; the umask is 0077; the process has no
/dev/tty; the standard input is set to the message;
the standard output and diagnostic output are set
to /dev/null; all other file-descriptors are
closed; the environment variables $USER, $HOME, and
$SHELL are set appropriately; no other environment
The process is given a certain amount of time to
execute. If the process does not exit within this
limit, it is terminated. The amount of time is calculated
as ((size x 60) + 300) seconds, where size
is the number of bytes in the message.
The exit status of the process is consulted to
determine the success of the action. An exit status
of 0 means that the action succeeded. Any other
exit status (or abnormal termination) means that
the action failed.
In order to avoid any time limitations, you might
implement a process that began by forking. The parent
would return the appropriate value immediately,
and the child could continue to do whatever it
wanted for as long as it wanted. This approach
should only be used if you do not care about the
outcome of the action, because the success or failure
of the child process cannot be passed back to
slocal. However, if the parent is going to return a
non-zero exit status, then this approach can lead
to quicker delivery into your maildrop. This is
similar to pipe, but executes the command directly,
after built-in variable expansion, without assistance
from the shell. This action always succeeds.
Indicates how the action should be performed. The
following values are valid: Perform the action. If
the action succeeded, then the message is considered
delivered. Perform the action. Regardless of
the outcome of the action, the message is not considered
delivered. Perform the action only if the
message has not been delivered. If the action succeeded,
then the message is considered delivered.
The file is always read completely, so that several
matches can be made and several actions can be taken. The
file must be owned either by the user or by root, and must
be writable only by the owner. If the file cannot be
found, or does not perform an action which delivers the
message, then the file /usr/lib/mh/maildelivery is read
according to the same rules. This file must be owned by
the root and must be writable only by the root. If this
file cannot be found or does not perform an action which
delivers the message, then standard delivery to the user's
maildrop, /usr/spool/mail/$USER, is performed.
Arguments in the file are separated by a comma (,) or by
white space. Since double quotes are honored, these characters
may be included in a single argument by enclosing
the entire argument in double quotes ("). A double quote
can be included by preceding it with a back-slash.
Four programs are currently available: rcvdist redistributes
incoming messages to additional recipients; rcvpack
saves incoming messages in a packf(1) file; and
rcvtty notifies the user of incoming messages. The fourth
program, rcvstore, is described in the rcvstore(1) reference
page. They all reside in the /usr/lib/mh directory.
The rcvdist program resends a copy of the message to all
of the addresses listed on its command line. It uses the
format string facility described in mh-format(4).
The rcvpack program appends a copy of the message to the
file listed on its command line. It is made obsolete by
The rcvtty program executes the named file with the message
as its standard input, and gives the resulting output
to the terminal access daemon for display on your terminal.
If the terminal access daemon is unavailable on your
system, then rcvtty writes the output to your terminal,
only if your terminal has world-writable permission. If no
valid file is specified, then rcvtty gives a one-line scan
listing to the terminal access daemon.
For compatibility with older versions of MH, if slocal
cannot find the user's file, it attempts to execute an
old-style rcvmail hook in the user's $HOME directory.
Specifically, it first attempts to execute the command:
.mh_receive file maildrop directory user
Failing that it attempts to execute:
$HOME/bin/rcvmail user file sender
If both of these fail, it gives up and write to the user's
In addition, whenever a hook or process is invoked, filedescriptor
three (3) is set to the message in addition to
the standard input.
Only two return codes are meaningful, others should be.
This section shows how slocal could be used.
In this example, line-by-line comments have been extracted
from the code to aid readability of the example. The line
numbers would not normally be in the code; they are there
to help you. The code fragment precedes the explanation:
field pattern action result string
(1) To mmdf2 file A mmdf2.log
(2) From mmdf pipe A err-messagearchive
(3) Sender uk-mmdf file ? mmdf2.log
(4) To Unix > A unix-news
(5) addr jpo=mmdf | A mmdf-redist
(6) addr jpo=ack | R resend -r
(7) From steve destroy A -
(8) default - > ? mailbox
(9) * - | R rcvalert
File mail with mmdf2 in the To: line into file mmdf2.log.
Messages from mmdf are piped to the program err-messagearchive.
Take anything with the address uk-mmdf in the
Sender: field, and file it in mmdf2.log, if it has not
already been filed by line 1. Put messages addressed to
Unix in the file unix-news. If the address is jpo=mmdf,
pipe the message into mmdf-redist. If the address is
jpo=ack, send an acknowledgement copy back. Destroy anything
from steve. Take anything that is not matched yet
and put it into mailbox. Always run rcvalert.
The system customization file. The system default file
controlling local delivery. The user-supplied alternative
to the system default file controlling local delivery.
[ Back ]