DELIVER(8)

NAME
deliver - deliver local mail

SYNOPSIS
deliver [ options ] address ...

DESCRIPTION
The deliver program collects a mail message from the standard input and delivers it. It is intended to take over the delivery of all local mail, a job usually handled by /bin/mail (System V), /usr/lib/sendmail (BSD), or /usr/lib/mail/mail.local (Xenix).

deliver introduces flexibility in the handling of local mail delivery. All files used to control deliver are shell scripts. Thus anything that can be called by a shell script can be used to control mail delivery.

OPTIONS

-b  Interpret all arguments as mailbox filenames instead of addresses. Note that the user running deliver must have write permissions on the given mailbox files. He may also need write permissions on their parent directories, depending on the existence of the mailbox file and the local locking protocol.

-n  Interpret arguments as addresses, but do not run any delivery files; simply deliver the message to the mailbox(es) of the given user(s). This option is most useful when deliver is executed recursively, since it prevents further recursion.

-A  Print resolved addresses; do not deliver the message. Note that deliver still collects a message from the standard input, since delivery files may do different things depending on message content. For simple testing, redirect standard input from /dev/null.

-d  Be verbose; don't deliver to any mailboxes or catch any signals.

-v  Be verbose, but still deliver.

-t  Do not remove temporary files before exiting.

-r sender
    Put sender on the generated From_ line. Default is to use the address on the From_ line in the input, or else the name corresponding to the real uid, or else "unknown".

-h hostname
    Set the host name. The default is configuration dependent.

-s system delivery file
    Specify an alternate system delivery file. The default is /usr/local/lib/deliver.sys. For security reasons, this option disables setuid privileges.

-p post-user delivery file
    Specify an alternate post-user delivery file. The default is /usr/local/lib/deliver.post. For security reasons, this option disables setuid privileges.

-e error delivery file
    Specify an alternate error delivery file. The default is /usr/local/lib/deliver.err. For security reasons, this option disables setuid privileges.

