The sendmail program allows each user to have a :include:
style list to customize the receipt of personal mail. That file
(actually a possible sequence of files) is defined by the
ForwardPath (J) option (see Section 34.8.27, ForwardPath (J)).
Traditionally, that file is located in a user's home directory.
[6]
We use the C-shell notation ~
to indicate user home directories, so we will compactly refer to
this file as ~/.forward.

[6] Prior to V8 sendmail the ~/.forward file could live only in the user's home directory and had to be called &.forward.

If a recipient address selects a delivery agent with the
F=w flag set (see Section 30.8.43, F=w),
that address is considered the address of a local
user whose ~/.forward file can be processed.
If it contains a backslash, sendmail
disallows further processing,
and the message is handed to the local
delivery agent's P= program for delivery to the mail-spooling
directory. If a backslash is absent, sendmail
tries to read that user's ~/.forward file.

If all the .forward files listed in the
ForwardPath (J) option (see Section 34.8.27)
cannot be read, their absence
is silently ignored. This is how sendmail behaves when those
files don't exist. Users often choose not to have ~/.forward
files. But problems may arise when users' home directories are remotely
mounted. If the user's home directory is temporarily absent (as it
would be if an NFS server is down),
or if a user has no home directory, sendmailsyslog(3)'s
the following error message and falls back to the other directories
in its ForwardPath (J) option:

forward: no home

V8 sendmail temporarily transforms itself into the user
[7]
before trying to read the ~/.forward file. This is done
so that reads will work across NFS.
If sendmail cannot read the ~/.forward file (for
any reason), it silently ignores that file.

Before reading the ~/.forward file, sendmail checks
to see whether it is a "safe" file - one that is owned
by the user or root and that has the read permission bit
set for the owner.
If the ~/.forward file is not safe, sendmail silently
ignores it.

If sendmail can find and read the ~/.forward file
and if that file is safe, sendmail opens the file for
reading and gathers a list of recipients from it.
Internally, the ~/.forward file is exactly
the same as a :include:
file. Each line of text in it may contain one or more recipient
addresses. Recipient addresses may be email addresses, the
names of files onto which the message should be appended, the names of
programs through which to pipe the message, or :include: files.

