May the source be with you, but remember the KISS principle ;-)
Home Switchboard Unix Administration Red Hat TCP/IP Networks Neoliberalism Toxic Managers
(slightly skeptical) Educational society promoting "Back to basics" movement against IT overcomplexity and  bastardization of classic Unix

Mail Administration

By Jeff Smith and Chris Byers

So, they've gone and made you postmaster, have they? Perhaps you're approaching this new job with a little trepidation--and you should. Electronic mail administration is one of the most complex system administration tasks and one of the most visible. If you break an obscure program that few people use, your mistake may go unnoticed. If you break the mail system, all the users on your system are affected, and most people consider electronic mail to be one of UNIX's most valuable services. Even worse, if your site is connected to the Internet, your mistakes may be visible at remote sites, and those sites' postmasters will not hesitate to inform you that, while your mother may love you, they consider you and your broken mail system to be little better than pond scum. (Those are the moderates--others may not be so kind.)

Still with me? Good. Despite the potential for making mistakes on a grand scale, mail administration at many sites is routine. You probably won't have to fuss with the e-mail system much once you manage to get it up and running, and this chapter helps you do just that. First, you get a broad overview of how e-mail works, an explanation of some of the terminology you'll see in this and other books, and pointers on where to get more information. Finally, you'll see a step-by-step example of how to set up the sendmail program and its configuration file,

What this chapter won't do is cover complex configurations like a multiprotocol mail hub that routes mail from the Internet to UUCP or a DECnet network. You won't learn how to set up the Domain Name System (DNS), although a properly working DNS is essential to the e-mail system. This is covered in Chapter 20, "Networking."

UUCP will be covered in more detail in Chapter 26, "UUCP Administration," but we touch on it here to show how it relates to e-mail. Finally, this chapter won't make you into a sendmail guru, but if you're lucky, you'll never need to be one.

Overview & Terminology: E-mail from Point A to Point B

An electronic mail message begins its life as a file on your computer's disk, created by a Mail User Agent (MUA). After you compose the letter, the MUA gives it to a mail router like sendmail. The mail router gives it to a Mail Transport Agent (MTA). The message traverses one or more hosts and networks and is given to a final delivery agent, which appends it to the recipient's mailbox, another disk file. Each of these terms is explained in detail later in this chapter.

An MUA is just a fancy name for a mail-reading and -sending program, such as the SVR4 mailx. Other examples of MUAs are elm and the Rand corporation's Mail Handler (MH) programs. An MUA is the only part of the mail system with which users usually interact, since a good MUA hides the complexity of the rest of the system from them (but not from the postmaster)!

A mail router is a program that takes a piece of mail and decides where it should go and how to get it there. For instance, depending on the recipient, a letter might need to travel over a TCP/IP network using the Simple Mail Transfer Protocol (SMTP), or via a dial-up connection using the UNIX to UNIX Copy (UUCP) protocol, or even to an office fax machine. The mail router uses the recipient address and its own internal configuration information to decide the best MTA, and then hands the letter to the MTA.

An MTA is a transport program that understands the e-mail protocols of a particular network and can transport a letter over that network. For instance, the UUCP transport agents understand UUCP protocols but know nothing about SMTP. If the mail router were to mistakenly route an SMTP letter to a UUCP transport agent, it wouldn't know how to deliver it.

The final delivery agent does nothing but take a mail message and append it to the recipient's mailbox, following whatever local conventions are used to separate messages within a mailbox. The program /bin/mail is the usual final delivery agent on SVR4 systems.

In real life, the distinctions between MTAs and MUAs and mail routers are sometimes blurred. For instance, sendmail, although primarily a mail router, can also function as an MTA because it understands the SMTP protocol and can transport mail over a TCP/IP network. Therefore, in Figure 24.1 the separate functions of mail router and MTA are really a single program. Further, the SMTP-server part of the remote end of the MTA is often another sendmail program, which may do additional routing and forwarding of the mail before it reaches its final delivery agent. Some MUAs even do their own mail routing, and some, like MH, can be configured to speak SMTP, an MTA function. Despite this real-world blurring of function, the conceptual framework outlined above is a good one to keep in mind.

