DELIVER(8)DELIVER(8)NAMEdeliver - deliver mail
SYNOPSISdeliver [ options ] address ...
The Deliver program collects a mail message from the standard input and
delivers it. Deliver is capable of handling the delivery of all mail.
However, Deliver is typically hung off the end of an existing mail sys‐
tem, where it handles the delivery of some or all local mail, a job
usually done by /bin/mail (System V and BSD) or
The way Deliver handles each message is controlled by shell scripts
which, given the message to be delivered and a list of addresses, pro‐
duce as their output new lists of addresses. Such scripts, when called
by Deliver, are called ``delivery files.'' Deliver allows a site
administrator to write delivery files with global effects. In addi‐
tion, each user may write a delivery file to control delivery of mail
addressed to himself.
OPTIONS-b Interpret arguments as mailbox filenames instead of addresses.
The user who executes Deliver must have write permissions on all
mailbox files. He may also need write permissions on their par‐
ent directories, depending on the existence of the mailbox files
and the local locking protocol.
-n Deliver to the given address(es), but do not run any delivery
files. This option is most useful when Deliver is executed
recursively, because it cannot cause infinite recursion.
-A Collect the message, run delivery files and print the resolved
address(es). Do not deliver the message. Note that when this
option is specified, Deliver still collects a message from the
standard input, because delivery files may vary their output
based on message content. To test simple delivery files, redi‐
rect standard input from /dev/null.
-d Turn on verbosity, collect the message and run delivery files.
Do not deliver the message.
-v Turn on verbosity while performing all tasks, including deliv‐
-t Do not remove temporary files before exiting.
Specify localsender as the name of the local sender, that is,
the name of the user who invoked Deliver. This option is only
believed if it is a valid user name with a user id equal to the
real user id of the Deliver process. If it is invalid, or if it
is not specified, then Deliver tries the values of the LOGNAME
and USER environment variables, and then the login name corre‐
sponding to the tty on which Deliver is running. If none of
these names matches the real user id, Deliver looks up the user
name that corresponds to its real user id.
Put sender on the generated From_ line. Default is to use the
address on the From_ line in the input, or else the local
Set the host name. The default is determined in a site-specific
way, typically by asking the kernel.
-s system delivery file
Specify an alternate system delivery file. The default is
-p post-user delivery file
Specify an alternate post-user delivery file. The default is
-e error delivery file
Specify an alternate error delivery file. The default is
-u user delivery file
Specify an alternate user delivery file. The default is
.deliver (in each user's home directory).
For security reasons, specifying one or more of the options ``-h host‐
name'', ``-s sysdelfile'', ``-p postdelfile'', ``-e errdelfile'' or
``-u userdelfile'' disables setuid privileges. That is, Deliver
revokes its setuid privileges before doing anything significant, just
as if Deliver had been installed without the setuid bit turned on.
All command line options are put into environment variables, examined
by Deliver on startup; thus all flags are propagated when Deliver is
invoked recursively. Note that setting these environment variables is
exactly equivalent to specifying the equivalent command line options;
in particular, they can cause Deliver to disable setuid privileges as
described in the previous paragraph.
For mail systems based on Smail 2.x, the LMAIL (local mailer) macro can
be changed to call Deliver. For mail systems based on Smail 3.x or
sendmail, a similar arrangement may be made; otherwise, individual
users can invoke Deliver by mentioning it in their .forward files (e.g.
For Xenix systems, Deliver may be used as a direct replacement for
For stock Unix systems, it may be possible to make /bin/rmail a link to
Deliver; however, this configuration has not been tested and is not
recommended. After all, any postmaster motivated enough to install
Deliver, and who wants something better than the standard /bin/rmail,
should install Smail 2.x or 3.x.
When Deliver starts execution, it interprets its arguments in one of
(1) If the -b (mailbox) option is specified, then Deliver interprets
its arguments as mailbox pathnames.
(3) If the -n option is specified, then Deliver interprets its argu‐
ments as addresses.
(3) If neither the -b nor the -n option is specified, Deliver uses the
system, user and post-user delivery files (described below) to deter‐
mine the address(es) to receive the message.
After attempting delivery, Deliver looks in its list of destinations
for failures of any kind. If any failed destinations are found, and if
the -n option is not specified, Deliver executes the error delivery
file with the entire list of failed addresses as its arguments. If the
error delivery file generates any destinations, Deliver attempts deliv‐
ery to them. However, if such delivery fails, Deliver will not re-exe‐
cute the error delivery file.
Delivery files are shell scripts executed by Deliver to determine the
address(es) to receive a message. Note that delivery files have con‐
trol over delivery to users and remote addresses, but not over delivery
to explicitly named mailboxes. (See also the -b option.)
The default shell used to execute delivery files is configuration-
dependent. Typically it is the Bourne shell (/bin/sh). However, you
can arrange for Deliver to execute any given delivery file with any
given shell by starting the delivery file with a ``#!'' line in the
style of Berkeley UNIX. For example, if the first line of a delivery
file is ``#!/bin/perl'', then Deliver will execute that delivery file
with /bin/perl instead of /bin/sh.
The four kinds of delivery files are described below.
system delivery file
The system delivery file, if it exists, is created by the post‐
master. By default, it is named ``/usr/pkg/etc/deliversys''.
It controls the delivery of all messages on the system where it
is installed. It is executed with arguments of the name(s)
specified on the Deliver command line. (Note, however, that
arguments containing shell metacharacters are rejected before
the system delivery file is run.)
user delivery file
Each user may create a user delivery file in his home directory.
By default, it is named ``.deliver''. A user delivery file is
always executed with exactly one argument: the name of the user
in whose home directory the file is found.
post-user delivery file
The post-user delivery file, if it exists, is created by the
postmaster. By default, it is named ``/usr/pkg/etc/deliver‐
post''. It is executed after the system and user delivery
files, but before any attempt at message delivery. Its argu‐
ments are those addresses which are about to receive the mes‐
sage, whether those addresses originated with Deliver command
line arguments or with a system or user delivery file. This
delivery file is particularly useful for implementing system-
wide aliases, since it can modify or delete addresses generated
by user delivery files, something the system delivery file can‐
error delivery file
The error delivery file, if it exists, is created by the post‐
master. By default, it is named ``/usr/pkg/etc/delivererr''.
After Deliver has attempted delivery to all requested destina‐
tions, and if delivery to one or more of those destinations
failed, Deliver executes the error delivery file with arguments
of all failed addresses. Note that failed addresses may contain
whitespace, shell metacharacters or other strangeness -- be
When Deliver runs a delivery file, it monitors the delivery file's
standard output for delivery directives, one directive per line.
Directives can take five forms:
Append the message to the given user's default mailbox. The
location of a user's default mailbox is configuration-dependent.
Append the message to the specified mailbox in the given user's
context. If the mailbox name is not an absolute pathname, it is
interpreted relative to the given user's home directory. Only
the superuser may request delivery to a mailbox in another
Execute the specified command in the given user's context, and
feed the message to its standard input. Only the superuser may
request command execution in another user's context.
Do not attempt delivery to the given user. Diagnostic messages,
including the bounce notice (if any), will include the specified
message. Only the superuser may report an error for another
Send the message with UUCP via the given bang path.
Note that the ``user:mailbox'', ``user|command'' and ``user?error mes‐
sage'' forms may omit the ``user'' part, in which case the current user
context is assumed.
When Deliver executes a delivery file, it sets several environment
variables, listed below. Note that these environment variables are
both set and used by Deliver; therefore, all command line options auto‐
matically propagate when Deliver is run recursively (within a delivery
file). The environment variable names set and used by Deliver are:
DELPID The process id of the running Deliver process. Used by a child
Deliver to determine its parent's process id.
The Deliver recursion level. Each time Deliver is called recur‐
sively, this value is incremented. When the maximum recursion
level (default: eight) is exceeded, Deliver assumes infinite
recursion and aborts.
The command line flags that do not take arguments, if any, that
were specified on the Deliver command line.
The local host name, either the real hostname or a name speci‐
fied with the -h option to Deliver.
The system delivery filename.
The post-user delivery filename.
The error delivery filename.
The user delivery filename, relative to the home directory of
The local sender, that is, the user who invoked Deliver. This
value is not believed by recursive Deliver processes, since the
user who invokes the child may not be the same as the user who
invoked the parent.
SENDER The original sender of the message. This value can be the
address specified with the -r option to Deliver, or the address
given in the From_ line of the message, or the local sender.
HEADER The name of the temporary file containing the message header.
BODY The name of the temporary file containing the message body.
Recursive execution of Deliver is useful, especially when used with the
the -b (mailbox) and -n (no delivery files) flags. For example, a user
may wish to transform a message body before it is stored in a mailbox.
This may be done with a user delivery file and recursive execution of
Deliver. For example, the following user delivery file translates all
incoming message bodies to lower case, and stores them in the user's
( cat $HEADER; tr '[A-Z]' '[a-z]' <$BODY ) | deliver-n "$1"
When Deliver executes a delivery file, it expects the delivery file to
output a complete list of all addresses and/or mailboxes that should
receive the message. Therefore, if a delivery file produces no output
at all, Deliver assumes that there is a problem. In that case, to
avoid total loss of the message, Deliver saves it in the ``undelivered
mail'' mailbox, named ``Undel.mail'' in the home directory of the
delivery file's owner. For the purpose of undelivered mail, system,
post-user and error delivery files are considered to be owned by root.
Therefore, the postmaster should occasionally check ``/Undel.mail'' for
mail that went undelivered due to errors in the systemwide delivery
Sometimes a delivery file writer really does want Deliver to drop a
message. For example, if a delivery file stores a message by running
``deliver -b'', then there's no need for the parent Deliver to save the
message again. A delivery file can tell Deliver not to save the mes‐
sage by outputting the string ``DROP''. A delivery file's outputting
``DROP'' removes the undelivered mail safety net for that delivery
file. Think of ``DROP'' as shorthand for: ``Trust me. I know what I'm
doing.'' If the delivery file outputs any addresses before and/or
after ``DROP'', then the ``DROP'' has no effect.
The example delivery file given above never generates any output.
Therefore, it should always output ``DROP'':
( cat $HEADER; tr '[A-Z]' '[a-z]' <$BODY ) | deliver-n "$1"
Note that the error delivery file is an exception to the ``DROP'' rule.
After all, the error delivery file never receives valid addresses as
arguments, so no output is expected (though it is allowed).
If Deliver is setuid root -- which it should be for normal operation --
then the system, post-user and error delivery files are executed as
root. Be very careful about its permissions and its contents! Care‐
lessness here can easily create a security problem.
All user delivery files are executed in the context of the user in
whose home directory they reside. A user's ``context'' includes the
uid, gid, and home directory as specified in /etc/passwd.
For security reasons, if a user's home directory is writable to the
world, Deliver will ignore any delivery file that might be found there.
For security reasons, no user can request writing a specific mailbox
under another user's context. Otherwise, any user could modify other
users' private files.
For security reasons, Deliver will not write to a system mailbox if it
has more than one hard link.
Deliver records its activity in two files: the ``delivery log'', named
/var/log/deliver.log, and the ``error log'', named
The deliver log is a record of activity of each Deliver process. Each
delivery log entry include the users or mailboxes named on the command
line, the users and/or mailboxes where delivery succeeded, and those
where it failed.
The error log is a record of any problems encounted during delivery.
Each error log entry includes all diagnostic output, a copy of the mes‐
sage header, and miscellaneous other information.
If you want a delivery log, you must create the delivery log file your‐
self. If the delivery log file does not exist, Deliver will not create
If Deliver is performing a ``dry run'' -- that is, if the -d (debug) or
-A (print address) flag is specified -- it will not write to either log
If the -v (verbose) flag is specified, Deliver will not write to the
Several preprocessor labels may be defined during compilation to con‐
trol the method(s) used by Deliver to lock mailboxes. These labels
Lock on exclusive creation of the mailbox name with ``.lock''
appended. (Version 7 and early BSD mailers use this method.)
Lock on exclusive creation of /tmp/basename.mlk, where basename
is the last component of the mailbox pathname. (Xenix mailers
use this method.)
Exclusively lock mailbox with lockf().
Exclusively lock mailbox with fcntl().
Exclusively lock mailbox with locking().
Neither, one or both of ML_DOTLOCK and ML_DOTMLK may be specified.
None or one of ML_LOCKF, ML_FCNTL or ML_LOCKING may be specified.
/usr/pkg/etc/deliversys system delivery file
/usr/pkg/etc/deliverpost post-user delivery file
/usr/pkg/etc/delivererr error delivery file
~user/.deliver user delivery file(s)
/var/log/deliver.log delivery log
/var/log/deliver.errlog error log
/etc/systemid system name (Xenix only)
Please mail enhancements, enhancement requests, trouble reports, etc.
to <email@example.com>. See also the Debian GNU/Linux bug tracking system
SEE ALSOheader(1), mail(1), uux(1), smail(8), sendmail(8)
Deliver 2.1 DELIVER(8)