Beginning with V8 sendmail, ~/.forward files may contain
comments (lines that begin with a # character).
Other versions of sendmail treat comment lines
as addresses and bounce mail that is seemingly addressed to #.

The traditional use of the ~/.forward file, as its name implies,
is to forward mail to another site. Unfortunately, as users move
from machine to machine, they can leave behind a series of
~/.forward files, each of which points to the next machine in a chain.
As machine names change and as old machines are retired, the
links in this chain can be broken.
One common consequence is a bounced mail message ("host unknown")
with a dozen or so Received:
(see Section 35.10.25, Received:) header lines.

As the mail administrator, you should beware of the ~/.forward
files of users at your site. If any contain offsite addresses,
you should periodically use the SMTP expn command
[8]
to examine them. For example, consider a local user whose
~/.forward contains the following line:

[8] Under old versions of sendmail the vrfy and expn
commands are interchangeable.
Under V8 sendmail and other, modern SMTP servers, the two commands
differ.

user@remote.domain

This causes all local mail for the user to be forwarded to
the host remote.domain for delivery there. The validity
of that address can be checked with telnet(1) at port 25
[9]
and the SMTP expn command:

[9] In place of specifying port 25, you can use either mail or
smtp. These are more mnemonic and easier to remember (although
we "oldtimers" tend to still use 25).

This shows that the user is known at remote.site but
also shows that mail will be forwarded (yet again) from
there to another.site. By repeating this process,
you will eventually find the site at which the user's mail will
be delivered.
Depending on your site's policies, you can either correct the
user's ~/.forward file or have the user correct it.
It should contain the address of the host where that user's mail will
ultimately be delivered.

Because ~/.forward files are under user control, the administrator
occasionally needs to break loops caused by improper use of those
files. To illustrate, consider a user who wishes to have mail
delivered on two different machines (call them machines A and B).
On machine A the user creates a ~/.forward file like this:

\user, user@B

Then, on machine B the user creates this ~/.forward file:

\user, user@A

The intention is that the backslashed name (\user) will
cause local delivery and the second address in each will forward
a copy of the message to the other machine. Unfortunately, this
causes mail to go back and forth between the two machines (delivering
and forwarding at each) until the mail is finally bounced with
the error message "too many hops."

On the machine that the administrator controls, a fix to this looping
is to temporarily edit the aliases database and insert an
alias for the offending user like this:

user: \user

This causes mail for user to be delivered locally and
that user's ~/.forward file to be ignored. After the user
has corrected the offending ~/.forward files, this alias can
be removed.

The ~/.forward file can contain the names of
files onto which mail is to be appended. Such filenames must begin
with a slash character that cannot be quoted. For example, if a user
wishes to keep a backup copy of incoming mail:

\user
/home/user/mail/in.backup

The first line (\user) tells sendmail to deliver
directly to the user's mail spool file using the local
delivery agent. The second line tells sendmail to append
a copy of the mail message to the file specified (in.backup).

Note that, prior to V8, sendmail did no file locking, so writing files by way
of the ~/.forward
file was not recommended. Beginning with V8, however, sendmail
locks those files during writing, so such use of the ~/.forward
file is now okay.

The ~/.forward file can contain the names of programs
to run. A program name is indicated by a leading pipe (|)
character, which may or may not be quoted (see Section 24.2.3, "Delivery via Programs").
For example, a user
may be away on a trip and want mail to be handled by the vacation(1)
program:

\user, "|/usr/ucb/vacation user"

Recall that prefixing a local address with a backslash tells sendmail
to skip additional alias transformations. For \user this
causes sendmail to deliver the message (via the local
delivery agent) directly to the user's spool mail box.

The quotes around the vacation program are necessary to prevent
the program and its single argument (user) from being
viewed as two separate addresses. The vacation program
is run with the command-line argument user, and the
mail message is given to it via its standard input.

Beginning with V8 sendmail, a user must have a valid shell
to run programs from the ~/.forward file. See
Section 18.8.34, PATH... for a description of this process and
for methods to circumvent it at the system level.

Because sendmail sorts all addresses and deletes duplicates
before delivering to any of them, it is important that programs in
~/.forward files be unique. Consider a
program that doesn't take an argument and suppose that two users
both specified that program in their ~/.forward files:

user 1 \user1, "|/bin/notify"user 2 \user2, "|/bin/notify"

Prior to V8 sendmail, when mail was sent to
both user1 and user2, the
address /bin/notify appeared twice in
the list of addresses.
The sendmail program
eliminated what seems to be a duplicate,
[10]
and one of the two users did not have the program run.

[10] V8 sendmail uses the owner of the ~/.forward
file in addition to the program name when comparing.

If a program requires no arguments
(as opposed to ignoring them), the ~/.forward program
specifications can be made unique by including a shell comment:

The deliver(1) program, by
Chip Salzenberg, is specifically designed to
handle all types of final delivery for users. It is intended
for use in the ~/.forward file but also functions
as a local delivery agent. The deliver program
supports a large number of command-line options and can reliably
handle delivery to files and
through programs. It is typically
used in the ~/.forward file like this:

"|/usr/local/bin/deliver user"

The deliver program is available via anonymous FTP
from many archive sites.

The procmail(1) program, by
Stephen R. van den Berg,
is purported to be the most
reliable of the delivery programs. It can sort incoming mail
into separate folders and files, run programs, preprocess mail (filtering
out unwanted mail), and selectively forward mail elsewhere.
It can function as a substitute for
the local delivery agent
or handle mail delivery for the individual user.
The procmail program is typically used in the ~/.forward file
like this:

"|exec /usr/local/bin/procmail #user"

Note that procmail does not accept a username as a command-line argument.
Because of this, a dummy shell comment is needed for pre-V8
versions of sendmail to make the address unique.
The procmail program is available via anonymous FTP
from many archive sites.

The slocal program, distributed with the mh distribution,
is useful for sorting incoming mail into
separate files and folders. It can be used with both UNIX-style
mail files and with mh-style mail directory folders.
It is typically used
in the ~/.forward file like this:

"| /usr/local/lib/mh/slocal -user user"

The disposition of mail is controlled using a companion file
called ~/.maildelivery.

Normally, a program in the user's ~/.forward file is executed
with the Bourne shell. The precise means that is used is defined by the
prog delivery agent.

Mprog, P=/bin/sh, F=lsDFMeuP, S=10, R=20, A=sh -c $u
The Bourne shell

One drawback to using the Bourne shell to run programs
is that it exits with a value of 1 when the program cannot be executed.
When sendmail sees the exit value 1, it bounces the mail message.

There will be times when bouncing a mail message because the program
could not execute is not desirable. For example, consider the
following ~/.forward file:

"| /usr/local/lib/slocal -user george"

If the directory /usr/local/lib is unavailable (perhaps because
a file server is down or because an automounter failed), the mail message
should be queued, rather than bounced. To arrange for requeueing
of the message on failure,
users should be encouraged to construct
their ~/.forward files like this:

"| /usr/local/lib/slocal -user george || exit 75"

Here, the || tells the Bourne shell to perform what follows
(the exit 75) if the preceding program could not be executed or
if the program exited because of an error.
The exit value 75 is special, in that it tells sendmail to
queue the message for later delivery, rather than to bounce it.