-u user delivery file
    Specify an alternate user delivery file. The default is .deliver (in each user's home directory). For security reasons, this option disables setuid privileges.

All command line options are put into environment variables, examined by deliver on startup; thus all flags are propagated when deliver is invoked recursively.

ENVIRONMENT
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; or individual users can invoke deliver by mentioning it in their .forward files.

For Xenix systems, deliver may be used as a direct replacement for /usr/lib/mail/mail.local.

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. Any postmaster motivated enough to install deliver, and who wants something better than the standard /bin/rmail, should install smail.

OPERATION
By default, deliver deposits mail in the system mailbox for the named user(s). Also, as a necessity for use with smail 2.x, deliver also understands UUCP-style bang addresses well enough to forward the message correctly, using uux.

However, this basic behavior only scratches the surface: the usefulness of deliver derives from its flexibility; its behavior can be made to depend on the recipient(s), content or any other aspect of mail messages.

When deliver starts execution, it interprets its arguments in one of three ways. If the -b (mailbox) option was specified, then all arguments are interpreted as mailbox pathnames. Otherwise, if a system delivery file exists and the -n (no delivery files) option was not specified, deliver executes the system delivery file with all of deliver's arguments as its arguments. deliver interprets the delivery file's output as described below. This procedure gives the postmaster control over delivery to non-existent hosts and users. If the -n option is specified or if there is no system delivery file, deliver interprets all its arguments as mail addresses.

After possibly executing the system delivery file, deliver looks in its list of destinations for valid user names without explicitly named mailboxes. If any of these users have user delivery files in their home directories, and if the -n option was not specified, deliver executes each user's delivery file with the name of the given user as its only argument.

After executing any user delivery files, deliver looks in its list of destinations for simple user names and UUCP addresses. If any are found, if the post-user delivery file exists, and if the -n option was not specified, deliver executes the post-user delivery file with these addresses as its arguments.

After executing the post-user delivery file (if any), deliver attempts delivery to all requested destinations.

After delivery to all destinations, deliver looks in its list of destinations for failures of any kind. If any failed destinations are found, and if the -n option was not specified, deliver executes the error delivery file with the complete list of failed addresses as its arguments. If the error delivery file generates any destinations, deliver attempts delivery to them. However, if such delivery fails, deliver will not execute the error delivery file more than once.

DELIVERY FILES
Delivery files are shell scripts. They are executed by deliver to control delivery to users. Note that delivery files do not control delivery to explicitly named mailboxes. (See the -b option.)

The default shell used to execute delivery files is configuration-dependant. Typically it is the Bourne shell (/bin/sh). However, you can make deliver execute a given delivery file with a different shell by putting a Berkeley-style "#!" line at the top of the delivery file. For example, if the first line of a delivery file is "#!/bin/perl", then deliver will execute /bin/perl instead of /bin/sh, but only for that one delivery file.

On each system the postmaster may create a system delivery file to controls delivery of all messages. The system delivery file, if it exists, is executed with the name(s) specified on the deliver command line as its arguments.

The postmaster may also create a post-user delivery file which is executed after any user delivery files, but before delivery of the message to any mailboxes. This file is particularly useful for implementing system-wide aliases, since it can deal with addresses generated by user delivery files, whereas the system delivery file cannot.

Each user may create a user delivery file in his home directory. User delivery files are always executed with exactly one argument: the name of the user in whose home directory the file is found.

Finally, the postmaster may create an error delivery file. After deliver has attempted delivery to all requested destinations, and if delivery to one or more of those destinations failed, deliver executes the error delivery file with the list of failed adresses as its arguments. Note that failed addresses may contain whitespace, shell metacharacters or other strangeness--be careful!

Recursive execution of deliver is useful, especially with 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 default mailbox:

(cat $HEADER; tr '[A-Z]' '[a-z]' <$BODY) | deliver -n "$1"

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 automatically 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. DELLEVEL The deliver recursion level. Each time deliver is called recursively, this value is incremented. When the maximum recursion level (default: eight) is exceeded, deliver assumes infinite recursion and aborts. DELFLAGS The command line flags, if any, specified on the deliver command line.

SYSDELFILE
    The system delivery filename.

POSTDELFILE
    The post-user delivery filename.

ERRDELFILE
    The error delivery filename.

USERDELFILE
    The user delivery filename, relative to the home directory of each user.

HOSTNAME
    The local host name, either the real hostname or a name specified with the -h option to deliver.

SENDER
    The sender, either an address specified with -r option to deliver, or the address given in the From_ line of the message, or the user who invoked deliver.

HEADER
    The name of the temporary file containing the message header.

BODY
    The name of the temporary file containing the message body.

deliver monitors the standard output of delivery files for lines in four formats:

host1!host2!user
    Send the message with UUCP via the given bang path.

user
    Append the message to the given user's default mailbox. The location of a user's default mailbox is configuration-dependant.

user:mailbox
    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. For security reasons, only the superuser may request delivery to a specific mailbox in another user's context.

user|command
    Execute the specified command in the given user's context, and feed the message to its standard input. For security reasons, only the superuser may request command execution in another user's context.

user?error message
    Do not attempt delivery to the given user. Diagnostic messages, including the bounce notice (if any), will include the specified message. For security reasons, only delivery files executing as the superuser may report an error for another user.

Note that for the "user:mailbox", "user|command" and "user?error message" forms, the user name may be omitted (for example: "?Sorry"). If the user name is omitted, the current user context is assumed.

UNDELIVERED MAIL
When deliver executes a delivery file, it expects a complete list of all users (and, optionally, mailboxes) that should receive the message. If a delivery file produces no output, deliver saves the message in the "undelivered mail" mailbox named "Undel.mail" in the home directory of the delivery file's owner. (System, post-user and error delivery files are "owned" by root.)

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 message by outputting the string "DROP". A delivery file's outputting "DROP" the "undelivered mail" safety net for that delivery file. Think of "DROP" as shorthand for: "Trust me. I know what I'm doing." However, if the delivery file outputs any names and/or addresses in addition to "DROP", then "DROP" has no effect.

Note, however, that the error delivery file is an exception to the "DROP" rule. The error delivery file never receives valid addresses as arguments, so producing no output is considered completely normal.

SECURITY
If deliver is setuid root -- which it should be for normal operation -- then the system delivery file is executed as root. Be very careful about its permissions and its contents! Carelessness 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 mailbox as another user. Otherwise, any user could modify other users' private files.

LOGGING
Deliver records its activity in two files: the "delivery log", named /usr/adm/deliver.log, and the "error log", named /usr/adm/deliver.errlog.

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. Note that deliver will write to the delivery log only if it already exists.

The error log is a record of any problems encounted during delivery. Each error log entry includes all diagnostic output, a copy of the message header, and other miscellaneous information that might prove helpful.

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 file.

If you want a delivery log, you must create the delivery log file yourself. If the delivery log file does not exist, deliver will not create it.

If the -v (verbose) flag is specified, deliver will not write to the error log.

LOCKING
Several preprocessor labels may be defined during compilation to control the method(s) used by deliver to lock mailboxes. These labels are:

    ML_DOTLOCK Lock on exclusive creation of the mailbox name with ".lock" appended. (Version 7 and early BSD mailers use this method.)

    ML_DOTMLK Lock on exclusive creation of /tmp/basename.mlk, where basename is the last component of the mailbox pathname. (Xenix mailers use this method.)

    ML_LOCKF Exclusively lock mailbox with lockf().

    ML_FCNTL Exclusively lock mailbox with fcntl().

    ML_LOCKING Exclusively lock mailbox with locking().

One or both of ML_DOTLOCK and ML_DOTMLK may be specified. At most one of ML_LOCKF, ML_FCNTL or ML_LOCKING may be specified.

FILES
/usr/local/lib/deliver.sys system delivery file
/usr/local/lib/deliver.post post-user delivery file
/usr/local/lib/deliver.err error delivery file
~user/.deliver user delivery file(s)
/usr/adm/deliver.log delivery log
/usr/adm/deliver.errlog error log
/etc/systemid system name (Xenix only)

SUPPORT
Enhancements, enhancement requests, trouble reports, etc., should be mailed to <chip@tct.uucp> or <uunet!ateng!tct!chip>.

SEE ALSO
mail(1), uux(1), smail(8), sendmail(8)