|
Chapter 37 Debugging with -d
|
|
The
sendmail
debugging switches vary from
vendor to vendor and from version to version. This section is
specific to V8.8.0
sendmail
.
These switches
are perhaps best used with a copy of the
sendmail
source by
your side. Be further advised that many of the internal details
shown here will change as
sendmail
continues to evolve and
improve.
In this section we provide a detailed description of each combination
of debugging category and level. In
Table 37.2
each debugging category and level that we consider useful for
the system administrator who is trying to solve a mail problem
is marked with "useful."
The others provide such complex and sophisticated output that
they may be of use only to those with access to the source.
Those marked in the section column with a "n/a" are debugging
switches that were introduced in the
sendmail
source too late
for documentation in this edition. All are presented in ascending
numerical order, first by category, then by level within each category.
Note that for all categories a
-d
category
and a
-d
category
.1
are always equivalent.
Table 37.2: Debugging Switches by Category
Category |
|
It is |
Description |
-d0.1 |
Section 37.5.1, -d0.1
|
useful |
Print version information
|
-d0.4 |
Section 37.5.2, -d0.4
|
useful |
Our name and aliases
|
-d0.10 |
Section 37.5.3, -d0.10
|
|
Operating System defines
|
-d0.15 |
Section 37.5.4, -d0.15
|
useful |
Dump delivery agents
|
-d0.20 |
Section 37.5.5, -d0.20
|
useful |
Print network address of each interface
|
-d0.22 |
Section 37.5.6, -d0.22
|
|
Show uname() failure
|
-d0.40 |
Section 37.5.7, -d0.40
|
|
Show scanning of interfaces
|
-d0.44 |
Section 37.5.8, -d0.44
|
|
Print addresses of strings
|
-d0.90 |
Section 37.5.9, -d0.90
|
obsolete |
Print first 10 rule sets
|
-d1.1 |
Section 37.5.10, -d1.1
|
|
Show sender information
|
-d1.5 |
Section 37.5.11, -d1.5
|
|
Dump the sender address
|
-d2.1 |
Section 37.5.12, -d2.1
|
|
End with finis()
|
-d2.9 |
Section 37.5.13, -d2.9
|
|
Show file descriptors with
dumpfd
()
|
-d3.1 |
Section 37.5.14, -d3.1
|
|
Print the load average
|
-d3.5 |
Section 37.5.15, -d3.5
|
|
Print load average
|
-d3.15 |
Section 37.5.16, -d3.15
|
|
Print three load averages
|
-d3.20 |
Section 37.5.17, -d3.20
|
|
Show offset for load average
|
-d3.30 |
Section 37.5.18, -d3.30
|
|
Show result of decision to queue
|
-d4.80 |
Section 37.5.19, -d4.80
|
useful |
Trace enoughspace()
|
-d5.4 |
Section 37.5.20, -d5.4
|
|
Tick for queued events
|
-d5.5 |
Section 37.5.21, -d5.5
|
|
Events set and cleared
|
-d5.6 |
Section 37.5.22, -d5.6
|
|
Show events triggered
|
-d6.1 |
Section 37.5.23, -d6.1
|
useful |
Show failed mail
|
-d6.5 |
Section 37.5.24, -d6.5
|
|
The current error state
|
-d6.20 |
Section 37.5.25, -d6.20
|
|
Show sender of return to sender
|
-d7.1 |
Section 37.5.26, -d7.1
|
|
The Queue filename
|
-d7.2 |
Section 37.5.27, -d7.2
|
|
Show assigned queue filename
|
-d7.9 |
Section 37.5.28, -d7.9
|
|
Dump file descriptor for the qf file
|
-d7.20 |
Section 37.5.29, -d7.20
|
|
Show queue names being tried
|
-d8.1 |
Section 37.5.30, -d8.1
|
useful |
Failure of MX search (low level)
|
-d8.2 |
Section 37.5.31, -d8.2
|
useful |
Call to getcanonname(3)
|
-d8.3 |
Section 37.5.32, -d8.3
|
useful |
Trace dropped local hostnames
|
-d8.5 |
Section 37.5.33, -d8.5
|
useful |
Hostname being tried in getcanonname(3)
|
-d8.7 |
Section 37.5.34, -d8.7
|
useful |
Yes/no response to -d8.5
|
-d8.8 |
Section 37.5.35, -d8.8
|
useful |
MX lookup gets wrong type
|
-d8.20 |
Section 37.5.36, -d8.20
|
|
Inconsistency in returned information
|
-d9.1 |
Section 37.5.37, -d9.1
|
|
Canonify hostname and RFC1413 queries
|
-d9.3 |
Section 37.5.38, -d9.3
|
|
Show raw RFC1413 reply
|
-d9.10 |
Section 37.5.39, -d9.10
|
|
Show RFC1413 query being sent
|
-d10.1 |
Section 37.5.40, -d10.1
|
|
Show recipient delivery
|
-d10.2 |
Section 37.5.41, -d10.2
|
|
Dump controlling user's address
|
-d10.5 |
Section 37.5.42, -d10.5
|
|
Show don't send to MeToo address
|
-d10.100 |
Section 37.5.43, -d10.100
|
|
Predelivery file descriptor dump
|
-d11.1 |
Section 37.5.44, -d11.1
|
useful |
Trace delivery
|
-d11.2 |
Section 37.5.45, -d11.2
|
useful |
Show the uid/gid running as during delivery
|
-d11.20 |
Section 37.5.46, -d11.20
|
|
Show tried D= directories
|
-d12.1 |
Section 37.5.47, -d12.1
|
useful |
Show mapping of relative host
|
-d13.1 |
Section 37.5.48, -d13.1
|
useful |
Show delivery
|
-d13.5 |
Section 37.5.49, -d13.5
|
|
Show addresses that we should not send to
|
-d13.6 |
n/a |
|
Trace envelope stripping, dropping, and moving
|
-d13.10 |
Section 37.5.50, -d13.10
|
|
Trace sendenvelope()
|
-d13.20 |
Section 37.5.51, -d13.20
|
|
Show final mode
|
-d13.21 |
n/a |
|
Show final send queue
|
-d13.25 |
n/a |
|
Watch owner deliveries
|
-d13.29 |
Section 37.5.52, -d13.29
|
|
Show autoqueueing
|
-d13.30 |
Section 37.5.53, -d13.30
|
|
Show envelopes being split
|
-d14.2 |
Section 37.5.54, -d14.2
|
|
Show header field commas
|
-d15.1 |
Section 37.5.55, -d15.1
|
|
Show network get request activity
|
-d15.2 |
Section 37.5.55
|
|
Incoming connections
|
-d15.101 |
Section 37.5.57, -d15.101
|
|
Kernel TCP debugging
|
-d16.1 |
Section 37.5.58, -d16.1
|
|
Outgoing Connections
|
-d16.101 |
Section 37.5.59, -d16.101
|
|
Kernel TCP debugging
|
-d17.1 |
Section 37.5.60, -d17.1
|
|
List MX hosts
|
-d17.9 |
Section 37.5.61, -d17.9
|
|
Show randomizing MX records
|
-d18.1 |
Section 37.5.62, -d18.1
|
|
Show SMTP replies
|
-d18.2 |
Section 37.5.63, -d18.2
|
|
Show entry to MAIL From:
|
-d18.100 |
Section 37.5.64, -d18.100
|
|
Pause on SMTP read error
|
-d19.1 |
Section 37.5.65, -d19.1
|
|
Show ESMTP MAIL and RCPT parameters
|
-d20.1 |
Section 37.5.66, -d20.1
|
useful |
Show resolving delivery agent: parseaddr()
|
-d21.1 |
Section 37.5.67, -d21.1
|
|
Trace rewriting rules
|
-d21.2 |
Section 37.5.68, -d21.2
|
useful |
Trace $& macros
|
-d21.3 |
Section 37.5.69, -d21.3
|
|
Show subroutine calls
|
-d21.4 |
Section 37.5.70, -d21.4
|
|
Result after rewriting by a rule
|
-d21.10 |
Section 37.5.71, -d21.10
|
|
Announce failure
|
-d21.12 |
Section 37.5.72, -d21.12
|
|
Announce success and show LHS
|
-d21.15 |
Section 37.5.73, -d21.15
|
|
Show $digit replacement
|
-d21.35 |
Section 37.5.74, -d21.35
|
|
Show token by token LHS matching
|
-d21.36 |
Section 37.5.75, -d21.36
|
|
Trace class matching in the LHS
|
-d22.1 |
Section 37.5.76, -d22.1
|
useful |
Trace tokenizing an address: prescan()
|
-d22.11 |
Section 37.5.77, -d22.11
|
useful |
Show address before prescan
|
-d22.12 |
Section 37.5.78, -d22.12
|
|
Show address after prescan
|
-d22.36 |
Section 37.5.79, -d22.36
|
|
Show each token
|
-d22.101 |
Section 37.5.80, -d22.101
|
|
Trace low-level state machine
|
-d24.4 |
Section 37.5.81, -d24.4
|
|
Trace address allocation
|
-d24.5 |
Section 37.5.82, -d24.5
|
|
Trace assembly of tokens
|
-d24.6 |
Section 37.5.83, -d24.6
|
|
Show result of buildaddr()
|
-d25.1 |
Section 37.5.84, -d25.1
|
useful |
Trace "sendtolist" |
-d26.1 |
Section 37.5.85, -d26.1
|
|
Trace recipient queueing |
-d26.8 |
Section 37.5.86, -d26.8
|
|
Trace self-destructing addresses |
-d26.10 |
Section 37.5.87, -d26.10
|
|
Show full send queue in testselfdestruct |
-d27.1 |
Section 37.5.88, -d27.1
|
useful |
Trace aliasing |
-d27.2 |
Section 37.5.89, -d27.2
|
useful |
Include file, self-reference, error on home |
-d27.3 |
Section 37.5.90, -d27.3
|
useful |
Forwarding path and alias wait |
-d27.4 |
Section 37.5.91, -d27.4
|
useful |
Print not safe |
-d27.5 |
Section 37.5.92, -d27.5
|
|
Trace aliasing with printaddr() |
-d27.8 |
Section 37.5.93, -d27.8
|
|
Show setting up an alias map |
-d27.9 |
Section 37.5.94, -d27.9
|
useful |
Show uid/gid changes with :include: reads |
-d27.14 |
Section 37.5.95, -d27.14
|
|
Show controlling user that caused change in identity |
-d27.20 |
Section 37.5.96, -d27.20
|
|
Show how alias will be looked up in a map |
-d28.1 |
Section 37.5.97, -d28.1
|
useful |
Trace user database transactions |
-d28.2 |
Section 37.5.98, -d28.2
|
|
Show no match |
-d28.4 |
Section 37.5.99, -d28.4
|
|
Show result of lookup |
-d28.8 |
Section 37.5.100, -d28.8
|
|
Try hes_getmailhost() |
-d28.16 |
Section 37.5.101, -d28.16
|
|
MX records for forward host |
-d28.20 |
Section 37.5.102, -d28.20
|
|
Show udb lookup |
-d28.80 |
Section 37.5.103, -d28.80
|
|
Preview lookups |
-d29.1 |
Section 37.5.104, -d29.1
|
|
Special rewrite of local recipient |
-d29.4 |
Section 37.5.105, -d29.4
|
useful |
Trace fuzzy matching |
-d29.5 |
Section 37.5.106, -d29.5
|
|
Preview rule set 5 |
-d29.7 |
Section 37.5.107, -d29.7
|
|
Show overaliasing fuzzy fallback |
-d30.1 |
Section 37.5.108, -d30
|
|
Trace processing of header |
-d30.2 |
Section 37.5.109, -d30.2
|
|
Eat from |
-d30.3 |
Section 37.5.110, -d30.3
|
|
Show a to-less header being added |
-d30.35 |
Section 37.5.111, -d30.35
|
|
Trace collect states |
-d30.94 |
Section 37.5.112, -d30.94
|
|
Trace collect states |
-d31.2 |
Section 37.5.113, -d31.2
|
useful |
Trace processing of headers |
-d31.6 |
Section 37.5.14
1_6 |
|
Is header known? |
-d32.1 |
Section 37.5.115, -d32.1
|
|
Show collected headers |
-d32.2 |
Section 37.5.116, -d32.2
|
|
Show ARPA mode with setsender |
-d33.1 |
Section 37.5.117, -d33.1
|
|
Watch crackaddr() |
-d34.1 |
Section 37.5.118, -d34.1
|
|
Watch header assembly for output |
-d34.11 |
Section 37.5.119, -d34.11
|
useful |
Trace header generation and skipping |
-d35.9 |
Section 37.5.120, -d35.9
|
useful |
Macro values defined |
-d35.14 |
Section 37.5.121, -d35.14
|
|
Macro identification |
-d35.24 |
Section 37.5.122, -d35.24
|
|
Macro expansion |
-d36.5 |
Section 37.5.123, -d36.5
|
|
Trace processing by stab() |
-d36.9 |
Section 37.5.124, -d36.9
|
|
Show hash bucket |
-d36.90 |
Section 37.5.125, -d36.90
|
|
Trace function applied to all symbols |
-d37.1 |
Section 37.5.126, -d37.1
|
useful |
Trace setting of options |
-d37.8 |
Section 37.5.127, -d37.8
|
useful |
Trace adding of words to a class |
-d38.2 |
Section 37.5.128, -d38.2
|
useful |
Show map opens and failures |
-d38.3 |
Section 37.5.129, -d38.3
|
|
Show passes |
-d38.4 |
Section 37.5.130, -d38.4
|
useful |
Show result of map open |
-d38.9 |
Section 37.5.131, -d38.9
|
|
Trace map closings and appends |
-d38.10 |
Section 37.5.132, -d38.10
|
|
Trace NIS search for end of aliases |
-d38.12 |
Section 37.5.133, -d38.12
|
|
Trace map stores |
-d38.19 |
Section 37.5.134, -d38.19
|
useful |
Trace switch map finds |
-d38.20 |
Section 37.5.135, -d38.20
|
useful |
Trace map lookups |
-d38.44 |
Section 37.5.136, -d38.44
|
|
Show nis_getcanonname() record |
-d39.1 |
Section 37.5.137, -d39.1
|
|
Display %digit database mapping |
-d40.1 |
Section 37.5.138, -d40.1
|
|
Trace processing of the queue |
-d40.3 |
Section 37.5.139, -d40.3
|
|
Show envelope flags |
-d40.4 |
Section 37.5.140, -d40.4
|
|
Show qf file lines as they are read |
-d40.8 |
Section 37.5.141, -d40.8
|
|
Show reasons for failure |
-d40.9 |
Section 37.5.142, -d40.9
|
|
Show qf and lock file descriptors |
-d40.32 |
Section 37.5.143, -d40.32
|
|
Dump the send queue |
-d41.1 |
Section 37.5.144, -d41.1
|
useful |
Trace queue ordering |
-d41.2 |
Section 37.5.145, -d41.2
|
|
Cannot open qf |
-d41.49 |
Section 37.5.146, -d41.49
|
|
Show excluded (skipped) queue files |
-d41.50 |
Section 37.5.147, -d41.50
|
|
Show every file in the queue |
-d42.2 |
Section 37.5.148, -d42.2
|
|
Show connection checking |
-d42.5 |
Section 37.5.149, -d42.5
|
|
Trace caching and uncaching connections |
-d43.1 |
Section 37.5.150, -d43.1
|
|
Trace MIME conversions |
-d43.3 |
Section 37.5.151, -d43.3
|
|
See the final MIME boundary name |
-d43.5 |
Section 37.5.152, -d43.5
|
|
Watch search for boundaries |
-d43.8 |
Section 37.5.153, -d43.8
|
|
Show the calculations |
-d43.35 |
Section 37.5.154, -d43.35
|
|
Show boundary lines as emitted |
-d43.36 |
Section 37.5.155, -d43.36
|
|
Show content transfer encoding |
-d43.40 |
Section 37.5.156, -d43.40
|
|
Show parse of Content-Type: header |
-d43.99 |
Section 37.5.157, -d43.99
|
|
Print the leading/following comments |
-d43.100 |
Section 37.5.158, -d43.100
|
|
Mark collect() and putheader() |
-d44.4 |
Section 37.5.159, -d44.4
|
|
Trace safefile() |
-d44.5 |
Section 37.5.160, -d44.5
|
useful |
Trace writable() |
-d45.1 |
Section 37.5.161, -d45.1
|
|
Show envelope sender |
-d45.3 |
Section 37.5.162, -d45.3
|
|
Show saved domain |
-d45.5 |
Section 37.5.163, -d45.5
|
|
Show don't send to sender |
-d46.9 |
Section 37.5.164, -d46.9
|
|
Show xf file's descriptors |
-d48.2 |
Section 37.5.165, -d48.2
|
useful |
Trace calls to the check_ rule sets |
-d49.1 |
Section 37.5.166, -d49.1
|
|
Trace checkcompat() |
-d50.1 |
Section 37.5.167, -d50.1
|
|
Show envelope being dropped |
-d50.2 |
Section 37.5.168, -d50.2
|
|
Show Booleans |
-d50.10 |
Section 37.5.169, -d50.10
|
|
Also show the send queue |
-d51.4 |
Section 37.5.170, -d51.4
|
|
Show queue entries being unlocked |
-d51.104 |
Section 37.5.171, -d51.104
|
|
Prevent unlink of xf file |
-d52.1 |
Section 37.5.172, -d52.1
|
|
Show isconnect from controlling TTY |
-d52.100 |
Section 37.5.173, -d52.100
|
|
Prevent disconnect from controlling tty |
-d53.99 |
Section 37.5.174, -d53.99
|
|
Trace xclose() |
-d54.1 |
Section 37.5.175, -d54.1
|
|
Show error return and output message |
-d54.8 |
Section 37.5.176, -d54.8
|
|
Show message and flags |
-d55.60 |
Section 37.5.177, -d55.60
|
|
Show file locking |
-d56.1 |
Section 37.5.178, -d56.1
|
|
Persistent host status tracing |
-d56.2 |
Section 37.5.179, -d56.2
|
|
More persistent host status tracing |
-d56.12 |
Section 37.5.180, -d56.12
|
|
Perform a sanity check |
-d56.80 |
Section 37.5.181, -d56.80
|
|
Trace creating the path to the status file |
-d56.93 |
Section 37.5.182, -d56.93
|
|
Dump MCI record for the host |
-d57.2 |
Section 37.5.183, -d57.2
|
|
Monitor vsnprintf() overflows |
-d59.1 |
Section 37.5.184, -d59
|
|
XLA from contrib |
-d60.1 |
Section 37.5.185, -d60.1
|
useful |
Trace map lookups inside rewrite() |
-d61.10 |
Section 37.5.186, -d61.10
|
|
Trace gethostbyname() |
-d62.1 |
Section 37.5.187, -d62.1
|
|
Log file descriptors before and after all deliveries |
-d62.8 |
Section 37.5.188, -d62.8
|
|
Log file descriptors before each delivery |
-d62.10 |
Section 37.5.189, -d62.10
|
|
Log file descriptors after each delivery |
-d80.1 |
Section 37.5.190, -d80.1
|
|
Content-Length: header (Sun enhancement) |
-d81.1 |
Section 37.5.191, -d81.1
|
|
> option for remote mode (Sun enhancement) |
-d91.100 |
Section 37.5.192, -d91.100
|
|
Log caching and uncaching connections |
-d99.100 |
Section 37.5.193, -d99.100
|
useful |
Prevent backgrounding the daemon |
Print version information
(useful)
The
-d0.1
(a.k.a.
-d0
) debugging switch previously prevented
sendmail
from forking and detaching itself, but that function has been
moved to the
-d99.100
debugging switch.
The
-d0.1
debugging switch now just tells
sendmail
to
print information about its version:
Version 8.8.4
Compiled with: LOG MATCHGECOS NAMED_BIND NDBM NEWDB NETINET NETUNIX
NIS
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
The
Version
is the current version of
sendmail
. Note that for
Sun the number may look like
SMI-8.7.5
.
The
Compiled with:
lists the compile-time definitions that
where specified when
sendmail
is compiled. All the available
definitions are listed in
Table 18.3
in
Section 18.8, "Alphabetized Reference"
.
The
SYSTEM IDENTITY
shows the value assigned to four important
macros. The meaning of each macro is contained in
Table 31.7
in
Section 31.10, "Alphabetized Reference"
.
Our name and aliases
(useful)
The
-d0.4
debugging switch tells
sendmail
to print several additional lines of information:
Version 8.8.4
Compiled with: LOG MATCHGECOS NAMED_BIND NDBM NEWDB NETINET NETUNIX
NIS
canonical name: here.US.EDU
additional
UUCP nodename: here
additional
a.k.a.: [123.45.67.89]
additional
============ 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
========================================================
To find the canonical name of the local host,
sendmail
calls
gethostname
(). If that call fails, the name
localhost
is used. The hostname is then looked up with the internal routine
sm_gethostbyname
(), which gathers additional information (such as
other names and addresses for the machine) and fixes several
bugs in some operating system's versions of the
gethostby...
routines.
Next the canonical
name for the local host is looked up. For operating systems that
normally support switched services, the name is looked up as specified.
For systems that specify switched services in the configuration file's
ServiceSwitchFile
option
(see
Section 34.8.61, ServiceSwitchFile
), switched services are not used because
the configuration file has not been read yet.
(This canonicalization process can be traced with the
-61.10
debugging switch.)
If the canonical is found and that name contains a dot,
sendmail
saves the
part of the name to the right of the leftmost dot as the domain
name in the
$m
macro (see
Section 31.10.24, $m
).
It also appends the part of the name to
the left of the leftmost dot to the class
w
(see
Section 32.5.8, $=w
).
If the canonical name doesn't contain a dot, the
$m
macro is
undefined, and the whole name is appended to the class
w
.
In addition,
sendmail
also sets the
$k
macro
(see
Section 31.10.21, $k
) to be
the correct UUCP name for the machine.
It uses
uname
(3), if available, to find that
name (see
Section 18.8.51, TRUST-POPEN
);
otherwise, it uses the same strategy as for class
w
above.
Then
sendmail
lists any other names or addresses (this latter in
square brackets) that it found.
If it finds any, it prints the name prefixed by
a.k.a.:
and appends each to the class
w
.
The aliases listed are only those found using
gethostbyname
(3). To
see each entry as it is added to the class
w
, use the
-d37.8
debugging switch.
Finally,
sendmail
scans the network hardware to find any other
names associated with interfaces.
If the
ioctl
(2) call to get that information fails, the
-d0.4
debugging switch causes
sendmail
to print that failure:
SIOGIFCONF failed:
reason here
If any are found, each is printed
with an
a.k.a.:
prefix and added to the
class macro
w
.
The
-d0.10
debugging switch causes
sendmail
to print
all the operating system specific definitions that were used
to compile your specific version of
sendmail
. This output
prints after the "Compiled with:" information described above:
OS Defines: HASFLOCK HASGETUSERSHELL HASINITGROUPS HASLSTAT
HASSETREUID HASSETSID HASSETVBUF HASUNAME IDENTPROTO
IP_SRCROUTE
Kernel symbols: /vmunix
Config file: /etc/sendmail.cf
Proc Id file: /etc/sendmail.pid
The
OS Defines
are described in
Table 18.3
in
Section 18.8
.
Most are automatically determined during compilation; others
are specified in
Makefile
.
The
Kernel symbols
is the name of file that is accessed to
determine the load average. It is automatically defined correctly
when
conf.c
is compiled.
The location of the configuration file and the process identifier file
are defined in the
Makefile
and
conf.h
in the
sendmail
source (see
Section 18.8.34, PATH...
).
Dump delivery agents
(useful)
The -d0.15 debugging switch causes
sendmail
to display
how it interpreted its delivery agent definitions.
The clarity and completeness of the delivery
agent information vary with the version of
sendmail
.
See the
=M
rule-testing command (
Section 38.4.2, "Show Delivery Agents with =M"
)
for an example of this output.
Print network address of each interface
(useful)
When
sendmail
scans the network hardware to find other names
for the local host, it uses only those names that are new. Each new name
was printed by the
-d0.4
debugging switch above. To see every name
that
sendmail
finds, new and old alike, use the
-d0.20
debugging switch:
128.32.201.55
already found
127.0.0.1
found new
a.k.a.: [127.0.0.1]
Ordinarily, if the UUCP name for the local host cannot be found (if
uname
(3) fails),
sendmail
silently uses the leftmost
component of the canonical name as the UUCP name.
To see whether
uname
(3)
failed - and, if so why - you can use the
-d0.22
debugging switch:
uname failed (
reason for failure here
)
Announce scanning of interfaces
The
-d0.40
debugging switch causes
sendmail
to announce that
it is about to scan for network interfaces:
scanning for interface specific names, ifc_len=64
a.k.a.: [127.0.0.1]
The
ifc_len
is the size in
bytes of the configuration list returned by the kernel.
Print addresses of strings
The
-d0.44
debugging switch causes
sendmail
to prefix
certain lists of strings that it prints with the
address in memory of each string and an equal sign. With this debugging level,
part of the output produced by the
-d21.12
debugging switch would
look like this:
--- rule fails
---trying rule:
0009ec68=@
0009ec78=$*
--- rule fails
This debugging level can be useful to the programmer who
wishes to modify the
sendmail
source. It might, for example,
be helpful in designing more efficient string storage.
Print first 10 rule sets
(obsolete)
The
-d0.90
debugging switch causes
sendmail
to display its internal interpretations of
the first 10 rewriting rules it took from the configuration file.
The rule sets are printed in numeric order, rather than in the order in which
they appeared in the configuration file. The rewriting rules are
printed under each rule set
(but these
are
in the order
in which they appeared in the configuration file).
Rule sets that are declared but lack rewriting rules
are not printed. Note that defined macros in the RHS
are expanded (the value used) when the configuration file is parsed.
Also note that expressions like
$+
may be printed as control
characters (e.g.,
^A
) under older versions of
sendmail
.
The preferred way to view individual rule sets is with
the
-bt
rule-testing mode's
=S
command
(see
Section 38.4.1, "Show Rules in a Rule Set with =S"
).
Although there are many kinds of information that one might like
to trace about the sender of an email message,
sendmail
provides the means to trace only one of them.
The
-d1.1
(a.k.a.
-d1
) debugging switch causes
sendmail
to print
its interpretation of whom the message is from (the name of the sender
as it was used in the envelope):
From person = "
sender
"
Here,
sender
is the user portion of the mail address of the sender.
This output is most useful when combined with the
-f
command-line switch (which sets the name of the sender
from the command line; see
Section 36.7.21, -f and -r
).
The
-d1.5
debugging switch causes
additional information about the sender to be printed. That output
looks like this:
main: QDONTSEND
output of printaddr
()
here (see
Section 37.3.1, "The Output Produced by printaddr()"
)
The QDONTSEND means that the sender is not a recipient and so
should not get a copy of the message. That is followed
by the output of the
printaddr
() routine.
Ordinarily,
sendmail
exits silently when it is done (unless
an error causes an error message to be printed).
The
-d2.1
(a.k.a.
-d2
) debugging switch causes
sendmail
to print three useful values when it
exits. The message it prints looks like this:
====finis: stat
num
e_id=
qid
e_flags=
flags
The
num
is the final value of the
sendmail
program's global
ExitStat
variable.
It is usually updated to contain the latest error value
as defined in
<sysexits.h>
.
See
Section 36.5, "sendmail's exit() Status"
for a detailed description of
the possible exit values.
The
qid
is either the queue identifier (such as SAA24069)
or the NOQUEUE if the message was never assigned an identifier
(such as if it was never queued).
The
flags
is a hexadecimal representation
of the possible envelope flags followed by a text representation
of those flags in angle brackets with the leading
EF_
removed, for example,
201003<OLDSTYLE,INQUEUE,GLOBALERRS,HAS_DF>
These are the envelope flags that were in effect with the
current envelope when
sendmail
exited. The possible values
are shown in
Table 37.3
.
Table 37.3: Hexadecimal Envelope Flags
Text |
Hex |
Description |
EF_OLDSTYLE |
0000001
|
Use spaces (not commas) in headers |
EF_INQUEUE |
0000002
|
This message is fully queued |
EF_NO_BODY_RETN |
0000004
|
Omit message body on error |
EF_CLRQUEUE |
0000008
|
Disk copy is no longer needed |
EF_SENDRECEIPT |
0000010
|
Send a return receipt |
EF_FATALERRS |
0000020
|
Fatal errors occurred |
EF_KEEPQUEUE |
0000040
|
Keep queue files always |
EF_RESPONSE |
0000080
|
This is an error or return receipt |
EF_RESENT |
0000100
|
This message is being forwarded |
EF_VRFYONLY |
0000200
|
Verify only (don't expand aliases) |
EF_WARNING |
0000400
|
Warning message has been sent |
EF_QUEUERUN |
0000800
|
This envelope is from queue |
EF_GLOBALERRS |
0001000
|
Treat errors as global |
EF_PM_NOTIFY |
0002000
|
Send return mail to postmaster |
EF_METOO |
0004000
|
Send to me too |
EF_LOGSENDER |
0008000
|
Need to log the sender |
EF_NORECEIPT |
0010000
|
Suppress all return-receipts |
EF_HAS8BIT |
0020000
|
At least one 8-bit character in body |
EF_NL_NOT_EOL |
0040000
|
Don't accept raw newline as end-of-line |
EF_CRLF_NOT_EOL |
0080000
|
Don't accept carriage-return/line-feed as end-of-line |
EF_RET_PARAM |
0100000
|
SMTP RCPT command had RET argument |
EF_HAS_DF |
0200000
|
Set when df file is instantiated |
EF_IS_MIME |
0400000
|
Really is a MIME message |
EF_DONT_MIME |
0800000
|
This message is not MIME-able |
For example, if the message were fully queued and required a
DSN return receipt, the
flags
would print as
e_flags=12<INQUEUE,SENDRECEIPT>
Note that this line of output is also produced by the
-d13.1
,
-d40.3
, and
-d50.1
debugging switches but under different
circumstances.
Show file descriptors with
dumpfd
()
The
-d2.9
debugging switch tells
sendmail
to display the
properties of each open file descriptor. That output is produced
by the
dumpfd
() routine, and each line of output
is for a single file descriptor:
num
: fl=
flags
mode=
mode type stats
Here, the
num
is the number of the open file descriptor. Note that
descriptors 0, 1, and 2 are usually tied to the standard input, output,
and error output.
The
flags
is a hexadecimal representation of the state flags
associated with a file descriptor. F_GETFL is used with
ioctl
(2) to fetch each, and all are described in
<sys/fcntlcom.h>
.
The
mode
is printed in octal and is the
st_mode
associated
with an
fstat
(2) of the file descriptor. The
type
examines
the file type portion of the
st_mode
and prints
SOCK for a socket,
CHR: for a character special device,
BLK: for a block special device,
FIFO: for a first-in-first-out file,
DIR: for a directory,
LNK: for a symbolic link,
and nothing otherwise (e.g., nothing if it is a file).
The
stats
are printed for all but the socket. They
look like this:
dev=
major
/
minor
ino=
inum
nlink=
nlink
u/gid=
uid
/
gid
size=
bytes
Here the
dev=
shows the major and minor device numbers for the device
that the file descriptor is associated with. The
inum
is the inode
number on the disk (if there is one) and
nlink
is the number of hard
links to the file on disk. The
uid/gid
shows the user and group
ownership associated with the file descriptor. The
size
is the
number of bytes in a file, and 0 for almost everything else.
For a socket, the
stats
part of each line looks like
this:
[
addr
]/
port
->
host
Here,
addr
is the IP address of the local end of the socket.
If the connection is of type AF_INET, the port number of the connection
is also shown as
/port
. The
host
is the hostname, as returned
by
getpeername
(3), of the connecting host. If any of these cannot
be found, the error string associated with
errno
is printed
parenthetically in its place.
The
-d7.9
,
-d40.9
, and
-d46.9
debugging
switches also print a line like this for specific file descriptors.
Also if
sendmail
is run with the
-d10.100
switch, or if
sendmail
fails to open a
tf
queue file (see
Section 23.2.6, "The Temporary qf Rewrite Image: tf"
),
or if
sendmail
exited because of too many open files, it will
syslog
all its open file descriptors within this format.
The
sendmail
program queues mail, rather than delivering it, if
the load average (number of processes in the run queue) exceeds
the value set by the
QueueLA
(
x
) option
(see
Section 34.8.50, QueueLA (x)
). Exceeding that value
also prevents messages that are already in the queue from being delivered
(prevents a queue run). If the load average becomes higher
than the value of the
RefuseLA
(
X
) option
(see
Section 34.8.54, RefuseLA (X)
),
sendmail
rejects incoming SMTP connections until the load average drops.
The
-d3.1
debugging switch (a.k.a.
-d3
) causes
sendmail
to
print the load average found by its internal
getla
() routine each
time that routine is called:
getla:
la
Here,
la
is the current load average printed as an integer.
If sendmail was compiled with LA_TYPE==LA_ZERO
(see
Section 18.8.14, LA-TYPE
), the following will be printed to
show that your
sendmail
binary completely lacks load
averaging support:
getla: ZERO
The
-d3.1
debugging switch also causes
sendmail
to print
any errors it encounters while obtaining the load average.
getla: open(/dev/kmem):
error
Here,
/dev/kmem
is the device that is used to access kernel memory.
The
error
is the system error that caused the failure, such as
"Permission denied" if
sendmail
is not properly
sgid
to the group
kmem
.
getla: nlist(
unix
):
error
The
nlist
(3) function extracts a list of symbols from
an executable binary (among them the symbol for the load average).
The binary that it extracts is the kernel whose pathname
is
unix
(such as
/vmunix
for SunOS 4.x). Here, the
error
is the reason
nlist
(3) failed. One possibility
is that you booted from a nonstandard kernel name (such as
/vmunix.new
)
and the expected file didn't exist:
getla: nlist(
unix
,
la
) ==> 0
If the expected kernel exists (
unix
) but the machine was booted
from a different kernel, the symbol representing the load average
may not be found. In that instance,
la
is the name of the kernel
variable that
sendmail
was trying to find.
The load average that
sendmail
uses is averaged over
the last minute. Internally, the kernel keeps track of three load
averages. In addition to the last minute, it also tracks the
last 5 and 15 minutes.
The
-d3.5
debugging switch causes V8
sendmail
to
print the load average over the last minute:
getla: averun =
1min
Print three load averages
The
-d3.15
debugging switch causes V8
sendmail
to
print all three load averages:
getla: averun =
1min
,
5min
,
15min
Here, the three load averages are printed either in integer or
in floating point, depending on the setting of LA_TYPE
(see
Section 18.8.14
).
Show offset for load average
The
nlist
(3) routine (described above)
provides the offset into the kernel file where the value
of the load average is found. The
-d3.20
debugging
switch causes that offset to be displayed:
getla: symbol address =
offset
Here, the
offset
is printed in hexadecimal. The load average
is read by seeking in the kernel file and reading it. If the seek
or read fails, the
-d3.1
debugging switch causes
sendmail
to print:
getla: seek or read:
error
This can indicate a wrong or corrupted kernel image.
Show result of decision to queue
The internal routine
shouldqueue
() is called just before
a mail message is delivered to recipients. That routine
determines whether mail will be delivered or queued on the basis of the
current load average and message
priority
. Upon entry it prints:
shouldqueue: CurrentLA=
load
, pri=
priority
If the
CurrentLA
is less than the limit set by the
QueueLA
(
x
) option (see
Section 34.8.50
),
sendmail
prints:
FALSE (CurrentLA < QueueLA)
Then the calculation described in
Section 34.8.49, QueueFactor (q)
for the
QueueFactor
(
q
) option is performed using the
pri
priority.
The result is printed as one of the following, where TRUE
represents a zero result and FALSE represents a nonzero result:
TRUE (by calculation)
FALSE (by calculation)
Trace enoughspace()
(useful)
The
MinFreeBlocks
(
b
) option
(see
Section 34.8.40, MinFreeBlocks (b)
)
defines the minimum
number of disk blocks that must be reserved on the queue disk.
If an incoming SMTP message will fill the disk beyond this
minimum, the message is rejected.
The
-d4.80
debugging switch
[1]
traces the
enoughspace
()
routine in
conf.c
. That routine examines the disk space
and allows or disallows incoming mail.
enoughspace: no threshold
This debugging output says that no limit was defined with the
MinFreeBlocks
(
b
) option.
enoughspace: bavail=
haveblocks
need=
needblocks
This debugging output shows that the number of blocks free (available)
on the disk is
haveblocks
and that the number of blocks
required by incoming mail is
needblocks
.
Note that
haveblocks
will always be -1 if
sendmail
was compiled with SFS_TYPE set to SFS_NONE
(see
Section 18.8.40, SFS-TYPE
).
enoughspace failure: min=
boption
need=
needblocks
If the required number of blocks (
needblocks
) exceeds the
minimum reserved as defined by the
MinFreeBlocks
(
b
) option (
boption
), use of the disk is disallowed.
Throughout its many possible levels of forks and children,
sendmail
must keep track of timeouts - the maximum
amount of time it should wait for an event to occur.
For example, a child must not wait forever
for an SMTP greeting message,
because the program at the other end may never
provide that message (because it died or is just too busy).
To keep track of which child should be notified at which time,
sendmail
maintains an internal queue of events.
The
sendmail
program uses the SIGALARM signal
and the
alarm
(2) system call to set
the interval it waits to next check its
queue of events for timeouts.
That interval (called a
tick
) is the
period of the timeout itself, or if the timeout is scheduled for
the present or past, the interval is three seconds.
The
-d5.4
debugging switch
[2]
causes
sendmail
to
print the current time whenever the
queue of events is examined:
tick: now=
time
Here,
time
is the current time in seconds as returned
by
time
(2).
Events are set by the process (child or parent) that needs
a timeout. The
-d5.5
debugging switch causes
sendmail
to print the information that is used to
set up for that timeout:
setevent: intvl=
secs
, for=
timeo
, func=
addr
, arg=
pass
, ev=
evnt
The information is the timeout interval in seconds (
secs
), the time
(now plus the interval) in seconds that the timeout
will occur (
timeo
), the address in memory of the subroutine that will
be called if a timeout occurs (
addr
), the argument to be
passed to that subroutine (
pass
), and the address in
memory of the
C language structure that contains this information (
evnt
).
The
addr
of the function to be called can be converted to a function
name by running
nm
(1) on an unstripped binary of
sendmail
. For example, if
the following output was produced by
/usr/lib/sendmail
:
setevent: intvl=3600, for=802463800, func=3ebc4, arg=0, ev=94b68
you could find the function name associated with the address
3ebc4
by
running
%
nm /usr/lib/sendmail | grep 3ebc4
0003ebc4 t _readtimeout
Here, the result is the name
readtimeout
, which corresponds to
the function
readtimeout
() in
util.c
.
When an event is cleared because a timeout was no longer needed,
sendmail
prints:
clrevent: ev=
evnt
Here,
evnt
is the address in memory of the C language structure
that stored the event information. This is the same as the
last item printed by
setevent
above.
The
-d5.6
debugging switch tells
sendmail
to print the following information when a timeout occurs:
tick: ev=
evnt
, func=
addr
, arg=
pass
, pid=
pid
This shows that the event stored in the C language structure,
whose address in memory is
evnt
, has timed out. The subroutine whose
address in memory is
addr
will be called with an argument of
pass
.
The process identification number of the parent process that
asked for the timeout is shown as
pid
.
Show failed mail
(useful)
Mail can fail for a wide variety of reasons.
The way that
sendmail
handles errors is determined
by the setting of the
ErrorMode
(
e
) option
(see
Section 34.8.24, ErrorMode (e)
) in the configuration file.
The
-d6.1
(a.k.a.
-d6
) debugging switch causes
sendmail
to print the error-handling mode that is in effect at the time
it first begins to handle failed mail:
savemail, errorMode =
char
, id =
qid
, ExitStat =
err
e_from=
output of printaddr() here (see
Section 37.3.1
)
Here,
char
is either:
p
for print errors;
m
for mail back errors;
w
for write back errors;
e
for special BERKnet processing;
or
q
for "don't print anything"
(all of which are described under the
ErrorMode
option in
Section 34.8.24
).
The
qid
is the queue identifier (such as KAA15019).
The
err
is the error that caused the message to fail (as defined
in
<sysexits.h>
).
And
e_from=
uses
printaddr
() to print details about
the sender's address.
If the error-processing mode is
m
(for mail back) and
the
-d6.1
debugging switch is in effect,
sendmail
prints details about how the message is being returned to
the sender:
***Return To Sender: msg=
reason
, depth=
num
, e=
addr
, returnq=
output of printaddr
()
here (see
Section 37.3.1
)
Here,
reason
is a quoted string of text that explains why
the mail failed. This may be an SMTP reply string. The
num
is zero for normal delivery and one for error delivery.
The
addr
is the location in memory of the
information about the current envelope.
Finally,
sendmail
calls
printaddr
()
to print the details of the queue of recipients (
returnq=
)
for the current message.
The
-d6.5
debugging switch tells
sendmail
to print the error state it was in when it finished processing the error that
caused the message to fail:
state
num
If
num
is 7 (successful delivery), nothing is printed.
Otherwise, the above message is printed, and the value of
num
represents one of the states shown in
Table 37.4
.
Table 37.4: Error Handling States
State |
Description |
0 |
Report to sender's terminal |
1 |
Mail back to sender |
2 |
Messages have already been returned |
3 |
Save in
~/dead.letter
|
4 |
Return to postmaster |
5 |
Save in
/usr/tmp/dead.letter
|
6 |
Leave the locked queue/transcript files |
7 |
The message has been successfully delivered |
Show sender of return to sender
The
-d6.20
debugging switch tells
sendmail
to print
additional information to that printed by
-d6.1
. Specifically,
it prints, via
printaddr
(), the address information about the
sender of returned mail:
***Return To Sender: msg=
reason
, depth=
num
, e=
addr
, returnq=
output of printaddr
()
here (see
Section 37.3.1
)
Sendq=
output of printaddr
()
here
The
sendmail
program stores mail messages in its queue for a variety
of reasons. For example, the
SuperSafe
(
s
) option
(see
Section 34.8.67, SuperSafe (s)
) causes it to queue all
messages just to be safe. Also, messages that cannot be delivered
because of a temporary lack of resources
(or for any correctable reason) are queued for later delivery.
Mail messages are stored in the queue in two parts. A data part contains
the body of the message. An information part stores headers
and other information about the message.
The filenames of the two parts are identical but for the
first two letters. A
df
begins the name of the data part, and
a
qf
begins the name of the information part.
A third type of queue file begins with the letters
xf
and is a "transcript" file that holds error messages
produced during delivery.
To ensure that these filenames do not conflict with the names of
files that may already be in the queue,
sendmail
uses the
following pattern to create new names:
qf
H
AA
pid
Here,
pid
is the process identification number of the incarnation
of
sendmail
that is trying to create the file. Because
sendmail
often
fork
(2)'s to process the queue, the
pid
is
likely unique and therefore creates a unique name.
The
H
represents the current hour of the day (using a 24-hour clock) and prefixes
the
AA
.
It is constructed by adding the current hour
to the letter
A
(thus 00:23 would produce
A+0=A
, while
15:45 would produce
A+15=P
).
Although it is not recommended, the hour character can be useful in viewing
the queue (with the
-bp
command-line switch) to observe the particular hours,
if any, that messages tend to queue.
The hour prefix does not increment.
If
sendmail
cannot create a file
(because a file with that name already exists), it increments the
rightmost
A
of the
AA
part of the name
to a
B
and tries again. It continues
this process, incrementing the right from
A
to
Z
and
the left from
A
to
~
until it succeeds. If a
unique name cannot be found,
sendmail
has failed in its attempt to queue the message.
The last filename tried is:
qf
H
~Zpid
This name is unlikely to ever appear, because the clocking provides
for over 1600 possible unique names. With some versions of
sendmail
,
however, it may appear if the queue directory is not writable. For example,
the
-C
command-line switch, when used by a normal user,
might cause
sendmail
to give up its
root
privilege, thus causing this message to be printed.
The
-d7.1
(a.k.a.
-d7
) debugging switch causes
sendmail
to print the portion of the queue name that is common to all the
files that constitute a single queued message.
queuename: assigned id
H
AA
pid
, env=
addr
Here,
sendmail
prints the identifier portion of the
filename
(the
H
AA
, or whatever letters succeeded, and the
pid
)
that is common to the
df
,
qf
, and
xf
files.
The
addr
is the address in memory of the
C language structure that describes the envelope for the
mail message that is queued.
Show assigned queue file name
The
-d7.2
debugging switch tells
sendmail
to print the full filename of the file that it just created in the queue
directory:
queuename:
letter
f
H
AA
pid
The first
letter
of the name is either
d
,
q
, or
x
. The
pid
is the process identification
number of the
sendmail
process that created the file.
Dump file descriptor for the qf file
Once
sendmail
successfully opens its
qf
file,
it has established the unique identifier.
The
-d7.9
debugging switch causes
sendmail
to dump
the file-descriptor for that open file:
lockfd=
output of dumpfd
()
here (see
Section 37.5.13
)
Show queue names being tried
The
-d7.20
debugging switch causes
sendmail
to print each filename that it is attempting to try as it clocks
the
AA
in the name from
AA
to
~Z
:
queuename: trying qfHAA16391
queuename: trying qfHAB16391
queuename: trying qfHAC16391
queuename: trying qfHAD16391
...
and so on
DNS name resolution
(useful)
Name resolution is the process of determining a machine's IP
address based on its fully qualified domain name. This is
done by using the Domain Name System (DNS).
The process that
sendmail
uses to resolve a name is described in
Section 21.2, "How sendmail Uses DNS"
.
When
sendmail
finds that a hostname is really an MX
(mail exchanger) record, it attempts to look up the A record
for the host that handles mail receipt.
That request
may fail for a variety of reasons. If the
-d8.1
(a.k.a.
-d8
) debugging
switch is specified,
sendmail
produces the following message:
getmxrr: res_search(
host
) failed (errno=
err
, h_errno=
herr
)
Here,
host
is the hostname that was being looked up,
err
is the system error number (if any) from
<errno.h>
, and
herr
is the resolver specific error from
<netdb.h>
as shown in
Table 37.5
.
Table 37.5: Resolver Errors from netdb.h
Value |
Mnemonic |
Description |
1 |
HOST_NOT_FOUND |
Host not found (authoritative answer returned) |
2 |
TRY_AGAIN |
Nonauthoritative server not found or server failure |
3 |
NO_RECOVERY |
Nonrecoverable errors and refusals |
4 |
NO_DATA |
Valid name but no record of requested type |
Call to getcanonname(3)
(useful)
The routine
dns_getcanonname
() in
domain.c
of the
sendmail
source converts a hostname to a fully qualified domain name. This routine
is called only if DNS is used to look up hostnames, as determined
by the
ResolverOptions
(
I
) option
(see
Section 34.8.55, ResolverOptions (I)
) and the
ServiceSwitchFile
option
(see
Section 34.8.61
).
If it is,
dns_getcanonname
() can be called from two places:
during startup to get the values for
$w
,
$j
, and
$m
(see
Section 37.5.2
) or when a host is looked up via the
$[
and
$]
canonify-operators
(see
Section 28.6.6, "Canonicalize Hostname: $[ and $]"
).
The
-d8.2
debugging
switch shows the hostname before it is fully qualified with this call:
dns_getcanonname(
host
,
flag
)
If the
flag
is nonzero,
calls to the
getmxrr
() routine (which looks up MX records)
are also traced.
On entry to that routine,
sendmail
will print:
getmxrr(
host
, droplocalhost=
bool
)
The
host
is the hostname that MX records are being looked
up for. The
bool
, if nonzero, means that all MX records
that are less preferred than the local host (as determined by
$=w
)
will be discarded. If zero, they will be retained.
The
-d8.2
debugging switch also causes
sendmail
to
show the result of processing the
ResolverOptions
(
I
) option's
settings (see
Section 34.8.55
)
while reading the configuration file:
_res.options =
hex
, HasWildcardMX =
1 or 0
The
hex
is a hexadecimal representation of the
state
structure's
options
variable as described in
<resolv.h>
.
The value of HasWildcardMX is determined by its prefix (
+
or
-
) when listed with the
ResolverOptions
(
I
) option.
Trace dropped local hostnames
(useful)
If a hostname is dropped because
bool
(above) is nonzero,
the
-d8.3
switch causes
sendmail
to print the following:
found localhost (
host
) in MX list, pref=
pref
The
host
is the hostname that is being dropped. The
pref
is the preference associated with the MX record.
Hostname being tried in getcanonname(3)
(useful)
The
-d8.5
debugging switch causes the
getcanonname
(3) routine
to print the hostname it is trying to fully qualify. It shows the
name with the local domain appended without the local domain appended,
and at each step in between. Each try is printed as:
getcanonname: trying
host.domain
(
type
)
Here, the
type
is the type of lookup and is either ANY,
A, or MX.
Yes/no response to -d8.5
(useful)
The
-d8.7
debugging switch causes
sendmail
to print a yes or no response to each of
the "trying" lines printed by
-8.5
.
Yes means that the
host
could successfully be fully canonicalized.
A yes answer prints just this:
YES
If the
host
could not be canonicalized, a more complex answer
is printed:
NO: errno=
err
, h_errno=
herr
The
err
is the system error number (if any) from
<errno.h>
, and
herr
is the resolver specific error from
<netdb.h>
as shown in
Table 37.5
.
Resolver debugging
(useful)
The
-d8.8
debugging switch causes the resolver library to
be put into debugging mode (if that was mode was included when
that library was compiled). The
ResolverOptions
(
I
) option
(see
Section 34.8.55
)
+DEBUG also turns on this debugging mode.
But be aware that turning on +DEBUG
will cause a large number of screens full of output to be produced
by the resolver library for every DNS lookup.
If the name server returns an answer to an MX lookup, and if
the answer is not an MX record or an error,
sendmail
will
skip that host.
The
-d8.8
debugging switch (or the resolver library
being in debug mode) then causes
sendmail
to print the following:
unexpected answer type
wrongtype
, size
bytes
The
wrongtype
is an integer that can be found in
<arpa/nameser.h>
.
Inconsistency in returned information
Internally, the resolver library (
libresolv.a
) stores host domain
names in compressed form (for transmission efficiency). We won't
cover the nature of that compression. For our purposes it is
sufficient to know that the
sendmail
program
calls
dn_skipname
(3) from the resolver library to skip past the
compressed part of a host domain name. That call should never fail,
but if it does, the
-d8.20
debugging switch causes
sendmail
to print:
qdcount failure (
questions
)
The
questions
is a count of the number of queries made.
Canonify hostname and RFC1413 queries
The
-d9.1
(a.k.a.
-d9
) debugging switch
can be used to watch
sendmail
convert hostnames and addresses
into canonical form.
This is done by watching the
host_map_lookup
() function
with
-d9.1
.
First the hostname is looked up in the symbol table. If it
exists there and if it is marked as a valid canonical entry,
sendmail
prints
host_map_lookup(
host
) => CACHE
canon
Here, the name
host
was found in the symbol table. The value
returned was a valid canonical name. If
host
had not
been found, the
canon
would have printed as NULL.
If
sendmail
is running in defer-delivery mode
(see the
DeliveryMode
(
d
)
option in
Section 34.8.16, DeliveryMode (d)
), it will
skip looking up the hostname further. This is done because dial-on-demand
connections should not be brought up merely to perform unnecessary
DNS lookups. When
sendmail
skips further lookups, it prints:
host_map_lookup(
host
) => DEFERRED
If the name is not in the symbol table, it is looked up with the
getcanonname
() function. First
sendmail
prints:
host_map_lookup(
host
) =>
with no trailing newline. Then, if the canonical name is returned
by
getcanonname
(), that returned name is printed. Otherwise,
FAIL is printed. If
sendmail
is compiled with NAMED_BIND defined
for DNS support
(see
Section 18.8.23, NAMED-BIND
), the FAIL is followed by the
resolver specific error (
herr
)
from
<netdb.h>
:
host_map_lookup(
host
) =>
herr
The
-d9
debugging switch is also used to display
identd
(8) queries. When a network connection is made from
a remote host to the local host, the local
sendmail
uses
the RFC1413 identification protocol to query the remote host
for the name of the user who instantiated the connection.
The result of that query is printed as:
getauthinfo:
result
Here,
result
is two pieces of information: an
address composed of the username, an
@
, and the
real name of the remote host and the IP address of that host:
getauthinfo: george@fbi.dc.gov [123.45.67.8]
If the query fails, nothing is printed.
The above information is not provided by the remote host
in that clear form. Instead,
sendmail
needs to parse
the needed information from a raw reply. The
-d9.3
debugging switch causes the raw reply to be printed:
getauthinfo: got
raw_reply
Show RFC1413 query being sent
The
-d9.10
debugging switch causes
sendmail
to display its outgoing RFC1413 query:
getauthinfo: sent
query
Here, the outgoing
query
is composed of two numbers:
the TCP port on the remote machine where its
RFC1413 server is running, followed by a dot and
the local port number for the original connection.
When
sendmail
is about to deliver a mail message, it
has already resolved three pieces of information: which
delivery agent to use, the name of the host that receives
the message, and the name of one or more recipients for that
message.
The
-d10.1
(a.k.a.
-d10)
debugging switch tells
sendmail
to display information about the recipient to
whom it is about to deliver:
-deliver, id=
mid
, mailer=
num
, host=`
hname
', first user=`
uname
'
Here,
mid
is the queue message identifier (such as PAA08463).
The
num
is the number of the delivery agent selected.
Delivery agent numbers can be displayed by using the
-d0.15
debugging switch.
The
hname
is the name of the
host that receives delivery. The
uname
is the name of the
first of possibly many users who receive the mail message.
The
uname
can be either a single name such as
joe
or a full forwarding address such as
joe@jokes.are.us
.
When
sendmail
attempts delivery, it may be delivering
to multiple recipients. It stores its list of recipients internally
as a linked list of C language structures, each of which holds information
that is specific to each recipient address.
The
-d10.1
debugging switch also causes
sendmail
to
print that information using the
printaddr
() routine:
send to
output of printaddr
()
here (see
Section 37.3.1
)
Dump controlling user's address
Every recipient address may have a controlling
user associated with it (see
Section 23.9.2, C line
). The
-d10.2
causes
sendmail
to
dump the address of the controlling user using the
printaddr
()
routine:
ctladdr=
output of printaddr
()
here (see
Section 37.3.1
)
Showq don't send to MeToo address
If the
MeToo
(
m
) option (see
Section 34.8.39, MeToo (m)
)
is set to false, the
-d10.5
debugging
switch tells
sendmail
to dump the address that won't receive
(the QDONTSEND) the mail message.
deliver: QDONTSEND
output of printaddr
()
here (see
Section 37.3.1
)
Predelivery file descriptor dump
The
-d10.100
debugging switch tells
sendmail
to dump
all its file descriptors just before it is about to attempt
delivery.
The
-d11.1
(a.k.a.
-d11
) debugging
switch is used to trace message delivery. For
each delivery agent the following is printed:
openmailer:
argv
Here,
argv
is the
A=
array for the delivery agent, with
macros expanded and printed.
The status of remote hosts is cached internally.
Before connecting to a remote host,
sendmail
checks its
cache to see whether that host is down. If it is, it skips
connecting to that host. If the
-d11.1
debugging switch is also
specified, the status of the down host is printed as:
openmailer:
output of mci_dump
()
here
The output of
mci_dump()
looks like this:
MCI@
memaddr
: flags=
mci_flags
<
flag,flag,...
>,
errno=
mci_errno
, herrno=
mci_herrno
, exitstat=
mci_exitstat
, state=
mci_state
,
pid=
mci_pid
, maxsize=
mci_maxsize
, phase=
mci_phase
, mailer=
mci_mailer
,
host=
mci_host
, lastuse=
mci_lastuse
The meaning of each
mci_
item in the above output is described in
Table 37.6
.
Table 37.6: The Meaning of the MCI Structure Items
Name |
What prints |
mci_memaddr
|
The address in memory of this C language structure |
mci_flags
|
The flag bits in hexadecimal (see
Table 37.7
) |
mci_errno
|
The error number of the last connection |
mci_herrno
|
The DNS h_errno of the last lookup |
mci_exitstat
|
The
<sysexits.h>
exit status of last connection |
mci_state
|
The current SMTP state (see
Table 37.16
) |
mci_maxsize
|
The maximum size message the host will accept |
mci_pid
|
The PID of the child process |
mci_phase
|
SMTP phase (string) such as "client greeting" (or NULL) |
mci_mailer
|
The (text) name of the delivery agent (or NULL) |
mci_host
|
The host's name (or NULL) |
mci_lastuse
|
Last usage time in
ctime
(3) format |
Table 37.7
shows what the individual flag bits in
mci_flags
mean,
and the human-readable
flags
text that corresponds to each bit.
Those text items are shown with the leading source
MCIF_
prefix
removed.
Table 37.7: The Meaning of mci_flags Hexadecimal Values
Value |
Name |
Meaning |
0001 |
VALID |
This entry is valid |
0002 |
TEMP |
Don't cache this connection |
0004 |
CACHED |
This connection currently in open cache |
0008 |
ESMTP |
This host speaks ESMTP |
0010 |
EXPN |
EXPN command supported |
0020 |
SIZE |
SIZE option supported |
0040 |
8BITMIME |
BODY=8BITMIME supported |
0080 |
7BIT |
Strip this message to 7 bits |
0100 |
MULTSTAT |
MAIL11V3: handles MULT status |
0200 |
INHEADER |
Currently outputting header |
0400 |
CVT8TO7 |
Convert from 8 to 7 bits |
0800 |
DSN |
DSN extension supported |
1000 |
8BITOK |
OK to send 8-bit characters |
2000 |
CVT7TO8 |
Convert from 7 to 8 bits |
4000 |
INMIME |
Currently reading MIME header |
After checking to see whether the host is down,
sendmail
attempts to connect to it
for network SMTP mail. If that connect fails, the
-d11.1
debugging
switch causes the following to be printed:
openmailer: makeconnection => stat=
exitstatus
, errno=
errno
Here,
exitstatus
is a numerical representation of the reason for
the failure as documented in
<sysexits.h>
, and
errno
is the system-level reason for the error, as documented in
<errno.h>
.
Other errors, such as failure to establish a
pipe
(2),
or failure to
fork
(2), causes the following to be printed:
openmailer: NULL
This message (although it contains no information) signals that
a more descriptive error message was logged with
syslog
(3) (see
Section 26.1, "Logging with syslog"
).
Show the uid/gid running as during delivery
(useful)
To perform delivery,
sendmail
often has to set its
uid
to something other than
root
's.
The logic behind that process is described in
Section 24.2.2
.
The
-d11.2
debugging switch tells
sendmail
to
print the real and effective
uid
's that it is running under
during delivery.
openmailer: running as r/euid=
ruid
/
euid
Also, the
-d11.2
debugging switch causes
sendmail
to
print any error response that may be produced by a delivery agent:
giveresponse: stat=
status
, e->e_message=
what
Here,
status
is the error that caused delivery to fail (or
succeed if it is 0) as defined in
<sysexits.h>
.
The
what
is either the error message produced by the
delivery agent or "<NULL>" if the delivery agent was silent.
Show tried D= directories
Execution of a delivery agent can take place in any of a sequence
of directories as defined by the
D=
delivery agent equate
(see
Section 30.4.3, D=
).
The
-d11.20
debugging switch causes each directory
to be printed as it is tried:
openmailer: trydir
dir
Here,
dir
is the name of the directory that
sendmail
is about to
chdir
(2) into.
Show mapping of relative host
(useful)
In the SMTP RCPT command,
sendmail
is required
to express the recipient's address relative to the local
host. For domain addresses, this simply means that the address
should be RFC822-compliant.
The
-d12.1
(a.k.a.
-d12
) debugging switch causes
sendmail
to print the address as it appeared
before it was made relative:
remotename(
addr
)
If the
addr
is for the sender or recipient and is being
processed from a queue file, then nothing more is printed, and
the
addr
is processed by rule set 3. If the delivery
agent for the recipient has the
F=C
flag set (see
Section 30.8.15, F=C
)
and the recipient
address
lacks a domain part, then the domain of the sender is
appended, and the result is processed by rule set 3 again.
Sender/recipient-specific rule sets are then applied (1 and
S=
for the sender, or 2 and
R=
for the recipient). Next,
rule set 4 is applied, and any macros in the result are expanded.
Finally, the fully qualified and relative address is printed as:
remotename => `
addr
'
The
-d13
(a.k.a.
-d13
) debugging switch causes
sendmail
to display information about the recipients
of each mail message as it is being delivered.
The
-d13.1
debugging switch tells
sendmail
to print the
mode of delivery and then the recipient information:
SENDALL: mode
dmode
, id=
mid
, e_from
output of printaddr
()
here (see
Section 37.3.1
)
e_flags =
envelope flags here
sendqueue:
output of printaddr
()
here (see
Section 37.3.1
)
Here,
dmode
is one of those shown in
Table 37.8
.
The
mid
is the queue message identifier (such as PAA08463).
The address of the sender,
e_from
, is dumped by
using the
printaddr
() routine.
Then the envelope flags,
e_flags
, are dumped
as described in
Table 37.3
.
Next, information about all the recipients (
sendqueue:
) is printed by using the
printaddr
() routine.
Table 37.8: Delivery Modes Used by
sendall
()
Mode |
Description |
i
|
Interactive delivery |
j
|
Deliver w/o queueing (obsolete as of V8) |
b
|
Deliver in background |
q
|
Queue, don't deliver |
d
|
Defer, queue w/o DNS lookups |
v
|
Verify only (used internally) |
Finally, the
-d13.1
debugging switch causes
sendmail
to print a message every time it splits an envelope in two:
sendall: split
orig
into
new
Here,
orig
is the original queue message identifier
for the original envelope (such as PAA08463) and
new
is the identifier for the new envelope, the near
identical clone of the first. Envelopes need to split if they
have different owners.
Show addresses that we should not send to
The
-d13.5
debugging switch is used to display
addresses to which mail should not be delivered.
One such address is that of the sender of the cloned envelope after a split:
sendall(split): QDONTSEND
output of printaddr
()
here (see
Section 37.3.1
)
Another is the sender address
(unless the
MeToo
(
m
) option, see
Section 34.8.39
, is set):
sendall: QDONTSEND
output of printaddr
()
here (see
Section 37.3.1
)
Finally, senders who are the
owner-
of mailing lists
(see
Section 25.3, "Defining a Mailing List Owner"
)
should not have mail sent to them.
sendall(owner): QDONTSEND
output of printaddr
()
here (see
Section 37.3.1
)
This latter sender address is derived by a call to
setsender
(),
which can be separately viewed with the
-d45
debugging switch.
The
-d13.10
debugging switch causes
sendmail
to print
the following upon entering its internal
sendenvelope
()
routine:
sendenvelope(
ident
) e_flags=
hex
The
ident
is either the queue identifier (such as SAA24069)
or the [NOQUEUE] if the message was never assigned an identifier
(such as if it was never queued).
The
e_flags
are dumped in hexadecimal
as described in
Table 37.3
.
The
sendmail
program's delivery mode (as initially
set with the
DeliveryMode
(
d
) option; see
Section 34.8.16
) can change during delivery
for a complex series of reasons. The
-d13.20
debugging
switch causes the final delivery mode to be displayed:
sendall: final mode =
char
Here,
char
is the one of the characters that can be
specified for the
DeliveryMode
(
d
) option.
If, after all recipient addresses are checked, none are left
to be delivered to (everyone of them was either dropped or queued),
and if the
DeliveryMode
(
d
) option
(see
Section 34.8.16
) is neither
q
,
d
, nor
v
, the
-d13.29
debugging switch will cause
sendmail
to print:
No deliveries: auto-queuing
Show envelopes being split
The process of creating another envelope for another
sender is called "splitting the envelope."
The
-d13.30
debugging switch causes
sendmail
to show
its initial scanning of the send queue to count the number of envelopes
(including split envelopes) that will be needed.
Checking
output of printaddr
() here (see
Section 37.3.1
)
Then, depending on the result, each owner will
have one of the following printed:
... QDONTSEND
... QBADADDR|QQUEUEUP
... expensive
... deliverable
The
Q
flags are described under the output of
printaddr
()
in
Section 37.3.1
.
Some programs require that addresses in a list of recipients be separated from
each other by space characters. This is called an "old-style" address.
RFC822 requires that addressees be separated
from each other with comma characters.
The
-d14.2
[3]
debugging switch tells
sendmail
to show each header line that may need spaces converted to
commas.
commaize(
header
:
list
)
Here,
header
is the caption part of a header line, such as
From:
. The
list
is a sequence of one or more
addresses.
Show network get request activity
When
sendmail
runs in daemon mode, it opens a socket on a
port, then listens on that socket for incoming SMTP connections.
The
-d15.1
(a.k.a.
-d15
) debugging switch prints information about
both of those steps.
Note that
-d15.1
should usually be combined
with
-d99.100
, or some output may be lost.
Before the socket is opened,
sendmail
prints the following:
getrequests: port 0x
portno
This shows that the port numbered
portno
(printed in hexadecimal notation)
is used to open the socket.
If that open fails,
sendmail
syslog
(3)'s one of
the following messages at LOG_CRIT and exits:
getrequests: problem creating SMTP socket
If the open succeeds,
sendmail
attempts to bind to that socket.
If it cannot bind, it
syslogs
the following message at LOG_CRIT
and exits:
getrequests: can't bind socket
After it binds,
sendmail
goes into a loop in which it listens
for and handles incoming SMTP requests. If the listen fails,
sendmail
syslog
(3)'s the following message at LOG_CRIT and exits:
getrequests: cannot listen
If
sendmail
starts to listen successfully, this
-d15.1
debugging switch causes it to print the number of
the socket on which it is listening:
getrequests:
sockno
This shows that
sendmail
is then listening on the socket whose
file descriptor is
sockno
.
In daemon mode,
sendmail
waits for an incoming SMTP
connection. When that connection is made,
sendmail
forks, and the child processes the connection from that
point on. The
-d15.2
debugging switch causes
sendmail
to print a message that confirms that it is performing this fork.
Note that
-d15.2
should usually be combined
with
-d99.100
, or some output may be lost:
getrequests: forking (fd =
sock
)
Here,
sock
is the value of the socket being used for the connection.
The
-d15.2
debugging switch also causes a message to be
printed when the child process exits:
getreq: returning (normal server)
getreq: returning (null server)
Here, failure of the connection to be validated (see
Section 22.4.1, "Accept/Reject Connections via libwrap.a"
and
Section 29.10.3, "The check_relay Rule Set"
), causes
null server
to be printed.
A successful connection causes
normal server
to be printed.
Finally, the
-d15.2
debugging switch causes the following to
be printed every time
opendaemonsocket
() routine is called:
opendaemonsocket()
On kernels that support this feature, the
-d15.101
debugging switch
turns on kernel debugging for the
socket that is opened to handle an incoming SMTP connection. Debugging is
turned off when the socket is closed at the end of receipt of the message.
The debugging information gathered can be viewed with the
trpt
(8)
program.
When mail messages are sent to a site that can be
reached via a TCP/IP connection, the
-d16.1
(a.k.a.
-d16
) debugging switch
causes
sendmail
to print one of the following messages when
it is about to make the connection:
makeconnection: (
host
[NULLADDR])
null address
makeconnection: (
host
[0])
no address family
makeconnection: (
host
[[UNIX:
path
]])
AF_UNIX family
makeconnection: (
host
[
ip address
])
AF_INET family
makeconnection: (
host
[[LINK:
name
]])
AF_LINK family
makeconnection: (
host
[Family
num
:0x
bytes
])
unknown family
Here,
host
is the name of the host to which the connection
is made. The form of the address information differs depending on
the address family.
If the connection can be successfully made,
the
-d16.1
debugging switch then causes
sendmail
to print:
makeconnection: fd=
sock
Here,
sock
is the socket descriptor that was issued for use with
the socket connection.
If the
DialDelay
option
(see
Section 34.8.17, DialDelay
) is nonzero and the connection fails,
sendmail
will sleep DialDelay seconds and try again. If the
-d16.1
debugging switch is also specified,
sendmail
will print:
Connect failed (
error message
); trying again...
Here,
error message
describes the reason for the initial failure.
If there is more than one address for a host,
sendmail
will try
each in turn until one connects successfully. The
-d16.1
debugging switch
causes the following to be printed for each failure:
Connect failed (
error message
); trying new address....
Note that the
-d16
debugging switch should usually be combined with
the
-d99.100
debugging switch, or some output may be lost.
See
-d15.101
. The only difference here is that
debugging is turned on for the outgoing socket.
When
sendmail
readies to deliver mail to a remote host, it
looks up that host using DNS to find Mail Exchanger (MX) records.
The
-d17.1
(a.k.a.
-d17
) debugging switch causes V8
sendmail
to
print the following:
hostsignature(
host
) =
records
Here,
host
is the host that was looked up with DNS.
The
records
is a colon-delimited list of MX records
for that host. That list might contain only the original hostname if
no MX records were found.
Show randomizing MX records
MX records have preferences. Delivery is to the record with
the lowest preference first, then to each higher preference,
in turn, until a delivery succeeds. When two or more preferences are
equal, V8
sendmail
randomizes them so that they are
tried in a different order. The order is the same each time,
so this is really a pseudo-randomization (actually a hash function).
The
-d17.9
debugging switch causes
sendmail
to
print the following each time it randomizes:
mxrand(
host
) =
hash
This shows that the MX records for
host
have been
given a hash value of
hash
.
The process of transmitting (or receiving) a mail message
using the SMTP protocol requires
sendmail
to send replies
as its side of the dialogue. The
-d18.1
(a.k.a.
-d18
) debugging switch causes
sendmail
to print each reply that it sends. It prefixes what it prints
with three right angle brackets:
>>> RCPT To: gw@wash.dc.gov
Note that this is the same output as produced with
the
-v
command-line switch (see
Section 36.7.41, -v
).
The
-d18.1
debugging switch also causes the following message to be
printed to the standard output if
the file descriptor for the connection is NULL:
smtpmessage: NULL mci_out
Prior to opening the connection, the
-d18.1
debugging switch causes
sendmail
to print:
smtpinit
output of mci_dump
()
here
Finally, the
-d18.1
debugging switch causes
sendmail
to
print:
reply
Each time it enters its
reply
() routine.
The
-d18.2
debugging switch causes
sendmail
to
show processing of the SMTP MAIL From: command that the local
machine will send.
smtpmailfrom: CurHost=
host
Here,
host
is the name of the current host that
sendmail
is dealing with.
The
-d18.100
debugging switch causes
sendmail
to
pause
(2)
after a read error when processing the SMTP dialog. The administrator
can then use
ps
(8) and
gcore
(8) to produce a core dump,
which can then be examined with a debugger to determine the reason for the read error.
Show ESMTP MAIL and RCPT parameters
Under Extended SMTP (ESMTP)
the MAIL and RCPT command can be followed
by other optional parameters. The
-d19.1
(a.k.a.
-d19
)
debugging switch displays those parameters.
We discuss the MAIL command first, then the RCPT command.
The
sendmail
program
recognizes four parameters that can follow the address in the
SMTP MAIL command:
[4]
SIZE, which specifies the size in bytes of the incoming message;
BODY, which specifies the nature of the message body (
8bitmime
or
7bit
);
ENVID, which is used to propagate a sender-specific unique identifier
for the envelope;
and RET, which specifies whether or not to return the message body
on an error return.
The
-d19.1
debugging switch causes
sendmail
to print
the parameters it received:
MAIL: got arg
param
="
value
"
The
param
is one of the parameters shown above.
The nature of the
value
depends on the
param
The
value
for SIZE is a positive integer. If SIZE
lacks a
value
, this error is issued:
501 SIZE requires a value
When multiple, illegal SIZE values are specified, the last is the one
whose value is used.
The
value
for BODY is a case-insensitive string. It can
either be
8bitmime
or
7bit
. If BODY lacks a
value
, the following
error is issued:
501 BODY requires a value
If BODY has neither of the approved strings as its value, the following error
is issued:
501 Unknown BODY type
bad string here
When multiple, illegal BODY values are specified, the last is the one
whose value is used.
The
value
for ENVID is a special envelope identifier.
It is composed of ASCII characters in the range
!
through
~
, excepting
+
and
=
. Characters outside
that range and those two excepted characters are replaced with a
+
followed by a hexadecimal representation of the character's
value (there must be exactly two hexadecimal digits).
If ENVID lacks a value, the following error is issued:
501 ENVID requires a value
If the text of the value is not as described above, the following error
is issued:
501 Syntax error in ENVID parameter value
If more than one ENVID specified is for a given envelope,
the second results in this error:
501 Duplicate ENVID parameter
The
value
for RET is one of two possible case-insensitive
strings:
hdrs
tells
sendmail
to return only the headers
of a bounced mail message;
full
tells
sendmail
to return
the headers and body of a bounced mail message. If no string is present,
the following error is issued:
501 RET requires a value
If a string is present but is something other than
hdrs
or
full
, the following is printed:
501 Bad argument
bad string here
If more than one RET is specified for a given envelope, the following
error is printed:
501 Duplicate RET parameter
If the parameter is not SIZE, BODY, ENVID, or
RET, the following error is issued:
501
param
parameter unrecognized
The
sendmail
program
recognizes two parameters that can follow the address in the
SMTP RCPT command:
NOTIFY, which specifies when to notify the sender;
and ORCPT, which specifies the original recipient's address.
The
-d19.1
debugging switch causes
sendmail
to print
the parameters it received:
RCPT: got arg
param
="
value
"
The
param
is one of the parameters shown above.
The nature of the
value
depends on the
param
The
value
for NOTIFY is either NEVER or a comma-separated list composed of
SUCCESS, which means to notify the sender upon final delivery
that the message was successfully delivered;
FAILURE, which means to notify the sender if the message cannot
be delivered;
and DELAY, which means to notify the sender if the message is
delayed.
If there is no
value
, the following error is issued:
501 NOTIFY requires a value
If a
value
is present but it is not one of the words shown above,
the following error is issued:
501 Bad argument \"
bad value here
\" to NOTIFY
Multiple, illegal NOTIFY parameters in an envelope cause the subsequent
values to be logically OR'd together.
The
value
for ORCPT is an address followed by
a semicolon, then an address that is encoded in the same way
as the envelope identifier described for ENVID above.
If that
value
is missing, the following error message is
issued:
501 ORCPT requires a value
If the
value
is syntactically wrong (i.e., if the
value
does not have a valid address following the semicolon),
this error message is issued:
501 Syntax error in ORCPT parameter value
If multiple ORCPT values are specified, the second one results
in this error:
501 Duplicate ORCPT parameter
Show resolving delivery agent: parseaddr()
(useful)
The
-d20.1
(a.k.a.
-d20
)
debugging switch causes
sendmail
to print
each recipient address before it is rewritten by rule sets 3 and 0:
-parseaddr(
addr
)
Here,
addr
is the recipient address before it is rewritten
and before any aliasing has been performed on it.
The
-d20.1
debugging switch also causes
sendmail
to print information
about problems that may exist in recipient addresses. If an address contains
any control character that is not an
isspace
(3) character,
sendmail
prints the following message and skips that address:
parseaddr->
bad address
If an address is empty (that is, if it is composed entirely of an
RFC822-style comment),
sendmail
prints the following and
skips that address:
parseaddr->NULL
After the recipient address has been rewritten by rule sets 3 and
0, and if a delivery agent was successfully selected,
sendmail
prints the result using the
printaddr
()
routine.
Note that
-d21
can be used to
watch the rule sets parse the address, and
-d24
can be used
to watch the resulting tokens being pasted back together.
Trace rewriting rules
(useful)
The
-d21.1
(a.k.a.
-d21
) debugging switch causes
sendmail
to print
each step that it takes in rewriting addresses with rules.
The
-d21.1
debugging switch causes output to
be produced that is identical to the output produced by the
-bt
command-line switch (see
Section 38.1, "Overview"
):
rewrite: rule set
num
input:
addr
rewrite: rule set
num
returns:
addr
Here,
num
is the rule-set number, and
addr
is, first,
the address (workspace) before rewriting and, second, the address after
rewriting.
Because rules are recursive by nature, they can sometimes
cause infinite loops (see
Section 28.6.2, "Rewrite Once Prefix: $:"
). When a rule loops more than 100
times, the following error is issued:
Infinite loop in rule set
num
, rule
rnum
If the
-d21.1
debugging switch was also invoked
the above error is followed by:
workspace:
state of rewritten address so far, here
The
-d21.2
debugging switch tells
sendmail
to show the
current value of any deferred-expansion macro (one that was declared
with the
$&
prefix). Each such macro that is encountered
in processing a rule prints as:
rewrite: LHS $&
char
=> "
value
"
rewrite: RHS $&
char
=> "
value
"
The
char
is the single-character name of the macro, and
the
value
is its current value. If that particular
macro lacks a value, it will print as (NULL). The
LHS
refers
to the left-hand side of the rule, and the
RHS
corresponds
to the right-hand side. Deferred-expansion macros are described
in
Section 31.5.3, "Use Value as Is with $&"
.
The
-d21.3
debugging switch causes
sendmail
to print
the rule-set number of each rule set called as a subroutine.
Rule sets are called as subroutines by using the
$>
rewrite-operator
in the RHS of rules (see
Section 28.6.4, "Rewrite Through Another Rule Set: $>set"
).
The output produced looks
like this:
---callsubr
rset
Here,
rset
is the text that was interpreted as the number
of the rule set, rather than the numeric value. If the number in
the configuration file was a symbolic name, then that symbolic
name is printed. (See
Section 28.6.4
for more details about the
$>
rewrite-operator.)
Result after rewriting by a rule
If the LHS of a rule matches the workspace, the workspace
is rewritten by the RHS of that rule. The
-d21.4
debugging
switch causes
sendmail
to print the result of a successful
rewrite:
rewritten as:
addr
Note that the rewritten address (
addr
) may be the result of
rewriting by a subroutine call.
If the LHS of a rule fails to match the workspace, the
-d21.10
debugging switch causes
sendmail
to print:
--- rule fails
Announce success and show LHS
If the LHS of a rule matches the workspace, the
-d21.12
debugging switch causes
sendmail
to print:
--- rule matches
The
-d21.12
debugging switch also causes the LHS of each
rule to be printed before it is tried:
---trying rule:
lhs
Remember that rules are pre-expanded when the configuration file is
read. As a consequence, defined macros appear as their values
in the
lhs
, rather than in their
$
letter
form.
The
-d21.15
debugging switch causes
sendmail
to print
each replacement that is the result of a
$
digit
rewrite-operator in the RHS:
$
digit
:
hex
=
token
...
Here,
$
digit
is followed by one or
more
hex
=
token
pairs.
The
hex
is the address in memory of the
token
,
and the
token
is the token from the LHS that is being
copied into the workspace. This output can run to many screens.
Show token by token LHS matching
In addition to the rewriting information shown by the debugging switches mentioned
above, the
-d21.35
debugging switch also shows each
and every attempt by the LHS to match the workspace. Each comparison
is printed like this:
ap=
workspace
rp=
operator
Here,
ap
(for
address part
) indicates
the token in the workspace that the rule is currently trying to match.
The
rp
(for
rule part
) is the operator or token at this
point in the LHS that is trying to match the workspace.
Note that the
workspace
is a single token
from the workspace, and the
operator
is a single operator
or token from the LHS of the current rule. A complete comparison
of the LHS
to the workspace can produce several lines of output
for each rule.
This output can be useful for understanding how the pattern-matching
algorithm works.
The
-d21.35
debugging switch also shows the index advancing
to the next operator and what the corresponding state of the workspace
is at that time.
ADVANCE rp=
operator
ap=
workspace
This is useful for watching the left-hand side trying to find
a match.
Trace class matching in the LHS
The
-d21.36
debugging switch causes
sendmail
to
print the following each time it finds a match for either the
$=
or
$~
class-operator:
CLMATCH
The
-d21.36
switch also shows how
sendmail
extends the token in the workspace and tries again,
should a match for any operator fail. That is, for all operators (not
just
$=
or
$~
), if the workspace contained
usa.edu
,
sendmail
would first look up
usa
, then
usa.
, and finally
usa.edu
. Each such attempt prints
as:
EXTEND rp=
operator
ap=
workspace
If there is still no match,
sendmail
has to back up
and try a different tack. In the case of
usa.edu
it would back up to the dot. For example, if it were trying
$=X
,
the output would look like this:
BACKUP rp=$=X, ap=.
Trace tokenizing an address: prescan()
(useful)
Processing of rules requires that all addresses be divided into
tokens.
The
-d22.1
(a.k.a.
-d22
) debugging switch causes
sendmail
to print the various steps it takes in tokenizing
an address.
In addition to tokenizing, the
prescan
() routine also normalizes
addresses. That is, it removes RFC822-style comments and recognizes
quoted strings.
Be aware that rules are also viewed as addresses and processed by
prescan
() when the configuration file is being read.
The
-d22.1
debugging switch tells
sendmail
to complain if
the first token in the address it is parsing turns out to be nothing
prescan: null leading token
This can happen if an address (or rule) contains only RFC822-style comments in parenthesis.
Show address before prescan
(useful)
The
-d22.11
debugging switch causes the address to be printed
as it appears before any tokenizing or normalization:
prescan:
addr
Show address after prescan
(useful)
The
-d22.12
debugging switch causes the address to be printed
as it appears after all tokenizing and normalization:
prescan==>
addr
The
-d22.36
debugging switch causes each token to be printed
when found:
tok=
token
Trace low-level state machine
For the purpose of tokenizing, an address is viewed as a stream
of characters.
The process of tokenizing and normalizing is driven by a
state
machine that handles the stream one character at a time.
For example, if the current character is
@
,
sendmail
sees that it has found both the start and end of
a token and so resets its state to begin looking for a new token.
But if the current character is
a
and
sendmail
is
currently gathering a token, it knows that it should continue
to gather.
The use of a state machine enables
sendmail
to easily
keep track of things such as the nesting level of angle brackets and
whether or not a quoted string is present.
The
-d22.101
debugging switch causes
sendmail
to
output two lines of information. The first shows entry into
a state (or continuation of a state):
c=
char
, s=
state
;
Here,
char
is the current character in the stream of characters
that makes up the original address. The
state
is a two-digit
octal representation of the current state. The first digit modifies
the second and is a 2 (which
means that this is a meta-character so don't pass it through), a 4 (which means
to break the token at this character), or a 6 (which means both 2 and 4).
The second digit indicates the state. The list of states and their
meanings are shown in
Table 37.9
.
The semicolon separates this output from the rest of the line that
is printed below.
The rest of the output produced by the
-d22.101
debugging switch shows the state changing to a new state:
ns=
nstate
Here,
nstate
is the new state number, printed in octal with
a leading zero.
Note that the level
101
in
-d22.101
means that this
debugging output is for true experts only.
The
-d24.4
debugging switch
[5]
tells
sendmail
to print a message upon its
entry into the
allocaddr
() routine:
allocaddr(flags=
flags
, paddr=
paddr
)
Here, the address in
paddr
will be copied into another address
(not shown). The
flags
is a hexadecimal representation of
the
RF_
flags used by
sendmail
to communicate with
some of its internal routines. The meanings of the bits in these
flags are shown in
Table 37.10
.
Table 37.10: sendmail's Internal RF_ flags
Hex |
Name |
Description |
000 |
RF_COPYNONE |
Don't copy anything |
001 |
RF_SENDERADDR |
Set = sender address, otherwise recipient |
002 |
RF_HEADERADDR |
Set = header address, otherwise envelope |
004 |
RF_CANONICAL |
Strip RFC822 comments |
008 |
RF_ADDDOMAIN |
Okay to append a domain |
010 |
RF_COPYPARSE |
Copy parsed user and host |
020 |
RF_COPYPADDR |
Copy the print address |
If RF_COPYPARSE is set in
flags
, the temporary strings
for the host and user in the passed address (not shown) are allocated
permanent storage in memory.
The
-d24.5
debugging switch tells
sendmail
to print
a message upon its entry into the
buildaddr
() routine.
buildaddr, flags=
flags
, tv=
tokens
The
buildaddr
() routine takes an array of separate tokens
and pastes them back together again. The
flags
are ORed
together hexadecimal values as documented in
Table 37.10
.
The RF_SENDERADDR and RF_HEADERADDR flags tell
buildaddr
() which rewriting rules to use in processing
the address.
The array of
tokens
being assembled is
printed on a single line, each separated from the other
by a space.
Show result of buildaddr()
The
-d24.6
debugging switch tells
sendmail
to
print the result of
buildaddr
()'s attempt to reconstruct an address.
buildaddr =>
output of printaddr
()
here (see
Section 37.3.1
)
Trace "sendtolist"
(useful)
Each recipient address for a mail message is added one-by-one to an
internal list of recipients. The
-d25.1
(a.k.a.
-d25
) debugging switch
causes
sendmail
to print each address as it is added to
this list:
sendto:
list
ctladdr=
output of printaddr
()
here (see
Section 37.3.1
)
After each is added, those that have selected a
delivery agent with the
F=A
(see
Section 30.8.12, F=A
)
and
F=w
(see
Section 30.8.43, F=w
) flags set
are further processed by aliasing and by reading
the user's
~/.forward
file. Each new address that results
from this processing is added to the list, and any duplicates
are discarded.
Trace recipient queueing
(useful)
The
-d26.1
(a.k.a.
-d26
) debugging switch causes
sendmail
to print the addresses of recipients as they are added to the
send queue
- an internal list of addresses that
sendmail
uses to sort and remove duplicates from the recipient addresses for
a mail message.
On entry to the
recipient
() routine, the
-d26.1
debugging switch causes
sendmail
to
print the raw address (as it appears before adding it to the send queue):
recipient (
level
):
output of printaddr
()
here (see
Section 37.3.1
)
An address can be the result of alias expansion. Because the process
of aliasing (including
:include:
and
.forward
files)
can be recursive, it is possible to get too many alias expansions.
The
level
shows the number of alias expansions so far. If that
number exceeds MaxAliasRecursion (as hard coded in
conf.c
as 10),
sendmail
issues this warning:
aliasing/forwarding loop broken (
level
aliases deep;
MAXRCRSN
max)
Next
sendmail
compares
the new address to others that are already in the send queue. If it finds
a duplicate, it prints the following message and skips the
new address:
addr
in sendq:
output of printaddr
()
here (see
Section 37.3.1
)
Here,
addr
is the duplicate address.
Information about that address is produced with the
printaddr
()
routine.
Trace self destructing addresses
Certain addresses can "self destruct" because they can cause an endless loop.
Consider the address
A
. If
A
is aliased to
B
and
B
is aliased to
A
,
A
is a self-destructive address.
The
-d26.8
debugging switch causes
sendmail
to print
the address that is being tested for self-destruction:
testselfdestruct:
output of printaddr
()
here (see
Section 37.3.1
)
Show full send queue in testselfdestruct
The
-d26.10
debugging switch causes the entire send queue to
be printed after the
testselfdestruct
above:
SENDQ:
output of printaddr
()
here (see
Section 37.3.1
)
--
The
-d27.1
(a.k.a.
-d27
) debugging switch causes
sendmail
to print
each step it takes when processing local addresses through aliasing.
First,
sendmail
prints the addresses being aliased:
alias(
addr
)
Here,
addr
is the address (usually a local username)
that is about to be aliased. Note that it
may already be the result of previous aliasing.
If the
addr
can be aliased, its transformation is printed as:
addr
(
host
,
user
) aliased to
newaddr
Here,
addr
is the address before aliasing,
and the
newaddr
is the new address that resulted
from successful aliasing.
The
host
and
user
are the hostname and username from
the recipient part of the envelope.
If the
addr
cannot be aliased, nothing is printed.
During initialization,
if the
aliases
database cannot be opened, the
-d27.1
debugging switch causes
sendmail
to print:
Can't open
aliasfile
Here,
aliasfile
is the full pathname of the
aliases
(5)
file, as declared by the
AliasFile
(
A
) option
(see
Section 34.8.1, AliasFile (A)
) or implied with
the service-switch file and the
ServiceSwitchFile
option
(see
Section 34.8.61
).
If the failure was due to a faulty map declaration,
sendmail
logs the following error:
setalias: unknown alias class
mapclass
If the map is not one that is allowed to provide alias services,
sendmail
logs this error:
setalias: map class
mapclass
can't handle aliases
If
sendmail
is trying to create a database file and it can't (usually
when it is run with the
-bi
command-line switch or run
as
newaliases
), the
-d27.1
debugging switch causes the following error to be printed:
Can't create database for
filename
:
reason here
A self-destructive alias can cause a dangerous loop to occur.
For example, the following two
aliases can lead to a loop on the host
mailhost
:
jake: Jake_Bair
Jake_Bair: jake@mailhost
The
-d27.1
debugging switch causes the following message to be printed when
sendmail
tests an address to see whether it loops:
self_reference(
addr
)
... no self ref
if it didn't loop
... cannot break loop for "
addr
"
if it's unbreakable
An alias loop is unbreakable if no local username can be found in the list
of aliases.
The
-d27.1
debugging
switch also causes
sendmail
to print the following message
when it is attempting to read the user's
~/.forward
file:
forward(
user
)
If the
user
has no home directory listed in the
passwd
(5)
file,
sendmail
issues
the following message with a
syslog
(3) level of LOG_CRIT:
forward: no home
The
-d27.1
debugging
switch also causes
sendmail
to print a warning if
it cannot open or lock an alias file for automatic rebuilding
(see
Section 34.8.4, AutoRebuildAliases (D)
, the
AutoRebuildAliases
(
D
) option):
Can't open
file
:
reason here
newaliases: cannot open
file
:
reason here
Here, the error might be caused by the file simply not existing (as would
be the case if it was NSF-mounted on a down host) or an I/O error
(as would be the case for a bad disk).
warning: cannot lock
file
:
reason here
Failure to lock can be caused by system errors or by the
file being read-only. Note that maintaining an aliases file
under revision control can cause a read-only copy to exist, resulting
in the following error:
Can't create database for
file
:
reason here
Cannot create database for alias file
file
This error indicates that the output file (the
dbm
(3) or
db
(3) file) could not be created or written.
Include file, self reference, error on home
(useful)
The
-d27.2
debugging switch causes each
:include:
and
.forward
filename to be printed before each
is opened for reading:
include(
file
)
The
-d27.2
debugging switch also causes additional information to be
printed for the alias loop check described above:
self_reference(
addr
)
... getpwnam(
user
)...found
if in passwd file
... getpwnam(
user
)...failed
otherwise
The
-d27.2
debugging switch also causes
sendmail
to print a message
every time it sleeps while waiting for the
aliases
database to be rebuilt:
aliaswait: sleeping for
sec
seconds
Also, when processing the
~/.forward
file,
sendmail
may experience
a temporary inability to read it (such as when an NFS server is down). In that
case the
-d27.2
debugging switch causes the following message to
be printed:
forward: transient error on
home
Here the message will be queued and tried again later.
Forwarding path and alias wait
(useful)
The
-d27.3
debugging
switch causes each path for a possible
.forward
file to be
printed before it is tried:
forward: trying
file
Here,
file
is each file in the path of files declared by
the
ForwardPath
(
J
) option (see
Section 34.8.27, ForwardPath (J)
).
The
-d27.3
debugging switch also causes
sendmail
to trace its
wait for another alias rebuild to complete
(see
Section 24.5.1, "Rebuild the Alias Database"
). First
sendmail
prints the class (such as
hash
) and filename for which it will wait:
aliaswait(
class
:
file
)
If the database is not rebuildable (as would be the case with a network
map class like
nis
,
nis+
, or
hesiod
), the
-d27.3
debugging switch
causes the following to be printed:
aliaswait: not rebuildable
If the
file
specified doesn't exist, the
-d27.3
debugging switch
prints
aliaswait: no source file
The
-d27.3
debugging switch also causes
sendmail
to print
an error message if there was a read error while processing a
:include:
or
.forward
file:
include: read error:
reason here
A
~/.forward
file must be owned by the user or by
root
.
If it is not, it is considered unsafe, and
sendmail
ignores it. The
-d27.4
debugging switch causes
sendmail
to print a message describing any such file it finds unsafe:
include: not safe (uid=
uid
)
Note that a file is considered unsafe if, among other things,
it lacks all read permissions.
The
-d27.4
debugging switch also causes
sendmail
to print
information about a
:include:
file beyond that printed
with
-d27.2
above:
include(
file
)
printed with -d27.2
ruid=
ruid
euid=
euid
printed with -d27.4
This shows the real userID (
ruid
) and effective userID
(
euid
) of the current running
sendmail
.
The
-d27.4
debugging switch also causes
sendmail
to print
an error if a
:include:
or
~/.forward
file cannot be opened for reading:
include: open:
reason here
Trace aliasing with printaddr()
The
-d27.5
debugging switch tells
sendmail
to print
several addresses with
printaddr
() (see
Section 37.3.1
)
as each one is handled.
When an address is aliased to another, the original needs to be
marked as one that shouldn't be delivered. The
QDONTSEND
below means just that:
alias: QDONTSEND
output of printaddr
()
here (see
Section 37.3.1
)
If there was a self-reference, the retained address is printed like this:
sendtolist: QSELFREF
output of printaddr
()
here (see
Section 37.3.1
)
If the original (before the test for a self-reference) is not the
same as the retained address, the original must be marked for nondelivery:
sendtolist: QDONTSEND
output of printaddr
()
here (see
Section 37.3.1
)
If an address resulted from a
:include:
or
~/.forward
file, it will have
a controlling user associated with it. That controlling user's address
needs to be marked for nondelivery:
include: QDONTSEND
output of printaddr
()
here (see
Section 37.3.1
)
Show setting up an alias map
The
-d27.8
debugging switch tells
sendmail
to print
the string passed to its internal
setalias
() routine.
setalias(
what
)
Here,
what
is one of the items listed with the
AliasFile
(
A
) option (see
Section 34.8.1
),
such as
/etc/aliases
,
or implied with
the service-switch file and the
ServiceSwitchFile
option
(see
Section 34.8.61
).
Show uid/gid changes with :include: reads
(useful)
The
-d27.9
debugging switch causes
sendmail
to trace
the setting and resetting of its
uid
and
gid
identities
when processing
:include:
and
~/.forward
files. First an additional line
is printed below the output of the
-d27.2
and
-d27.4
debugging switches:
include(
file
)
printed with -d27.2
ruid=
ruid
euid=
euid
printed with -d27.4
include: old uid =
ruid
/
euid
The second and third lines above both contain the same information. After the
new line is printed,
sendmail
may or may not change its identity depending on the
nature of a
:include:
or
~/.forward
file and that file's controlling user.
Whether it changed or not,
sendmail
prints:
include: new uid =
ruid
/
euid
After
sendmail
has finished processing a
:include:
or
~/.forward
file,
it resets its
uid
and
gid
back to their original values
and displays the result:
include: reset uid =
ruid
/
euid
Show controlling user that caused change in identity
The
-d27.14
debugging switch causes
sendmail
to print
the controlling user's address that led to the changing of the
uid
and
gid
or the currently running process:
include(
file
)
printed with -d27.2
ruid=
ruid
euid=
euid
printed with -d27.4
ctladdr
addr
output of printaddr
()
produced with this -d27.14
include: old uid =
ruid
/
euid
printed with -d27.9
The output of the
printaddr
() routine is described
in
Section 37.3.1
.
Show how alias will be looked up in a map
The
-d27.20
debugging switch causes
sendmail
to show
how it is about to look up an alias in one of its database maps:
setalias(
what
)
printed with -d27.8
map
class
:
map
what
Here,
class
is the type of map being looked up, such
as
hash
or
implicit
(see
Section 33.3, "The K Configuration Command"
).
The
map
is the map name, such as
Alias0
.
The
what
is one of the items listed with the
AliasFile
(
A
) option (see
Section 34.8.1
),
such as
/etc/aliases
, or implied with
the service-switch file and the
ServiceSwitchFile
option
(see
Section 34.8.61
).
Trace user database transactions
(useful)
The
sendmail
program can be compiled to use the user database (see
Section 33.5, "The User Database"
) by defining USERDB in the
Makefile
(see
Section 18.8.54, USERDB
).
If an address is selected
by rule set 0 for delivery by a delivery agent with the
F=l
flag
set, and if it remains unaliased even if the
F=A
flag is set,
it is looked up in the user database.
The
-d28.1
(a.k.a.
-d28
) debugging switch is used to watch the interaction
between
sendmail
and the user database:
udbexpand(
addr
)
Here,
addr
is the address being looked up.
The sender is looked up in a similar fashion. The intent in this case is
to correct information such as the return address:
udbmatch(
login
,
what
)
Here,
login
is the login name of the sender and
what
is the
mailname
for sender lookups.
If the lookup is via
hesiod
,
sendmail
will print the same
information like this:
hes_udb_get(
login
,
what
)
If the sender
is found in the database,
sendmail
prints:
udbmatch ==>
login
@
defaulthost
Here,
login
may be a new login name. The
defaulthost
is
either the sitewide host for all reply mail as defined in the user database
or the default destination host for a particular user.
In the event that a
db
(3) style user database fails to open,
the
-d28.1
debugging switch displays the following error message:
dbopen(
database
):
reason for failure here
The
-d28.2
debugging switch causes
sendmail
to
print any failures in lookups:
udbmatch: no match on
login
(
length
) via
method
This shows that the name
login
was looked up with a particular length, using
the database
method
, where
method
is either
db
or
hesiod
.
The
-d28.4
debugging switch causes
sendmail
to print
the result of its attempt to open (initialize) each database. There are three
possible results:
-
If a file on the local machine contains the information sought,
sendmail
prints
FETCH: file
fname
Here,
fname
is the name of the local file.
-
If a mail message should be sent to another host for delivery,
sendmail
prints:
FORWARD: host
hostname
Here,
hostname
is the full canonical name of the host that
takes delivery.
-
An unknown result causes the address to remain
unchanged and the following message to be printed:
UNKNOWN
If
sendmail
is compiled with HES_GETMAILHOST defined
(see
Section 18.8.11, HES-GETMAILHOST
),
the following is printed when the
-d28.8
debugging
switch is used:
udbmatch: no match on
login
(
length
)
from -d28.2
... trying hes_getmailhost (
login
)
udbexpand: hesiod-getmail
login
stat
err
Here,
hes_getmailhost
() is called to retrieve the name of the
post office that handles this
login
. If that call fails,
the last line is printed, showing that the
hesiod
error
err
occurred.
MX records for forward host
If a lookup is for a forwarding host (FORWARD above) and the
forwarding host has MX records, the
-d28.16
debugging switch
causes those records to be printed:
getmxrr(
host
):
number
first MX record here
second MX record here
etc.
Here,
host
is the name of the host to which the lookup
is forwarded. The
number
is the number of MX records
found. That line is then followed by
number
MX records for
that host.
The internal
udb_map_lookup
() routine is called each time
anything is looked up in the udb database. Upon entry into
that routine, the
-d28.20
debugging switch causes
sendmail
to
print
udb_map_lookup(
name
,
what
)
Here, the
what
is key about to be looked up in the map named
name
.
This routine in turn calls
udbmatch
().
Note that the
-d38.20
debugging switch also produces this output.
The
-d28.80
debugging switch causes
sendmail
to show
what it is about to lookup.
udbexpand: trying
login
(
length
) via
method
This shows that the name
login
was looked up with a particular
length
, using
the database
method
, where
method
is either
db
or
hesiod
.
The
-d28.80
debugging switch also causes the result of a lookup to be displayed:
udbexpand: match
login
:
result
Here,
login
was found, and the lookup returned
result
.
The
-d28.80
debugging switch also causes the result of
hes_udb_get
()
to be displayed:
hes_udb_get(
login
,
what
)
printed with -d28.1
hes_udb_get =>
result
printed with -d28.80
Here, the hesiod library routine
hes_resolve
(3) is called with the two
arguments
login
and
what
. The
result
(a string) is printed
on the second line.
Special rewrite of local recipient
With a level 2 or greater configuration file (see the
V
configuration command in
Section 27.5, "The V Configuration Command"
), V8
sendmail
passes
the user part (
$u
) of local recipient addresses through rule set 5
as a hook to select a new delivery agent. Rule set 5 is called
if the address is unchanged after all aliasing (including the
~/.forward
file).
The
-d29.1
(a.k.a.
-d29
) debugging switch causes the address to be printed
as it appears before the rule set 5 rewrite:
maplocaluser:
output of printaddr
()
here (see
Section 37.3.1
)
Information about the address is printed
with the
printaddr
() routine.
The output of
maplocaluser
() becomes the input to
recipient
(),
so the result of rewriting can be seen by using the
-d26.1
debugging switch in combination with this one.
Note that the particulars about whether or not an address will
be processed by rule set 5 are described in
-d29.5
below.
Trace fuzzy matching
(useful)
Fuzzy matching is the attempt to match a local recipient name to
one of the names in the
gecos
field of the
passwd
(5)
file (or NIS map).
The
-d29.4
debugging switch causes the process of fuzzy
matching to be traced:
finduser(
name
)
Here,
name
is an address in the form of a local user address,
without the host part. The
name
is first looked up in the
passwd
(5) file on the assumption that it is a login name.
If it is found,
sendmail
prints
found (non-fuzzy)
If
sendmail
was compiled with
hesiod
support, all numeric login names
will not work properly, resulting in the following:
failed (numeric input)
If the name is looked up and not found,
the entire
passwd
(5) is searched, to see
whether
name
appears in any of the
gecos
fields. This
search is done only if MATCHGECOS (see
Section 18.8.18, MATCHGECOS
)
was defined when
sendmail
was compiled and if the
MatchGECOS
(
G
) option
(see
Section 34.8.34, MatchGECOS (G)
)
is true.
If MATCHGECOS was undefined, the search ends and the not-found
name
causes the mail to bounce. If the
MatchGecos
(
G
) option
is false,
sendmail
bounces the message and prints the following:
not found (fuzzy disabled)
If the
MatchGecos
(
G
) option is true,
the
gecos
fields are searched.
But before the search starts, any underscore characters (and the character
defined by the BlankSub (
B
) option; see
Section 34.8.5, BlankSub (B)
)
that appear in
name
are converted
to spaces. Then, in turn, each
gecos
field has
the full name extracted (everything following the first comma, semicolon,
or percent is truncated off, including that character),
and any
&
characters found are converted to the login name.
The two are then compared in a case-insensitive fashion. If they
are identical,
sendmail
prints:
fuzzy matches
gecos
If all
gecos
fields are compared and no match is found,
sendmail
bounces the message and prints the following:
no fuzzy match found
There is no debugging flag to watch each comparison.
The
-d29.5
debugging switch causes
sendmail
to print
an address just before it is tested to see whether rule set 5 should be
called:
recipient: testing local? cl=
level
, rr5=
addr
,
output of printaddr
()
here (see
Section 37.3.1
)
For the address to be rewritten, the configuration file version as displayed by
level
must be 2 or more, the address in memory for rule set
5 (shown with
rr5
) must be nonzero, the
flags
in
addr
must not contain QNOTREMOTE,
QDONTSEND, QQUEUEUP, or QVERIFIED,
and the delivery agent for the address must have the
F=5
flag set.
The
-d29.5
debugging switch also causes
sendmail
to display
the following if the address is rewritten by rule set 5:
maplocaluser: QDONTSEND
output of printaddr
()
here (see
Section 37.3.1
)
Here the
printaddr
() routine
prints the old address that is being canceled.
Show over-aliasing fuzzy fallback
If a fuzzy match causes
more than three transformations to occur during aliasing,
sendmail
emits the
following error:
aliasing/forwarding loop for
login
broken
Here,
login
is the login name of the recipient that started
the suspected runaway aliasing.
The
-d29.5
debugging switch also causes
sendmail
to print
that it is trying to fall back to the original login name
for delivery:
at trylocaluser
login
Note that this message is printed before the message printed by the
-d26
switch (which shows the testing for a self-destructive addresses).
Trace processing of header
When
sendmail
reads a mail message, it first collects (reads) the header
portions of that message (everything up to the first blank line) and
places the result into a temporary file in the queue directory.
While it is processing the header, if the
SaveFromLine
(
f
)
option (see
Section 34.8.59, SaveFromLine (f)
),
is false, the UNIX-style "
From
" header is removed, and
the important information in it is saved for later use.
The
-d30.1
(a.k.a.
-d30
) debugging switch causes
sendmail
to
print the following succinct message when it finds the end of
the header portion of a mail message:
EOH
If end-of-headers was caused by a read error or a broken connection,
sendmail
prints:
collect: premature EOM:
reason for failure here
If end-of-headers was caused by a
Message:
or
Text:
header, then the rest of the header portion of the message is
ignored.
The
-d30.2
debugging switch first causes
sendmail
to
print its entry into
collect
():
collect
Then, when
sendmail
strips (eats) the UNIX-style,
five-character "
From
" header
from a mail message, it tries to extract (and save) the date from the header.
The
-d30.2
debugging switch causes
sendmail
to print
the
field
portion of the header as it appears before
the date is extracted:
eatfrom(
field
)
The
eatfrom
() routine will vanish if NOTUNIX
(see
Section 18.8.32, NOTUNIX
)
is defined when compiling
sendmail
.
Show a to-less header being added
If the header of a mail message lacks recipient information (lacks
all of the
To:
,
Cc:
,
Bcc
:, and
Apparently-To:
header lines),
then
sendmail
adds a header as defined
by the
NoRecipientAction
option (see
Section 34.8.43, NoRecipientAction
).
The
-d30.3
debugging switch causes
sendmail
to
print which
header
it is adding:
Adding
header
:
recipient
Here,
header
is the text of the header being saved, and
recipient
is the address of the recipient as taken from
the envelope of the message.
The process of collecting the message header and body over an SMTP
connection is driven by a state engine inside
sendmail
. The
-d30.35
debugging switch causes
sendmail
to display
each state just before it is processed:
top, istate=
is
, mstate=
ms
Here,
is
is the current input state as described in
Table 37.11
and
ms
is the current message state as described in
Table 37.12
.
Table 37.11: collect() Input States
istate |
Name |
Description |
0 |
IS_NORM |
Currently in middle of a line |
1 |
IS_BOL |
Currently at beginning of a line |
2 |
IS_DOT |
Just read a dot at beginning of line |
3 |
IS_DOTCR |
Just read ".\r" at beginning of line |
4 |
IS_CR |
Just read a carriage return |
Table 37.12: collect() Message States
mstate |
Name |
Description |
0 |
MS_UFROM |
Currently reading UNIX from line |
1 |
MS_HEADER |
Currently reading message header |
2 |
MS_BODY |
Currently reading message body |
The
-d30.35
debugging switch also causes the same information
to be printed every time
sendmail
goes to a new state:
nextstate, istate=
is
, mstate=
ms
, line = "
header
"
Here, the extra information is the current text of the header being
processed.
The
-d30.94
debugging switch causes
sendmail
to print
the input state (see
Table 37.11
)
for each character being processed:
istate=
is
, c=
char
(
hex
)
Each character is printed both as the character it is (
char
) and
how it is represented in hexadecimal (
hex
).
Trace processing of headers
(useful)
Header lines (see
Section 35.1, "The H Configuration Command"
)
from the configuration file and from mail messages
are processed by the
chompheader
() routine before they
are included in any mail message.
That routine parses each header line to save critical information,
to check for validity, and to replace default values with new
values.
The
-d31.2
debugging switch
[6]
shows that
sendmail
is
about to check whether it should replace a
From:
or
Resent-From:
header with
the one defined by the
H
configuration command.
If the configuration file is not being read and if
sendmail
is
not processing the queue, the following test is made:
comparing header from (
header
) against default (
addr
or
name)
The value of the
From:
or
Resent-From:
header
is compared to the sender's address (
addr
)
and to the sender's
name
. If it is that same as either one,
the address is replaced.
The
-d31.6
debugging switch shows each header as it
appears when it enters the
chompheader
() routine:
chompheader:
line
Here,
line
is the exact text of the original header before
processing.
Unfortunately, there is no debugging
switch that allows the result of this processing to be viewed.
To determine how it should handle a header,
sendmail
compares
each header to its list of headers in
sendmail.h
.
The
-d31.6
debugging switch also shows the result after the
comparisons have been done:
no header match
header match, hi_flags=
flags in hexadecimal here
The flags and their hexadecimal equivalence are shown
in
Table 35.2
in
Section 35.5, "Header Behavior in conf.c"
.
The
-d32.1
(a.k.a.
-d31
) debugging switch causes
sendmail
to print
the header lines that it collected from a received mail message:
--- collected header ---
header lines here
--------------
Each header line is printed with the header name on the left, a colon,
and the value for that header on the right.
If there is no value,
sendmail
prints <NULL>.
If the H_DEFAULT flag is set for any header (see
Section 35.5.3, "H_DEFAULT"
),
the value for the header is printed inside parentheses with macros
unexpanded, just before it is printed in expanded form. For example,
Full-Name: ($x) Your Full Name
Show ARPA mode with setsender
The
-d32.2
debugging switch works only if the mode
set with the
-b
command-line switch is in ARPA (
-ba
) mode
(see
Section 36.7.3, -ba
).
It shows the sender address being extracted from the header
with
setsender
():
eatheader: setsender(*
value
==
realvalue
)
The
setsender
() routine can be further traced with the
-d45.1
debugging switch.
The
crackaddr
() routine's job is to find an email address
amidst other nonaddress text, then to save that nonaddress part:
gw@wash.dc.gov (George Washington)
crackaddr
()
$g (George Washington)
The
-d33.1
(a.k.a.
33
) debugging switch causes
sendmail
to
print the potential address prior to cracking and, after that,
the address that it found:
crackaddr(
potential
)
crackaddr=>`
addr
'
The legal ways that addresses can be placed within
other text is described in
Section 35.3, "Header Field Contents"
.
See also the
/parse
rule-testing command (
Section 38.5.5, "Parse an Address with /parse"
)
to put
crackaddr
() in context.
Watch header assembly for output
The
sendmail
program uses
putheader
()
to create headers that didn't exist before.
The
-d34.1
(a.k.a.
-d34
) debugging switch causes
sendmail
to
print the following on entry to that routine:
-- putheader, mailer =
agent
--
Here,
agent
is the symbolic name of the
delivery agent that will deliver the bounced message.
Trace header generation and skipping
(useful)
Each header line created is displayed with
two leading spaces. For example,
-- putheader, mailer = *file* --
Return-Path: you
Then certain headers are excluded from the bounced mail message
header. Those with the H_CTE flag set
(see
Section 35.5.12, "H_CTE"
)
and either the MCIF_CVT8TO7 or MCIF_INMIME
mci
flags set
(see
Table 37.17
)
will have the text:
(skipped (content-transfer-encoding))
appended and that header skipped (excluded).
Any header that has both H_CHECK and H_ACHECK flags
set and doesn't have identical delivery agent flags set for itself and its cached connection information will also be skipped:
(skipped)
All resent headers (those marked with H_RESENT) are also skipped:
(skipped (resent))
Return-receipt headers are also skipped:
(skipped (receipt))
If a
Bcc:
header (see
Section 35.10.4, Bcc:
) is being skipped, this
is printed:
(skipped - bcc)
Finally, valueless headers are also skipped with this message:
(skipped - null value)
Any headers that survive this skipping process are included in the
eventually delivered bounced message. Note that MIME headers
are not generated or displayed here (see -d43).
Macro values defined
(useful)
The
-d35.9
debugging switch
[7]
causes
sendmail
to print each macro as it is defined. The output looks like this:
define(
name
as "
value
")
Here, the
name
is the macro's name, and the
value
is the value (text) assigned to the macro.
If the macro already has a value assigned to it,
sendmail
prints:
redefine(
name
as "
value
")
With the introduction of multicharacter macro names, it is now
necessary for
sendmail
to convert each macro name from text
form into
sendmail
's internal form. Single-character macro
names are represented by themselves. Multicharacter names are
represented by values from 0240 (octal) upward.
The
-d35.14
debugging switch causes
sendmail
to
print each macro name as it is being looked up:
macid(
name
) =>
value
The
name
is the text immediately following a
$
character,
including any trailing junk in the line. For example, the following
miniconfigurations file:
V7
D{FOO}foo
R$H ${FOO} note no $H defined
produces this output (with only the
macid
lines shown):
macid({FOO}foo) => 0xa0
macid(H\t${FOO}\tnote no $H defined) => H
macid({FOO}\tnote no $H defined) => 0xa0
macid(H defined) => H
Macros that are included in text must be translated
into values (expanded) so that the values may be used. The
-d35.24
debugging switch tells
sendmail
to display such
text both before and after the macros in it have been expanded.
The "before" looks like this:
expand("
text
")
For example,
expand("$w.$D")
The
text
(here
$w.$D
)
may be any ASCII string. In it, special characters like
the newline character are printed in C language, backslash-escaped
notation (such as
\n
). Macros are printed with either
the
$
prefix (such as
$w
above with V8
sendmail
)
or some other prefix (IDA uses
^Aw.^AD
,
SunOS uses
/w./D
; others use the archaic
\001w.\001D
notation).
Expansion is performed only on defined macros (using the
$
prefix), on macro conditionals (in which one
of two values is used, depending on whether a macro has a value
or not, such as
$?x$x$|nobody$.
), and
and on the
$&
prefix (deferred expansion).
After the first (leftmost) macro or conditional is expanded in
text
,
sendmail
prints the transformed text as
follows:
expanded ==> "
text
"
For example,
expanded ==> "wash.$D"
If any unexpanded macros or conditionals remain in
text
, this
expanded
process is
recursively
repeated until everything that can be expanded
has been expanded.
This process of recursion allows macros to have
other macros as their values.
Trace processing by stab()
The symbol table is a block of memory that contains information
about all the symbolic names used by
sendmail
. Symbolic
names are delivery agent names (such as
local
),
aliases, database classes, hostnames, and macros.
Symbols are placed into the symbol table with the
stab
() routine.
That routine is also used to see whether a symbol has already been
inserted and, if so, to obtain its value.
The
-d36.5
debugging switch
[8]
causes
sendmail
to print
the following upon its entry into the
stab
() routine:
STAB:
name
type
Here,
name
is the symbolic name to be inserted or looked up.
The
type
is one of the values listed in
Table 37.13
.
Table 37.13: Types of Symbols Recognized by stab()
Type |
Mnemonic |
Description |
0 |
ST_UNDEF |
Undefined type |
1 |
ST_CLASS |
Class (from
C
and
F
configuration commands) |
2 |
ST_ADDRESS |
An address in parsed format |
3 |
ST_MAILER |
A delivery agent (from
M
configuration command) |
4 |
ST_ALIAS |
An alias, if no external database |
5 |
ST_MAPCLASS |
A database class (
K
command) |
6 |
ST_MAP |
Function that handles a class |
7 |
ST_HOSTSIG |
Host MX signature |
8 |
ST_NAMECANON |
Cached canonical name |
9 |
ST_MACRO |
Macro name to id value mapping |
10 |
ST_RULESET |
Ruleset name to number mapping |
11 |
ST_SERVICE |
Service switch file entry |
16 |
ST_MCI |
SMTP connection status\*[=a] |
This is the base (offset) of types 16 through 16+
n
, where
n
is 16 plus MAXMAILERS as defined in
conf.h
.
If
stab
() is being used to insert a symbol, the above output
is concluded with:
entered
If
stab
() is being used to look up a symbol, one of the
two following messages is printed:
not found
type
type
val
hex hex hex hex
If it is found, four hexadecimal values are printed, which
show the first four 4-byte words of the value.
A hashing algorithm is used to make the symbol table more efficient.
The
-d36.9
debugging switch is used to see the hash
value selected for any given symbol:
(hfunc=
hash
)
The number of possible hash-table buckets is limited by STABSIZE, as defined
in
stab.c
.
[9]
Trace function applied to all symbols
The
-d36.90
debugging switch causes the name and type of
each symbol to be printed as a common function is applied to each with
sendmail
's internal
stabapply
() function.
stabapply: trying
type
/
name
The
stabapply
() routine is used to initialize maps and
to print the members of a class.
Trace setting of options
(useful)
Options can be set on the command line or in the configuration file.
The
-d37.1
(a.k.a.
-d37
) debugging switch allows you to watch each option
being defined. As each is processed,
this message is first
printed, without a trailing newline:
setoption:
name
(
char
).
sub
=
val
Here,
name
is the option's multicharacter name,
char
is its single-character equivalent (or a hexadecimal
value if it is non-ASCII), and
sub
is the
subvalue for that option if there was one.
Finally,
val
is the value being given to that option.
If the option has already been set from the command line and
is thus prohibited from being set in the configuration file,
sendmail
prints:
(ignored)
A newline is then printed, and the job is done. If
defining the option is permitted,
sendmail
next checks to see whether
it is
safe
. If it is not,
sendmail
prints:
(unsafe)
If it is unsafe,
sendmail
checks to see whether it should
relinquish its
root
privilege. If so, it prints:
(Resetting uid)
A newline is then printed, and the option has been defined. Options
in general and safe versus unsafe are covered in
Chapter 34,
Options
.
Trace adding of words to a class
(useful)
The adding of words to a class (
C
or
F
configuration commands) can be traced with the
-d37.8
debugging switch. Each word is printed like this:
setclass(
name
,
text
)
The
text
is added to the class whose symbolic name is
name
. Class names can be single-character or multicharacter
(see
Section 32.1, "Class Configuration Commands"
).
Show map opens and failures
(useful)
Most maps are declared directly with the
K
configuration
command (see
Section 33.3
). Others are declared internally by
sendmail
,
such as the
host
and
alias
maps.
The
-d38.2
debugging switch
[10]
first shows maps being initialized:
map_init(
class
:
name
,
file
,
pass
)
Here,
class
is one of the internal classes allowed by
sendmail
,
such as
host
, and
dequote
(see
Section 33.3
, the
K
configuration command).
The
name
is either the name you gave to the map with the
K
configuration command or one assigned internally by
sendmail
(like
aliases.files
).
The
file
is either NULL or the name of the database file (such
as
/etc/aliases
).
And
pass
is a flag that tells
sendmail
whether or
not it should open the database, rebuild the database, or do neither.
Next the
-d38.2
debugging switch causes
sendmail
to show each map as it is about to be
opened. The output that is produced will look like one of the
following lines:
bt_map_open(
name
,
file
,
mode
)
hash_map_open(
name
,
file
,
mode
)
hes_map_open(
name
,
file
,
mode
)
impl_map_open(
name
,
file
,
mode
)
ldap_map_open(
name
,
mode
)
ndbm_map_open(
name
,
file
,
mode
)
ni_map_open(
name
,
file
,
mode
)
nis_map_open(
name
,
file
,
mode
)
nisplus_map_open(
name
,
file
,
mode
)
stab_map_open(
name
,
file
,
mode
)
switch_map_open(
name
,
file
,
mode
)
text_map_open(
name
,
file
,
mode
)
user_map_open(
name
,
mode
)
In all of the previous lines, the
mode
is a decimal representation
of the file permissions that are used during the open. The name prefixing
each line corresponds to the class of map. For example,
impl
corresponds to the
implicit
class.
The
-d38.2
debugging switch also causes
sendmail
to
display the
nis
domain that was used if one was specified for the
nisplus
class:
nisplus_map_open(
file
): using domain
ypdomain
The
-d38.2
debugging switch also allows other silent errors
to be printed about some open failures.
Under
nis+
, lookups are performed by named columns (as in the case of
the password database, the columns are named
passwd
,
shell
,
and so on):
nisplus_map_open(
name
): can not find key column
colname
nisplus_map_open(
name
): can not find column
colname
Text files that are used as maps must be declared with a filename that
is an absolute path (begins with a
/
character thus forming
a fully qualified pathname), that exists, and that is a regular file.
If there is a problem, one of the following
is logged (even if
-d38.2
is not specified):
text_map_open: file name required
text_map_open(
file
): file name must be fully qualified
text_map_open(
name
): can not stat
file
text_map_open(
name
):
file
is not a file
Text files should be syntactically correct. The delimiting character,
char
, will print either as a single character or as the phrase
(whitespace)
. Note that the third line below will be
reported only when the
-d38.2
debugging switch is used:
text_map_open(
file
): -k should specify a number, not
badtext
text_map_open(
file
): -v should specify a number, not
badtext
text_map_open(
file
): delimiter =
char
The
sendmail
program initializes maps in passes so that it
can open a map for reading or rebuild. That is, pass 0 opens it for
reading only, and passes 1 and 2 open it for updating.
This gives
sendmail
the opportunity to detect optional maps.
The
-d38.3
debugging switch causes
sendmail
to print
wrong pass
every time it skips rebuilding because the pass is inappropriate:
map_init(
class
:
name
,
file
,
pass
)
from -d38.2
wrong pass
The
-d38.3
debugging switch also causes
sendmail
to print
a failure message if an
implicit
class map does not exist:
impl_map_open(
name
,
file
,
mode
)
from -d38.2
no map file
Show result of map open
(useful)
When rebuilding the aliases files, each database is opened before it is
rebuilt or not. The
-d38.4
debugging switch shows the success or
failure of each open:
map_init(
class
:
name
,
file
,
pass
)
from -d38.2
class
:
name
file
valid
or
invalid
The status is
valid
if the open succeeded; otherwise, it is
invalid
.
The
-d38.4
debugging switch also shows each map being looked up
in a
switch
class map (see
Section 33.8.17, switch
).
switch_map_open(
name
,
file
,
mode
)
from -d38.2
map_stack[
index
] =
class
:
name
If the
name
is not one that was declared in a
K
configuration
command, the following error is printed:
Switch map
class
: unknown member map
name
Trace map closings and appends
The
-d38.9
debugging switch traces map closures for those kind
of maps that can be closed:
ndbm_map_close(
name
,
file
,
flags
)
db_map_close(
name
,
file
,
flags
)
impl_map_close(
name
,
file
,
flags
)
prog_map_lookup(
name
) failed (
errno
) - closing
seq_map_close(
name
)
Here, the
name
is either the name you gave to the map with the
K
configuration command or one assigned internally by
sendmail
(like
aliases.files
).
The
file
is the filename on disk
that contains the database.
The
flags
describe the specific features of a map. They are printed
in hexadecimal, and the meanings of the values printed are listed in
Table 37.14
.
Table 37.14: Flags Describing Properties of Database Maps
Hex |
Text |
Description |
00001
|
MF_VALID |
This entry is valid. |
00002
|
MF_INCLNULL |
Include null byte in key. |
00004
|
MF_OPTIONAL |
Don't complain if map not found. |
00008
|
MF_NOFOLDCASE |
Don't fold case in keys. |
00010
|
MF_MATCHONLY |
Don't use the map value. |
00020
|
MF_OPEN |
This entry is open. |
00040
|
MF_WRITABLE |
Open for writing. |
00080
|
MF_ALIAS |
This is an alias file. |
00100
|
MF_TRY0NULL |
Try with no null byte. |
00200
|
MF_TRY1NULL |
Try with the null byte. |
00400
|
MF_LOCKED |
This map is currently locked. |
00800
|
MF_ALIASWAIT |
Alias map in aliaswait state. |
01000
|
MF_IMPL_HASH |
Implicit: underlying hash database. |
02000
|
MF_IMPL_NDBM |
Implicit: underlying ndbm database. |
04000
|
MF_UNSAFEDB |
This map is world writable. |
08000
|
MF_APPEND |
Append new entry on rebuild. |
10000
|
MF_KEEPQUOTES |
Don't dequote key before lookup. |
In addition to tracing map closures, the
-d38.9
debugging switch
traces map appends allowed by the MF_APPEND flag
(see
Section 33.3.4.1, "-A append values for duplicate keys (V8.7 and above)"
) as specified
when the database is declared by the
K
configuration command:
ndbm_map_store append=
new
db_map_store append=
new
Here
new
is
new value appended to the old. Since this property is used for alias files, the
new and old values have a comma inserted between them.
The NIS alias map needs to contain a
@:@
entry to indicate
that it is fully updated and ready for reading. But
because HP-UX omits the
@:@
, it is useful only as
a check to see whether the NIS map exists. The
-d38.10
debugging switch
causes the result of this check to be printed as:
nis_map_open: yp_match(@,
domain
,
nismap
)
Here,
domain
is the NIS domain, and
nismap
is usually
mail.aliases
(but it can be redefined in your
configuration file; see
Section 34.8.1
).
If the map is not marked as optional
(see
Section 33.3.4.8, "-o the database file is optional (V8.1 and above)"
), the following error will be printed:
Cannot bind to map
nismap
in domain
domain
:
reason here
The
-d38.10
debugging switch also traces the NIS+ open's check for a valid
table.
nisplus_map_open:
nisplusmap.domain
is not a table
Essentially, this says that the NIS+ map
nisplusmap
(in the
domain shown) does not exist. The error is printed
even if the
-o
(optional) database switch (see
Section 33.3.4.8
) is missing.
The
-d38.12
debugging switch shows values being stored in maps
that support updates.
db_map_store(
name
,
key
,
value
)
ndbm_map_store(
name
,
key
,
value
)
seq_map_store(
name
,
key
,
value
)
Here, the
name
is either the name you gave to the map with the
K
configuration command or the
name
assigned internally by
sendmail
(like
aliases.files
).
The
key
is the key for which the new value is being stored,
and the
value
is the value for that key.
Trace switch map finds
(useful)
A switched map is one that, either as the result of a service-switch file or
because of
sendmail
's internal logic, causes lookups to follow
a select path. For example, Sun's Solaris 2
nsswitch.conf
might
specify that aliases be looked up in the order
files
, then
nis
:
switch_map_open(
name
,
file
,
mode
)
from -d38.2
switch_map_find =>
nmaps
maptype
...
First the number of maps found is printed with
nmaps
, then each
type of map found in the list is printed. Each is a class name, such as
files
, or
nis
.
Trace map lookups
(useful)
The -d38.20 debugging switch traces many different map lookups.
The
getcanonname
() routine looks up a hostname and tries
to canonify it:
getcanonname(
host
), trying
maptype
getcanonname(
host
), found
getcanonname(
host
), failed, stat=
error
Here,
host
is the hostname that is being looked up, and
maptype
is one of
files
,
nis
,
nisplus
,
dns
, or
netinfo
.
If the canonical name is not found, the
error
shows one of the
errors listed in
<sysexits.h>
.
The process of canonifying the name is handled by calling special
subroutines based on the
maptype
:
text_getcanonname(
host
)
maptype is files
nis_getcanonname(
host
)
maptype is nis
nisplus_getcanoname(
host
), qbuf=
query
maptype is nisplus
dns_getcanonname(
host
,
flag
)
maptype is dns, printed with -d8.2
ni_getcanonname(
host
)
maptype is netinfo
The
nisplus_getcanoname
() routine is far more verbose than the other. In
addition to the information printed above, the
-d38.20
switch also prints
nisplus_getcanoname(
host
), got
count
entries, all but first ignored
nisplus_getcanoname(
host
), found in directory "
nisdir
"
nisplus_getcanonname(
host
), found
result
nisplus_getcanonname(
host
), failed, status=
nsistatus
, nsw_stat=
errno
The -d38.20 debugging switch also traces general lookups in various
kinds of databases. Again note that
nisplus
is more verbose
than the others:
ndbm_map_lookup(
name
,
key
)
db_map_lookup(
name
,
key
)
nis_map_lookup(
name
,
key
)
nisplus_map_lookup(
name
,
key
)
qbuf=
query
nisplus_map_lookup(
key
), got
count
entries, additional entries ignored
nisplus_map_lookup(
key
), found
value
nisplus_map_lookup(
key
), failed
hes_map_lookup(
name
,
key
)
ni_map_lookup(
name
,
key
)
stab_lookup(
name
,
key
)
impl_map_lookup(
name
,
key
)
user_map_lookup(
name
,
key
)
prog_map_lookup(
name
,
key
)
prog_map_lookup(
name
): empty answer
seq_map_lookup(
name
,
key
)
Here, the
name
is either the name you gave to the map with the
K
configuration command or one assigned internally by
sendmail
(such as
aliases.files
). The
key
is the item being
looked up. The
file
is the pathname of the file that contains the database.
Show nis-getcanonname() record
The
-d38.20
debugging switch described above prints the
nis
lookup of the canonical
hostname. This
-d38.44
debugging switch prints the result of that lookup:
nis_getcanonname(
host
)
from -d38.20
got record `
result
\'
Display %digit database mapping
When the RHS of a rule matches an entry in a database map with
$(
and
$)
, that entry replaces the key. If the entry contains
%
digit
literals, they are replaced by corresponding
$@
values in the RHS (see
Section 33.4.2, "Specify Numbered Substitution with $@"
).
The
-d39.1
(a.k.a.
-d39
) debugging switch causes
sendmail
to print
the entry and any replacement values:
map_rewrite(
entry
), av =
value1
value2
...
etc
After the RHS is rewritten (after all the
$@
values have
replaced all the
%
digit
literals),
sendmail
prints the result:
map_rewrite =>
rewritten RHS here
Trace processing of the queue
The
-d40.1
(a.k.a.
-d40
) debugging switch traces the placing
of a mail message into the queue and the processing of
queued files.
When a mail message is placed into the queue, its
qf
file is written as a
tf
temporary file; then that temporary
file is closed and renamed to be the
qf
file. The
-d40.1
debugging switch causes
sendmail
to announce
that it is beginning that process by printing the queued message's
identifier:
>>>>> queueing
qid
(new id) >>>>>
queueing
for each recipient, output of printaddr
()
here (see
Section 37.3.1
)
<<<<< done queueing
qid
<<<<<
First, the queue identifier is printed (
qid
). If this
identifier is brand-new, the phrase "
(new id)
" is printed.
Next,
sendmail
prints complete information about each recipient
for the message using the
printaddr
() routine.
Finally,
done queueing
is printed, and the queuing
of the
qid
item is finished.
When
sendmail
processes files in the queue, it first prereads
all the
qf
files and sorts the jobs by priority.
After the list has been sorted, the
-d40.1
debugging
switch causes
sendmail
to print that list, one
message per line, in the following format:
qfname
: pri=
priority
Here,
qfname
is the basename of the
qf
file, and
priority
is the current priority of each message
(see
Section 34.8.53, RecipientFactor (y)
).
After the sorted list of messages has been processed, and if there
are any messages in that list,
sendmail
attempts to
deliver each of the messages in the order in which
it appears in the list.
The
-d40.1
debugging switch causes
sendmail
to print the following line of information
for each message processed:
dowork: (
qfname
)
The
-d40.3
debugging switch causes the envelope flags for
each message to be printed as it is queued:
>>>>> queueing
qid
(new id) >>>>>
from -d40.1
e_flags=
output of printenvflags
()
here
The envelope flags are
described in
Table 37.3
in
Section 37.5.12
.
Show qf file lines as they are read
The
qf
file is composed of individual lines of information
(see
Section 23.9.11, P line
).
The
-d40.4
debugging switch causes
sendmail
to print each of those lines as it is read:
+++++
X
text
Each line begins with five plus characters. The
qf
file's
key
letter (here,
X
) follows, then the rest of the
text
that made up that line. In the
qf
file, indented lines
(lines that begin with a space or tab character) that immediately
follow the key line are appended to that key line.
Those joined lines are printed after they are joined.
Note that the lines of the
qf
file are printed before they are processed
by
sendmail
. An error in a line is printed after
the line is printed.
If the queue file could not be read,
the
-d40.4
debugging switch instead causes
sendmail
to print this error:
readqf(
qid
) failed
Here,
qid
is the queue identifier for the message.
Note that reading can legitimately fail if the queue file is locked.
Use
-d40.8
(described below) to see the exact reason for
failure.
The
-d40.8
debugging switch causes
sendmail
to print
the reason it could not process a message's
qf
file.
One possibility is:
readqf(
qfname
): fopen failure (
error text here
)
If the failure was caused by anything other than the file's nonexistence,
the following is also logged:
readqf: no control file
qfname
If the
qf
file could not be read
because it is locked by another incantation of
sendmail
(a valid reason),
the
-d40.8
debugging switch prints:
qid
: locked
Here,
qid
is the identifier portion of the
qf
file.
If the log level is set to greater than 19
(see the
LogLevel
(
L
) option,
Section 34.8.33, LogLevel (L)
),
the above message will also be logged.
For security the
sendmail
program
fstat
(2)'s the
qf
file after it is open to make sure it cannot be fooled by a
race condition. If that
fstat
(2) fails, the following is
printed if the
-d40.8
debugging switch was specified:
readqf(
qid
): fstat failure (
error text here
)
If the
qf
file is owned by someone other than the effective
uid
of
sendmail
, the
qf
file will be renamed into
a
Qf
file (see
Section 23.3, "A Bogus qf File (V8 only): Qf"
).
If this
-d40.8
debugging switch was specified,
the following message will also be printed:
readqf(
qid
): bogus file
The
MinQueueAge
option (see
Section 34.8.41, MinQueueAge
) determines the interval
between queue runs for any given file. If a
qf
file was not
last run at least
MinQueueAge
minutes ago, it is skipped
and the
-d40.8
debugging switch causes the following message
to be printed:
qid
: too young (
howlong
)
If the log level is set to greater than 19
(see the
LogLevel
(
L
) option,
Section 34.8.33
),
the above message will also be logged.
Show qf and lock file descriptors
After
sendmail
has opened the
qf
file (with
-d40.1
)
and printed the envelope flags (with
-d40.3
), this
-d40.9
debugging switch will cause the file descriptors for the
qf
file
and its corresponding lock file to be dumped:
>>>>> queueing
qid
(new id) >>>>>
from -d40.1
e_flags=
from -d40.3
tfp=
output of dumpfd
()
here
lockfp=
output of dumpfd
()
here
The
e_flags
are
described in
Table 37.3
of
Section 37.5.12
.
Here,
tfp=
shows the file descriptors for the
qf
file,
and
lockfp=
shows the descriptors for the lock. See
-d2.9
(
Section 37.5.13
) for a description of
output of dumpfd().
Trace queue ordering
(useful)
The
-d41
(a.k.a.
-d41
)
debugging switch causes
sendmail
to print its ordering
of the queue. First it prints
orderq:
QueueLimitId =
qid
if
-qI
used
QueueLimitSender =
sid
if
-qS
used
QueueLimitRecipient =
rid
if
-qR
used
See
Section 23.6.2.3, "Process by identifier/recipient/sender: -q[ISR]"
for an explanation of how the
-qI
,
-qS
, and
-qR
command-line switches can limit the scope of a queue run. If none of them were
specified, only
orderq:
is printed.
The
-d41.1
debugging switch is extremely handy for previewing the
effect of the
-qI
,
-qS
, and
-qR
command-line switches. When
combined with
-bp
(
mailq
), these switches limit
the queue listing
and thus preview the effect of a limited queue run:
%
mailq
Mail Queue (1 request)
-Q-ID- -Size- ---Q-Time--- ------Sender/Recipient------
MAA11111 4560 Tue Dec 31 12:37 you
you@here.us.edu
%
mailq -d41.1 -qI22222
orderq:
QueueLimitId = 22222
Mail queue is empty
The
-d41.1
debugging switch also traces the growth of the queue working
list. Every time the limit of that list is reached, the internal
routine
grow_wlist
() is called to extend the list size
by QUEUESEGSIZE (where QUEUESEGSIZE is
described in
Section 18.8.38, QUEUESEGSIZE
).
grow_wlist: WorkListSize=
current
grow_wlist: WorkListSize now
newsize
If the log level is set to greater than 1
(see the
LogLevel
(
L
) option,
Section 34.8.33
),
the following is also logged each time the list size grows:
grew WorkList for
qdirectory
to
newsize
If the size could not be increased (because the program reached
the limit of available memory) and if the
LogLevel
(
L
) option
is greater than 0,
sendmail
will log this error at LOG_ALERT:
FAILED to grow WorkList for
qdirectory
to
newsize
This message will repeat until there are no more queue entries
to process after the limit is received. However, all the files that are
already in the work list will be processed, so presumably the next
run will catch the failed messages.
Ordinarily,
sendmail
is silent about failures to open a
qf
file, but the
-d41.2
debugging
switch causes it to print the reason the open failed:
orderq: cannot open
qfname
(
reason for failure here
)
Here,
qfname
is the name of the
qf
file that could
not be opened.
Show excluded (skipped) queue files
The
41.49
debugging switch
causes
sendmail
to display the queue files that were not
included in the work list:
skipping
qfname
(
bit
)
Here, the
bit
is a hexadecimal representation of the
requirement that was not met. These bits are listed in
Table 37.15
.
Note that nothing will be printed if the message was skipped
because its identifier did not match the
-qI
specification.
Show every file in the queue
The
sendmail
program scans the queue directory looking for
all the
qf
files to set up its working list. If a file
doesn't start with the letters "qf," it is ordinarily silently
skipped. The
-d41.50
debugging switch causes
sendmail
to display every single file it finds in its queue directory:
orderq: checking
file
The
file
can be a directory, such as
..
, or a regular
file, such as a
df
or
qf
file.
V8
sendmail
can be configured with the
ConnectionCacheSize
(
k
) option
(see
Section 34.8.10, ConnectionCacheSize (k)
)
to maintain open SMTP connections to a few other hosts.
Before making a new SMTP connection,
sendmail
checks to see if it already has one established.
The
-d42.2
[11]
debugging switch causes
sendmail
to print the result of that check.
mci_get(
host
mailer
): mci_state=
state
, _flags=
flag
, _exitstat=
stat
, _errno=
err
Here, the
host
is the name of the host to which the connection is to
be made, and the
mailer
is the symbolic name of the delivery agent.
The
state
is the status of the current SMTP connection (if there
is one) as shown in
Table 37.16
.
Table 37.16: mci_get() Connection States
State |
Mnemonic |
Description |
0 |
MCIS_CLOSED |
No traffic on this connection |
1 |
MCIS_OPENING |
Sending initial protocol |
2 |
MCIS_OPEN |
Connection is open |
3 |
MCIS_ACTIVE |
Message being sent |
4 |
MCIS_QUITING |
Running SMTP quit protocol |
5 |
MCIS_SSD |
SMTP service shutting down |
6 |
MCIS_ERROR |
I/O error on connection |
The
flag
describes the overall status of the connection. It can
have one or more values from those shown in
Table 37.17
where those values are OR'd together.
Table 37.17: mci_get() Status Flags
Flag |
Mnemonic |
Description |
0x0001 |
MCIF_VALID |
If set, this entry is valid |
0x0002 |
MCIF_TEMP |
If set, don't cache this connection |
0x0004 |
MCIF_CACHED |
If set, connection is currently in open cache |
0x0008 |
MCIF_ESMTP |
This host speaks ESMTP |
0x0010 |
MCIF_EXPN |
EXPN command supported |
0x0020 |
MCIF_SIZE |
SIZE option supported |
0x0040 |
MCIF_8BITMIME |
BODY=8BITMIME supported |
0x0080 |
MCIF_7BIT |
Strip this message to 7 bits |
0x0100 |
MCIF_MULTSTAT |
MAIL11V3, handles MULT status |
0x0200 |
MCIF_INHEADER |
Currently outputting header |
0x0400 |
MCIF_CVT8TO7 |
Convert from 8 to 7 bits |
0x0800 |
MCIF_DSN |
DSN extension supported |
0x1000 |
MCIF_8BITOK |
Okay to send 8 bit characters |
0x2000 |
MCIF_CVT7TO8 |
Convert from 7 to 8 bits |
0x4000 |
MCIF_INMIME |
Currently reading MIME header |
The
stat
is the exit status of the last delivered mail message
to this connection. It is one of the values defined in
<sysexits.h>
.
The
err
is the value of the last system error (if any), as
defined in
<errno.h>
.
Trace caching and uncaching connections
The
-d42.5
debugging switch shows connections being cached and
freed:
mci_cache: caching
addr
(
host
) in slot
slot
mci_uncache: uncaching
addr
(
host
) from slot
slot
(
doquit
)
Here,
addr
is the address in memory of the C language structure
(
struct mailer_con_info
defined in
sendmail.h
) that defines
the current (or about to be made) connection. The
host
is the name of the host to which the connection is to be made.
The
slot
is an index into the array of structures that
contain the connection information. For uncaching, the
doquit
is a Boolean that tells
sendmail
to close the connection if
it is nonzero.
The
-d91.100
debugging switch produces information identical to the
above but logs its output at LOG_DEBUG instead of printing it:
qid
: mci_cache: caching
addr
(
host
) in slot
slot
qid
: mci_uncache: uncaching
addr
(
host
) from slot
slot
(
doquit
)
Note that each line is prefixed by the queue identifier
for the message (
qid
). The
-d91.100
debugging switch is especially
handy for monitoring caching when running
sendmail
as a daemon.
V8.7
sendmail
can convert 8-bit MIME to 7 bits.
The
-d43.1
(a.k.a.
-d43
) debugging switch traces this process.
mime8to7: flags =
mflags
, boundaries =
boundaries printed here
Here, the internal
mime8to7
() routine has been called to do the
conversion. The
mflags
are printed in hexadecimal, and are
described in
Table 37.18
.
The
boundaries
is either
<none>
or a list of the boundaries
found in the message.
In multipart messages the
-d43.1
debugging switch causes each boundary
to be printed as it is found:
mime8to7: multi part boundary
boundary printed here
See the final MIME boundary name
The
-d43.3
debugging switch is used to see the
final MIME boundary name that is selected:
mime8to7=>
boundary
(multipart)
mime8to7=>
boundary
(basic)
Each line is prefixed with three tabs.
The
-d43.3
debugging switch is also used to trace
7- to 8-bit conversion. If a delivery agent has the
F=9
flag set (see
Section 30.8.6, F=9
) and if the message has
a
Content-Transfer-Encoding:
header that specifies Base64
or Quoted-Printable,
sendmail
will attempt to convert
it from its encoded 7-bit form back into 8-bit form:
mime7to8 =>
base64 or quoted-printable
to 8bit done
Watch search for boundaries
The
-d43.5
debugging switch allows you to watch the search
for boundaries. First each line read is printed:
mimeboundary: line="
line is printed here
"...
boundary, if found, printed here
Then, if the line contained a valid MIME boundary, the
found boundary is printed at the end of the preceding.
The
sendmail
program determines how to convert the MIME message
by examining the first eighth of the file. If the first
eighth of the total number of characters in the file have the high bit set, conversion
will be with Base64; otherwise, it will be with Quoted-Printable
(see
Section 34.8.22, EightBitMode (8)
).
If the message is marked as binary, it is always converted
with Base64.
The
-d43.8
debugging switch causes
sendmail
to print
the result of this calculation:
mime8to7:
hcount
high bit(s) in
bcount
byte(s), cte=
type
Here,
cte=
is either
[none]
or the content-transfer-encoding
type, such as
binary
.
Show boundary lines as emitted
The
-43.35
debugging switch causes each new boundary line
to be printed as it is inserted into the message:
...-
mid-boundary here
...-
end boundary here
-
The midboundary marks begin with a
-
. The ending-boundary
mark begins and ends with a
-
.
Show content transfer encoding
The
-43.36
debugging switch causes the encoding header
to be printed as it is added to the message:
...Content-Transfer-Encoding:
type of encoding here
The type of encoding will either be the original as printed
with
cte=
in
-d43.8
above or Base64
or Quoted-Printable.
Show parse of Content-Type: header
The
-43.40
debugging switch causes
the contents of the parsed
Content-Type:
header to
be displayed.
pvp[
n
] = "
item
"
For zero through
n
items that were parsed, each is printed
on its own line.
Print the leading/following comments
The
-d43.99
debugging switch tells
sendmail
to print each line
of MIME commentary that precedes the leading boundary:
...
leading commentary here
...-
midboundary here
and the commentary that follows the last boundary:
...-
end boundary here
-
...
trailing commentary here
Mark collect() and putheader()
The
-d43.100
debugging switch causes
sendmail
to print a mark just after it has called
collect
()
and after it has called
putheader
():
+++after collect
+++after putheader
The
collect
() routine is traced with the
-d30
debugging switch, and
putheader
() is traced with the
-d34
debugging switch.
The V8
sendmail
program tries to be extra careful about
file permissions, and the key to checking them is the
internal
safefile
() function.
The
-d44.4
debugging switch
[12]
prints the parameters passed to the
safefile
() function:
safefile(
fname
, uid=
uid
, gid=
gid
, flags=
sff_flags
, mode=
wantmode
)
Here, the file named
fname
is being checked
to determine whether the user identified by the
uid
, with the group
gid
,
is allowed to find or use the file. The range of checking is determined
by the hexadecimal
sff_flags
, described in
Table 37.19
.
Where a file's permissions are required, the mode printed in
wantmode
will be used.
Table 37.19: safefile() Access Flags
Flag |
Mnemonic |
Description |
0x000 |
SFF_ANYFILE |
No special restrictions |
0x001 |
SFF_MUSTOWN |
Uid must own this file |
0x002 |
SFF_NOSLINK |
File must not be a symbolic link |
0x004 |
SFF_ROOTOK |
Okay for root to own this file |
0x008 |
SFF_RUNASREALUID |
If no controlling user, run as real
uid
|
0x010 |
SFF_NOPATHCHECK |
Don't bother checking leading path |
0x020 |
SFF_SETUIDOK |
Setuid files are okay |
0x040 |
SFF_CREAT |
Okay to create the file if necessary |
0x080 |
SFF_REGONLY |
Allow regular files only |
0x100 |
SFF_OPENASROOT |
Open as root instead of as
uid
|
If the SFF_NOPATHCHECK flag is clear (0),
sendmail
examines
each component of the path leading the file. If any component of the
path is rejected, the
-d44.4
debugging switch causes
sendmail
to print:
[dir
fname
]
reason for the rejection here
A path component can fail because
stat
(2) failed. If the
uid
is
0 for
root
, a warning is logged if a component is found to be group-
or world-writable:
WARNING: writable directory
fname
For each component in the path,
safefile
() checks to verify that
this user has permission to search the directory. If the SFF_ROOTOK flag
is not set (is clear),
root
(
uid
0) access is special cased
in that all directory components must be world-searchable.
Otherwise, the path component is accepted if it is owned by the
uid
and
has the user search bit set or if its group is the same as
gid
and
has the group search bit set.
If NO_GROUP_SET is undefined when
sendmail
is compiled
(see
Section 18.8.31, NO-GROUP-SET
) and the
DontInitGroups
option (see
Section 34.8.19, DontInitGroups
) is not set,
each group to which
uid
belongs is also checked.
Otherwise, the directory must be world-searchable.
If the
fname
could not be checked with
stat
(2), the
-d44.4
debugging switch causes the reason to be printed:
reason for failure here
If the file does not exist, it may need to be created.
If so,
sendmail
checks to be sure that the
uid
has write permission.
The result is printed with the
-d44.4
debugging switch like this:
[final dir
fname
uid
uid
mode
wantmode
]
error here
If the file exists and if symbolic links are supported, the file is rejected if
it is a symbolic link and if the SFF_NOSLINK flag is set. If the
-d44.4
debugging switch is specified, this error is printed:
[slink mode
mode
] EPERM
If the SFF_REGONLY flag is set the file must be a regular file. If it is not,
it is rejected, and
-d44.4
causes the following to be printed:
[non-reg mode
mode
] EPERM
If
wantmode
has the write bits set, and the existing file has
any execute bits set, the file is rejected and
-d44.4
causes
the following to be printed:
[exec bits
mode
] EPERM
If the file has more than one link, the file is rejected and
-d44.4
causes the following to be printed:
[link count
nlinks
] EPERM
If the SFF_SETUIDOK flag is specified, if the file exists,
if it has the
suid
bit set in the mode but no execute bits set
in the mode, and if it is
not
owned by
root
,
sendmail
performs subsequent checks under the
suid
and
sgid
identities
of the existing file.
A similar process occurs with the
sgid
bit.
Sendmail
then prints:
[uid
new_uid
, stat
filemode
, mode
wantmode
]
If access is finally allowed,
sendmail
concludes the above with:
OK
Otherwise, it concludes with:
EACCES
Trace writable()
(useful)
The
-d44.5
debugging switch displays the values passed to
sendmail
's internal
writable
() routine. This routine
nearly duplicates the function of the
access
(3) call
[13]
but does
it much more safely and allows checks to be made under the
identity of the controlling user:
writable(
fname
,
sff_flags
)
Here, the
fname
is the full pathname of the file being checked.
The
sff_flags
are documented in
Table 37.19
above. Success or failure is described under
-d44.4
.
The
-d45.1
(a.k.a.
-d45
) debugging switch causes
sendmail
to
print the current form of the envelope sender address before it has
fully rewritten that address into its final form:
setsender(
addr
)
If the
addr
is empty (as would be the case if the sender
were being gathered from the header),
sendmail
prints NULL.
The final envelope sender address is placed into the
$f
macro. (See
Section 31.10.14, $f
for a description of that macro and
the process used by
sendmail
to set the sender's address.)
If the
F=C
flag (see
Section 30.8.15
)
is set for the delivery agent
selected for the sender,
sendmail
will save the domain part
of the address for later use. The
-d45.3
causes the
saved domain part to be printed:
Saving from domain:
domain
The domain is saved in the
e_fromdomain
part of the C language
structure that contains the envelope information for the sender.
Later, if the
F=C
flag is set, this domain will be appended
to any recipient addresses that lack a domain part.
Show don't send to sender
Unless a message is bounced, it will not be sent to the sender.
The
-d45.5
debugging switch causes
sendmail
to
display sender information when this decision is made:
setsender: QDONTSEND
output of printaddr
()
here (see
Section 37.3.1
)
Show xf file's descriptors
The
xf
queue file (see
Section 23.2.7, "The Transcript File: xf"
)
contains a record of
the errors and other information produced by a delivery
agent. That information is used for bounced mail.
The
-d46.9
debugging switch
[14]
causes
sendmail
to dump the file descriptors for the opened
xf
file:
openxscript(xf
qid
):
output of dumpfd
()
here (see
Section 37.5.13
)
If
sendmail
cannot open an
xf
file, it logs
this warning:
Can't create transcript file xf
qid
It then tries to open
/dev/null
so that it can continue
with the delivery. If that fails, it logs the following panic message
and immediately exits:
Can't open /dev/null
Once the file is open (or not),
sendmail
turns
it into an I/O stream with a call to
fdopen
(3). If that
call fails,
sendmail
logs this message and immediately
exits:
Can't create transcript stream xf
qid
Trace calls to the check- rule sets
Beginning with V8.8,
sendmail
calls rule sets whose names
begin with
check_
(see
Section 29.10, "The check_... Rule Sets"
) to
filter incoming and outgoing mail. The
-d48.2
debugging
switch
[15]
can be used to display the workspace being passed to each such
rule set:
rscheck(
name
,
left
,
right
)
The
name
is the name of the named rule set being called.
If
right
is missing, it prints as NULL, and the
workspace passed to the rule set is:
left
If
right
is present, the workspace is:
left
$|
right
Here, the
$|
in the workspace is the
$|
operator.
The
checkcompat
() routine inside
conf.c
can be tuned to solve many problems
(see
Section 20.1, "How checkcompat() Works"
).
The default
-d49.1
(a.k.a.
49
)
debugging switch inside it prints the arguments that were passed to it:
checkcompat(to=
recipient
, from=
sender
)
When designing your own
checkcompat
(), you should
only use the
-d49
category to trace it.
Show envelope being dropped
Deallocating an envelope frees that envelope's C language
structure for future reuse. Deallocation also causes all the
queued files for that mail message to be removed (except
as possibly prevented by the
-d51
debugging switch described in the
next section). An envelope is deallocated after
its mail message has been delivered
to all recipients (including any failed deliveries).
The
-d50.1
(a.k.a.
-d50
) debugging switch causes
sendmail
to print
information about each envelope that is being deallocated:
dropenvelope
loc
id=
ident
flags=
output of printenvflags() here
This output shows the address in memory for the envelope's
C language structure (
loc
), the queue identifier (
ident
,
as used to name queued files),
and the envelope flags as printed by
printenvflags
()
(see
Table 37.3
in
Section 37.5.12
).
Note that if the version of
sendmail
is pre-8.7,
a
Return-Receipt:
header was in the message,
and delivery was to at least one local recipient,
the process of deallocation also causes
acknowledgment of delivery to be returned to the sender and triggers
error returns.
The
-d50.1
debugging switch also shows the
qf
and
df
files
just before they are removed:
===== Dropping [dq]f
qid
... queueit=
bool
, e_flags=
output of printenvflags() here
The
-d50.2
debugging switch shows the setting of three variables that
determine how the envelope will be treated:
failure_return=
val
delay_return=
val
success_return=
val
queueit=
val
A 1 indicates that the variable is true, a 0 indicates that it is false.
The
-d50.10
debugging switch causes the current send queue to also be printed:
sendq=
output of printaddr
()
here (see
Section 37.3.1
)
Show queue entries being unlocked
The
-d51.4
[16]
debugging switch causes V8
sendmail
to print
the following each time an envelope is unlocked in the queue:
unlockqueue(
qid
)
Here,
qid
is the queue identifier.
Prevent unlink of xf file
The
xf
file (one of the files that form a queued mail message)
holds error messages generated by a delivery agent. The last line
of text in this file is
made the value of the
M
line in the
qf
file
(see
Section 23.9.9, M line
).
Ordinarily, the
xf
file is removed after that error line is saved.
The
-d51.104
debugging switch prevents
sendmail
from removing the
xf
file.
If mail continually fails, this debugging switch can
be used to save all error messages instead of just the one that is
usually saved in the
qf
file.
Show disconnect from controlling TTY
When
sendmail
runs as a daemon, it must disconnect itself
from the terminal device that is used to run it. This prevents keyboard
signals from killing it and prevents it from hanging
(on a dial-in line waiting for carrier detect, for example).
The
-d52.1
(a.k.a.
-d52
) debugging switch shows
sendmail
disconnecting from the controlling terminal device:
disconnect: In
fd
Out
fd
, e=
addr
For both its input and output connections, the
fd
is a decimal
representation of the file descriptor number.
The
addr
is a hexadecimal representation of the address
that contains the envelope information.
If the
L
logging level option is greater than 71,
sendmail
syslog
(3)'s the following message
to show that it has disconnected:
in background, pid=
pid
Here,
pid
is the process identification number of the child
process (the daemon).
Prevent disconnect from controlling tty
(useful)
The
-d52.100
debugging switch
[17]
prevents
sendmail
from
disconnecting from its controlling terminal device. To show
that it is skipping the disconnect, it prints:
don't
This debugging switch is useful for debugging the daemon.
Note that this
-d52.100
prevents the detach but allows the
daemon to
fork
(2). This differs from the behavior
of the
-d99.100
debugging switch.
Ordinarily, files are closed silently.
The
-d53.99
[18]
debugging switch
can be used to observe file closings. Just before the file is
closed,
sendmail
prints:
xfclose(
fp
)
what
file
Here,
fp
is the file pointer for the open file, printed
in hexadecimal. The
what
is an indication of the internal function
that requires the close (such as
savemail
or
mci_uncache
).
The
file
is the name of the file to be closed.
If the close fails, the following is also printed:
xfclose FAILURE:
why
Here,
why
is the text corresponding to the error value
returned by
fclose
(3) (see
sys_errlist
(3)).
Show error return and output message
The exit values that are returned by
sendmail
are documented in
Section 36.5
.
The
-d54.1
debugging switch shows the exit value being
set by the internal
syserr
() routine:
syserr: ExitStat =
num
Here,
num
corresponds to the values defined in
<sysexits.h>
.
The
-d54.8
debugging switch causes the text of the error
message to be printed along with the flags that control its
actual output:
--
message
(hold) (held)
If
(hold)
appears, it means that the
message
will be held (stored) and not output.
If
(held)
appears, it means that the
message
was previously held and should not be added to the
xf
file.
If neither is printed, the
message
will be logged and
appended to the
xf
file.
If the message on output fails,
sendmail
will attempt to log this
panic message:
qid
: SYSERR: putoutmsg (
host
): error on output channel sending "
message
":
err
If the message was never queued, the
qid
will print as NOQUEUE.
If you are not currently connected to a
host
,
it will print as NO-HOST.
The
err
is the error that caused the message to fail (as defined
in either
<sys/errno.h>
or
sysexits.h
).
The
sendmail
program tries to lock every file before reading or writing it.
If
sendmail
was compiled
with HASFLOCK defined (see
Section 18.8.9, HAS...
),
it uses
flock
(3) to
lock and unlock files. If HASFLOCK is not defined,
sendmail
tries to lock and unlock with
fcntl
(2).
The
-d55.60
[19]
debugging switch tells
sendmail
to print
how it is about to try to lock a file:
lockfile(
filename
, action=
set
, type=
l_type
)
lockfile(
filename
, type=
what
)
The first form is printed if HASFLOCK is not defined. In it,
sendmail
is about to use
fcntl
(2) to lock the file.
The
action
is a decimal representation of the F_SET
flag that is
fcntl
(2)'s second argument. The
l_type
is the
l_type
structure member of
fcntl
(2)'s
third argument (see the online manual for
fcntl
(2)).
The second form is printed if HASFLOCK is defined so that
flock
(2) will be used.
In it,
what
is the type of locking to be performed, printed
in octal, as described in
Table 37.20
.
For both forms of locking, if the file is successfully locked, the above
debugging output is concluded with:
SUCCESS
Otherwise, it is concluded with:
(
error message here
) FAILURE
In this later instance, regardless of the setting of this
debugging flag,
sendmail
will also log the following
error message:
cannot
lock
(
filename
, fd=
num
, type=
what
, omode=
octal
, euid=
euid
)
Here,
lock
is either
lockf
or
flock
. The
filename
and
fd
are the file name and file descriptor
for the file. The
what
is the same as described in
Table 37.20
.
If F_GETFL
was defined at the system level when
sendmail
was compiled, then
omode
is an octal representation of the value returned by
an
fcntl
(2) F_GETFL call; otherwise, it is a -1 in octal.
The
euid
is the effective
uid
under which
sendmail
was running at the time.
Persistent host status tracing
The
-d56.1
(a.k.a.
-d56
) debugging switch tells
sendmail
to print a record of each step it is going through when saving and updating
its persistent host status. The
HostStatusDirectory
option
(see
Section 34.8.31, HostStatusDirectory
) specifies where and whether persistent host
status will be saved. Just before a status file is updated, and if
the
SingleThreadDelivery
option (see
Section 34.8.64, SingleThreadDelivery
)
is true, it needs to be locked:
mci_lock_host: attempting to lock
host
Here,
host
is the name of the host whose status is being saved
or updated. If the hostname is empty (as in the case of an address that contains
only an RFC822 comment), one of the following errors is printed for
an attempt to lock or unlock the host information:
mci_lock_host: NULL mci
mci_unlock_host: NULL mci
After the status file is locked,
sendmail
will transfer the information
from that file into its internal
mci
structure:
mci_load_persistent: Attempting to load persistent information for
host
Again, if the hostname is empty, this error will print:
mci_load_persistent: NULL
If
sendmail
was unable to translate the hostname into a UNIX path,
the
-d56.1
debugging switch causes it to print:
mci_load_persistent: Couldn't generate host path
If
sendmail
was unable open the host status file, it prints:
mci_load_persistent: open(
filename
):
host
Similarly, when
sendmail
needs to store or update the host
information, it first prints that it is doing so:
mci_store_persistent: Storing information for
host
If
sendmail
could not open the host status file, it
prints:
mci_store_persistent: no statfile
The internals of the status file are described in
Appendix
Appendix B,
Host Status File Internals
.
Ordinarily,
sendmail
is silent about its inability to
open status files when printing its host information with
the
hoststat
(1) command (see
Section 36.1.1, "hoststat (V8.8 and Above)"
).
But if the
-d56.1
debugging switch is used,
sendmail
will complain:
mci_print_persistent: cannot open
filename
:
host
When its host information is being purged with the
purgestat
(1)
command (see
Section 36.1.4, "purgestat (V8.8 and Above)"
), the
-d56.1
debugging switch tells
sendmail
to show what
it is trying to achieve:
mci_purge_persistent: purging
path
mci_purge_persistent: dpurge
directory
More persistent host status tracing
The
-d56.2
debugging switch causes
sendmail
to show
additional information about what it is trying to do.
Just before attempting to lock a status file, it prints:
mci_lock_host: attempting to lock
host
If a path could not be generated from the hostname,
sendmail
prints this error:
mci_lock_host: Failed to generate host path for
host
If
sendmail
could not lock the status file, it prints:
mci_lock_host: couldn't get lock on
filename
When
sendmail
is about to update a status file, just
before unlocking that file, it announces that fact:
mci_unlock_host: store prior to unlock
The process of updating or reading a status file begins by
sendmail
traversing the directory hierarchy under which that file is stored.
If
sendmail
is unable to
stat
(2) any component of that
path, it prints the following error:
mci_traverse: Failed to stat
component
:
reason for failure
If
sendmail
cannot descend into the next directory, it prints:
mci_traverse: opendir
component
:
reason for failure
When purging its host information with the
purgestat
(1)
command (see
Section 36.1.4
), if
sendmail
cannot
remove the status file, it prints:
mci_purge_persistent: failed to unlink
filename
:
reason for failure
And if it cannot remove any of the directory components, it prints:
mci_purge_persistent: rmdir
directory
:
reason for failure
As a "sanity check," the
-d56.12
debugging switch
causes
sendmail
to print the following if the lock was successfully
acquired on the status file:
mci_lock_host: Sanity check - lock is good
Trace creating the path to the status file
If the status file does not exist,
sendmail
recursively makes
the directories leading to it. The
-d56.80
debugging switch
is used to trace this process:
mci_generate_persistent_path(
host
): FAILURE
errno
mci_generate_persistent_path(
host
): SUCCESS
path
If this process of making directories fails,
errno
is printed,
as listed in
<errno.h>
. If it succeeds, the
path
created
is displayed.
Dump MCI record for the host
The
-d56.93
debugging switch causes
sendmail
to dump the
connection cache information associated with a host's status file:
mci_read_persistent: fp=
hex
, mci=
output of mci_dump() here (see
Section 37.5.44
)
Here,
hex
is the file pointer of the open status file printed in
hexadecimal. That is followed by a dump of the MCI record for the
host.
Monitor vsnprintf() overflows
If HASSNPRINTF is not defined,
sendmail
emulates
the
snprintf
(3) function. If the internal buffer
of that emulation overflows, the
-d57.2
debugging switch causes this warning to be printed:
vsnprintf overflow:
first 200 characters of buffer
Note that you may have to also use the
-v
command-line switch
to make this output visible.
XLA from contrib
(obsolete)
See the XLA package in the
contrib/xla
directory as distributed
with the V8
sendmail
source. Note that XLA is no longer distributed
with
sendmail
as of V8.8.
Trace map lookups inside rewrite()
(useful)
Rules defined by the
R
configuration command are rewritten
by
sendmail
's internal
rewrite
() subroutine.
The
$[
and
$(
lookup operators
(see
Section 33.4.3, "$[ and $]: A Special Case"
and
Section 33.4, "Use Maps with $( and $) in Rules"
)
cause
sendmail
to look up keys in databases (maps).
If
sendmail
is running in deferred mode
(see
Section 34.8.16
), it
skips map lookups because they may cause DNS accesses. The
-d60.1
(a.k.a.
-d60
) debugging switch causes
sendmail
to print that it is
skipping the lookup:
map_lookup(
name
,
key
) => DEFERRED
Here,
name
is the map type, such as
dequote
or
host
. The
key
is the information being looked up.
If running in something other than deferred mode,
sendmail
performs the lookup.
If the lookup fails (if
key
is not found),
sendmail
prints:
map_lookup(
name
,
key
) => NOT FOUND (
stat
)
Here,
stat
is the number of the error that caused the failure.
If it is 0, then the lookup failed merely because the
key
was not found. Otherwise, it corresponds to the error numbers in
<sysexits.h>
. Then if
stat
is the special value 75 (for
EX_TEMPFAIL),
sendmail
also prints:
map_lookup(
name
,
key
) tempfail: errno=
err
Here,
err
is the error number that corresponds to the errors
listed in
<errno.h>
.
If the
key
is successfully found,
sendmail
prints:
map_lookup(
name
,
key
) =>
replacement value here
(
stat
)
Note that the replacement value will be whatever value was defined by
the
-a
database switch when the
K
command defined
the map (see
Section 33.3.4.2, "-a append tag on successful match (V8.1 and above)"
).
The
gethostbyname
(3) library routine is called by
sendmail
every time
sendmail
needs to find the canonical name of a host. The
-d61.10
[20]
debugging switch shows the result of that lookup:
_switch_gethostbyname_r(
host
)...
canonical name here
__switch_gethostbyname(
host
)...
canonical name here
gethostbyname(
host
)...
canonical name here
In all three lines of output, the
host
was looked up to find its canonical
name. If one was found, its canonical name is printed; otherwise,
failure
is
printed.
The first two lines show variations on
gethostbyname
(3) that was required
by some early SysVR4-based machines.
These represent
sendmail
's attempt to canonify the
host
no matter what.
Log file descriptors before and after all deliveries
The
-d62.1
(a.k.a.
-d62
) debugging switch causes
sendmail
to log the state of all of its file descriptors. It does this once just
before it starts to process the list of its recipients and again just
after it has completed delivery of all its recipients. Note that this
debugging switch is unusual in that it causes its output
to be logged with
syslog
(3), rather than written to
stdout
.
Log file descriptors before each delivery
The
-d62.8
debugging switch causes
sendmail
to log the state of all its file descriptors just before undertaking
delivery of each message.
Log file descriptors after each delivery
The
-d62.10
debugging switch causes
sendmail
to log the state of all its file descriptors just after completing
delivery of each message.
Content-Length: header (Sun enhancement)
The
-d80.1
(a.k.a.
-d80
) debugging switch is used to watch how
Sun's version of
sendmail
handles the
Content-Length:
header.
As soon as the size of the body of a message is known, Sun's
sendmail
stores it in the envelope information. When the time comes to emit
the
Content-Length:
header, that information is fetched.
If the size is unknown, the
-d80.1
debugging switch
causes
sendmail
to print:
content_length(): Error: Message bodysize undefined !
If the size is known, it is reduced by the number and size of
the end-of-line characters (as defined by the delivery agent's
E =
equate). If the delivery agent's
F=E
flag is
set (see
Section 30.8.19, F=E
),
the size is further reduced by the number of five character
"
From
" strings that begin lines in the message body.
The
-d80
debugging switch then causes the final result
to be printed:
Content length =
final length here
> option for remote mode (Sun enhancement)
In V8.1
sendmail
the letter
R
was co-opted by the
Berkeley distribution as an option name. This forced Sun to change the
name of its former
R
option into the new
>
option. The
-d81.1
(a.k.a.
-d80
) debugging switch causes Sun's
sendmail
to display
the status of this remote mode:
verify_mail_server(): remote mode is
either
on
or
off
mail server =
host name here
If the
>
option is declared,
on
is printed, and the
name of the remote mail host is displayed, if known. See
Section 38.18, "The > Option"
for a further description of this option.
Log caching and uncaching connections
The
-d91.100
debugging switch
[21]
causes the same information to be logged
with
syslog
(3)
as is printed by the
-d42.5
debugging switch.
Prevent backgrounding the daemon
(useful)
The
-d99.100
debugging switch
[22]
prevents the
sendmail
daemon
from forking and putting itself into the background. This leaves
the running daemon connected to your terminal so that you can see
other debugging output. For example,
#
/usr/lib/sendmail -bd -d99.100 -d9.30
This allows you to watch the daemon perform RFC1413 identification
queries when SMTP connections are made. See also
-d52.100
, which prevents
sendmail
from
disconnecting from its controlling terminal device, or the
-bD
command-line switch (
Section 36.7.4, -bD
), which does both.
|