The Different Mail Front-Ends (MUA's)

Although there are only a few MTA's available for transferring mail across the Internet, there are a number of MUA's available for use. I will go into some detail about each of the more commonly used MUA's and discuss some of their advantages and disadvantages in this section.

The more widely used mail user agents are mail, elm, and pine, and each have their own personalities and quirks (much like system administrators).

A Look at mail

The original flavor of a mail front end was the rather fiendishly cryptic (though very useful and effective) UNIX mail utility.

Even though one always ran the risk of accidentally deleting a mail message (which always came in handy as a good excuse for "missing" a message), it was still a reliable and effective MUA and is still in wide use today by many UNIX users and administrators.

In general, mail allows you to browse, display, save, delete, and respond to messages. When you send a message, mail lets you edit and review messages being composed and lets you include text from files or other messages.

Setting Up Mail for Users

The incoming mail for each user is stored in the system mailbox. This is a file named after the user in /var/spool/mail (on AT&T flavors of UNIX). mail looks in this file for incoming messages, but by manipulating the mail environment variable you can have it look in a different file, which you define. At the time you read a message, it is marked to be moved to a secondary file for storage. This file is then called mbox and is put in your home directory. Like the incoming mail location, mbox can also be changed by setting the MBOX environment variable. All messages remain in the mbox file until they are manually removed.

Mail Commands and Switches

Mail comes with a large number of switches and configuration settings to allow for highly customized use. These options are as follows:

-d Start debugging output.
-e See if there is any mail present. If there isn't, it returns nothing to the screen and gives a successful return code.
-F Put the message in a file whose name is that of the first recipient. This also overrides the record variable, if it is set.
-H Print only the header.
-I Ignore interrupts (can also be set with the ignore variable).
-n Don't initialize mail from the system default Mail.rc file.
-N Don't print header.
-U Convert uucp addresses to Internet standard addresses. This option overrides the environment variable conv.
-v This passes the -v flag to the sendmail utility.
-f [filename] Tells it to read messages from filename instead of the system mailbox. If there is no filename specified, it reads messages from mbox.
-f [folder] Use the file folder in folder directory (this is the same as the folder command). The name of the directory is listed in the folder variable.
-h [number] This is the number of network "hops" made to this point. This is provided so that infinite delivery loops do not occur. This is also related to the TTL, or time to live for a mail message packet.
-r [address] Pass the address to the MTA or network delivery software. It is important to note that all tilde (~) commands are invalid in this option.
-s [subject] Make the Subject header field as subject.
-T [file] This option prints the contents of the article-id fields of all messages on file. This is used for network news programs such as pointcast, etc.
-u [user] This options allows you to read a specific user's mailbox. This only works of you have the correct permissions to that user's home directory.

On starting mail, a system-wide file is read for commands. This file is /usr/lib/Mail.rc. These commands are read to initialize certain variables, after which it reads from the private start-up file of the user who started the mail utility. This file is called .mailrc, and it is normally placed in the user's home directory. It can, however, be placed and accessed elsewhere by modifying the MAILRC environment variable for your personal commands and variable settings.

The .mailrc file is usually used for setting up initial display options and lists of aliases. You store your initial commands here when you start up mail. The following commands, however, are not valid in this file: !, Copy, edit, followup, Followup, hold, mail, preserve, reply, Reply, replyall, replysender, shell, and visual. Also, if there is an error in that file, the remaining lines are ignored.

By using a template .mailrc file, you can easily standardize each user's mail interface with very little difficulty. All you have to do (obviously) is copy that template into the users' home directories, and (if necessary) do some minor editing for each user's particular needs.

You can send a message directly to another user or users by including names of recipients on the command line. If no recipients appear on the mail command line, mail enters command mode, where you can read messages sent to you. If you don't have any messages, it simply sends the message to standard output no mail for username and then exits the mail utility.

While you are in command mode (that is, while reading messages), you can also send messages.

When you are composing a message to send, mail is in input mode. If you don't specify a subject as an argument to the command, mail queries you for a subject. After you enter a subject, mail enters input mode, at which point you can start writing the body of the message you want to send.

While you're typing the message, mail stores it in a temporary file. This temporary file is used for reviewing or modifying the message. By using the appropriate tilde escape sequences (~:) at the beginning of an input line, you can modify the message text.

After you are in the body of your text, enter a dot (EOF) on a line by itself to actually send the message. At this point, mail submits the message to sendmail for routing to each recipient.

The recipients can be a local username or usernames, an internet address (name@domain), a uucp address of the form [host!!]host!username, filenames for which you have write permission, or alias groups. If the name of the recipient begins with a pipe symbol (|), the remainder of the name is taken as a shell through which the message is piped. This can be used with any program that reads standard input, such as lpr, to record outgoing mail on a printout.

An alias group is simply the name of a list of recipients that is set by the alias command. The alias command takes the names from the /etc/aliases file, or it can be taken from the Network Information Service (NIS) aliases domain.

While you are composing messages to send, the following tilde escape commands can be used. They all must appear at the start of the input line. The escape character (~) can be changed by setting a new value for the escape variable. The escape character can be entered as text by typing it twice.

~! [shell-command] This lets you escape to the shell. If a shell command is entered, it is then run.
~. This simulates EOF (terminate mail message input and send message)
~: mail-command


~_ mail-command
These allow you to perform the indicated command. You can only use them when sending a message while reading a mail message.
~? This prints a summary of the tilde escapes.
~A This inserts the autograph string Sign into the current message.
~a This inserts the autograph string sign into the message.
~b name ... This adds the names to the blind carbon copy (Bcc) list. This command is similar to the carbon copy (Cc) list, but the names in the Bcc list are not shown the message header.
~c name ... This adds the names to the carbon copy (Cc) list (and these names show up in the message header).
~d This command lets you read in the dead.letter file. This file's name is listed in the variable DEAD, which can be modified.
~e This command invokes the editor to edit the message. The default editor is ex. This is defined in the EDITOR variable.

TIP: Using the ex editor is a real pain. If you are used to using the vi editor, change the EDITOR variable to vi.
-f [message-list] This command lets you forward the listed messages or the current message being read. This only works when sending a message while you are reading mail. The messages are inserted without being altered.
~h This command prompts you for the message header lines: Subject, To, From, Cc and Bcc. To edit the header lines, simply backspace over it and retype.
~i [variable] This lets you insert the value of the named variable into the message.
~m [message-list] This command lets you insert text from the specified messages or the current message into the letter. This is only valid if you are sending a message while reading mail. The text message gets shifted to the right, and whatever string is contained in the indentprefix variable gets inserted as the leftmost characters of each line.
~p This prints the message being entered.
~q This gets you out of the input mode. If you were entering a message and did not save it, whatever you entered to that point is saved in the dead.letter file.
~r filename


~< filename


~<! Shell-command
These commands let you read in the text from the specified file or the standard output of the specified shell-command.
~s subject This sets the subject line to subject.
~t name Add each name to the list of recipients. This is similar to setting up a distribution list.
~v This command invokes the visual editor to edit the message. The particular editor that it uses is listed in the VISUAL variable, and the default is the vi editor.
~w filename This writes the message text into the specified filename, minus the header.
~x This exits the message the same as ~q, but it does not save the message in the dead.letter file.
~| shell-command This pipes the body of the message through the given shell command. If the shell command exits successfully, the command output replaces the message.

Reading Your Mail

The first thing you see when you enter the command mode (immediately after running the mail command) is a header summary of the first several messages, followed by a prompt for one of the commands listed below. By default, the prompt is an ampersand (&).

Each message has a reference number in front of it. The current message is marked by a > in the header summary. The commands that take an optional list of messages should be used with the reference number; if no number is given, the current message is affected.

The message-list is simply a list of message specification, separated by space characters (space delimited), which can include the following:

. Specifies the current message.
n Denotes the message number n
^ Specifies the first undeleted message.
$ Specifies the last message.
+ Specifies the last message.
- Specifies the previous undeleted message.
* Specifies all messages.
n-m Specifies an inclusive range of message numbers.
User Specifies all the messages from user.
/string Specifies all the messages with string in the subject line (upper and lower case is ignored).
:c This specifies all messages of type c. c can be one of the following:
d deleted messages
n new messages
o old messages
r read messages
u unread messages

Mail Commands

If you are in command mode and you just hit enter with no arguments, mail assumes that you want to print the messages and starts printing to the default printer (if one is defined). The complete list of commands is as follows:

! shell-command

This command escapes you to the shell command. The shell to which you escape (Bourne, Korn, etc.) is defined in the SHELL variable.

# comments

This can be used or placing comments in your command, just as you would place comments in you .mailrc file. You must have a blank space between the # sign and the start of your comments.


This lets you print the current message number.


This will show you a summary of commands (for people like me with poor memories).

alias [alias recipient...]


group [alias recipient] This declares an alias for the given list of recipients. In much the same way as distributions lists work in other mail readers, mail will be sent to the entire alias (or group) specified. These aliases can be defined in the .mailrc file. To get a listing of the defined aliases, simply type in the command "alias" by itself.

alternates name...

This command lets you declare a list of alternate names for your login. When responding to a message, mail will not be sent to these names. If no arguments are supplied, this will show a current list of alternate names.

cd [directory]


chdir [directory]

This command allows you to change the current directory. Just as within the Korn or Bourne shell, cd without an argument uses the environment variable $HOME as the directory.

copy [message-list][filename]

This command copies messages to the filename without marking the messages as saved. All other functions are equivalent to the save command.

Copy [message-list]

This saves the specified messages in a file whose name is derived from the authors user name, also without marking the message as saved. This is otherwise equivalent to the Save command.

delete [message-list]

This deletes messages from the system mailbox.If the autoprint variable is set to on, it also prints the next message following the last message that was deleted.

discard [header-field...]


ignore [header-field...]

These commands will suppress the printing of the specified header fields when displaying messages on the screen, such as "Status" and "Received". By default, unless the variable alwaysignore is set, all header fields are included in the saved message. This does not apply to the Type or Print commands.

dp [message-list]


dt [message-list]

These commands are equivalent to the delete command followed by the print command, as they first deletes the specified messages from the system mailbox and prints the following one.

edit [message-list]

This command edits the given messages. Each of the messages are put in a temporary file and the EDITOR variable is used to the name of the editor (preferably vi). The default editor is ex.




These commands will exit you from the system mailbox without any changes. If you use this command, you will not save any messages in mbox.

file [filename]
folder [filename]

These commands quit you out of the current malbox file and read in the named mailbox file. There are certain special characters used as filenames, such as:

% The current user's mailbox.
& Read previously read messages from your mbox.
+filename A filename in a specified folder directory. The folder directory is also listed in the folder variable.

If no arguments are used, file simply shows the name of the current mail file, as well as the number of characters and messages it contains.


This command only prints the name of each mail file in the folder directory.

followup [message]

This commands responds to a message and records the response in a file. The name of this file is derived from the author of the message. This command also overrides the record variable if it is set.

from [message-list]

This shows the header information for the indicated message or current message.


This prints a summary of all commands.

hold [message-list]


preserve [message-list]

These commands hold the specified messages in the system mailbox.

if s|r|t

This is a conditional execution, used primarily in the .mailrc file. The command will execute up to an elseif or an endif. If s is used, the command will run if the program is in send mode; if r is chosen, the command executes only if in receive mode; if t is chosen, the command is run only if mail is run from a terminal.

load [message] filename

This command will let you load the specified message from the name file. This allows you to load a single saved message from filename, including headers.

mail recipient

This command sends a message to the specified recipient.

Unread [message-list]

This marks each message in a message list as having been read.


This exits the mail command. It also saves the messages that were read in the mbox file and keeps the unread messages in the system mailbox.

reply [message-list]


respond [message-list]


replysender [message-list]

These commands allow you to send a response to the author of each message in messasge-list.

Reply [message]


Respond [message]


replyall [message]

These commands let you reply to the specified message, sending a response to each recipient of that message. If the replyall variable is set, the replyall command always sends the reply to all recipients of the message.

save [message-list] [filename]

This command will save the specified message in the specified filename. If the filename does not exist, it is created. If no filename is specified, the file named in the MBOX variable is used (mbox by default). Once the message is saved it is deleted from the system mailbox unless the keepsave variable is set.

set [variable[=value]]

This lets you define a variable and assign a value to it. You must use an = sign between the variable name and the value (with no spaces).


This invokes the shell as defined in the SHELL variable.

source filename

This let you read commands from the given file name and return to the command mode.

undelete [message-list]

This restores deleted messages. It only works on messages deleted in the current mail session.

unset variable ...

This will undefine a specified variable or variables. This will not work on imported variables such as environment variables from the shell.


This will scroll the header display either forward (+) or backward (-) by one screen.

Forwarding Your Messages

In order to forward a message you must include it in a message to the recipients with the ~f or ~m tilde escapes. You can define a list of recipients in a file in your home directory to forward mail to automatically called .forward. The list must be comma separated and the address must be valid or the messages will bounce without any warnings.

Defining Variables

Mail behavior is defined by a set of variables in your .mailrc file. The necessary environment variables are as follows:


This is the user's home directory.


This is the name of the initial mailbox file to read. By default it is set to /var/spool/mail/username.


This is the name of each user's personal start-up file, which is $HOME/.mailrc by default.

These variables cannot be modified from within mail. They must be set before you begin a mail session.

The specific mail variable for each user is set in the .mailrc file in each user's home directory. The following are all of the mail variables that can be altered either in the .mailrc file or by using the set (or unset) command:


For all network names whose login name components match, treat them as identical. The default is noallnet.


This tells mail to always ignore the header fields, not just during print or type. This will affect the save, Save, copy, Copy, top, pipe, and write commands, as well as the ~m and ~f tilde escapes.


This will append messages to the end of the mbox file when you exit instead of prepending them. By default this is set as noappend.


This will prompt you for the Cc list after you enter a message. The default is noaskcc.


This will ask you for a subject. This is enabled by default.


This will automatically print messages after the delete or undelete commands are run. By default this is set to noautoprint.


This enables use of the exclamation point or "bang" as a shell escape command, such as in the vi editor.


This will set the default command for the pipe command. This has no default value.


This variable converts UUCP addresses to the address style you specify. The style can be one of the following:


Use this if you are using a mail delivery program that conforms to the RFC232 standard for electronic mail addressing.


This will remove loops in the UUCP address path, which are usually generated by the reply command. There is no rerouting performed since mail doesn't know anything about UUCP routes or connections.

Conversion is disabled by default.


This will pipe the messages which contain more than number lines through the command which is specified by the PAGER variable. This is the more command by default.


You can specify the name of the file where a partial letter is saved in case of an interrupted session. By default this is defined as the dead.letter file in the user's home directory.


This will turn on the verbose diagnostics for debugging. The default setting is nodebug.


This will read a dot on a line by itself as an EOF marker. By default this is set as nodot, but dot is set in the global startup file.


This enables you to edit the headers as well as the body of the message when you use the ~e and ~v commands.


This defines the editor (or command) to run when you use the edit or ~e command. By default this is set to ex.


This will substitute c for the tilde (~) escape character.


This is the defined directory for saving standard mail files. If the user specifies a file name beginning with a plus (+), the file name is expanded with the directory name preceding it.


This prints the header when you enter mail. This is enabled by default.


This keeps all read messages in the system mailbox instead of moving them to mbox. The default is nohold.


This will tell it to ignore interrupts while entering messages. The default is noignore.


By default, string is set the TAB key. It is used to mark indented lines from messages included with ~m.


This is set by default to the ls command; used to list the files in the folder directory.


This sets the file name where messages are saved after being read. The default is $HOME/mbox.


This can be used in a local area network (no router between machines). Normally, when several recipients are sent mail, their addresses are forced to be relative to the originating author's machine, which allows ease of response from the recipients. This flag greatly reduces traffic "over the wire."


This locates the files used to save the outgoing messages. The default is nooutfolder.


This will insert a form feed after each message sent through a pipe. nopage is the default.


This is used for paginating the messages on the screen. By default it is set to more, but pg can also be used.


This will allow you to set the prompt in command mode. By default it's set to &.


This will enter mail without the opening message being displayed. This is disabled by default.


This will record all outgoing mail in filename. This is disabled by default.


This will have the opposite the effect of the reply and Reply commands.


If this is set on, the mail message will be saved to the dead.letter file if it is interrupted on delivery. Set on as default.


This will define how many lines you can have for headers. This is used by the headers command.


This allows the background mailer to finish before returning to command mode. The default setting is nosendwait.


This will define the preferred shell you use when you escape to a shell. By default it is set to sh. It will first go to the inherited shell from the environment.


If the ~a (autograph) command is given, includes the autograph text in the message. There is no default.


This tells the top command how many lines of the header to print. This is set to 5 by default.


This will invoke sendmail with the -v flag.


This points to the preferred visual screen editor, which is vi by default.

So much for the .mailrc settings. If you have the mail utility installed on your server or workstation, take a look at the .mailrc file to get a feel for how the file is put together.

A related file is the /usr/lib/Mail.rc file. This is the global startup file, which was referred to earlier in this section. This sets up the initial settings for the mail utility for each user, and it contains most of the default variables that are included with the initial .mailrc file.

A look at elm

At this point, you may be wondering, why go into so much detail about an outdated utility? Well, for one thing, most of the newer and easier to use MUAs are based on the old original mail utility, and much of the same functionality has been added to them and enhanced. Also, this is a good way to illustrate why you would want to move to another utility such as pine or elm.

In this section, I'll take a look at elm, followed by pine in the next section, since these are the most popular text-based MUAs in use today.

The biggest difference between elm and mail is that elm uses a screen-oriented interface, as opposed to the command line interface used by mail. It is also a great deal more intuitive to use, as well as being highly tunable for mail administrators. As with mail, elm will also run on virtually every flavor of UNIX without any modifications.

Elm is also 100 percent compliant with the RFC-822 electronic mail header protocol guide, which means that it will comply with all existing mail standards. In terms of reliability, it has been in use for many years by tens of thousands of sites with no problems.

The Main Menu of elm

Upon looking at the main menu, which appears after opening elm, you will see the first line (showing the name of the current folder, the number of messages in the folder and the current version of elm), the list of messages and a paragraph at the bottom showing the available one-letter commands.

In the list of messages, the inverse video bar will indicate the currently active message. The status field is the first field on the screen, and it can be blank or it can have a combination of characters, where the first character has a temporary status and the second has a permanent status. The characters are: E for an expired message, N for a new message, O for an old message, D for a deleted message, U for urgent mail, A for messages that have an action associated with them, and F for a form letter. There may also be a "+" in the third field which would indicate a tagged message.

In the next field, each message is numbered, which can come in handy for quickly opening a specific message.

The third field from the left indicates the date that the message was sent, in the format MMM, DD.

The fourth field from the left shows who sent the message. By default, elm tries to display the full name of the person who sent the message, but if this is unavailable, it will show either the login name and address of the person who sent it or just the sender's login name.

The fifth field in the list shows the number of lines in the message. And, finally, the sixth field shows the subject of the message (if one is included).

Elm will show ten or more messages at one time, depending on the screen settings. To read a mail message, simply highlight the one you want to read and hit enter.

The functions available from the main screen are as follows:

<return> or <space>--This will read the current message.

|--This allows you to pipe the message to a system command, such as lp.

!--This escapes to the shell.

$--This will resynchronize the folder.

?--This puts you into help mode; any key pressed will be explained.

+ or <right>--This will put you into the next page of messages.

- or <left>--This will put you into the previous page of messages.

=--This will set the current message number to 1.

*--Make the current message number equal to the last one.

<number><return>--This will set the message number of the highlighted message.

/--This starts a pattern search in the subject/from lines.

//--This starts a pattern search for the entire folder.

<--This will let you search for specific calendar entiries.

>>--This is the same as `s' for saving a message.

a--This will put you into the alias mode.

b--This will bounce (or remail) a message. This is related to the forward command.

C--This will copy the current message or all of the tagged messages to the folder.

c--This changes the current folder to another elm folder.

d--This will delete the current message.

<ctrl>-D--This will delete all messages matching a user-supplied pattern.

e--This will edit the current folder.

f--This let you forward a message to a specific user. The only difference between this and bounce is that a bounced message will show as being sent from the original sender, where a forwarded message is designated as being sent from the person who forwarded it.

g--This will let you do a group reply to everyone who received the current message.

h--This will disable the headers in messages.

J--This moves the current message to the next one in line.

j or <down>--This will move you to the next message that is not marked as deleted.

K--This will move you up the list to the previous message.

k or <up>--This will move you up the list to the previous message if it is not marked as deleted.

<ctrl>-L--This will refresh the screen.

m--This will send mail to arbitrary users.

n--This lets you read the current message then go to the next undeleted message in the list.

o--This will let you go into the options menu, where you can change the mail system options interactively.

p--This lets you print the current message, or all of the tagged messages.

Q--This known as the quick quit, since it quits without prompting the user.

r--This lets you reply to the author of the current message.

s--This is the command to save the current message to the folder.

t--This tags the highlighted message for later manipulation.

<ctrl>-T--This will allow you to tag all of the messages matching a specified pattern.

u--This will undelete only the current message.

<ctrl>-U--This allows you to undelete all messages which match a specified pattern.

x--This is the exit command, and it will prompt you for saving messages, etc.

X--This will exit immediately, without prompting.

Luckily, most of these commands are listed at the bottom of the main menu, so you don't have to memorize them (unlike the mail utility).

You can also send a file (or attachment) on the command line to a specific user if it will save you time. You can do this by typing the following command:

elm -s "message subject" recipient<filename

The configuration file is called elmrc in the user's home directory. Use this to define specific settings as needed for the special needs of your users.

Debugging the elm mailer

How many times have you heard this from your users; "Where's my mail? I lost my saved messages!"? Elm has a few debugging tools to help you track down some of the more common problems.

In the first menu screen you can use the h, or headers command, to show all of the header information that might be sorted out with weeding settings. This might help to see if the address field got buggered somewhere along the line.

The @ command can also be somewhat helpful. It simply shows a screen of debugging information for each message, such as the number of lines and offsets.

The # command will actually show the entire record structure for the current message to see if the message format is corrupted somehow.

To see the full return address of the current message, the % command can be used. Like the h command, this is useful to see if the address got corrupted or mislabeled.

You can also start elm with the -d option, which starts the debugger. This will create a file in the user's home directory called, which will give a good deal of debugging information useful for tracking down problems.

If you use the debugging option, you might need to get the AT&T System V Interface Definition Reference Manual to look up the error names that get reported.

Inclusion in Xwindows

Most Xwindows interfaces give you an option to include a post office in the user's setup. This can be done somewhat easily by modifying the Xwindows configuration file and adding that specific mailer.

As an example, on HP-UX systems, these modifications take place in the user's $HOME/.vue/mwmrc file. In this file, you can specify that a mailbox be present and which mailer you want to use. This is elm by default in HP-UX. See your system's specific Xwindows guide for more details.

The pine mailer

Line elm, pine is a text-based full screen mail utility (MUA). It has a few more features than elm, and is probably more widely used than it as well.

Pine was developed by a few unix gurus at the University of Washington to act as a simple e-mail front end for their users on campus. Because of its ease of use for novice users as well as its stability and configurability, it was quickly adopted first by other Universities and then by a large number of Internet Service Providers as their default mail interface.

Pine can get and send mail from almost any mail format because it uses the c-client library to access mail files, which can act as a switch between different mail formats and drivers. If used with IMAP (Interactive Mail Access Protocol), you can have an IMAP server, like imapd, running on a central host, letting users access their mail without actually having to log onto the central host. (See RFC1176 for more on IMAP).

Mail can be handed off to either sendmail (as is usually the case) or it can be sent using SMTP. This and other configuration settings will be covered later in this section (see RFC822 for more details on SMTP).

MIME is also supported in pine for moving multipart and multimedia e-mail. MIME stands for Multipurpose Internet Mail Extensions (defined in RFC-1341). By using this, any received MIME message gets saved to files, whatever their format. This also allows users to attach files to their messages, such as GIF files, which can be detached and displayed (if running X-terminal).

On starting up pine, you can give it the following options:

-d debug-level

This sets debugging a debugging level (0 means off) and sends the output to the .pinedebugX file in the user's home directory.

-f folder

This opens a named folder in place of the default INBOX.

-i keystrokes

This is like a startup script, where the keystrokes, separated with commas, run on startup. By default, pine starts up in the FOLDER INDEX screen if no keystrokes are specified.


This tells it to use the function keys for commands.


This expands the folder list.

-n message-number

The specified message number will be opened immediately.

-p config-file

Let's use the defined configuration file. By default, this is the .pinerc file.

-P config-file

This will make it use the specified configuration file instead of the global configuration file pine.conf.


This puts you into the restricted demo mode, where you can only send mail to yourself.

-sort order

This tells it to sort the display of the index by arrival, subject, from, date, size, or reverse order. By default, the arrival order is chosen.


This will enable the interrupt command ^Z so that a user can suspend pine.


This will send mail directly to the given address and drop you into the message composer on startup.


This displays the help files for pine.


This will print on the screen a fresh copy of the system pine configuration file (not to be confused with the .pinerc file).

Each of these options is shown at the bottom of the screen when you use pine. As a very easy-to-use mail front end, it is easily the most popular one in use.

Configuring Pine

As I mentioned before, pine has a configuration file for all users called .pinerc located in each home directory. The following shows this file and how to configure it.

The variables are:


This will override the full name defined in the /etc/passwd.


This will set the domain name for the sender's "From:" field.


This is left blank if you are using sendmail as your MTA. You define your list of SMTP servers here.


This will set the news-collections for news reading, as well as defining the NNTP server used for posting news.


This will define the path of the local or remote INBOX, such as $HOME/INBOX or {mail.domain}inbox.


This will list all the incoming message folders.


This is similar to a path statement, as it lists the directories where saved message folders may be found.


This is only needed if the NNTP server name is not set or news is located on a different server.


This will override the default path where the sent-mail folder is kept.


This will override the default path where the postponed messages are located.


This will define where the read messages are to be moved when you quit pine.


This will define where the signature file is located. The default for pine is $HOME/.signature.


This will define the path for a shared or global address book, if one is used.


This specifies the path for the personal address book. By default, this is the $HOME/.addressbook file.


This will define a set of features (shown in the setup/options menu). This will set defaults such as select-without-confirm, and so on. By default, each is prepended with the no- option.


This allows a list of one letter commands to be executed on startup.


This will cause it to display these headers when composing messages.


When composing a message, this will add customized headers to the message.


This will determine the default name for save folders.


This will specify the default name for Fcc.


This will set the order of presentation of messages in the index.


This sets the order of presentation for address book entries.


This is set to the screen settings of the window or screen you are using. By default this number is set to US_ASCII.


This will specify the program used in the Composer.


This sets the program that will be called to view images.


This will strip the hostname used in the From: field if the user-domain is not set.


This lets you select your printer.


This is used if special print drivers are needed for a nonstandard printer.


This is set by pine to control the beginning-of-month pruning for sent mail.


This is also set by pine for displaying the new version of pine.

UUCP as an MTA

There is an alternative to sendmail that has been around for many years, although it isn't purely a mail transfer agent. UUCP (UNIX to UNIX Copy) can act as an MTA as well. In fact, one could make the argument that it was the original MTA, since it was used to copy text files used as messages from one host to another in the early days of the Internet (or Arpanet at that point).

The utility is quite simple to use. All you need is the source file name and the hostname to which you want to copy a file.

If all hosts at your site are defined in the Domain Name Service and you know for sure that each of your To: addresses are defined (no problem, right?), then you can send your mail through a point-to-point UUCP connection, rather than through a default mailer. This is done through a file called uucpxtable. This file uses aliases for each hostname which points to their particular domain. Mail can then be queued for delivery with UUCP.

Arguments against UUCP as an MTA

As you can see, this may not be such a hot idea, especially if you have a large number of local hosts and/or a number of recipients at remote domains. Quite often systems accumulate a number of direct UUCP connections that are very rarely used, and even if they are you really can't rely on the connection to get your message there.

This is a good argument for using such MTA's as sendmail or SMTP, since their connection schemes are more dynamic in nature, ensuring that only the connection(s) you presently need are used. In addition, UUCP leaves much to be desired in the area of security.

Background Material and Other Sources

E-mail administration is a complex endeavor. This chapter gives you enough background to get you out of the gate and running, but you must carefully study the following materials to really understand what you're doing. It's a lot better to learn it now--with a warm cup of cocoa in hand--than to wait until you've got a dozen angry users in your office demanding that you fix the mail system immediately. Trust me on this one.

Don't worry if some of the documents mentioned below don't make sense on a first reading; you don't have to understand every little clause of RFC 822 (described in the next section) to be a successful postmaster, and if you persevere you'll understand as much as you need to know at first. After you gain some experience, you'll re-read them and understand them even better.

Request for Comments Documents (RFCs) RFCs are issued by working groups of the Internet Engineering Task Force (IETF). They are known initially as a request for comments, but as they are adopted as Internet standards, you should think of them as requirements for compliance. So if you want to exchange e-mail with another site on the Internet, you must comply with the provisions of both RFCs 821 and 822. RFCs are available for anonymous ftp on the host The RFCs mentioned below are also on the UNIX Unleashed CD-ROM.

Sendmail Documentation V8 sendmail comes with three important documents:

All three were written by Eric Allman, the author of the sendmail program. The SIOG is an essential reference manual that explains the guts of sendmail. The other documents are more general overviews of mail router design. All are worth reading, but the SIOG is your essential guide to sendmail. You'll want to read it several times and highlight parts relevant to your site's configuration.

sendmail, The Book The book sendmail by Bryan Costales, Eric Allman, and Neil Rickert (O'Reilly & Associates, Inc., 1993) is the most comprehensive treatment of the care and feeding of V8 sendmail. If you manage a complex site or must write custom configuration files, it is invaluable. If your site is fairly simple or you find that you can get most of what you need from this chapter, the standard V8 sendmail documentation, comp.mail.sendmail and the RFCs, save your money.

Comp.mail.sendmail If your site receives USENET news, don't pass go, don't collect $200, just add the newsgroup comp.mail.sendmail to your newsreader's subscription list. Eric Allman, the author of sendmail, contributes regularly along with other sendmail wizards. You can get more quality, free advice here than anywhere else on the USENET.

However, as with any newsgroup, read it for a few weeks before you make your first posting, and save yourself the embarrassment of asking a question that has already been answered a hundred times by first reading the V8 sendmail Frequently Asked Questions (FAQ) document and the other documentation mentioned in this chapter. It may take a little longer to get your burning question answered, but you'll still respect yourself in the morning.

Internet Mail Protocols

In order to understand the different jobs that sendmail does, you need to know a little about Internet protocols. Protocols are simply agreed-upon standards that software and hardware use to communicate.

Protocols are usually layered, with higher levels using the lower ones as building blocks. For instance, the Internet Protocol (IP) sends packets of data back and forth without building an end-to-end connection such as-used by SMTP and other higher-level protocols. The Transmission Control Protocol (TCP) is built on top of IP and provides for connection-oriented services like those used by programs such as telnet and the Simple Mail Transfer Protocol (SMTP). Together, TCP/IP provide the basic network services for the Internet. Higher-level protocols like the File Transfer Protocol (FTP) and SMTP are built on top of TCP/IP. The advantage of such layering is that programs which implement the SMTP or FTP protocols don't have to know anything about transporting packets on the network and making connections to other hosts. They can use the services provided by TCP/IP for that.

SMTP defines how programs exchange e-mail on the Internet. It doesn't matter whether the program exchanging the e-mail is sendmail running on an HP workstation or an SMTP client written for an Apple Macintosh. As long as both programs implement the SMTP protocol correctly, they will be able to exchange mail.

The following example of the SMTP protocol in action may help demystify it a little. The user betty at is sending mail to joe at

$ sendmail -v [email protected] < letter
[email protected]... Connecting to via tcp...
Trying  connected. SMTP ready at Mon, 6 Jun 1994 18:56:22 -0500
220 ESMTP spoken here
>>> HELO
250 Hello [], pleased to meet you
>>> MAIL From:<[email protected]>
250 <[email protected]>... Sender ok
>>> RCPT To:<[email protected]>
250 <[email protected]>... Recipient ok
>>> DATA
354 Enter mail, end with "." on a line by itself
>>> .
250 SAA08680 Message accepted for delivery
>>> QUIT
221 closing connection
[email protected]... Sent

The first line shows one way to invoke sendmail directly rather than letting your favorite MUA do it for you. The -v option tells sendmail to be verbose and shows you the SMTP dialogue. The other lines show an SMTP client and server carrying on a conversation. Lines prefaced with >>> are the client (or sender) on, and the lines that immediately follow are the replies of the server (or receiver) on The first line beginning with 220 is the SMTP server announcing itself after the initial connection, giving its hostname and the date and time, and the second line informs the client that this server understands the Extended SMTP protocol (ESMTP) in case the client wants to use it. Numbers such as 220 are reply codes that the SMTP client uses to communicate with the SMTP server. The text following the reply codes is only for human consumption.

Although this dialogue may still look a little mysterious, it will soon be old hat if you take the time to read RFC 821. Running sendmail with its -v option also helps you understand how an SMTP dialogue works.

The Domain Name System (DNS) and E-Mail

Names like are convenient for humans, but computers insist on using numeric IP addresses like The Domain Name System (DNS) provides this hostname to IP address translation and other important information.

In the olden days when most of us walked several miles to school through deep snow, there were only a few thousand hosts on the Internet. All hosts were registered with the Network Information Center (NIC), which distributed a host table listing the host names and IP addresses of all the hosts on the Internet. Those simple times are gone forever. No one really knows how many hosts are connected to the Internet now, but they number in the millions, and an administrative entity like the NIC can't keep their names straight. Thus was born the DNS.

The DNS distributes authority for naming and numbering hosts to autonomous administrative domains. For instance, a company could maintain all the information about the hosts in its own domain. When the host wished to send mail or telnet to the host, it would send an inquiry over the network to the name server, which might run on a host named The name server would reply to with the IP address of (and possibly other information), and the mail would be sent or the telnet connection made. Because is authoritative for the domain, it can answer any inquiries about hosts regardless of where they originate; the authority for naming hosts in this domain has been delegated.

Now, what if someone on wants to send mail to [email protected]? has no information about hosts in the domain, but it knows how to find out. When a name server receives a request for a host in a domain for which it has no information, it asks the root name servers for the names and IP addresses of servers authoritative for that domain, in this case The root name server gives the name server the names and IP addresses of hosts running name servers with authority for The name server inquires of them and forwards the reply back to

From the description above you can see that the DNS is a large, distributed database containing mappings between hostnames and IP addresses, but it contains other information as well. When a program like sendmail delivers mail, it must translate the recipient's host name into an IP address. This bit of DNS data is known as an A (Address) record, and it is the most fundamental data about a host. A second piece of host data is the Mail eXchanger (MX) record. An MX record for a host like lists one or more hosts that are willing to receive mail for it.

What's the point? Why shouldn't simply receive its own mail and be done with it? Isn't a postmaster's life complicated enough without having to worry about mail exchangers? Well, while it's true that the postmaster's life is often overly complicated, MX records serve useful purposes:

Mail Delivery and MX Records When an SMTP client delivers mail to a host, it must do more than translate the hostname into an IP address. First, it asks for MX records. If any exist, it sorts them according to the priority given in the record. For instance, might have MX records listing the hosts,, and as the hosts willing to receive mail for it (and the "host" might not exist except as an MX record, meaning that there might be no IP address for it). Although any of these hosts will accept mail for, the MX priorities specify which of those hosts the SMTP client should try first, and properly behaved SMTP clients will do so. In this case the system administrator has set up a primary mail relay, an on-site backup, and arranged with the system administrator at for an off-site backup. They have set the MX priorities so that SMTP clients will try the primary mail relay first, the on-site backup second, and the off-site backup third. This setup takes care of the problems with the vendor who doesn't ship your parts on time as well as the wayward backhoe operator, who severs the fiber optic cable that provides your site's Internet connection.

After collecting and sorting the MX records, the SMTP client gathers the IP addresses for the MX hosts and attempts delivery to them in order of MX preference. You should keep this in mind when debugging mail problems. Just because a letter is addressed to [email protected], it doesn't necessarily mean that a host named exists. Even if it does, it might not be the host that is supposed to receive the mail.

Header and Envelope Addresses The distinction between header and envelope addresses is important because mail routers may process them differently. An example will help explain the difference between the two.

Suppose you have a paper memo that you want to send to your colleagues Mary and Bill at the Gonzo Corporation, and Ted and Ben at the Whizzer company. You give a copy of the memo to your trusty mail clerk Alphonse, who notes the multiple recipients. Since he's a clever fellow who wants to save your company 29 cents, he makes two copies of the memo and puts each in an envelope addressed to the respective companies (rather than sending a copy to each recipient). On the cover of the Gonzo envelope he writes Mary and Bill, and on the cover of the Whizzer envelope he writes Ted and Ben. When his counterparts at Gonzo and Whizzer receive the envelopes, they make copies of the memo and send them to Mary, Bill, Ted and Ben, without inspecting the addresses in the memo itself. As far as the Gonzo and Whizzer mail clerks are concerned, the memo itself might be addressed to the pope; they only care about the envelope addresses.

SMTP clients and servers work in much the same way. Suppose that [email protected] sends mail to his colleagues [email protected] and [email protected]. The recipient list in the letter's headers may look like this:

To: [email protected], [email protected]

The SMTP client at connects to the mailer to deliver Fred's copy. When it's ready to list the recipients (the envelope address), what should it say? If it gives both recipients as they are listed in the To: line above (the header address), Betty will get two copies of the letter because the mailer will forward a copy to The same problem occurs if the SMTP client connects to and lists both Betty and Fred as recipients. The mailer will forward a second copy of Fred's letter.

The solution is the same one that Alphonse and his fellow mail clerks used. The SMTP client puts an envelope around the letter that contains only the names of the recipients on each host. The complete recipient list is still in the letter's headers, but those are inside the envelope, and the SMTP servers at and don't look at them. In this example, the envelope for the mailer would list only fred, and the envelope for would only list betty.

Aliases illustrate another reason why header and envelope addresses differ. Suppose you send mail to the alias homeboys, which includes the names alphonse, joe, betty, and george. In your letter you write To: homeboys. However, sendmail expands the alias and constructs an envelope that includes all of the recipients. Depending on whether those names are also aliases, perhaps on other hosts, the original message might be put into as many as four different envelopes and delivered to four different hosts. In each case the envelope will contain only the name of the recipients, but the original message will contain the alias homeboys (expanded to so replies will work).

A final example shows another way in which envelope addresses may differ from header addresses. sendmail allows you to specify recipients on the command line. Suppose you have a file named letter that looks like this:

$ cat letter
To: null recipient <>
Subject: header and envelope addresses

and you send it with the following command (substituting your own login name for yourlogin):

$ sendmail yourlogin < letter

You will receive the letter even though your login name doesn't appear in the letter's headers because your address was on the envelope. Unless told otherwise (with the -t flag), sendmail constructs envelope addresses from the recipients you specify on the command line, and there isn't necessarily a correspondence between the header addresses and the envelope addresses.

sendmail's Jobs

To better understand how to set up sendmail, you need to know what different jobs it does and how those jobs fit into the scheme of MUAs, MTAs, mail routers, final delivery agents, and SMTP clients and servers. sendmail can act as a mail router, an SMTP client and an SMTP server. However, it does not do final delivery of mail.

sendmail as Mail Router sendmail is primarily a mail router, meaning it takes a letter, inspects the recipient addresses, and decides the best way to send it. How does sendmail do this?

sendmail determines some of the information it needs on its own, like the current time and the name of the host on which it's running, but most of its brains are supplied by you, the postmaster, in the form of a configuration file, This somewhat cryptic file tells sendmail exactly how you want various kinds of mail handled. It is extremely flexible and powerful, and at first glance seemingly inscrutable. However, one of the strengths of V8 sendmail is its set of modular configuration file building blocks. Most sites can easily construct their configuration files from these modules, and many examples are included. Writing a configuration file from scratch is a daunting task and you should avoid it if you can.

sendmail as MTA--Client (Sender) and Server (Receiver) SMTP As mentioned before, sendmail can function as an MTA since it understands the SMTP protocol (V8 sendmail also understands ESMTP). Because SMTP is a connection-oriented protocol, there is always a client and a server (also known as a sender and a receiver). The SMTP client delivers a letter to an SMTP server, which listens continuously on its computer's SMTP port. sendmail can be an SMTP client or an SMTP server. When run by an MUA, it becomes an SMTP client and speaks client-side SMTP to an SMTP server (not necessarily another sendmail program). When your system boots and it starts in daemon mode, it runs continuously, listening on the SMTP port for incoming mail.

sendmail as a Final Delivery Agent (NOT!) One thing sendmail doesn't do is final delivery. sendmail's author wisely chose to leave this task to other programs. sendmail is a big, complicated program that runs with super-user privileges, an almost guaranteed recipe for security problems, and there have been quite a few in sendmail's past. The additional complexity of final mail delivery is the last thing sendmail needs.

sendmail's Auxiliary Files

sendmail depends on a number of auxiliary files to do its job. The most important are the aliases file and the configuration file, The statistics file,, can be created or not depending on whether you want the statistics. sendmail.hf is the SMTP help file, and should be installed if you intend to run sendmail as an SMTP server (most sites do). That's all that needs to be said about and sendmail.hf (there are other auxiliary files that are covered in the SIOG), but the aliases and files are important enough to be covered in their own sections.

The Aliases File

sendmail always checks recipient addresses for aliases, which are alternate names for a recipient. For instance, each Internet site is required to have a valid address postmaster to which mail problems may be reported. Most sites don't have an actual account of that name but divert the postmaster's mail to the person or persons responsible for e-mail administration. For instance, at the mythical site, the users joe and betty are jointly responsible for e-mail administration, and the aliases file has the following entry:

postmaster: joe, betty

This line tells sendmail that mail to postmaster should instead be delivered to the login names joe and betty. In fact, those names could also be aliases:

postmaster: firstshiftops, secondshiftops, thirdshiftops
firstshiftops: joe, betty
secondshiftops: lou, emma
thirdshiftops: ben, mark, clara

In all of these examples, the alias name is the part on the left side of the colon, and the aliases for those names are on the right side. sendmail repeatedly evaluates aliases until they resolve to a real user or a remote address. In the previous example, to resolve the alias postmaster, sendmail first expands it into the list of recipients firstshiftops, secondshiftops, and thirdshiftops and then expands each of these into the final list, joe, betty, lou, emma, ben, mark, and clara.

Although the right side of an alias may refer to a remote host, the left side may not. The alias joe: [email protected] is legal, but [email protected]: [email protected] is not.

Reading Aliases from a File--the :include: Directive Aliases may be used to create mailing lists (in the example above, the alias postmaster is in effect a mailing list for the local postmasters). For big or frequently changing lists, you can use the :include: alias form to direct sendmail to read the list members from a file. If the aliases file contains the line:

homeboys: :include:/home/alphonse/homeboys.aliases

and the file /home/alphonse/homeboys.aliases contains:


The effect is the same as the alias:

homeboys: alphonse, joe, betty, george

This is handy for mailing lists that change frequently, or those managed by users other than the postmaster. If you find a user is asking for frequent changes to a mail alias, you may want to put it under her control.

Mail to Programs The aliases file also may be used to send the contents of e-mail to a program. For instance, many mailing lists are set up so that you can get information about the list or subscribe to it by sending a letter to a special address, list-request. The letter usually contains a single word in its body, such as help or subscribe, which causes a program to mail an information file to the sender. Suppose that the gonzo mailing list has such an address called gonzo-request:

gonzo-request: |/usr/local/lib/auto-gonzo-reply

In this form of alias, the pipe sign (|) tells sendmail to use the program mailer, which is usually defined as /bin/sh (see "The M command--defining mailers" below). sendmail feeds the message to the standard input of /usr/local/lib/auto-gonzo-reply, and if it exits normally, sendmail considers the letter to be delivered.

Mail to Files You can also create an alias that causes sendmail to send mail to files. An example of this is the alias nobody, which is common on systems running the Network File System (NFS):

nobody: /dev/null

Aliases that specify files cause sendmail to append its message to the named file. Because the special file /dev/null is the UNIX bit-bucket, this alias simply throws mail away.

Setting up sendmail

The easiest way to show you how to set up sendmail is to use a concrete example. However, because sendmail runs under many different versions of UNIX, your system may vary from the examples shown below. For the sake of concreteness, these examples assume that you're setting up sendmail on a Solaris 2.3 system, Sun Microsystem's version of SVR4 UNIX.

First you must obtain the source and compile sendmail. Next you must choose a file that closely models your site's requirements and tinker with it as necessary. Then you must test sendmail and its configuration file. Finally, you must install sendmail,, and other auxiliary files.

Those are the basic steps, but depending on where you install sendmail, you may also have to modify a file in the directory /etc/init.d so that sendmail will be started correctly when the system boots. In addition, if your system doesn't already have one, you must create an aliases file, often named /usr/lib/aliases or /etc/mail/aliases (the location of the aliases file is given in, so you can put it wherever you want). You may also have to make changes to your system's DNS database, but that won't be covered here.

Obtaining the Source

sendmail version 8.6.9 is on the UNIX Unleashed CD. This is the most recent version available as this book goes to press, and it is the version documented in the O'Reilly book sendmail. However, if your site is on the Internet and you want to obtain the absolutely latest version, ftp to the host and look in the directory ~ftp/pub/ucb/sendmail. Use the following steps to download it:

$ ftp
Connected to
220 kohler FTP server (Version wu-2.4(4) Fri May 6 16:09:33 PDT 1994) ready.
Name ( anonymous
331 Guest login ok, send your complete e-mail address as password.
Password: (Type your e-mail address)
230 Guest login ok, access restrictions apply.
ftp> cd ucb/sendmail
250-This directory contains sendmail source distributions, currently for
250-Release 8. The latest version is in four files:
250-   sendmail.${VER}.base.tar.Z -- the base system source & documentation.
250-   sendmail.${VER}.cf.tar.Z -- configuration files.
250-   sendmail.${VER}.misc.tar.Z -- miscellaneous support programs.
250-   sendmail.${VER}.xdoc.tar.Z -- extended documentation, with postscript.
250-The status of various ${VER}s is:
250-8.6.9  This is the version documented in the O'Reilly sendmail book.
250-       and which will be on the 4.4BSD-Lite tape. The files
250-       sendmail.8.6.[123456789].patch will upgrade an 8.6 source to
250-       this version (apply all of them).
250-8.6.8  The previous version. It fixes some significant security
250-       problems; you should be running at least this version.
250 CWD command successful.
ftp> binary
200 Type set to I.
ftp> mget sendmail.8.6.9.base.tar.Z
mget sendmail.8.6.9.base.tar.Z? y
200 PORT command successful.
150 Opening BINARY mode data connection for sendmail.8.6.9.base.tar.Z (500945 bytes).
226 Transfer complete.
local: sendmail.8.6.9.base.tar.Z remote: sendmail.8.6.9.base.tar.Z
500945 bytes received in 14 seconds (34 Kbytes/s)
mget y
200 PORT command successful.
150 Opening BINARY mode data connection for (199863 bytes).
226 Transfer complete.
local: remote:
199863 bytes received in 3.3 seconds (59 Kbytes/s)
ftp> quit
221 Goodbye.

Note that the exact name of the files to download differs depending on the current version of V8 sendmail, in this case version 8.6.9. Also, because the files are compressed, you must give ftp the binary command before transferring them. Note too that you should include your complete e-mail address as the password, for instance, [email protected]. You may also wish to download the extended documentation and the support programs, which in this example would have been contained in the files sendmail.8.6.9.xdoc.tar.Z and sendmail.8.6.9.misc.tar.Z.

Unpacking the Source and Compiling sendmail

Now that you've got the source, you need to unpack it. Because it's a compressed tar image, you must first decompress it and then extract the individual files from the tar archive. If you're using the version from the CD-ROM, these steps are not necessary.

$ mkdir /usr/src/local/sendmail
$ mv sendmail.8.6.9.* /usr/src/local/sendmail
$ cd /usr/src/local/sendmail
$ uncompress *Z
$ ls
$ tar xf sendmail.8.6.9.base.tar; tar xf
$ ls -CF
FAQ                    cf/             
KNOWNBUGS              doc/                      src/
Makefile               mailstats/                test/
READ_ME                makemap/
RELEASE_NOTES          sendmail.8.6.9.base.tar
$ rm *tar

Now you're almost ready to compile sendmail, but first read the following files, which contain the latest news pertinent to the specific release of sendmail you've downloaded:


Now run cd and ls to see what files are in the source directory:

$ cd src
$ ls
Makefile               Makefile.SunOS.5.1     mailq.1
Makefile.386BSD        Makefile.SunOS.5.2     mailstats.h
Makefile.AIX           Makefile.SunOS.5.x     main.c
Makefile.AUX           Makefile.Titan         makesendmail
Makefile.BSD43         Makefile.ULTRIX        map.c
Makefile.BSDI          Makefile.UMAX          mci.c
Makefile.CLIX          Makefile.Utah          newaliases.1
Makefile.ConvexOS      Makefile.dist          parseaddr.c
Makefile.DGUX          READ_ME                pathnames.h
Makefile.Dell          TRACEFLAGS             queue.c
Makefile.DomainOS      alias.c                readcf.c
Makefile.Dynix         aliases                recipient.c
Makefile.FreeBSD       aliases.5              savemail.c
Makefile.HP-UX         arpadate.c             sendmail.8
Makefile.IRIX          cdefs.h                sendmail.h
Makefile.Linux         clock.c                sendmail.hf
Makefile.Mach386       collect.c              srvrsmtp.c
Makefile.NCR3000       conf.c                 stab.c
Makefile.NeXT          conf.h                 stats.c
Makefile.NetBSD        convtime.c             sysexits.c
Makefile.OSF1          daemon.c               trace.c
Makefile.RISCos        deliver.c              udb.c
Makefile.SCO           domain.c               useful.h
Makefile.SVR4          envelope.c             usersmtp.c
Makefile.Solaris       err.c                  util.c
Makefile.SunOS         headers.c              version.c
Makefile.SunOS.4.0.3   macro.c

As you can see, because sendmail runs on a variety of hosts and operating systems, a Makefile is provided for many UNIX variants. Since in this example we're assuming a Sun Microsystems Solaris system, we'll use Makefile.Solaris to compile sendmail. But before we type make, we should look at the files conf.h and Makefile.Solaris.

You probably won't want to change much in conf.h, but Makefile.Solaris is a different story. At the very least you should make sure that the correct version of the Solaris operating system is defined. In this case, since we're compiling for Solaris 2.3, we must replace the line ENV=-DSOLARIS with the line ENV=-DSOLARIS_2_3 (Makefile.Solaris tells us to do so). If you've purchased the SunPro cc compiler, you may want to change the definition of the CC macro to use that instead of gcc. You may want to make other changes; for example, you may not want to install sendmail in the default location. Read the Makefile carefully and make changes as needed.

Remember, when in doubt, you can always type make -n arguments to see what would happen before it happens. This is always an especially good idea when you're working as the super-user.

Now you're ready to compile. Type:

$ make -f Makefile.Solaris sendmail
gcc -I.  -I/usr/sww/include/db -DNDBM -DNIS -DSOLARIS_2_3 -c  alias.c
gcc -I.  -I/usr/sww/include/db -DNDBM -DNIS -DSOLARIS_2_3 -c  util.c
gcc -I.  -I/usr/sww/include/db -DNDBM -DNIS -DSOLARIS_2_3 -c version.c
gcc -o sendmail alias.o arpadate.o clock.o collect.o conf.o convtime.o daemon.o
deliver.o domain.o envelope.o err.o headers.o macro.o main.o  map.o mci.o
parseaddr.o queue.o readcf.o recipient.o  savemail.o srvrsmtp.o stab.o stats.o
sysexits.o  trace.o udb.o usersmtp.o util.o version.o
-L/usr/sww/lib -lresolv -lsocket -lnsl -lelf

The [...] above covers many deleted lines of output, as well as some warning messages from the compiler. Carefully inspect the output and determine whether the compiler warnings are pertinent. If necessary (and it should only be necessary if you're porting sendmail to a new architecture), correct any problems and compile again. Configuration File

Now you've got a working sendmail, but like the Wizard of Oz's Scarecrow, it's brainless. The file provides sendmail with its brains, and because it's so important, we're going to cover it in fairly excruciating detail. Don't worry if you don't understand everything in this section the first time through. It will make more sense upon rereading, and after you've had a chance to play with some configuration files of your own.

sendmail's power lies in its flexibility, which comes from its configuration file, statements comprise a cryptic programming language that at first glance doesn't inspire much confidence (but C language code probably didn't either the first time you saw it). However, learning the language isn't that hard, and you won't have to learn the nitty-gritty details unless you plan to write a from scratch--a bad idea at best. You do need to learn enough to understand and adapt the V8 sendmail configuration file templates to your site's needs.

General Form of the Configuration File

Each line of the configuration file begins with a single command character that tells the function and syntax of that line. Lines beginning with a # are comments, and blank lines are ignored. Lines beginning with a space or tab are a continuation of the previous line, although you should usually avoid continuations.

Table 24.1 shows the command characters and their functions. It is split into three parts corresponding to the three main functions of a configuration file, which are covered later in "A Functional Description of the Configuration File."

Table 24.1. command characters.

Command Character Command Syntax and Example Function
# # comments are ignored A comment line. Always use lots of comments.
# Standard RFC822 parsing
D DX string Define a macro X to have the string value string.
C CX word1, word2,… Define a class X as word1, word2,…
Cwlocalhost myuucpname
F FX/path/to/a/file Define a class X by reading it from a file.
H H?mailerflag?name:template Define a mail header.
H?F?From: $q
O OX option arguments Set option X. Most command-line options may be set in
OL9 # set log level to 9
P Pclass=nn Set mail delivery precedence based on the class of the mail.
V Vn Tell V8 sendmail the version level of the configuration file.
K Kname class arguments Define a key file (database map).
Kuucphosts dbm /etc/mail/uucphsts
M Mname,field_1=value_1, Define a mailer.
Mprog,P=/bin/sh,F=lsD,A=sh -c $u
S Snn Begin a new rule-set.
R Rlhs rhs comment Define a matching / rewriting rule.
R$+ $:$>22 call ruleset 22

A Functional Description of the Configuration File

A configuration file does three things. First, it sets the environment for sendmail by telling it what options you want set and the locations of the files and databases it uses.

Second, it defines the characteristics of the mailers (delivery agents or MTAs) that sendmail uses after it decides where to route a letter. All configuration files must define local and program mailers to handle delivery to users on the local host; most also define one or more SMTP mailers; and sites that must handle UUCP mail define UUCP mailers.

Third, the configuration file specifies rulesets that rewrite sender and recipient addresses and select mailers. All rulesets are user-defined, but some have special meaning to sendmail. Ruleset 0, for instance, is used to select a mailer. Rulesets 0, 1, 2, 3, and 4 all have special meaning to sendmail and are processed in a particular order (see "The S and R Operators--Rulesets and Rewriting Rules") later in this chapter.

In the following sections we'll cover the operators in more detail, in the order in which they appear in Table 24.1.

The D Operator--Macros

Macros are like shell variables. Once you define a macro's value you can refer to it later in the configuration file and its value will be substituted for the macro. For instance, a configuration file might have many lines that mention our hypothetical mail hub, Rather than typing that name over and over, you can define a macro R (for relay mailer):

When sendmail encounters a $R in, it substitutes the string

Macro names are always a single character. Quite a few macros are defined by sendmail and shouldn't be redefined except to work around broken software1. sendmail uses lower-case letters for its predefined macros. Uppercase letters may be used freely. V8 sendmail's predefined macros are fully documented in section 5.1.2 of the SIOG.

The C and F Operators--Classes

Classes are similar to macros but are used for different purposes in rewriting rules (see below, "The S and R operators--rulesets and rewriting rules"). As with macros, classes are named by a single character. Lowercase letters are reserved to sendmail, and uppercase letters for user-defined classes. A class contains one or more words. For instance, you could define a class H containing all the hosts in the local domain:

CH larry moe curly

For convenience, large classes may be continued on subsequent lines. The following definition of the class H is exactly the same as the previous one:

CH larry
CH moe
CH curly

You can also define a class by reading its words from a file:


If the file /usr/local/lib/localhosts contains the words larry, moe, and curly, one per line, this definition is equivalent to the previous two.

Why use macros and classes? The best reason is that they centralize information in the configuration file. In the example above, if you decide to change the name of the mail hub from to, you only have to change the definition of the $R macro remedy and the configuration file will work as before. If the name is scattered throughout the file, you might forget to change it in some places. Also, if important information is centralized, you can comment it extensively in a single place. Because configuration files tend to be obscure at best, a liberal dose of comments is a good antidote to that sinking feeling you get when, six months later, you wonder why you made a change.

The H Operator--Header Definitions You probably won't want to change the header definitions given in the V8 sendmail configuration files because they already follow accepted standards. Here are some sample headers:

H?D?Date: $a
H?F?Resent-From: $q
H?F?From: $q
H?x?Full-Name: $x

Note that header definitions can use macros, which are expanded, when inserted into a letter. For instance, the $x macro used in the Full-Name: header definition above expands to the full name of the sender.

The optional ?mailerflag? construct tells sendmail to insert a header only if the chosen mailer has that mailer flag set. (See "The M Operator--Mailer Definitions" later in this chapter.)

Suppose that the definition of your local mailer has a flag Q, and sendmail selects that mailer to deliver a letter. If your configuration file contains a header definition like the following one, sendmail will insert that header into letters delivered through the local mailer, substituting the value of the macro $F:

H?Q?X-Fruit-of-the-day: $F

Why would you use the ?mailerflag? feature? Different protocols may require different mail headers. Since they also need different mailers, you can define appropriate mailer flags for each in the mailer definition, and use the ?mailerflag? construct in the header definition to tell sendmail whether to insert the header.

The O Operator--Setting Options sendmail has many options that change its operation or tell it the location of files it uses. Most of them may be given either on the command line or in the configuration file. For instance, the location of the aliases file may be specified in either place. To specify the aliases file on the command line, you use the -o option:

$ sendmail -oA/etc/mail/aliases [other arguments...]

To do the same thing in the configuration file, you include a line like this:


Either use is equivalent, but options such as the location of the aliases file rarely change and most people set them in The V8 sendmail options are fully described in section 5.1.6 of the SIOG.

The P Operator--Mail Precedence Users can include mail headers indicating the relative importance of their mail, and sendmail can use those headers to decide the priority of competing letters. Precedences for V8 sendmail are given as:


If a user who runs a large mailing list includes the header Precedence: bulk in his letters, sendmail gives it a lower priority than a letter with the header Precedence: first-class.

The V Version Levels As V8 sendmail evolves its author adds new features. The V operator lets V8 sendmail know what features it should expect to find in your configuration file. Older versions of sendmail don't understand this command. Section 5.1.8 of the SIOG explains the different configuration file version levels in detail.

NOTE: The configuration file version level does not correspond to the sendmail version level. V8 sendmail understands versions 1 through 5 of configuration files, and there is no such thing as a version 8 configuration file.

The K Operator--Key Files sendmail has always used keyed databases, for instance, the aliases databases. Given the key postmaster, sendmail looks up the data associated with that key and returns the names of the accounts to which the postmaster's mail should be delivered. V8 sendmail extends this concept to arbitrary databases, including NIS maps (Sun's Network Information Service, formerly known as Yellow Pages or YP). The K operator tells sendmail the location of the database, its class, and how to access it. V8 sendmail supports the following classes of user-defined databases: dbm, btree, hash, and NIS. Depending on which of these databases you use, you must compile sendmail with different options. See section 5.1.9 of the SIOG for the lowdown on key files.

The M Operator--Mailer Definitions Mailers are either MTAs or final delivery agents. Recall that the aliases file allows you to send mail to a login name (which might be aliased to a remote user), a program, or a file. A special mailer may be defined for each purpose. And even though the SMTP MTA is built-in, it must have a mailer definition to tailor sendmail's SMTP operations.

Mailer definitions are important because all recipient addresses must resolve to a mailer in ruleset 0. Resolving to a mailer is just another name for sendmail's main function, mail routing. For instance, resolving to the local mailer routes the letter to a local user via the final delivery agent defined in that mailer (usually /bin/mail), and resolving to the SMTP mailer routes the letter to another host via sendmail's built-in SMTP transport, as defined in the SMTP mailer. A concrete example of a mailer definition will make this clearer. Since sendmail requires a local mailer definition, let's look at that:

Mlocal, P=/bin/mail, F=lsDFMfSn, S=10, R=20, A=mail -d $u

All mailer definitions begin with the M operator and the name of the mailer, in this case local. Other fields follow, separated by commas. Each field consists of a field name and its value, separated by an equals sign (=). The allowable fields are explained in section 5.1.4 of the SIOG.

In the local mailer definition above, the P= equivalence gives the pathname of the program to run to deliver the mail, /bin/mail. The F= field gives the sendmail flags for the local mailer. (See also "The H Operator--Defining Headers" earlier in the chapter.) These flags are not passed to the command mentioned in the P= field but are used by sendmail to modify its operation depending on the mailer it chooses. For instance, sendmail usually drops its super-user status before invoking mailers, but you can use the S mailer flag to tell sendmail to retain it for certain mailers.

The S= and R= fields specify rulesets for sendmail to use in rewriting sender and recipient addresses. Since you can give different R= and S= flags for each mailer you define, you can rewrite addresses differently for each mailer. For instance, if one of your UUCP neighbors runs obsolete software that doesn't understand domain addressing, you might declare a special mailer just for that site and write mailer-specific rulesets to convert addresses into a form its mailer could understand.

The S= and R= fields can also specify different rulesets to rewrite the envelope and header addresses. (See "Header and Envelope Addresses".) A specification like S=21/31 tells sendmail to use ruleset 21 to rewrite sender envelope addresses and ruleset 31 to rewrite sender header addresses. This comes in handy for mailers that require addresses to be presented differently in the envelope and the headers.

The A= field gives the argument vector (command line) for the program that will be run, in this case /bin/mail. In this example, sendmail runs the command as mail -d $u, expanding the $u macro to the name of the user to which the mail should be delivered, for instance:

/bin/mail -d joe

This is exactly the same command that you could type to your shell at a command prompt.

There are many other mailer flags you may want to use to tune mailers, for instance to limit the maximum message size on a per-mailer basis. These flags are all documented in section 5.1.4 of the SIOG.

The S and R Operators--Rulesets and Rewriting Rules A configuration file is composed of a series of rulesets, which are somewhat like subroutines in a program. Rulesets are used to detect bad addresses, to rewrite addresses into forms that remote mailers can understand, and to route mail to one of sendmail's internal mailers. (See the previous section, "The M Operator--Mailer Definitions".)

sendmail passes addresses to rulesets according to a built-in order. Rulesets may also call other rulesets not in the built-in order. The built-in order varies depending on whether the address being handled is a sender or receiver address, and what mailer has been chosen to deliver the letter.

Rulesets are announced by the S command, which is followed by a number to identify the ruleset. sendmail collects subsequent R (rule) lines until it finds another S operator, or the end of the configuration file. The following example defines ruleset 11:

# Ruleset 11
R$+       $: $>22 $1     call ruleset 22

This ruleset doesn't do much that is useful. The important thing to note is that sendmail collects ruleset number 11, composed of a single rule.

sendmail's Built-In Ruleset Processing Rules sendmail uses a three-track approach to processing addresses, one to choose a delivery agent, another to process sender addresses, and one for receiver addresses.

All addresses are first sent through ruleset 3 for preprocessing into a canonical form that makes them easy for other rulesets to handle. Regardless of the complexity of the address, ruleset 3's job is to decide the next host to which a letter should be sent. Ruleset 3 tries to locate that host in the address and mark it within angle brackets. In the simplest case, an address like [email protected] becomes joe<>.

Ruleset 0 then determines the correct delivery agent (mailer) to use for each recipient. For instance, a letter from [email protected] to [email protected] (an Internet site) and pinhead!zippy (an old-style UUCP site) will require two different mailers: an SMTP mailer for and an old-style UUCP mailer for pinhead. Mailer selection determines later processing of sender and recipient addresses because the rulesets given in the S= and R= mailer flags vary from mailer to mailer.

Addresses sent through ruleset 0 must resolve to a mailer. This means that when an address matches the lhs, the rhs gives a triple2 of mailer, user, host. The following line shows the syntax for a rule that resolves to a mailer:

Rlhs      $#mailer $@host $:user   your comment here...

The mailer is the name of one of the mailers you've defined in an M command, for instance smtp. The host and user are usually positional macros taken from the lhs match. (See "The Righthand Side (rhs) of Rules," later in the chapter.)

After sendmail selects a mailer in ruleset 0, it processes sender addresses through ruleset 1 (often empty), and then sends them to the ruleset given in the S= flag for that mailer.

Similarly, it sends recipient addresses through ruleset 2 (also often empty), and then to the ruleset mentioned in the R= mailer flag.

Finally, sendmail post-processes all addresses in ruleset 4, which among other things removes the angle brackets inserted by ruleset 3.

Why do mailers have different S= and R= flags? Consider the example above of the letter sent to [email protected] and pinhead!zippy. If [email protected] sends the mail, her address must appear in a different form to each recipient. For Joe, it should be a domain address, [email protected]. For Zippy, since expects old-style UUCP addresses (and assuming it has a UUCP link to pinhead and's UUCP hostname is whizzer), the return address should be whizzer!betty. Joe's address must also be rewritten for the pinhead UUCP mailer, and Joe's copy must include an address for Zippy that his mailer can handle.

Processing Rules Within Rulesets sendmail passes an address to a ruleset, and then processes it through each rule line by line. If the lhs of a rule matches the address, it is rewritten by the rhs. If it doesn't match, sendmail continues to the next rule until it reaches the end of the ruleset3. At the end of the ruleset, sendmail returns the rewritten address to the calling ruleset or to the next ruleset in its built-in execution sequence.

If an address matches the lhs and is rewritten by the rhs, the rule is tried again--an implicit loop (but see the $@ and $: modifiers below for exceptions).

As shown in Table 24.1, each rewriting rule is introduced by the R command and has three fields, the left-hand side (lhs, or matching side), the righthand side (rhs, or rewriting side) and an optional comment, each of which must be separated by tab characters:

Rlhs      rhs       comment

Parsing--Turning Addresses into Tokens sendmail parses addresses and the lhs of rules into tokens and then matches the address and the lhs, token by token. The macro $o contains the characters that sendmail uses to separate an address into tokens. It's often defined like this:

# address delimiter characters

All of the characters in $o are both token separators and tokens. sendmail takes an address such as [email protected] and breaks it into tokens according to the characters in the o macro, like this:

"rae"     "@"     "rainbow"     "."     "org"

sendmail also parses the lhs of rewriting rules into tokens so they can be compared one by one with the input address to see if they match. For instance, the lhs [email protected] gets parsed as:

"$-"     "@"     "rainbow"     "."     "org"

(Don't worry about the $- just yet. It's a pattern-matching operator similar to shell wild cards that matches any single token, and is covered below in "The Left-hand Side (lhs) of Rules.") Now we can put the two together to show how sendmail decides whether an address matches the lhs of a rule:

"rae"     "@"     "rainbow"     "."     "org"
"$-"     "@"     "rainbow"     "."     "org"

In this case, each token from the address matches a constant string (e.g., rainbow) or a pattern-matching operator ($-), so the address matches and sendmail would use the rhs to rewrite the address.

Consider the effect (usually bad!) of changing the value of $o. As shown above, sendmail breaks the address [email protected] into five tokens. However, if the @ character were not in $o, the address would be parsed quite differently, into only three tokens:

"rae@rainbow"     "."     "org"

You can see that changing $o has a drastic effect on sendmail's address parsing, and you should leave it alone until you really know what you're doing. Even then you probably won't want to change it since the V8 sendmail configuration files already have it correctly defined for standard RFC 822 and RFC 976 address interpretation.

The Left-hand Side (lhs) of Rules The lhs is a pattern against which sendmail matches the input address. The lhs may contain ordinary text or any of the pattern-matching operators shown in Table 24.2:

Table 24.2. lhs pattern-matching operators.

$- Match exactly one token4
$+ Match one or more tokens
$* Match zero or more tokens
$@ Match the null input (used to call the error mailer)

The values of macros and classes are matched in the lhs with the operators shown in Table 24.3:

Table 24.3. lhs macro and class matching operators.

$X Match the value of macro X
$=C Match any word in class C
$~C Match if token is not in class C

The pattern-matching operators and macro- and class-matching operators are necessary because most rules must match many different input addresses. For instance, a rule might need to match all addresses that end with and begin with one or more of anything.

The Right-hand Side (rhs) of Rules The rhs of a rewriting rule tells sendmail how to rewrite an address that matches the lhs. The rhs may include text, macros, and positional references to matches in the lhs. When a pattern-matching operator from Table 24.2 matches the input, sendmail assigns it to a numeric macro $n, corresponding to the position it matches in the lhs. For instance, suppose the address [email protected] is passed to the following rule:

R$+ @ $+       $: $1 < @ $2 >           focus on domain

In this example, joe matches $+ (one or more of anything), so sendmail assigns the string joe to $1. The @ in the address matches the @ in the lhs, but constant strings are not assigned to positional macros. The tokens in the string match the second $+ and are assigned to $2. The address is rewritten as $1<@$2>, or joe<>.

$: and $@--Altering a Ruleset's Evaluation Consider the following rule:

R$*  $: $1 < @ $j > add local domain

After rewriting an address in the rhs, sendmail tries to match the rewritten address with the lhs of the current rule. Since $* matches zero or more of anything, what prevents sendmail from going into an infinite loop on this rule? After all, no matter how the rhs rewrites the address, it will always match $*.

The $: preface to the rhs comes to the rescue; it tells sendmail to evaluate the rule only once.

There are also times when you want a ruleset to terminate immediately and return the address to the calling ruleset or the next ruleset in sendmail's built-in sequence. Prefacing a rule's rhs with $@ causes sendmail to exit the ruleset immediately after rewriting the address in the rhs.

$>--Calling Another Ruleset A ruleset can pass an address to another ruleset by using the $> preface to the rhs. Consider the following rule:

R$*       $: $>66 $1          call ruleset 66

The lhs $* matches zero or more of anything, so sendmail always does the rhs. As we saw in the previous section, the $: prevents the rule from being evaluated more than once. The $>66 $1 calls ruleset 66 with $1 as its input address. Since the $1 matches whatever was in the lhs, this rule simply passes the entirety of the current input address to ruleset 66. Whatever ruleset 66 returns is passed to the next rule in the ruleset.

Testing Rules and Rulesets--the -bt, -d and -C Options Debugging a can be a tricky business. Fortunately, sendmail provides several ways to test rulesets before you install them.

NOTE: The examples in this section assume that you have a working sendmail. If your system doesn't, try running them again after you've installed V8 sendmail.

The -bt option tells sendmail to enter its rule-testing mode:

$ sendmail -bt
ADDRESS TEST MODE (ruleset 3 NOT automatically invoked)
Enter <ruleset> <address>

NOTE: Notice the warning ruleset 3 NOT automatically invoked. Older versions of sendmail ran ruleset 3 automatically when in address test mode, which made sense since sendmail sends all addresses through ruleset 3 anyway. V8 sendmail does not, but it's a good idea to invoke ruleset 3 manually since later rulesets expect the address to be in canonical form.

The > prompt means sendmail is waiting for you to enter one or more ruleset numbers, separated by commas, and an address. Try your login name with rulesets 3 and 0. The result should look something like this:

> 3,0 joe
rewrite: ruleset  3   input: joe
rewrite: ruleset  3 returns: joe
rewrite: ruleset  0   input: joe
rewrite: ruleset  3   input: joe
rewrite: ruleset  3 returns: joe
rewrite: ruleset  6   input: joe
rewrite: ruleset  6 returns: joe
rewrite: ruleset  0 returns: $# local $: joe

The output shows how sendmail processes the input address joe in each ruleset. Each line of output is identified with the number of the ruleset processing it, the input address, and the address that the ruleset returns. The > is a second prompt indicating that sendmail is waiting for another line of input. When you're done testing, just type Ctrl+D.

Indentation and blank lines better show the flow of processing in this example:

rewrite: ruleset  3   input: joe
rewrite: ruleset  3 returns: joe

rewrite: ruleset  0   input: joe

     rewrite: ruleset  3   input: joe
     rewrite: ruleset  3 returns: joe

     rewrite: ruleset  6   input: joe
     rewrite: ruleset  6 returns: joe

rewrite: ruleset  0 returns: $# local $: joe

The rulesets called were 3 and 0, in that order. Ruleset 3 was processed and returned the value joe, and then sendmail called ruleset 0. Ruleset 0 called ruleset 3 again, and then ruleset 6, an example of how a ruleset can call another one by using $>. Neither ruleset 3 nor ruleset 6 rewrote the input address. Finally, ruleset 0 resolved to a mailer, as it must.

Often you need more detail than -bt provides--usually just before you tear out a large handful of hair because you don't understand why an address doesn't match the lhs of a rule. You may remain hirsute because sendmail has verbose debugging built-in to most of its code.

You use the -d option to turn on sendmail's verbose debugging. This option is followed by a numeric code that tells which section of debugging code to turn on, and at what level. The following example shows how to run sendmail in one of its debugging modes and the output it produces:

$ sendmail -bt -d21.12
Version 8.6.7
ADDRESS TEST MODE (ruleset 3 NOT automatically invoked)
Enter <ruleset> <address>
> 3,0 joe
rewrite: ruleset  3   input: joe
----trying rule: $* < > $*
---- rule fails
----trying rule: $* < $* < $* < $+ > $* > $* > $*
---- rule fails

The -d21.12 in the example above tells sendmail to turn on level 12 debugging in section 21 of its code. The same command with the option -d21.36 gives more verbose output (debug level 36 instead of 12).

NOTE: You can combine one or more debugging specifications separated by commas, as in -d21.12,14.2, which turns on level 12 debugging in section 21 and level 2 debugging in section 14. You can also give a range of debugging sections, as in -d1-10.35, which turns on debugging in sections 1 through 10 at level 35. The specification -d0-91.104 turns on all sections of V8 sendmail's debugging code at the highest levels and produces thousands of lines of output for a single address.

The -d option is not limited to use with sendmail's address testing mode (-bt); you can also use it to see how sendmail processes rulesets while sending a letter, as the following example shows:

$ sendmail -d21.36 [email protected] < /tmp/letter
[lots and lots of output...]

Unfortunately, the SIOG doesn't tell you which numbers correspond to which sections of code. Instead, the author suggests that it's a lot of work to keep such documentation current (which it is), and that you should look at the code itself to discover the correct debugging formulas.

The function tTd() is the one to look for. For example, suppose you wanted to turn on debugging in sendmail's address-parsing code. The source file parseaddr.c contains most of this code, and the following command finds the allowable debugging levels:

$ egrep tTd parseaddr.c
        if (tTd(20, 1))
        if (tTd(24, 4))
        if (tTd(22, 11))

The egrep output shows that debugging specifications like -d20.1, -d24.4, and -d22.11 (and others) will make sense to sendmail.

If perusing thousands of lines of C code doesn't appeal to you, the book sendmail documents the debugging flags for sendmail version 8.6.9.

The -C option allows you to test new configuration files before you install them, which is always a good idea. If you want to test a different file, use -C/path/to/the/file. This can be combined with the -bt and -d flags. For instance, a common invocation for testing new configuration files is:

sendmail -bt -d21.12

WARNING: For security, sendmail drops its super-user permissions when you use the -C option. Final testing of configuration files should be done as the super-user to ensure that your testing is compatible with sendmail's normal operating mode.

Conclusion Now you know a lot about the language as well as some useful debugging techniques. However, configuration files will be easier to grasp when you look at some real ones. The section below shows you how to create one from the m4 templates included with V8 sendmail.

Creating a

In this section, we'll develop a for a Solaris 2.3 system, using the templates supplied with V8 sendmail. However, because every site is different, even if you're developing a for another Solaris 2.3 system, yours will probably differ from the one below.

Previous versions of sendmail included complete, sample configuration files to adapt for your site. By contrast, the V8 sendmail configuration files are supplied as m4 templates that you use like building blocks to create a custom configuration file. This is a big advantage for most people. In previous versions, if your site did not want UUCP support, you had to pick through hundreds of lines of a configuration file and remove it line by line. In this version, you simply insert the statement FEATURE(nouucp) into your configuration file template and you are done.

M4 is a programming language that reads a file of macro definitions and commands and creates an output file from it. As a trivial example, suppose you create a document and find yourself repeatedly typing the phrase sendmail Installation and Operation Guide. To avoid the extra typing, you could define a macro siog and enter that instead:

$  cat > test.m4
define('siog','Sendmail Installation and Operation Guide')dnl
Testing: siog
$ m4 test.m4
Testing: Sendmail Installation and Operation Guide

Running m4 on the file test.m4 converts all occurrences of siog to sendmail Installation and Operation Guide. This example only hints at m4's capabilities. The V8 templates make full use of them.

The templates and m4 support files are in the cf directory you created earlier when you unpacked V8 sendmail:

$ cd cf
$ ls -CF
README       domain/      hack/        mailer/      sh/
cf/          feature/     m4/          ostype/      siteconfig/

Please note the file README. If you don't read it, you have little hope of making a working configuration file.

The cf subdirectory is the main one of interest. It contains m4 templates for configuration files used at the University of California at Berkeley (UCB). You should look at them all; one of them may be very close to what you need, and all of them provide good examples for you to adapt to your own site.

The other subdirectories contain m4 support files, the building blocks that are included based on the template you define in the cf subdirectory. You probably won't have to change any of these, although you may need to create site-specific files in the domain and siteconfig subdirectories.

The cf subdirectory contains the following configuration file templates:

$ cd cf
$ ls -CF
Makefile.dist                       obj/                                    sunos3.5-cs-hidden.m

The template is intended for a generic Internet site without UUCP connections. We'll use that as a starting point to develop our own. Since we don't want to modify the original file, we'll make a copy called and modify that. Although we won't show this in the examples below, it's a good idea to use a version control system like SCCS or RCS, or some other version control system to track changes you make to your configuration file template.

Stripped of its comments (a copyright notice), blank lines, and an m4 directive, looks like this:

VERSIONID('@(#)      8.2 (Berkeley) 8/21/93')

This doesn't look like much, but m4 expands it to almost 600 lines. We'll look at this template line-by-line to show what it does.

The line include('../m4/cf.m4') must come first in all configuration file templates, immediately after any comments. It contains the macro definitions that m4 uses to build your configuration file, and if you don't include it here, nothing else will work.

The VERSIONID() macro provides a place to put version information for the edification of humans--sendmail ignores it. If you use RCS or SCCS, you can include their version information here. For instance, for RCS you can include the $Id$ keyword:


and the RCS co (check-out) command expands this to:

VERSIONID('$Id:,v 1.1 1994/03/26 21:46:12 joe Exp joe $')

The FEATURE() macro is used to specify which features you want (or don't want). The line FEATURE(nouucp) in this configuration file template removes UUCP support from the resulting configuration file. Other features are documented in the README file mentioned above. Some features of particular interest are redirect, which provides a clever way to notify senders when someone leaves your site; and nullclient, which creates a bare-bones configuration file that knows just enough to forward mail to a relay. (See the template for an example of its use.)

The next two lines are MAILER() macros to specify the mailers included in this The MAILER() macro takes a single argument, the name of the mailer when m4 expands the MAILER() macro into one or more ruleset definitions, rules to select them in ruleset 0, and the rulesets given in the R= and S= flags. Selecting the smtp mailer actually causes three SMTP mailers to be included. The V8 templates also provide mailer definitions for UUCP mailers, a FAX mailer, and a POP (Post Office Protocol) mailer. See the README file for details.

This is almost enough of a specification to create a working for an SMTP-only site, but you'll want to tune it a little first with additional macros.

The OSTYPE() macro also takes a single argument, the name of a file in ../ostype. This file should contain definitions particular to your operating system, for instance, the location of the aliases file. A wide variety of operating system definitions are included with the V8 configuration files:

$ cd ../ostype
$ ls
aix3.m4       bsdi1.0.m4     hpux.m4        osf1.m4        sunos3.5.m4
aux.m4        dgux.m4        irix.m4        riscos4.5.m4   sunos4.1.m4
bsd4.3.m4     domainos.m4    linux.m4       sco3.2.m4      svr4.m4
bsd4.4.m4     dynix3.2.m4    nextstep.m4    solaris2.m4    ultrix4.1.m4

Since we're developing a configuration file for a Solaris 2.3 system, we'll look at that file:

$ cat solaris2.m4
define('ALIAS_FILE', /etc/mail/aliases)
define('HELP_FILE', /etc/mail/sendmail.hf)
define('STATUS_FILE', /etc/mail/
define('LOCAL_MAILER_FLAGS', 'fSn')

This is pretty straightforward--the file gives the location of sendmail's auxiliary files on that system and specifies local mailer flags appropriate for the Solaris version of /bin/mail. We'll include an OSTYPE() macro just after the VERSIONID() macro, dropping the .m4 filename extension.

The other things you may define in an OSTYPE file are documented in the README.

You may also want to create a domain file and use the DOMAIN() macro to collect site-wide definitions such as your site's UUCP or BITNET relay hosts. You should only put things in this file that are true for all the hosts in your domain. If you only have a single host, you may want to forego creating a domain file and keep this information in your m4 template.

The DOMAIN() macro takes a single argument, the name of a file in ../domain. For instance, DOMAIN(gonzo) would cause m4 to look for a file named ../domain/gonzo.m4. (Note that the .m4 extension is not included in the macro argument.)

WARNING: If you copy one of the UCB templates that includes a DOMAIN() macro, make sure you change that line to use your own domain file, or delete it.

A common feature to include in a domain file is the MASQUERADE_AS() macro, which causes all hosts using that to masquerade as your mail hub. For example, if the Solaris 2.3 host we're building this configuration file for is one of many, all named, the following line would cause all their outbound mail to be addressed as [email protected], regardless of which workstation sent it:


This line could also be included in the m4 template if you don't want to create a domain file. Now the template looks like this, with the lines we've added or changed in boldface type:


To create the working, run m4 on the template:

$ m4 >

This creates a 600-line configuration file, which should be tested thoroughly before you install it. We will do just that in the next section, "Testing sendmail and"

But first, considering that building a file from the V8 macros is so easy, you may be wondering why I went on at such length about the guts of it. After all, if including an SMTP mailer is as easy as typing MAILER(smtp), why bother to learn the grungy details? The first answer is that someday you'll probably need them; something will go wrong and you'll have to figure out exactly why your sendmail isn't working the way it should. You can't do that unless you understand the details. A second answer is that you can't properly test your unless you know what's going on under the simplified m4 gloss. Finally, although the V8 configuration file templates are easy to work with compared to those included with previous versions of sendmail, they're still not exactly on a par with plugging in a new toaster and shoving in a couple of slices of rye. If sendmail were a toaster, instead of a single lever it would have hundreds of complicated knobs and dials, a thick instruction manual, and despite your best efforts, would periodically burst into flames.

Testing sendmail and

Before installing a new or modified you must test it thoroughly. Even small, apparently innocuous changes can lead to disaster, and as mentioned in the introduction to this chapter, people get really irate when you mess up the mail system.

The first step in testing is to create a list of addresses that you know should work at your site. For instance, at, an Internet site without UUCP connections, they know that the following addresses must work:

[email protected]
[email protected]

If has a UUCP link, those addresses must also be tested. Other addresses to consider include the various kinds of aliases (e.g., postmaster, a :include: list, an alias that mails to a file and one that mails to a program), nonlocal addresses, source-routed addresses, and so on. If you want to be thorough, you can create a test address for each legal address format in RFC822.

Now that you've got your list of test addresses, you can use the -C and -bt options to see what happens. At a minimum you'll want to run the addresses through rulesets 3 and 0 to make sure they are routed to the correct mailer. An easy way to do this is to create a file containing the ruleset invocations and test addresses, and run sendmail on that. For instance, if the file addr.test contains the following lines:

3,0 joe
3,0 [email protected]
3,0 [email protected]

you can test your configuration file by typing:

$ sendmail -bt < addr.test
rewrite: ruleset  3   input: joe
rewrite: ruleset  3 returns: joe

You may also want to follow one or more addresses through the complete rewriting process. For instance, if an address resolves to the smtp mailer and that mailer specifies R=21, you can test recipient address rewriting with 3,2,21,4 test_address.

If the appears to work correctly so far, it's time to move on to sending some real letters. You can do so with a command like this:

$ sendmail -v -oQ/tmp recipient < /dev/null

The -v option tells sendmail to be verbose so you can see what's happening. Depending on whether the delivery is local or remote, you may see something as simple as joe... Sent, or an entire SMTP dialogue.

The -oQ/tmp tells sendmail to use /tmp as its queue directory. This is necessary because sendmail drops its super-user permissions when run with the -C option and can't write queue files into the normal mail queue directory. Because you are using the -C and -oQ options, sendmail also includes the following warning headers in the letter to help alert the recipient of possible mail forgery:

X-Authentication-WARNING Processed from queue /tmp
X-Authentication-WARNING Processed by joe with -C

sendmail also inserts the header Apparently-to: joe because although you specified a recipient on the command line, there was none in the body of the letter. In this case the letter's body was taken from the empty file /dev/null, so there was no To: header. If you do your testing as the super-user, you can skip the -oQ argument, and sendmail won't insert the warning headers. You can avoid the Apparently-to: header by creating a file like this:

To: recipient


and using it as input instead of /dev/null.

The recipient should be you so you can inspect the headers of the letter for correctness. In particular, return address lines must include an FQDN for SMTP mail. That is, a header like From: joe@gonzo is incorrect since it doesn't include the domain part of the name, but a header like From: [email protected] is fine.

You should repeat this testing for the same variety of addresses you used in the first tests. You may have to create special aliases that point to you for some of the testing.

The amount of testing you do depends on the complexity of your site and the amount of experience you have, but a beginning system administrator should test things very thoroughly, even for apparently simple installations. Remember the flaming toaster.

Installing sendmail and Friends

Once you're satisfied that your sendmail and work, you must decide where to install them. The most popular approach is to put sendmail and its other files in the same place that your vendor puts its distributed sendmail files. The advantage of this approach is conformity; if someone else familiar with your operating system tries to diagnose a mail problem, he will know where to look.

However, some people prefer to install local programs separately from vendor programs, for several good reasons. First, operating system upgrades are usually easier when local modifications are clearly segregated from vendor programs. Second, some vendors, notably Sun Microsystems, release operating system patches that bundle together everything including the kitchen sink. If you naively install such a patch, you may inadvertently overwrite your V8 sendmail with your vendor's version, and it probably won't understand your V8

Therefore, you may want to install sendmail in a subdirectory of /usr/local, the traditional directory for local enhancements to the vendor's operating system. The locations of sendmail's auxiliary files are given in, so you can either leave them in the vendor's usual locations or install them in /usr/local and modify the to match. If you want to change the compiled-in location of the configuration file, redefine the C preprocessor macro _PATH_SENDMAILCF in src/Makefile and recompile sendmail. For example, add the definition:


to the CFLAGS macro in the Makefile.

Once you've decided where the files should go, look at the Makefile you used to compile sendmail and see if it agrees. The easiest way is to use make's -n option to see what would have happened. The results look like this for the V8 distribution's Makefile.Solaris:

$ make -n install
/usr/ucb/install -o root -g sys -m 6555 sendmail /usr/lib
for i in /usr/ucb/newaliases /usr/ucb/mailq; do rm -f $i; ln -s /usr/lib/sendmai
l $i; done
/usr/ucb/install -c -o root -g sys -m 644 /dev/null \
/usr/ucb/install -c -o root -g sys -m 444 sendmail.hf /etc/mail
nroff -h -mandoc aliases.5 > aliases.0
nroff -h -mandoc mailq.1 > mailq.0
nroff -h -mandoc newaliases.1 > newaliases.0
nroff -h -mandoc sendmail.8 > sendmail.0

If this isn't what you want, modify the Makefile as necessary.

Note that the sendmail manual pages use the 4.4BSD mandoc macros, which your system probably doesn't have. You can ftp the mandoc macros from the host, in the directory /systems/unix/bsd-sources/share/tmac.

If your system doesn't have the /usr/ucb/install program, you can copy the new files instead, and use chown, chgrp and chmod to set the correct owner, group, and mode. However, if you're installing on top of your vendor's files, it's a good idea to first copy or rename them in case you ever need them again.

After you install sendmail and its auxiliary files, rebuild the aliases database by running sendmail -bi. You'll also need to kill and restart your sendmail daemon. If your vendor's system uses a frozen configuration file (sendmail.fc), remove it; V8 sendmail doesn't use one.

Modifying sendmail's Boot-Time Startup In its SMTP server role, sendmail starts when the system boots and runs continuously. If you install it in a non-standard location like /usr/local, you'll have to modify your system's startup scripts. Even if you install it in the standard location, you should ensure that the default system startup is correct for V8 sendmail.

When SVR4 UNIX systems boot, they run a series of short shell scripts in the directories /etc/rcX.d, where the X corresponds to the system run level. For instance, shell scripts that bring the system to run level 2 are found in /etc/rc2.d.

However, SVR4 systems have many run levels and some software subsystems should be started in each of them. Therefore, the shell scripts in /etc/rcX.d are located in /etc/init.d and linked to the files in the /etc/rcX.d directories. The /etc/init.d directory is therefore the best place to look for your sendmail startup script.

The following example shows how to find how sendmail starts on a Solaris 2.3 system. Other SVR4 systems are similar:

$ cd /etc/init.d
$ grep sendmail *
sendmail:#ident "@(#)sendmail   1.4   92/07/14 SMI"   /* SVr4.0 1.5 */
sendmail:# /etc/init.d/sendmail - Start/Stop the sendmail daemon
sendmail:# If sendmail is already executing, don't re-execute it.
sendmail:if [ -f /usr/lib/sendmail -a -f /etc/mail/ ]; then
sendmail:               /usr/lib/sendmail -bd -q1h;
sendmail:pid='/usr/bin/ps -e | /usr/bin/grep sendmail | [...]
sendmail:echo "usage: /etc/rc2.d/S88sendmail {start|stop}"

NOTE: Some of the lines above are truncated and shown as [...] due to page-width limitations.

In this case the grep output shows that the vendor starts sendmail with a script named sendmail because each line of the grep output is prefixed with that filename. Examine the script sendmail to see if any changes are necessary. This script expects sendmail to be located in /usr/lib. If you install V8 sendmail somewhere else, you'll have to modify the script to match, changing paths like /usr/lib/sendmail to /usr/local/lib/sendmail. If the command-line flags in the script aren't what you want, change those too.


It's not possible in a single chapter to tell you all you must know about e-mail administration, but as Yogi Berra (or maybe that was Casey Stengel) once said, "You could look it up," and you should. There are a lot of things you'll only learn by reading the documentation mentioned previously in "Background Material and Other Sources." However, this chapter should give you a good basis for understanding the theory behind Internet e-mail delivery and enough of the specifics of V8 sendmail to get your e-mail system up and running.

1. For instance, sendmail sets $j to your system's fully qualified domain name (FQDN, e.g., If your system's gethostbyname() function returns something other than the FQDN, you must define $j in

2. The local mailer omits the $@host.

3. Ruleset 0 is an exception to this rule. sendmail stops evaluating rules in ruleset 0 as soon as a rule resolves to a mailer.

4. Tokens are explained in "Tokens--How sendmail Interprets Input Patterns."



Groupthink : Two Party System as Polyarchy : Corruption of Regulators : Bureaucracies : Understanding Micromanagers and Control Freaks : Toxic Managers :   Harvard Mafia : Diplomatic Communication : Surviving a Bad Performance Review : Insufficient Retirement Funds as Immanent Problem of Neoliberal Regime : PseudoScience : Who Rules America : Neoliberalism  : The Iron Law of Oligarchy : Libertarian Philosophy


War and Peace : Skeptical Finance : John Kenneth Galbraith :Talleyrand : Oscar Wilde : Otto Von Bismarck : Keynes : George Carlin : Skeptics : Propaganda  : SE quotes : Language Design and Programming Quotes : Random IT-related quotesSomerset Maugham : Marcus Aurelius : Kurt Vonnegut : Eric Hoffer : Winston Churchill : Napoleon Bonaparte : Ambrose BierceBernard Shaw : Mark Twain Quotes


Vol 25, No.12 (December, 2013) Rational Fools vs. Efficient Crooks The efficient markets hypothesis : Political Skeptic Bulletin, 2013 : Unemployment Bulletin, 2010 :  Vol 23, No.10 (October, 2011) An observation about corporate security departments : Slightly Skeptical Euromaydan Chronicles, June 2014 : Greenspan legacy bulletin, 2008 : Vol 25, No.10 (October, 2013) Cryptolocker Trojan (Win32/Crilock.A) : Vol 25, No.08 (August, 2013) Cloud providers as intelligence collection hubs : Financial Humor Bulletin, 2010 : Inequality Bulletin, 2009 : Financial Humor Bulletin, 2008 : Copyleft Problems Bulletin, 2004 : Financial Humor Bulletin, 2011 : Energy Bulletin, 2010 : Malware Protection Bulletin, 2010 : Vol 26, No.1 (January, 2013) Object-Oriented Cult : Political Skeptic Bulletin, 2011 : Vol 23, No.11 (November, 2011) Softpanorama classification of sysadmin horror stories : Vol 25, No.05 (May, 2013) Corporate bullshit as a communication method  : Vol 25, No.06 (June, 2013) A Note on the Relationship of Brooks Law and Conway Law


Fifty glorious years (1950-2000): the triumph of the US computer engineering : Donald Knuth : TAoCP and its Influence of Computer Science : Richard Stallman : Linus Torvalds  : Larry Wall  : John K. Ousterhout : CTSS : Multix OS Unix History : Unix shell history : VI editor : History of pipes concept : Solaris : MS DOSProgramming Languages History : PL/1 : Simula 67 : C : History of GCC developmentScripting Languages : Perl history   : OS History : Mail : DNS : SSH : CPU Instruction Sets : SPARC systems 1987-2006 : Norton Commander : Norton Utilities : Norton Ghost : Frontpage history : Malware Defense History : GNU Screen : OSS early history

Classic books:

The Peter Principle : Parkinson Law : 1984 : The Mythical Man-MonthHow to Solve It by George Polya : The Art of Computer Programming : The Elements of Programming Style : The Unix Haterís Handbook : The Jargon file : The True Believer : Programming Pearls : The Good Soldier Svejk : The Power Elite

Most popular humor pages:

Manifest of the Softpanorama IT Slacker Society : Ten Commandments of the IT Slackers Society : Computer Humor Collection : BSD Logo Story : The Cuckoo's Egg : IT Slang : C++ Humor : ARE YOU A BBS ADDICT? : The Perl Purity Test : Object oriented programmers of all nations : Financial Humor : Financial Humor Bulletin, 2008 : Financial Humor Bulletin, 2010 : The Most Comprehensive Collection of Editor-related Humor : Programming Language Humor : Goldman Sachs related humor : Greenspan humor : C Humor : Scripting Humor : Real Programmers Humor : Web Humor : GPL-related Humor : OFM Humor : Politically Incorrect Humor : IDS Humor : "Linux Sucks" Humor : Russian Musical Humor : Best Russian Programmer Humor : Microsoft plans to buy Catholic Church : Richard Stallman Related Humor : Admin Humor : Perl-related Humor : Linus Torvalds Related humor : PseudoScience Related Humor : Networking Humor : Shell Humor : Financial Humor Bulletin, 2011 : Financial Humor Bulletin, 2012 : Financial Humor Bulletin, 2013 : Java Humor : Software Engineering Humor : Sun Solaris Related Humor : Education Humor : IBM Humor : Assembler-related Humor : VIM Humor : Computer Viruses Humor : Bright tomorrow is rescheduled to a day after tomorrow : Classic Computer Humor

The Last but not Least Technology is dominated by two types of people: those who understand what they do not manage and those who manage what they do not understand ~Archibald Putt. Ph.D

Copyright © 1996-2021 by Softpanorama Society. was initially created as a service to the (now defunct) UN Sustainable Development Networking Programme (SDNP) without any remuneration. This document is an industrial compilation designed and created exclusively for educational use and is distributed under the Softpanorama Content License. Original materials copyright belong to respective owners. Quotes are made for educational purposes only in compliance with the fair use doctrine.

FAIR USE NOTICE This site contains copyrighted material the use of which has not always been specifically authorized by the copyright owner. We are making such material available to advance understanding of computer science, IT technology, economic, scientific, and social issues. We believe this constitutes a 'fair use' of any such copyrighted material as provided by section 107 of the US Copyright Law according to which such material can be distributed without profit exclusively for research and educational purposes.

This is a Spartan WHYFF (We Help You For Free) site written by people for whom English is not a native language. Grammar and spelling errors should be expected. The site contain some broken links as it develops like a living tree...

You can use PayPal to to buy a cup of coffee for authors of this site


The statements, views and opinions presented on this web page are those of the author (or referenced source) and are not endorsed by, nor do they necessarily reflect, the opinions of the Softpanorama society. We do not warrant the correctness of the information provided or its fitness for any purpose. The site uses AdSense so you need to be aware of Google privacy policy. You you do not want to be tracked by Google please disable Javascript for this site. This site is perfectly usable without Javascript.

Last modified: March 12, 2019