---
name: "deliver"
section: "8"
platform: "linux"
package: "deliver"
version: "2.1.14-4"
release: "Debian 4.0 (Etch)"
platforms: ["linux"]
url: "https://new.carta.tech/deliver/8"
---

# deliver(8)

deliver mail

## NAME

deliver - deliver mail

## SYNOPSIS

**deliver** \[ options \] address ...

## DESCRIPTION

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 system, where it handles the delivery of some or all local mail, a job usually done by */bin/mail* (System V and BSD) or */usr/lib/mail/mail.local* (Xenix).

The way *Deliver* handles each message is controlled by shell scripts which, given the message to be delivered and a list of addresses, produce 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 addition, 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 parent 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, redirect 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 delivery.

- **-t**

  Do not remove temporary files before exiting.

- **-l** *localsender*

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

- **-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 local sender.

- **-h** *hostname*

  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 */etc/deliver/sys.*

- **-p** *post-user delivery file*

  Specify an alternate post-user delivery file.  The default is */etc/deliver/post.*

- **-e** *error delivery file*

  Specify an alternate error delivery file.  The default is */etc/deliver/err.*

- **-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 hostname'', \`\`-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.

## 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; otherwise, individual users can invoke *Deliver* by mentioning it in their *.forward* files (e.g. \`\`\|/usr/bin/deliver myname'').

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

## DEFAULT OPERATION

When *Deliver* starts execution, it interprets its arguments in one of three ways.

(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 arguments 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 determine 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 delivery to them.  However, if such delivery fails, *Deliver* will not re-execute the error delivery file.

## DELIVERY FILES

Delivery files are shell scripts executed by *Deliver* to determine the address(es) to receive a message.  Note that delivery files have control 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 postmaster. By default, it is named \`\`/etc/deliver/sys''.  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 \`\`/etc/deliver/post''. It is executed after the system and user delivery files, but before any attempt at message delivery.  Its arguments are those addresses which are about to receive the message, 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 cannot do.

- *error delivery file*

  The error delivery file, if it exists, is created by the postmaster. By default, it is named \`\`/etc/deliver/err''.  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 arguments of all failed addresses.  Note that failed addresses may contain whitespace, shell metacharacters or other strangeness -- be careful!

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:

- **user**

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

- **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.  Only the superuser may request delivery to a 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.  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.  Only the superuser may report an error for another user.

- **host1!host2!user**

  Send the message with UUCP via the given bang path.

Note that the \`\`user:mailbox'', \`\`user\|command'' and \`\`user?error message'' forms may omit the \`\`user'' part, in which case the current user context is assumed.

## ENVIRONMENT VARIABLES

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 that do not take arguments, if any, that were specified on the *Deliver* command line.

- **HOSTNAME**

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

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

- **LOCALSENDER**

  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 default mailbox:

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

## UNDELIVERED MAIL

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

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'' 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"
    echo DROP
```

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

## SECURITY

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

## LOGGING

*Deliver* records its activity in two files: the \`\`delivery log'', named */var/log/deliver.log,* and the \`\`error log'', named */var/log/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.

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 miscellaneous other information.

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 *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 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().

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.

## FILES

/etc/deliver/sys            system delivery file\
 /etc/deliver/post           post-user delivery file\
 /etc/deliver/err            error delivery file\
 \~user/.deliver              user delivery file(s)\
 /var/log/deliver.log        delivery log\
 /var/log/deliver.errlog     error log

## SUPPORT

Please mail enhancements, enhancement requests, trouble reports, etc. to \<chip@pobox.com\>.  See also the Debian GNU/Linux bug tracking system at http://www.debian.org/Bugs/.

## SEE ALSO

[*header*(1)](/header/1.md), [*mail*(1)](/mail/1.md), [*uux*(1)](/uux/1.md), [*smail*(8)](/smail/8.md), [*sendmail*(8)](/sendmail/8.md)
