1.7 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.
1.7.1 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.
Table 1-1. Some command-line switches
-b
|
Set operating mode
|
-v
|
Run in verbose mode
|
-d
|
Run in debugging mode
|
1.7.1.1 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.
Table 1-2. Forms of the -b command-line switch
-ba
|
Use ARPAnet (Grey Book) protocols
|
-bD
|
Run as a daemon, but don't fork
|
-bd
|
Run as a daemon
|
-bH
|
Purge persistent host status
|
-bh
|
Print persistent host status
|
-bi
|
Rebuild alias database
|
-bm
|
Be a mail sender
|
-bP
|
Print number of entries in the queue (V8.12 and above)
|
-bp
|
Print the queue
|
-bs
|
Run SMTP on standard input
|
-bt
|
Test mode: resolve addresses only
|
-bv
|
Verify: don't collect or deliver
|
-bz
|
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.
Table 1-3. Other names for sendmail
hoststat
|
-bh
|
Print persistent host status
|
mailq
|
-bp
|
Display the queue
|
newaliases
|
-bi
|
Initialize alias database
|
purgestat
|
-bH
|
Purge persistent host status
|
smtpd
|
-bd
|
Run as a daemon
|
1.7.1.2 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.
1.7.2 Kill and Restart, Beginning with V8.7
Killing and restarting the sendmail daemon
became easier beginning with V8.7. A single command 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.
1.7.2.1 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`
1.7.2.2 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.
1.7.2.3 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.
1.7.3 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.
1.7.4 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. 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.
1.7.5 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
1.7.6 Verbose (-v)
The -v command-line switch
tells sendmail to run in
verbose mode. In that mode,
sendmail prints a blow-by-blow 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. 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.
1.7.7 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
|