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, 
sendmail
 
syslog
(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.
[7] This is supported only under operating systems that properly support seteuid (3) or setreuid (3) (see Section 18.8.55, USESETEUID ).
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.
[email protected]
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).
%telnet remote.domain 25Trying 123.45.123.45 ... Connected to remote.domain. Escape character is '^]'. 220 remote.domain Sendmail 8.6.13/8.6.12 ready at Tue, 7 May 1996 13:39:21 -0700 220 ESMTP spoken hereexpn user250 <[email protected]>quit221 remote.domain closing connection Connection closed by foreign host. %
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.
If the 
SafeFileEnvironment
 option (see 
Section 34.8.58, SafeFileEnvironment
) is set, the user should be advised to specify the path of that safe directory:
\user /arch/bob.backuphere /arch was specified by the SafeFileEnvironment option
When the 
SafeFileEnvironment
 option is used, the cooperation of the system administration may be needed if users are to have the capability of saving mail to files via the 
~/.forward
 file.
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:
user 1\user1, "|/bin/notify #user1" user 2
\user2, "|/bin/notify #user2"
Rather than expecting users to write home-grown programs for use in ~/.forward files, offer them any or all of the publicly available alternatives. The most common are listed below.
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 $uThe 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.