Basic Modes of sendmail
Besides the daemon mode (discussed earlier), sendmail can be run in a number of other useful modes. In this section we’ll have a look at some of these. Others we’ll leave for later.
How to Run sendmail
One way to run sendmail is to provide it with
the name of a recipient as the only command-line argument. For
example, the following sends a mail message to
george
:
% /usr/lib/sendmail george
Multiple recipients can also be given. For example, the following
sends a mail message to george
,
truman
, and teddy
:
% /usr/lib/sendmail george,truman,teddy
The sendmail
program accepts two different kinds of command-line arguments.
Arguments that do not begin with a
-
character (such as george
)
are assumed to be recipients. Arguments that do
begin with a -
character are taken as switches
that determine the behavior of sendmail. The
recipients must always follow all the switched arguments. Any
switched arguments that follow recipients will be interpreted as
recipient addresses, potentially causing bounced mail.
In this chapter we will cover only a few of these switch-style command-line arguments (see Table 1-1). The complete list of command-line switches, along with an explanation of each, is presented in Chapter 15.
Flag |
Description |
-b |
Set operating mode |
-v |
Run in verbose mode |
-d |
Run in debugging mode |
Become a mode (-b)
The sendmail program can function in a number of
different ways depending on which form of -b
argument you use. One form, for example, causes
sendmail to display the contents of the queue.
Another causes sendmail to rebuild the
aliases database. A complete list of the
-b
command-line
mode-setting switches is shown in Table 1-2. We
will cover only a few in this chapter.
Form |
Description |
|
Use ARPAnet (Grey Book) protocols |
|
Run as a daemon, but don’t fork |
|
Run as a daemon |
|
Purge persistent host status |
|
Print persistent host status |
|
Rebuild alias database |
|
Be a mail sender |
|
Print number of entries in the queue (V8.12 and above) |
|
Print the queue |
|
Run SMTP on standard input |
|
Test mode: resolve addresses only |
|
Verify: don’t collect or deliver |
|
Freeze the configuration file (obsolete) |
The effects of some of the options in Table 1-2 can also be achieved by running sendmail using a different name. Other names and a description of their results are shown in Table 1-3. Each name can be a hard link with or a symbolic link to sendmail.
Daemon mode (-bd)
The sendmail program can run as a daemon in the background, listening for incoming mail from other machines. The sendmail program reads its configuration file only once, when it first starts as a daemon. It then continues to run forever, never reading the configuration file again. As a consequence, it will never see any changes to that configuration file.
Thus, when you change something in the sendmail.cf configuration file, you always need to kill and restart the sendmail daemon. But before you can kill the daemon, you need to know how to correctly restart it. This information is in the /var/run/sendmail.pid file or one of your system rc files.
On a Berkeley Unix-based system, for example, the daemon is usually started like this:
/usr/sbin/sendmail -bd -q1h
The -bd
command-line
switch specifies daemon mode. The -q
switch tells
sendmail how often to look in its queue to
process pending mail. The -q1h
switch says to
process the queue at one (1
) hour
(h
) intervals.
The actual command to start the sendmail daemon on your system might be different from what we’ve shown. If you manage many different brands of systems, you’ll need to know how to start the daemon on all of them.
Kill and Restart, Beginning with V8.7
Killing and restarting the sendmail daemon became easier beginning with V8.7. A single command[13] will kill and restart the daemon. In the following command, you might need to replace the path /var/run with one appropriate to your operating system (such as /etc/mail):
% kill -HUP `head -1 /var/run/sendmail.pid`
This single command has the same effect as the two commands shown for V8.6 in the following sections.
Kill and restart, with V8.6
Before you can start the sendmail daemon, you need to make sure there is not a daemon running already.
Beginning with V8.6, the pid of the currently running daemon is found in the first line of the /etc/mail/sendmail.pid file. The process of killing the daemon looks like this:
% kill -15 `head -1 /etc/mail/sendmail.pid`
After killing the currently running daemon, you can start a new daemon with the following simple command:
% `tail -1 /etc/mail/sendmail.pid`
Kill and restart, old versions
Under old versions of sendmail you need to use the ps(1) program to find the pid of the daemon. How you run ps is different on BSD Unix and System V Unix. For BSD Unix the command you use and the output it produces resemble the following:
%ps ax | grep sendmail | grep -v grep
99 ? IW 0:07 /usr/lib/sendmail -bd -q1h %kill -15 99
Here, the leftmost number printed by ps (the
99
) was used to kill the daemon.
For System V-based systems you use different arguments for the ps command, and its output differs:
%ps -ae | grep sendmail
99 ? 0:01 sendmail %kill -15 99
Under old versions of sendmail you must look in your system rc files for the way to restart sendmail.
If you forget to kill the daemon
If you forget to kill the daemon before starting a new one, you might see a stream of messages similar to the following, one printed every 5 seconds (probably to your console window):
getrequests: cannot bind: Address already in use getrequests: cannot bind: Address already in use getrequests: cannot bind: Address already in use getrequests: cannot bind: Address already in use getrequests: cannot bind: Address already in use getrequests: cannot bind: Address already in use getrequests: cannot bind: Address already in use getrequests: cannot bind: Address already in use getrequests: cannot bind: Address already in use getrequests: cannot bind: Address already in use getrequests: cannot bind: Address already in use opendaemonsocket: server SMTP socket wedged: exiting
This shows that the attempt to run a second daemon failed.[14]
Show Queue Mode (-bp)
The sendmail program can
also display the contents of its queue directories. It can do this in
two ways: by running as a program named mailq or by being
run as sendmail with the
-bp
command-line switch. Whichever way you
run it, the contents of the queue are
printed. If the queue is empty,
sendmail prints the following:
/var/spool/mqueue is empty
If, on the other hand, mail is waiting in the queue, the output is far more verbose, possibly containing lines similar to these:
/var/spool/mqueue (1 requests) --Q-ID------ --Size-- ----Q-Time------ ------------Sender/Recipient------------ d8BJXvF13031* 702 Thu Jan 1 16:51 <you@here.us.edu> Deferred: Host fbi.dc.gov is down <george@fbi.dc.gov>
Here, the output produced with the -bp
switch
shows that only one mail message is in the queue. If there were more,
each entry would look pretty much the same as this. Each message
results in at least two lines of output.
The first line shows details about the message and the sender. The
d8BJXvF13031 identifies this message in the queue directory
/var/spool/mqueue. The * shows that this message is
locked and currently being processed. The 702
is
the size of the message body in bytes (the size of the
df
file as mentioned in Section 1.6.3). The date shows when this message was
originally queued. The address shown is the name of the sender.
A second line might appear giving a reason for failure (if there was one). A message can be queued intentionally or because it couldn’t immediately be delivered.
The third and possibly subsequent lines show the addresses of the recipients.
If there is more than one queue, each queue will print the preceding information, and the last queue’s information will be followed by a line that looks like this:
Total Requests: num
Here, beginning with V8.10, the num will be the total number of messages stored in all the queue directories.
The output produced by the -bp
switch is covered
more fully in Chapter 11.
Rebuild Aliases Mode (-bi)
Because sendmail might have to search through thousands of names in the aliases file, a version of the file is stored in a separate dbm(3) or db(3) database format file. The use of a database significantly improves lookup speed.
Although early versions of sendmail can
automatically update the database whenever the
aliases file is changed, that is no longer
possible with modern versions.[15] Now, you need to rebuild the database yourself, either by
running sendmail using the command
newaliases or with
the -bi
command-line switch. Both do the same
thing:
%newaliases
%/usr/lib/sendmail -bi
There will be a delay while sendmail rebuilds the aliases database; then a summary of what it did is printed:
/etc/mail/aliases: 859 aliases, longest 615 bytes, 28096 bytes total
This line shows that the database was successfully rebuilt. Beginning with V8.6 sendmail, multiple alias files became possible, so each line (and there might be many) begins with the name of an alias file. The information then displayed is the number of aliases processed, the size of the biggest entry to the right of the : in the aliases file, and the total number of bytes entered into the database. Any mistakes in an alias file will also be printed here.
The aliases file and how to manipulate it are covered in Chapter 12.
Verify Mode (-bv)
A handy tool for
checking aliases is the -bv
command-line switch. It
causes sendmail to recursively look up an alias
and report the ultimate real name that it found.
To illustrate, consider the following aliases file:
animals: farmanimals,wildanimals bill-eats: redmeat birds: farmbirds,wildbirds bob-eats: seafood,whitemeat farmanimals: pig,cow farmbirds: chicken,turkey fish: cod,tuna redmeat: animals seafood: fish,shellfish shellfish: crab,lobster ted-eats: bob-eats,bill-eats whitemeat: birds wildanimals: deer,boar wildbirds: quail
Although you can figure out what the name ted-eats
ultimately expands to, it is far easier to have
sendmail do it for you. By using
sendmail, you have the added advantage of being
assured accuracy, which is especially important in large and complex
aliases files.
In addition to expanding aliases, the -bv
switch
performs another important function. It verifies whether the expanded
aliases are, in fact, deliverable. Consider the following one-line
aliases file:
root: fred,larry
Assume that the user fred
is the system
administrator and has an account on the local machine. The user
larry
, however, has left, and his account has been
removed. You can run sendmail with the
-bv
switch to find out whether both names are
valid:
% /usr/lib/sendmail -bv root
This tells sendmail to verify the name
root
from the aliases file.
Because larry
(one of root’s
aliases) doesn’t exist, the output produced looks
like this:
larry... User unknown fred... deliverable: mailer local, user fred
Verbose (-v)
The -v
command-line switch
tells sendmail to run in
verbose mode. In that mode,
sendmail prints a blow-by-blow[16] description of
all the steps it takes in delivering a mail message. To watch
sendmail run in verbose mode, send mail to
yourself as you did in Section 1.5.1, but this time
add a -v
switch:
%/usr/lib/sendmail -v
you<sendstuff
The output produced shows that sendmail delivers your mail locally:
you...
Connecting to local.
..you...
Sent
When sendmail forwards mail to another machine
over a TCP/IP network, it communicates with that other machine using
the SMTP protocol. To see what SMTP looks like, run
sendmail again, but this time, instead of using
you
as the recipient, give
sendmail your address on another machine:
%/usr/lib/sendmail -v
you@remote.domain<sendstuff
The output produced by this command line will look similar to the following:
you@remote.domain... Connecting to remote.domain via smtp... 220 remote.Domain ESMTP Sendmail 8.12.7/8.12.7 ready at Thu, 1 Jan 2002 06:36:12 - 0800 >>> EHLO here.us.edu 250-remote.domain Hello here.us.edu [123.45.67.89], pleased to meet you 250-ENHANCEDSTATUSCODES 250-8BITMIME 250-SIZE 250-DSN 250-ETRN 250-DELIVERBY 250 HELP >>> MAIL From:<you@here.us.edu> SIZE=4537 250 2.1.0 <you@here.us.edu> ... Sender ok >>> RCPT To:<you@remote.domain> 250 2.1.5 <you@remote.domain> ... Recipient ok >>> DATA 354 Enter mail, end with "." on a line by itself >>> . 250 2.0.0 d9L29Nj20475 Message accepted for delivery you@remote.domain... Sent (d9L29Nj20475 Message accepted for delivery) Closing connection to remote.domain >>> QUIT 221 remote.domain closing connection
The lines that begin with numbers and the lines that begin with
>>>
characters constitute a record of the
SMTP conversation. We’ll discuss those shortly. The
other lines are sendmail on your local machine
telling you what it is trying to do and what it has successfully
done:
you@remote.domain... Connecting to remote.domain via smtp... ... you@remote.domain... Sent (d9L29Nj20475 Message accepted for delivery) Closing connection to remote.domain
The first line shows to whom the mail is addressed and that the
machine remote.domain
is on the network. The last
two lines show that the mail message was successfully sent.
In the SMTP conversation your local machine displays what it is
saying to the remote host by preceding each line with
>>>
characters. The messages (replies)
from the remote machine are displayed with leading numbers. We now
explain that conversation.
220 remote.Domain ESMTP Sendmail 8.12.7/8.12.7 ready at Thu, 1 Jan 2002 06:36:12 -0800
Once your sendmail has connected to the remote
machine, your sendmail waits for the other
machine to initiate the conversation. The other machine says it is
ready by sending the number 220
and its
fully qualified hostname (the only
required information). If the other machine is running
sendmail, it can also say the program name is
sendmail and state the version. It must also
state that it is ready and gives its idea of the local date and time.
The ESMTP
means that the remote site understands
Extended SMTP.
If sendmail waits too long for a connection without receiving this initial message, it prints "Connection timed out” and queues the mail message for later delivery.
Next the local sendmail sends (the
>>>
) the word EHLO
, for
Extended Hello, and its own hostname:
>>> EHLO here.us.edu 250-remote.domain Hello here.us.edu [123.45.67.89], pleased to meet you 250-ENHANCEDSTATUSCODES 250-8BITMIME 250-SIZE 250-DSN 250-ETRN 250-DELIVERBY 250 HELP
The E
of the EHLO
says that the
local sendmail speaks ESMTP too. The remote
machine replies with 250
, then lists the ESMTP
services that it supports. All but the last reply line contain a dash
following the 250
. That dash signals that an
additional reply line will follow. The last line, the
HELP
line, lacks a dash, and so completes the
reply.
One problem that could occur is your machine sending a short hostname
(“here”) in the
EHLO
message. This would cause an error because
the remote machine wouldn’t find
here
in its domain
remote.domain
. This is one reason why it is
important for your sendmail to always use your
machine’s
fully qualified hostname. A fully
qualified name is one that begins with the host’s
name, followed by a dot, then the entire DNS domain.
If all has gone well so far, the local machine sends the name of the sender of the mail message and the size of the message in bytes:
>>> MAIL From:<you@here.us.edu> SIZE=4537 250 2.1.0 <you@here.us.edu> ... Sender ok
Here, that sender address was accepted by the remote machine, and the size was not too large.
Next the local machine sends the name of the recipient:
>>> RCPT To:<you@remote.domain> 250 2.1.5 <you@remote.domain> ... Recipient ok
If the user you
were not known on the remote
machine, it might reply with an error of
"User unknown.” Here,
the recipient is ok
. Note that
ok
does not necessarily mean that the address is
good. It can still be bounced later. The ok
means
only that the address is acceptable.
After the envelope information has been sent, your sendmail attempts to send the mail message (header and body combined):
>>> DATA 354 Enter mail, end with "." on a line by itself >>> .
DATA
tells the remote
host to “get ready.” The remote
machine says to send the message, and the local machine does so. (The
message is not printed as it is sent.) A dot on a line by itself is
used to mark the end of a mail message. This is a convention of the
SMTP protocol. Because mail messages can contain lines that begin
with dots as a valid part of the message,
sendmail doubles any dots at the beginning of
lines before they are sent.[17] For example, consider when the
following text is sent through the mail:
My results matched yours at first: 126.71 126.72 ... 126.79 But then the numbers suddenly jumped high, looking like noise saturated the line.
To prevent any of these lines from being wrongly interpreted as the end of the mail message, sendmail inserts an extra dot at the beginning of any line that begins with a dot, so the actual text transferred is:
My results matched yours at first: 126.71 126.72 .... ←note extra dot 126.79 But then the numbers suddenly jumped high, looking like noise saturated the line.
The SMTP-server program running at the receiving end (for example, another sendmail) strips those extra dots when it receives the message.
The remote sendmail shows the queue identification number that it assigned to the mail it accepted:
250 2.0.0 d9L29Nj20475 Message accepted for delivery . . . >>> QUIT 221 remote.domain closing connection
The local sendmail sends QUIT
to say it is all done. The remote machine acknowledges by closing the
connection.
Note that the -v
(verbose) switch for
sendmail is most useful with mail sent to remote
machines. It allows you to watch SMTP conversations as they occur and
can help in tracking down why a mail message fails to reach its
destination.
Debugging (-d)
The sendmail program can also produce
debugging
output. The sendmail program is placed in
debugging mode by using the -d
command-line
switch. That switch produces far more information than
-v
does. To see for yourself, enter the following
command line, but substitute your own login name in place of the
you
:
%/usr/lib/sendmail -d
you< /dev/null
This command line produces a great deal of output. We won’t explain this output because it is explained in Chapter 16. For now just remember that the sendmail program’s debugging output can produce a great deal of information.
In addition to producing lots of debugging information, the
-d
switch can be modified to display specific
debugging information. By adding a numeric argument to the
-d
switch, output can be limited to one specific
aspect of the sendmail
program’s behavior.
Type in this command line, but change you
to your own login name:
%/usr/lib/sendmail -d0
you< /dev/null
Here, the -d0
is the debugging switch with a
category of 0
. That category limits
sendmail’s program output to
information about how sendmail was compiled. A
detailed explanation of that output is covered in -d0.4.
In addition to a category, a level can also be
specified. The level adjusts the amount of output produced. A low
level produces little output; a high level produces greater and more
complex output. The string following the -d
has
the form:
category.level
For example, enter the following command line:
% /usr/lib/sendmail -d0.1 -bp
The -d0
instructs sendmail to
produce general debugging information. The level
.1
limits sendmail to its
minimal output. That level could have been omitted because a level
.1
is the default. Recall that
-bp
causes sendmail to print
the contents of its queue. The output produced looks something like
the following:
Version 8.12.7 Compiled with: LOG NAMED_BIND NDBM NETINET NETUNIX NIS SCANF XDEBUG == == == == == == SYSTEM IDENTITY (after readcf) == == == == == == (short domain name) $w = here (canonical domain name) $j = here.us.edu (subdomain name) $m = us.edu (node name) $k = here == == == == == == == == == == == == == == == == == == == == /var/spool/mqueue is empty
Here, the -d0.1
switch causes
sendmail to print its version, some information
about how it was compiled, and how it interpreted your host (domain)
name. Now run the same command line again, but change the level from
.1
to .11
:
% /usr/lib/sendmail -d0.11 -bp
The increase in the level causes sendmail to print more information:
Version 8.12.7 Compiled with: LOG NAMED_BIND NDBM NETINET NETUNIX NIS SCANF XDEBUG OS Defines: HASFLOCK HASGETUSERSHELL HASINITGROUPS HASLSTAT HASSETREUID HASSETSID HASSETVBUF HASUNAME IDENTPROTO IP_SRCROUTE Config file: /etc/mail/sendmail.cf Pid file: /etc/mail/sendmail.pid canonical name: here.us.edu UUCP nodename: here a.k.a.: [123.45.67.89] == == == == == == SYSTEM IDENTITY (after readcf) == == == == == == (short domain name) $w = here (canonical domain name) $j = here.us.edu (subdomain name) $m = us.edu (node name) $k = here == == == == == == == == == == == == == == == == == == == == /var/spool/mqueue is empty
[13] Provided that the daemon was originally started with a full pathname.
[14] Note that some multicast-capable versions of Unix allow multiple sendmail daemons to run simultaneously. This is a known bug in the SO_REUSEADDR ioctl(2) call for Transmission Control Protocol (TCP) under multicasting. Contact your vendor for a fix.
[15] Beginning with V8.10 sendmail, it was recognized that auto-rebuilding the aliases file posed a security risk. For versions V8.10 and V8.11 use of this function was discouraged. Beginning with V8.12, this function has been eliminated. (See AutoRebuildAliases for an explanation of the risk.)
[16] Verbose mode is actually far more powerful than we’ve shown here.
[17] This is called the "hidden dot algorithm” or “dot stuffing” and is documented in RFC2821.
Get Sendmail, 3rd Edition now with the O’Reilly learning platform.
O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.