summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--usr.sbin/sendmail/FAQ343
-rw-r--r--usr.sbin/sendmail/KNOWNBUGS131
-rw-r--r--usr.sbin/sendmail/Makefile24
-rw-r--r--usr.sbin/sendmail/READ_ME239
-rw-r--r--usr.sbin/sendmail/RELEASE_NOTES2556
-rw-r--r--usr.sbin/sendmail/cf/README1232
-rw-r--r--usr.sbin/sendmail/cf/cf/Makefile86
-rw-r--r--usr.sbin/sendmail/cf/cf/Makefile.dist85
-rw-r--r--usr.sbin/sendmail/cf/cf/clientproto.mc49
-rw-r--r--usr.sbin/sendmail/cf/cf/knecht.mc44
-rw-r--r--usr.sbin/sendmail/cf/cf/mail.cs.mc55
-rw-r--r--usr.sbin/sendmail/cf/cf/mail.eecs.mc54
-rw-r--r--usr.sbin/sendmail/cf/cf/tcpproto.mc50
-rw-r--r--usr.sbin/sendmail/cf/cf/ucbarpa.mc43
-rw-r--r--usr.sbin/sendmail/cf/cf/ucbvax.mc101
-rw-r--r--usr.sbin/sendmail/cf/cf/uucpproto.mc49
-rw-r--r--usr.sbin/sendmail/cf/feature/allmasquerade.m441
-rw-r--r--usr.sbin/sendmail/cf/feature/always_add_domain.m440
-rw-r--r--usr.sbin/sendmail/cf/feature/bitdomain.m449
-rw-r--r--usr.sbin/sendmail/cf/feature/domaintable.m440
-rw-r--r--usr.sbin/sendmail/cf/feature/mailertable.m440
-rw-r--r--usr.sbin/sendmail/cf/feature/nocanonify.m440
-rw-r--r--usr.sbin/sendmail/cf/feature/nodns.m440
-rw-r--r--usr.sbin/sendmail/cf/feature/notsticky.m440
-rw-r--r--usr.sbin/sendmail/cf/feature/nouucp.m440
-rw-r--r--usr.sbin/sendmail/cf/feature/nullclient.m461
-rw-r--r--usr.sbin/sendmail/cf/feature/redirect.m448
-rw-r--r--usr.sbin/sendmail/cf/feature/use_cw_file.m446
-rw-r--r--usr.sbin/sendmail/cf/feature/uucpdomain.m449
-rw-r--r--usr.sbin/sendmail/cf/hack/cssubdomain.m444
-rw-r--r--usr.sbin/sendmail/cf/m4/cf.m4149
-rw-r--r--usr.sbin/sendmail/cf/m4/nullrelay.m4302
-rw-r--r--usr.sbin/sendmail/cf/m4/proto.m4689
-rw-r--r--usr.sbin/sendmail/cf/m4/version.m439
-rw-r--r--usr.sbin/sendmail/cf/mailer/fax.m450
-rw-r--r--usr.sbin/sendmail/cf/mailer/local.m466
-rw-r--r--usr.sbin/sendmail/cf/mailer/pop.m453
-rw-r--r--usr.sbin/sendmail/cf/mailer/smtp.m4126
-rw-r--r--usr.sbin/sendmail/cf/mailer/usenet.m447
-rw-r--r--usr.sbin/sendmail/cf/mailer/uucp.m4172
-rw-r--r--usr.sbin/sendmail/cf/ostype/aix3.m440
-rw-r--r--usr.sbin/sendmail/cf/ostype/aux.m443
-rw-r--r--usr.sbin/sendmail/cf/ostype/bsd4.3.m439
-rw-r--r--usr.sbin/sendmail/cf/ostype/bsd4.4.m442
-rw-r--r--usr.sbin/sendmail/cf/ostype/bsdi1.0.m438
-rw-r--r--usr.sbin/sendmail/cf/ostype/dgux.m439
-rw-r--r--usr.sbin/sendmail/cf/ostype/domainos.m442
-rw-r--r--usr.sbin/sendmail/cf/ostype/dynix3.2.m439
-rw-r--r--usr.sbin/sendmail/cf/ostype/linux.m438
-rw-r--r--usr.sbin/sendmail/cf/ostype/nextstep.m444
-rw-r--r--usr.sbin/sendmail/cf/ostype/osf1.m441
-rw-r--r--usr.sbin/sendmail/cf/ostype/riscos4.5.m442
-rw-r--r--usr.sbin/sendmail/cf/ostype/sco3.2.m445
-rw-r--r--usr.sbin/sendmail/cf/ostype/solaris2.m443
-rw-r--r--usr.sbin/sendmail/cf/ostype/sunos3.5.m437
-rw-r--r--usr.sbin/sendmail/cf/ostype/sunos4.1.m437
-rw-r--r--usr.sbin/sendmail/cf/ostype/svr4.m445
-rw-r--r--usr.sbin/sendmail/cf/sh/makeinfo.sh77
-rw-r--r--usr.sbin/sendmail/cf/siteconfig/uucp.cogsci.m46
-rw-r--r--usr.sbin/sendmail/cf/siteconfig/uucp.old.arpa.m44
-rw-r--r--usr.sbin/sendmail/cf/siteconfig/uucp.ucbarpa.m41
-rw-r--r--usr.sbin/sendmail/cf/siteconfig/uucp.ucbvax.m473
-rw-r--r--usr.sbin/sendmail/contrib/README10
-rw-r--r--usr.sbin/sendmail/contrib/bitdomain.c409
-rw-r--r--usr.sbin/sendmail/contrib/converting.sun.configs446
-rwxr-xr-xusr.sbin/sendmail/contrib/expn.pl1365
-rw-r--r--usr.sbin/sendmail/contrib/mail.local.linux205
-rw-r--r--usr.sbin/sendmail/contrib/mh.patch193
-rw-r--r--usr.sbin/sendmail/contrib/mmuegel2079
-rw-r--r--usr.sbin/sendmail/contrib/oldbind.compat.c79
-rw-r--r--usr.sbin/sendmail/contrib/xla/README207
-rw-r--r--usr.sbin/sendmail/contrib/xla/xla.c532
-rw-r--r--usr.sbin/sendmail/doc/changes/Makefile13
-rw-r--r--usr.sbin/sendmail/doc/changes/changes.me997
-rw-r--r--usr.sbin/sendmail/doc/changes/changes.ps1088
-rw-r--r--usr.sbin/sendmail/doc/intro/Makefile13
-rw-r--r--usr.sbin/sendmail/doc/intro/intro.me1478
-rw-r--r--usr.sbin/sendmail/doc/intro/intro.ps1295
-rw-r--r--usr.sbin/sendmail/doc/op/Makefile13
-rw-r--r--usr.sbin/sendmail/doc/op/op.me6921
-rw-r--r--usr.sbin/sendmail/doc/op/op.ps5477
-rw-r--r--usr.sbin/sendmail/doc/usenix/Makefile12
-rw-r--r--usr.sbin/sendmail/doc/usenix/usenix.me1076
-rw-r--r--usr.sbin/sendmail/doc/usenix/usenix.ps1004
-rw-r--r--usr.sbin/sendmail/mailstats/Makefile8
-rw-r--r--usr.sbin/sendmail/mailstats/mailstats.c209
-rw-r--r--usr.sbin/sendmail/makemap/Makefile8
-rw-r--r--usr.sbin/sendmail/makemap/makemap.8128
-rw-r--r--usr.sbin/sendmail/makemap/makemap.c373
-rw-r--r--usr.sbin/sendmail/praliases/Makefile9
-rw-r--r--usr.sbin/sendmail/praliases/praliases.c132
-rw-r--r--usr.sbin/sendmail/src/Makefile42
-rw-r--r--usr.sbin/sendmail/src/READ_ME872
-rw-r--r--usr.sbin/sendmail/src/TRACEFLAGS64
-rw-r--r--usr.sbin/sendmail/src/alias.c770
-rw-r--r--usr.sbin/sendmail/src/aliases.5106
-rw-r--r--usr.sbin/sendmail/src/arpadate.c173
-rw-r--r--usr.sbin/sendmail/src/clock.c276
-rw-r--r--usr.sbin/sendmail/src/collect.c579
-rw-r--r--usr.sbin/sendmail/src/conf.c2377
-rw-r--r--usr.sbin/sendmail/src/conf.h1191
-rw-r--r--usr.sbin/sendmail/src/convtime.c197
-rw-r--r--usr.sbin/sendmail/src/daemon.c1547
-rw-r--r--usr.sbin/sendmail/src/deliver.c2409
-rw-r--r--usr.sbin/sendmail/src/domain.c769
-rw-r--r--usr.sbin/sendmail/src/envelope.c777
-rw-r--r--usr.sbin/sendmail/src/err.c561
-rw-r--r--usr.sbin/sendmail/src/headers.c1192
-rw-r--r--usr.sbin/sendmail/src/macro.c279
-rw-r--r--usr.sbin/sendmail/src/mailq.188
-rw-r--r--usr.sbin/sendmail/src/mailstats.h49
-rw-r--r--usr.sbin/sendmail/src/main.c1479
-rw-r--r--usr.sbin/sendmail/src/makesendmail113
-rw-r--r--usr.sbin/sendmail/src/map.c1339
-rw-r--r--usr.sbin/sendmail/src/mci.c398
-rw-r--r--usr.sbin/sendmail/src/newaliases.168
-rw-r--r--usr.sbin/sendmail/src/parseaddr.c1964
-rw-r--r--usr.sbin/sendmail/src/pathnames.h46
-rw-r--r--usr.sbin/sendmail/src/queue.c1571
-rw-r--r--usr.sbin/sendmail/src/readcf.c1681
-rw-r--r--usr.sbin/sendmail/src/recipient.c1059
-rw-r--r--usr.sbin/sendmail/src/savemail.c833
-rw-r--r--usr.sbin/sendmail/src/sendmail.8501
-rw-r--r--usr.sbin/sendmail/src/sendmail.h973
-rw-r--r--usr.sbin/sendmail/src/sendmail.hf58
-rw-r--r--usr.sbin/sendmail/src/srvrsmtp.c1032
-rw-r--r--usr.sbin/sendmail/src/stab.c166
-rw-r--r--usr.sbin/sendmail/src/stats.c130
-rw-r--r--usr.sbin/sendmail/src/sysexits.c67
-rw-r--r--usr.sbin/sendmail/src/trace.c131
-rw-r--r--usr.sbin/sendmail/src/udb.c985
-rw-r--r--usr.sbin/sendmail/src/useful.h77
-rw-r--r--usr.sbin/sendmail/src/usersmtp.c905
-rw-r--r--usr.sbin/sendmail/src/util.c1467
-rw-r--r--usr.sbin/sendmail/src/version.c39
135 files changed, 65486 insertions, 0 deletions
diff --git a/usr.sbin/sendmail/FAQ b/usr.sbin/sendmail/FAQ
new file mode 100644
index 0000000..743dc36
--- /dev/null
+++ b/usr.sbin/sendmail/FAQ
@@ -0,0 +1,343 @@
+ Sendmail Version 8
+ Frequently Asked Questions
+ Version 8.4 of 4/20/94
+
+
+This FAQ is specific to Version 8 of sendmail. Other questions,
+particularly regarding compilation and configuration, are answered
+in src/READ_ME and cf/README.
+
+----------------------------------------------------------------------
+ * Where can I get Version 8?
+
+ Via anonymous FTP from FTP.CS.Berkeley.EDU in /ucb/sendmail.
+----------------------------------------------------------------------
+ * What are the differences between Version 8 and other versions?
+
+ See doc/changes/changes.me in the sendmail distribution.
+----------------------------------------------------------------------
+ * What happened to sendmail 6.x and 7.x?
+
+ When I released a new version of sendmail, I changed it to
+ Release 6. Development continued in that tree until 4.4BSD
+ was released, when everything on the 4.4 tape was set to be
+ version 8.1. Version 7.x never existed.
+----------------------------------------------------------------------
+ * Version 8 requires a new version of "make". Where can I get this?
+
+ Actually, Version 8 does not require a new version of "make".
+ It includes a collection of Makefiles for different architectures,
+ only one or two of which require the new "make". If you are
+ porting to a new architecture, start with Makefile.dist.
+
+ If you really do want the new make, it is available on any of
+ the BSD Net2 or 4.4-Lite distribution sites. These include:
+
+ ftp.uu.net /systems/unix/bsd-sources
+ gatekeeper.dec.com /.0/BSD/net2
+ ucquais.cba.uc.edu /pub/net2
+ ftp.luth.se /pub/unix/4.3bsd/net2
+
+ Diffs and instructions for building this version of make under
+ SunOS 4.1.x are available on ftp.css.itd.umich.edu in
+ /pub/systems/sun/Net2-make.sun4.diff.Z.
+----------------------------------------------------------------------
+ * What macro package do I use to format the V8 man pages?
+
+ The BSD group switched over the the ``mandoc'' macros for
+ the 4.4 release. These include more hooks designed for
+ hypertext handling. However, new man pages won't format
+ under the old man macros. Fortunately, old man pages will
+ format under the new mandoc macros.
+
+ Get the new macros with the BSD Net2 or 4.4-Lite release.
+
+ This macro set is also available with newer versions of groff.
+----------------------------------------------------------------------
+ * What books are available describing sendmail?
+
+ There is one book available devoted to sendmail:
+
+ Costales, Allman, and Rickert, _Sendmail_. O'Reilly &
+ Associates.
+
+ Several books have sendmail chapters, for example:
+
+ Nemeth, Snyder, and Seebass, _Unix System Administration
+ Handbook_. Prentice-Hall.
+ Carl-Mitchell and Quarterman, _Practical Internetworking with
+ TCP/IP and UNIX_. Addison-Wesley.
+ Hunt, _TCP/IP Network Administration_. O'Reilly & Associates.
+
+ Another book about sendmail is due out "soon":
+
+ Avolio & Vixie, _Sendmail Theory and Practice_. Digital
+ Press (release date unknown).
+----------------------------------------------------------------------
+ * How do I make all my addresses appear to be from a single host?
+
+ Using the V8 configuration macros, use:
+
+ MASQUERADE_AS(my.dom.ain)
+
+ This will cause all addresses to be sent out as being from
+ the indicated domain.
+----------------------------------------------------------------------
+ * How do I rewrite my From: lines to read ``First_Last@My.Domain''?
+
+ There are a couple of ways of doing this. This describes using
+ the "user database" code. This is still experimental, and was
+ intended for a different purpose -- however, it does work
+ with a bit of care. It does require that you have the Berkeley
+ "db" package installed (it won't work with DBM).
+
+ First, create your input file. This should have lines like:
+
+ loginname:mailname First_Last
+ First_Last:maildrop loginname
+
+ Install it in (say) /etc/userdb. Create the database:
+
+ makemap btree /etc/userdb.db < /etc/userdb
+
+ You can then create a config file that uses this. You will
+ have to include the following in your .mc file:
+
+ define(confUSERDB_SPEC, /etc/userdb.db)
+ FEATURE(notsticky)
+----------------------------------------------------------------------
+ * So what was the user database feature intended for?
+
+ The intent was to have all information for a given user (where
+ the user is the unique login name, not an inherently non-unique
+ full name) in one place. This would include phone numbers,
+ addresses, and so forth. The "maildrop" feature is because
+ Berkeley does not use a centralized mail server (there are a
+ number of reasons for this that are mostly historic), and so
+ we need to know where each user gets his or her mail delivered --
+ i.e., the mail drop.
+
+ We are in the process of setting up our environment so that
+ mail sent to an unqualified "name" goes to that person's
+ preferred maildrop; mail sent to "name@host" goes to that
+ host. The purpose of "FEATURE(notsticky)" is to cause
+ "name@host" to be looked up in the user database for delivery
+ to the maildrop.
+----------------------------------------------------------------------
+ * Why are you so hostile to using full names for e-mail addresses?
+
+ Because full names are not unique. For example, the computer
+ community has two Andy Tannenbaums and two Peter Deutsches.
+ At one time, Bell Labs had two Stephen R. Bournes with offices
+ a few doors apart. You can create alternative addresses
+ (e.g., Stephen_R_Bourne_2), but that's even worse -- which
+ one of them has to have their name desecrated in this way?
+ And you can bet that they will get most of the other person's
+ email.
+
+ So called "full names" are just longer versions of unique
+ names. Rather that lulling people into a sense of security,
+ I'd rather that it be clear that these handles are arbitrary.
+ People should use good user agents that have alias mappings
+ so that they can attach arbitrary names for their personal
+ use to those with whom they correspond.
+
+ Even worse is fuzzy matching in e-mail -- this can make good
+ addresses turn bad. For example, I'm currently (to the best
+ of my knowledge) the only ``Allman'' at Berkeley, so mail
+ sent to "Allman@Berkeley.EDU" should get to me. But if
+ another Allman ever appears, this address could suddenly
+ become ambiguous. I've been the only Allman at Berkeley for
+ over fifteen years -- to suddenly have this "good address"
+ bounce mail because it is ambiguous would be a heinous wrong.
+
+ Finger services should be as fuzzy as possible. Mail services
+ should be unique.
+----------------------------------------------------------------------
+ * When I use sendmail V8 with a Sun config file I get lines like:
+
+ /etc/sendmail.cf: line 273: replacement $3 out of bounds
+
+ the line in question reads:
+
+ R$*<@$%y>$* $1<@$2.LOCAL>$3 user@ether
+
+ what does this mean? How do I fix it?
+
+ V8 doesn't recognize the Sun "$%y" syntax, so as far as it
+ is concerned, there is only a $1 and a $2 (but no $3) in this
+ line. Read Rick McCarty's paper on "Converting Standard Sun
+ Config Files to Sendmail Version 8", in the contrib directory
+ (file "converting.sun.configs") on the sendmail distribution
+ for a full discussion of how to do this.
+----------------------------------------------------------------------
+ * Should I use a wildcard MX for my domain?
+
+ If at all possible, no.
+
+ Wildcard MX records have lots of semantic "gotcha"s. For
+ example, they will match a host "unknown.your.domain" -- if
+ you don't explicitly test for unknown hosts in your domain,
+ you will get "config error: mail loops back to myself"
+ errors.
+----------------------------------------------------------------------
+ * I'm connected to the network via a SLIP link. Sometimes my sendmail
+ process hangs (although it looks like part of the message has been
+ transfered). Everything else works. What's wrong?
+
+ Most likely, the problem isn't sendmail at all, but the low
+ level network connection. It's important that the MTU (Maximum
+ Transfer Unit) for the SLIP connection be set properly at both
+ ends. If they disagree, large packets will be trashed and
+ the connection will hang.
+----------------------------------------------------------------------
+ * I just upgraded to 8.x and suddenly I'm getting messages in my
+ syslog of the form "collect: I/O error on connection". What is
+ going wrong?
+
+ Nothing. This is just a diagnosis of a condition that had
+ not been diagnosed before. If you are getting a lot of these
+ from a single host, there is probably some incompatibility
+ between 8.x and that host. If you get a lot of them in general,
+ you may have network problems that are causing connections to
+ get reset.
+----------------------------------------------------------------------
+ * How can I get sendmail to deliver local mail to $HOME/.mail
+ instead of into /usr/spool/mail (or /usr/mail)?
+
+ This is a local mailer issue, not a sendmail issue. Either
+ modify your local mailer (source code will be required) or
+ change the program called in the "local" mailer configuration
+ description to be a new program that does this local delivery.
+ I understand that "procmail" works well, although I haven't
+ used it myself.
+
+ You might be interested in reading the paper ``HLFSD: Delivering
+ Email to your $HOME'' available in the Proceedings of the
+ USENIX System Administration (LISA VII) Conference (November
+ 1993). This is also available via public FTP from
+ ftp.cs.columbia.edu:/pub/hlfsd/{README.hlfsd,hlfsd.ps}.
+----------------------------------------------------------------------
+ * Under V8, the "From " header gets mysteriously munged when I send
+ to an alias.
+
+ ``It's not a bug, it's a feature.'' This happens when you have
+ a "owner-list" alias and you send to "list". V8 propogates the
+ owner information into the envelope sender field (which appears
+ as the "From " header on UNIX mail or as the Return-Path: header)
+ so that downstream errors are properly returned to the mailing
+ list owner instead of to the sender. In order to make this
+ appear as sensible as possible to end users, I recommend making
+ the owner point to a "request" address -- for example:
+
+ list: :include:/path/name/list.list
+ owner-list: list-request
+ list-request: eric
+
+ This will make message sent to "list" come out as being
+ "From list-request" instead of "From eric".
+----------------------------------------------------------------------
+ * There are four UUCP mailers listed in the configuration files.
+ Which one should I use?
+
+ The choice is partly a matter of local preferences and what is
+ running at the other end of your UUCP connection. Unlike good
+ protocols that define what will go over the wire, UUCP uses
+ the policy that you should do what is right for the other end;
+ if they change, you have to change. This makes it hard to
+ do the right thing, and discourages people from updating their
+ software. In general, if you can avoid UUCP, please do.
+
+ If you can't avoid it, you'll have to find the version that is
+ closest to what the other end accepts. Following is a summary
+ of the UUCP mailers available.
+
+ uucp-old (obsolete name: "uucp")
+ This is the oldest, the worst (but the closest to UUCP) way of
+ sending messages accros UUCP connections. It does bangify
+ everything and prepends $U (your UUCP name) to the sender's
+ address (which can already be a bang path itself). It can
+ only send to one address at a time, so it spends a lot of
+ time copying duplicates of messages. Avoid this if at all
+ possible.
+
+ uucp-new (obsolete name: "suucp")
+ The same as above, except that it assumes that in one rmail
+ command you can specify several recipients. It still has a
+ lot of other problems.
+
+ uucp-dom
+ This UUCP mailer keeps everything as domain addresses.
+ Basically, it uses the SMTP mailer rewriting rules.
+
+ Unfortunately, a lot of UUCP mailer transport agents require
+ bangified addresses in the envelope, although you can use
+ domain-based addresses in the message header. (The envelope
+ shows up as the From_ line on UNIX mail.) So....
+
+ uucp-uudom
+ This is a cross between uucp-new (for the envelope addresses)
+ and uucp-dom (for the header addresses). It bangifies the
+ envelope sender (From_ line in messages) without adding the
+ local hostname, unless there is no host name on the address
+ at all (e.g., "wolf") or the host component is a UUCP host name
+ instead of a domain name ("somehost!wolf" instead of
+ "some.dom.ain!wolf").
+
+ Examples:
+
+ We are on host grasp.insa-lyon.fr (UUCP host name "grasp"). The
+ following summarizes the sender rewriting for various mailers.
+
+ Mailer sender rewriting in the envelope
+ ------ ------ -------------------------
+ uucp-{old,new} wolf grasp!wolf
+ uucp-dom wolf wolf@grasp.insa-lyon.fr
+ uucp-uudom wolf grasp.insa-lyon.fr!wolf
+
+ uucp-{old,new} wolf@fr.net grasp!fr.net!wolf
+ uucp-dom wolf@fr.net wolf@fr.net
+ uucp-uudom wolf@fr.net fr.net!wolf
+
+ uucp-{old,new} somehost!wolf grasp!somehost!wolf
+ uucp-dom somehost!wolf somehost!wolf@grasp.insa-lyon.fr
+ uucp-uudom somehost!wolf grasp.insa-lyon.fr!somehost!wolf
+----------------------------------------------------------------------
+ * I'm trying to to get my mail to go into queue only mode, and it
+ delivers the mail interactively anyway. (Or, I'm trying to use
+ the "don't deliver to expensive mailer" flag, and it doesn't
+ delivers the mail interactively anyway.) I can see it does it:
+ here's the output of "sendmail -v foo@somehost" (or Mail -v or
+ equivalent).
+
+ The -v flag to sendmail (which is implied by the -v flag to
+ Mail and other programs in that family) tells sendmail to
+ watch the transaction. Since you have explicitly asked to
+ see what's going on, it assumes that you do not want to to
+ auto-queue, and turns that feature off. Remove the -v flag
+ and use a "tail -f" of the log instead to see what's going on.
+
+ If you are trying to use the "don't deliver to expensive mailer"
+ flag (mailer flag "e"), be sure you also turn on global option
+ "c" -- otherwise it ignores the mailer flag.
+----------------------------------------------------------------------
+ * I'm getting "Local configuration error" messages, such as:
+
+ 553 relay.domain.net config error: mail loops back to myself
+ 554 <user@domain.net>... Local configuration error
+
+ How can I solve this problem?
+
+ You have asked mail to the domain (e.g., domain.net) to be
+ forwarded to a specific host (in this case, relay.domain.net)
+ by using an MX record, but the relay machine doesn't recognize
+ itself as domain.net. Add domain.net to /etc/sendmail.cw
+ (if you are using FEATURE(use_cw_file)) or add "Cw domain.net"
+ to your configuration file.
+----------------------------------------------------------------------
+ * I want to run Sendmail version 8 on my DEC system, but you don't
+ have MAIL11V3 support in sendmail. How do I handle this?
+
+ Get Paul Vixie's reimplementation of the mail11 protocol
+ from gatekeeper.dec.com in /pub/DEC/gwtools.
+----------------------------------------------------------------------
diff --git a/usr.sbin/sendmail/KNOWNBUGS b/usr.sbin/sendmail/KNOWNBUGS
new file mode 100644
index 0000000..f34c6b7
--- /dev/null
+++ b/usr.sbin/sendmail/KNOWNBUGS
@@ -0,0 +1,131 @@
+
+
+ K N O W N B U G S I N S E N D M A I L
+ (for 8.6.7)
+
+
+The following are bugs or deficiencies in sendmail that I am aware of
+but which have not been fixed in the current release. You probably
+want to get the most up to date version of this from FTP.CS.Berkeley.EDU
+in /ucb/sendmail/KNOWNBUGS. For descriptions of bugs that have been
+fixed, see the file RELEASE_NOTES (in the root directory of the sendmail
+distribution).
+
+This list is not guaranteed to be complete.
+
+
+* Null bytes are not handled properly.
+
+ Sendmail should handle full binary data. As it stands, it handles
+ any value from 0x01-0xFF in the body and 0x01-0x80 and 0xA0-0xFF in
+ the header. Notably missing is 0x00, which would require a major
+ restructuring of the code -- for example, almost no C library support
+ could be used to handle strings.
+
+* Duplicate error messages.
+
+ Sometimes identical, duplicate error messages can be generated. As
+ near as I can tell, this is rare and relatively innocuous.
+
+* No "exposed users" in "nullrelay" configuration.
+
+ The "nullrelay" configuration hides all addresses behind the mail
+ hub name. Some sites might prefer to expose some names such as
+ root. This information is always available in Received: lines.
+
+* $c (hop count) macro improperly set.
+
+ The $c macro is supposed to contain the current hop count, for use
+ when calling a mailer. This macro is initialized too early, and
+ is always zero (or the value of the -c command line flag, if any).
+ This macro will probably be removed entirely in a future release;
+ I don't believe there are any mailers left that require it.
+
+* If you EXPN a list or user that has a program mailer, the output of
+ EXPN will include ``@local.host.name''. You can't actually mail to
+ this address. It's not clear what the right behaviour is in this
+ circumstance.
+
+* REDIRECT aliases don't work with `n' option.
+
+ If you have option `n' set when you use newaliases and have
+ REDIRECT addresses in your aliases file, you'll get the error
+ messages during the newaliases instead of when email is sent to
+ the address in question. The workaround is to turn off the `n'
+ option.
+
+* MX records that point at non-existent hosts work strangly.
+
+ Consider the DNS records:
+
+ hostH MX 1 hostA
+ MX 2 hostB
+ hostA A 128.32.8.9
+
+ (note that there is no A record for hostB). If hostA is down,
+ an attempt to send to hostH gives "host unknown" -- that is, it
+ reflects out the status on the last host it tries, which in this
+ case is hostB, which is unknown. It probably ought to eliminate
+ hostB early in processing.
+
+* NAME environment variables with commas break.
+
+ If you define your NAME environment variable to have a comma
+ (e.g., ``Lastname, Firstname''), and you are using the $q definition
+ that uses ``name <address>'' format, sendmail treats the first and
+ last names as two addresses, thus producing a bogus From line. You
+ can work around this by changing the $q definition to use
+ ``address (name)''.
+
+* \231 considered harmful.
+
+ Header addresses that have the \231 character (and possibly others
+ in the range \201 - \237) behave in odd and usually unexpected ways.
+
+* DEC Alphas (OSF/1 1.3) sometimes time out on sending mail.
+
+ I have one report that DEC Alphas acting as SMTP clients sometimes
+ will apparently not see the "250 OK" message in response to the
+ dot that indicates the end of the message. This only happens if
+ the message is run from the queue -- if it gets through on first
+ try, everything is fine. I have been unable to reproduce this
+ problem at Berkeley.
+
+* accept() problem on SVR4.
+
+ Apparently, the sendmail daemon loop (doing accept()s on the network)
+ can get into a wierd state on SVR4; it starts logging ``SYSERR:
+ getrequests: accept: Protocol Error''. The workaround is to kill
+ and restart the sendmail daemon. We don't have an SVR4 system at
+ Berkeley that carries more than token mail load, so I can't validate
+ this. It is likely to be a glitch in the sockets emulation, since
+ "Protocol Error" is not possible error code with Berkeley TCP/IP.
+
+ I've also had someone report the message ``sendmail: accept:
+ SIOCGPGRP failed errno 22'' on an SVR4 system. This message is
+ not in the sendmail source code, so I assume it is also a bug
+ in the sockets emulation. (Errno 22 is EINVAL "Invalid Argument"
+ on all the systems I have available, including Solaris 2.x.)
+
+* Sending user deletion not done properly in :include: lists.
+
+ If you don't have the "m" (me too) option set, then a person
+ sending to a list that contains themselves should not get a copy
+ of the message. However, if that list points to a :include: file
+ that has one address per line, this will break, and the sender
+ will always get a copy of their own message, just as though the
+ "m" option were set.
+
+ You can eliminate this by adding commas at the end of each line
+ of the :include: file.
+
+* Excessive mailing list nesting can run out of file descriptors.
+
+ If you have a mailing list that includes lots of other mailing
+ lists, each of which has a separate owner, you can run out of
+ file descriptors. Each mailing list with a separate owner uses
+ one open file descriptor (prior to 8.6.6 it was three open
+ file descriptors per list). This is particularly egregious if
+ you have your connection cache set to be large.
+
+(Version 8.18, last updated 3/14/94)
diff --git a/usr.sbin/sendmail/Makefile b/usr.sbin/sendmail/Makefile
new file mode 100644
index 0000000..3b21e37
--- /dev/null
+++ b/usr.sbin/sendmail/Makefile
@@ -0,0 +1,24 @@
+# @(#)Makefile 8.4 (Berkeley) 4/22/94
+
+SUBDIR= src mailstats makemap praliases cf/cf
+FTPDIR= barad-dur:/disks/barad-dur/ftp/sendmail/.
+VER= XX
+
+tar: Files.base Files.cf Files.misc Files.xdoc
+ (cd src; ${MAKE})
+ (cd doc; PRINTER=ps ${MAKE})
+ (cd doc; chmod 444 op/op.ps intro/intro.ps usenix/usenix.ps)
+ (cd cf/cf; ${MAKE})
+ pax -w -x tar -L -f sendmail.${VER}.base.tar `grep -v ^# Files.base`
+ compress sendmail.${VER}.base.tar
+ pax -w -x tar -L -f sendmail.${VER}.cf.tar `grep -v ^# Files.cf`
+ compress sendmail.${VER}.cf.tar
+ pax -w -x tar -L -f sendmail.${VER}.misc.tar `grep -v ^# Files.misc`
+ compress sendmail.${VER}.misc.tar
+ pax -w -x tar -L -f sendmail.${VER}.xdoc.tar `grep -v ^# Files.xdoc`
+ compress sendmail.${VER}.xdoc.tar
+
+ftp: sendmail.${VER}.base.tar.Z sendmail.${VER}.cf.tar.Z sendmail.${VER}.misc.tar.Z sendmail.${VER}.xdoc.tar.Z
+ rcp sendmail.${VER}.*.tar.Z RELEASE_NOTES FAQ KNOWNBUGS ${FTPDIR}
+
+.include <bsd.subdir.mk>
diff --git a/usr.sbin/sendmail/READ_ME b/usr.sbin/sendmail/READ_ME
new file mode 100644
index 0000000..016fa7f
--- /dev/null
+++ b/usr.sbin/sendmail/READ_ME
@@ -0,0 +1,239 @@
+/*-
+ * @(#)READ_ME 8.10 (Berkeley) 4/13/94
+ */
+
+ SENDMAIL RELEASE 8
+
+This directory has the latest sendmail software from Berkeley. See
+doc/op/op.me for a summary of changes since 5.67.
+
+Report any bugs to sendmail@CS.Berkeley.EDU.
+
+The latest version of sendmail is kept on FTP.CS.Berkeley.EDU, directory
+/ucb/sendmail; check there for the latest revision.
+
+
++--------------+
+| MANUAL PAGES |
++--------------+
+
+The sendmail manual pages use contemporary Berkeley troff macros. If
+your system does not process these manual pages, you can pick up the
+new macros in a BSD Net/2 FTP site (e.g. on FTP.UU.NET, the files
+/systems/unix/bsd-sources/share/tmac/me/strip.sed and
+/systems/unix/bsd-sources/share/tmac/*).
+
+The strip.sed file is only used in installation.
+
+After installation, edit tmac.doc and tmac.andoc to reflect the
+installation path of the tmac files. Those files contain pointers to
+/usr/share/tmac/, and those pointers are not changed by the `make
+install` process.
+
+Rename the existing tmac.an to be tmac.an.old, and rename tmac.andoc
+to be tmac.an.
+
+tmac.an will choose between tmac.an.old, your old macros, or tmac.doc,
+which are the new macros, so that both the new man pages and the
+existing man pages will be translated properly.
+
+I'm also told that the groff distribution from MIT has a tmac.doc
+macro set that is compatible with these macros.
+
+
++-----------------------+
+| RELATED DOCUMENTATION |
++-----------------------+
+
+There are other files you should read. Rooted in this directory are:
+
+ CHANGES-R5-R8
+ Describes changes between Release 5 and Release 8 of sendmail.
+ There are some things that may behave somewhat differently.
+ For example, the rules governing when :include: files will
+ be read have been tightened up for security reasons.
+ FAQ
+ Answers to Frequently Asked Questions.
+ KNOWNBUGS
+ Known bugs in the current release. I try to keep this up
+ to date -- get the latest version from FTP.CS.Berkeley.EDU
+ in /ucb/sendmail/KNOWNBUGS.
+ RELEASE_NOTES
+ A detailed description of the changes in each version. This
+ is quite long, but informative.
+ src/READ_ME
+ Details on compiling and installing sendmail.
+ cf/README
+ Details on configuring sendmail.
+ doc/op/op.me
+ The sendmail Installation & Operations Guide. Be warned: if
+ you are running this off on SunOS or some other system with an
+ old version of -me, you need to add the following macro to the
+ macros:
+
+ .de sm
+ \s-1\\$1\\s0\\$2
+ ..
+
+ This sets a word in a smaller pointsize.
+
+
++--------------+
+| RELATED RFCS |
++--------------+
+
+There are several related RFCs that you may wish to read -- they are
+available via anonymous FTP to several sites, including nic.ddn.mil
+(directory rfc), ftp.nisc.sri.com (rfc), nis.nsf.net (RFC),
+nisc.jvnc.net (rfc), venera.isi.edu (in-notes), and wuarchive.wustl.edu
+(info/rfc). They can also be retrieved via electronic mail by sending
+email to one of:
+
+ mail-server@nisc.sri.com
+ Put "send rfcNNN" in message body
+ nis-info@nis.nsf.net
+ Put "send RFCnnn.TXT-1" in message body
+ sendrfc@jvnc.net
+ Put "RFCnnn" as Subject: line
+
+Important RFCs for electronic mail are:
+
+ RFC821 SMTP protocol
+ RFC822 Mail header format
+ RFC974 MX routing
+ RFC976 UUCP mail format
+ RFC1123 Host requirements (modifies 821, 822, and 974)
+ RFC1413 Identification server
+ RFC1341 MIME: Multipurpose Internet Mail Extensions
+ RFC1344 Implications of MIME for Internet Mail Gateways
+
+Other standards that may be of interest (but which are less directly
+relevant to sendmail) are:
+
+ RFC987 Mapping between RFC822 and X.400
+ RFC1049 Content-Type header field (extension to RFC822)
+
+Warning to AIX users: this version of sendmail does not implement
+MB, MR, or MG DNS resource records, as defined as experiments in
+RFC883.
+
+
++-------------------+
+| DATABASE ROUTINES |
++-------------------+
+
+IF YOU WANT TO RUN THE NEW BERKELEY DB SOFTWARE: **** DO NOT ****
+use the version that was on the Net2 tape -- it has a number of
+nefarious bugs that were bad enough when I got them; you shouldn't have
+to go through the same thing. Instead, get a new version via public
+FTP from ftp.CS.Berkeley.EDU, file ucb/4bsd/db.tar.Z. This software
+is highly recommended; it gets rid of several stupid limits, it's much
+faster, and the interface is nicer to animals and plants. You will
+also probably find that you have to add -I/where/you/put/db/include
+to the sendmail makefile to get db.h to work properly.
+
+Be sure you remove ndbm.h and ndbm.o from the db distribution. These
+will cause problems with sendmail because sendmail already understands
+about NEWDB and NDBM coexisting.
+
+
++--------------------+
+| Host Name Services |
++--------------------+
+
+If you compile with NAMED_BIND (the default) sendmail will use
+DNS (the Domain Name System) for most host name lookups. If
+you do not have DNS running at your site you may have to turn
+this off to cause sendmail to use NIS and/or the /etc/hosts file.
+In particular, on SunOS you have to choose to use DNS (which
+you should do if you are attached to the Internet, otherwise
+you lose MX records, which are required) or NIS -- there is no
+way to try both.
+
+If you are using NIS and /etc/hosts, it is critical that you
+list the long (fully qualified) name first in the /etc/hosts file
+used to build the NIS database. For example, the line should read
+
+ 128.32.149.68 mastodon.CS.Berkeley.EDU mastodon
+
+**** NOT ****
+
+ 128.32.149.68 mastodon mastodon.CS.Berkeley.EDU
+
+If you use the wrong order, sendmail will conclude that your
+canonical name is the short version and use that in messages.
+The name "mastodon" doesn't mean much outside of Berkeley,
+and so this creates incorrect and unreplyable messages.
+
+
++-------------+
+| USE WITH MH |
++-------------+
+
+This version of sendmail notices and reports certain kinds of SMTP
+protocol violations that were ignored by older versions. If you
+are running MH you may wish to install the patch in contrib/mh.patch
+that will prevent these warning reports. This patch also works
+with the old version of sendmail, so it's safe to go ahead and
+install it.
+
+
++-----------+
+| MAKEFILES |
++-----------+
+
+The Makefiles in this release use the new Berkeley "make" that is
+available in BSD Net/2 and 4.4BSD. If you are using this version
+of make, you may notice one or two places where the Makefile includes
+"../../Makefile.inc". This file is not included with the sendmail
+distribution because it's not part of sendmail. However, it is,
+in toto:
+
+ # @(#)Makefile.inc 8.1 (Berkeley) 6/6/93
+
+ BINDIR?= /usr/sbin
+
+The other directories should all have Makefile.dist files that work
+on the old make, albeit without all the niceties included.
+
+You can also get a new Berkeley make from the Net2 release (available
+on many public FTP archives). This version should also interpret old
+Makefiles, so you could drop it in as your default make.
+
+For more details, see src/READ_ME.
+
+
++---------------------+
+| DIRECTORY STRUCTURE |
++---------------------+
+
+The structure of this directory tree is:
+
+cf Source for Berkeley configuration files. These are
+ different than what you've seen before. They are a
+ fairly dramatic rewrite, requiring the new sendmail
+ (since they use new features).
+contrib Some contributed tools to help with sendmail. THESE
+ ARE NOT SUPPORTED by Berkeley -- contact the original
+ authors if you have problems. (This directory is not
+ on the 4.4BSD tape.)
+doc Documentation. If you are getting source, read
+ op.me -- it's long, but worth it.
+mailstats Statistics printing program. It has the pathname of
+ sendmail.st compiled in, so if you've changed that,
+ beware. This isn't all that useful.
+makemap A program that creates the keyed maps used by the $( ... $)
+ construct in sendmail. It is primitive but effective.
+ It takes a very simple input format, so you will probably
+ expect to preprocess must human-convenient formats
+ using sed scripts before this program will like them.
+ But it should be functionally complete.
+praliases A program to print the DBM version of the aliases file.
+ It hasn't been converted to understand the new Berkeley
+ DB format (which we are using).
+rmail Source for rmail(8). This is used as a delivery
+ agent for for UUCP, and could presumably be used by
+ other non-socket oriented mailers. Older versions of
+ rmail are probably deficient.
+src Source for the sendmail program itself.
+test Some test scripts (currently only for compilation aids).
diff --git a/usr.sbin/sendmail/RELEASE_NOTES b/usr.sbin/sendmail/RELEASE_NOTES
new file mode 100644
index 0000000..8f7e9e8
--- /dev/null
+++ b/usr.sbin/sendmail/RELEASE_NOTES
@@ -0,0 +1,2556 @@
+ SENDMAIL RELEASE NOTES
+ @(#)RELEASE_NOTES 8.6.9.3 (Berkeley) 4/19/94
+
+This listing shows the version of the sendmail binary, the version
+of the sendmail configuration files, the date of release, and a
+summary of the changes in that release.
+
+8.6.9/8.6.9 94/04/19
+ Do all mail delivery completely disconnected from any terminal.
+ This provides consistency with daemon delivery and
+ may have some security implications.
+ Make sure that malloc doesn't get called with zero size,
+ since that fails on some systems. Reported by Ed
+ Hill of the University of Iowa.
+ Fix multi-line values for $e (SMTP greeting message). Reported
+ by Mike O'Connor of Ford Motor Company.
+ Avoid syserr if no NIS domain name is defined, but the map it
+ is trying to open is optional. From Win Bent of USC.
+ Changes for picky compilers from Ed Gould of Digital Equipment.
+ Hesiod support for UDB from Todd Miller of the University of
+ Colorado. Use "hesiod" as the service name in the U
+ option.
+ Fix a problem that failed to set the "authentic" host name (that
+ is, the one derived from the socket info) if you called
+ sendmail -bs from inetd. Based on code contributed by
+ Todd Miller (this problem was also reported by Guy Helmer
+ of Dakota State University). This also fixes a related
+ problem reported by Liudvikas Bukys of the University of
+ Rochester.
+ Parameterize "nroff -h" in all the Makefiles so people with
+ variant versions can use them easily. Suggested by
+ Peter Collinson of Hillside Systems.
+ SMTP "MAIL" commands with multiple ESMTP parameters required two
+ spaces between parameters instead of one. Reported by
+ Valdis Kletnieks of Virginia Tech.
+ Reduce the number of system calls during message collection by
+ using global timeouts around the collect() loop. This
+ code was contributed by Eric Wassenaar.
+ If the initial hostname name gathering results in a name
+ without a dot (usually caused by NIS misconfiguration)
+ and BIND is compiled in, directly access DNS to get
+ the canonical name. This should make life easier for
+ Solaris systems. If it still can't be resolved, and
+ if the name server is listed as "required", try again
+ in 30 seconds. If that also fails, exit immediately to
+ avoid bogus "config error: mail loops back to myself"
+ messages.
+ Improve the "MAIL DELETED BECAUSE OF LACK OF DISK SPACE" error
+ message to explain how much space was available and
+ sound a bit less threatening. Suggested by Stan Janet
+ of the National Institute of Standards and Technology.
+ If mail is delivered to an alias that has an owner, deliver any
+ requested return-receipt immediately, and strip the
+ Return-Receipt-To: header from the subsequent message.
+ This prevents a certain class of denial of service
+ attack, arguably gives more reasonable semantics, and
+ moves things more towards what will probably become a
+ network standard. Suggested by Christopher Davis of
+ Kapor Enterprises.
+ Add a "noreceipts" privacy flag to turn off all return receipts
+ without recompiling.
+ Avoid printing ESMTP parameters as part of the error message
+ if there are errors during parsing. This change is
+ purely cosmetic.
+ Avoid sending out error messages during the collect phase of
+ SMTP; there is an MVS mailer from UCLA that gets
+ confused by this. Of course, I think it's their bug....
+ Check for the $j macro getting undefined, losing a dot, or getting
+ lost from $=w in the daemon before accepting a connection;
+ if it is, it dumps state, prints a LOG_ALERT message,
+ and drops core for debugging. This is an attempt to
+ track down a bug that I thought was long since gone.
+ If you see this, please forward the log fragment to
+ sendmail@CS.Berkeley.EDU.
+ Change OLD_NEWDB from a #ifdef to a #if so it can be turned off
+ with -DOLD_NEWDB=0 on the command line. From Christophe
+ Wolfhugel.
+ Instead of trying to truncate the listen queue for the server
+ SMTP port when the load average is too high, just close
+ the port completely and reopen it later as needed.
+ This ensures that the other end gets a quick "connection
+ refused" response, and that the connection can be
+ recovered later. In particular, some socket emulations
+ seem to get confused if you tweak the listen queue
+ size around and can never start listening to connections
+ again. The down side is that someone could start up
+ another daemon process in the interim, so you could
+ have multiple daemons all not listening to connections;
+ this could in turn cause the sendmail.pid file to be
+ incorrect. A better approach might be to accept the
+ connection and give a 421 code, but that could break
+ other mailers in mysterious ways and have paging behaviour
+ implications.
+ Fix a glitch in TCP-level debugging that caused flag 16.101 to
+ set debugging on the wrong socket. From Eric Wassenaar.
+ When creating a df* temporary file, be sure you truncate any
+ existing data in the file -- otherwise system crashes
+ and the like could result in extra data being sent.
+ DOC: Replace the CHANGES-R5-R8 readme file with a paper in the
+ doc directory. This includes some additional
+ information.
+ CONFIG: change UUCP rules to never add $U! or $k! on the front
+ of recipient envelope addresses. This should have been
+ handled by the $&h trick, but broke if people were
+ mixing domainized and UUCP addresses. They should
+ probably have converted all the way over to uucp-uudom
+ instead of uucp-{new,old}, but the failure mode was to
+ loop the mail, which was bad news.
+ Portability fixes:
+ Newer BSDI systems (several people).
+ Older BSDI systems from Christophe Wolfhugel.
+ Intergraph CLIX, from Paul Southworth of CICNet.
+ UnixWare, from Evan Champion.
+ NetBSD from Adam Glass.
+ Solaris from Quentin Campbell of the University of
+ Newcastle upon Tyne.
+ IRIX from Dean Cookson and Bill Driscoll of Mitre
+ Corporation.
+ NCR 3000 from Kevin Darcy of Chrysler Corporation.
+ SunOS (it has setsid() and setvbuf() calls) from
+ Jonathan Kamens of OpenVision Technologies.
+ HP-UX from Tor Lillqvist.
+ New Files:
+ src/Makefile.CLIX
+ src/Makefile.NCR3000
+ doc/changes/Makefile
+ doc/changes/changes.me
+ doc/changes/changes.ps
+
+8.6.8/8.6.6 94/03/21
+ SECURITY: it was possible to read any file as root using the
+ E (error message) option. Reported by Richard Jones;
+ fixed by Michael Corrigan and Christophe Wolfhugel.
+
+8.6.7/8.6.6 94/03/14
+ SECURITY: it was possible to get root access by using wierd
+ values to the -d flag. Thanks to Alain Durand of
+ INRIA for forwarding me the notice from the bugtraq
+ list.
+
+8.6.6/8.6.6 94/03/13
+ SECURITY: the ability to give files away on System V-based
+ systems proved dangerous -- don't run as the owner
+ of a :include: file on a system that allows giveaways.
+ Unfortunately, this also applies to determining a
+ valid shell.
+ IMPORTANT: Previous versions weren't expiring old connections
+ in the connection cache for a long time under some
+ circumstances. This could result in resource exhaustion,
+ both at your end and at the other end. This checks the
+ connections for timeouts much more frequently. From
+ Doug Anderson of NCSC.
+ Fix a glitch that snuck in that caused programs to be run as
+ the sender instead of the recipient if the mail was
+ from a local user to another local user. From
+ Motonori Nakamura of Kyoto University.
+ Fix "wildcard" on /etc/shell matching -- instead of looking
+ for "*", look for "/SENDMAIL/ANY/SHELL/". From
+ Bryan Costales of ICSI.
+ Change the method used to declare the "statfs" availability;
+ instead of HASSTATFS and/or HASUSTAT with a ton of
+ tweaking in conf.c, there is a single #define called
+ SFS_TYPE which takes on one of six values (SFS_NONE
+ for no statfs availability, SFS_USTAT for the ustat(2)
+ syscall, SFS_4ARGS for a four argument statfs(2) call,
+ and SFS_VFS, SFS_MOUNT, or SFS_STATFS for a two argument
+ statfs(2) call with the declarations in <sys/vfs.h>,
+ <sys/mount.h>, or <sys/statfs.h> respectively).
+ Fix glitch in NetInfo support that could return garbage if
+ there was no "/locations/sendmail" property. From
+ David Meyer of the University of Virginia.
+ Change HASFLOCK from defined/not-defined to a 0/1 definition
+ to allow Linux to turn it off even though it is a
+ BSD-like system.
+ Allow setting of "ident" timeout to zero to turn off the ident
+ protocol entirely.
+ Make 7-bit stripping local to a connection (instead of to a
+ mailer); this allows you to specify that SMTP is a
+ 7-bit channel, but revert to 8-bit should it advertise
+ that it supports 8BITMIME. You still have to specify
+ mailer flag 7 to get this stripping at all.
+ Improve makesendmail script so it handles more cases automatically.
+ Tighten up restrictions on taking ownership of :include: files
+ to avoid problems on systems that allow you to give away
+ files.
+ Fix a problem that made it impossible to rebuild the alias
+ file if it was on a read-only file system. From
+ Harry Edmon of the University of Washington.
+ Improve MX randomization function. From John Gardiner Myers
+ of CMU.
+ Fix a minor glitch causing a bogus message to be printed (used
+ %s instead of %d in a printf string for the line number)
+ when a bad queue file was read. From Harry Edmon.
+ Allow $s to remain NULL on locally generated mail. I'm not
+ sure this is necessary, but a lot of people have complained
+ about it, and there is a legitimate question as to whether
+ "localhost" is legal as an 822-style domain.
+ Fix a problem with very short line lengths (mailer L= flag) in
+ headers. This causes a leading space to be added onto
+ continuation lines (including in the body!), and also
+ tries to wrap headers containing addresses (From:, To:,
+ etc) intelligently at the shorter line lengths. Problem
+ Reported by Lars-Johan Liman of SUNET Operations Center.
+ Log the real user name when logging syserrs, since these can have
+ security implications. Suggested by several people.
+ Fix address logging of cached connections -- it used to always
+ log the numeric address as zero. This is a somewhat
+ bogus implementation in that it does an extra system
+ call, but it should be an inexpensive one. Fix from
+ Motonori Nakamura.
+ Tighten up handling of short syslog buffers even more -- there
+ were cases where the outgoing relay= name was too long
+ to share a line with delay= and mailer= logging.
+ Limit the overhead on split envelopes to one open file descriptor
+ per envelope -- previously the overhead was three
+ descriptors. This was in response to a problem reported
+ by P{r (Pell) Emanuelsson.
+ Fixes to better handle the case of unexpected connection closes;
+ this redirects the output to the transcript so the info
+ is not lost. From Eric Wassenaar.
+ Fix potential string overrun if you macro evaluate a string that
+ has a naked $ at the end. Problem noted by James Matheson
+ <jmrm@eng.cam.ac.uk>.
+ Make default error number on $#error messages 553 (``Requested
+ action not taken: mailbox name not allowed'') instead of
+ 501 (``Syntax error in parameters or arguments'') to
+ avoid bogus "protocol error" messages.
+ Strip off any existing trailing dot on names during $[ ... $]
+ lookup. This prevents it from ending up with two dots
+ on the end of dot terminated names. From Wesley Craig
+ of the University of Michigan and Bryan Costales of ICSI.
+ Clean up file class reading so that the debugging information is
+ more informative. It hadn't been using setclass, so you
+ didn't see the class items being added.
+ Avoid core dump if you are running a version of sendmail where
+ NIS is compiled in, and you specify an NIS map, but
+ NIS is not running. Fix from John Oleynick of
+ Rutgers.
+ Diagnose bizarre case where res_search returns a failure value,
+ but sets h_errno to a success value.
+ Make sure that "too many hops" messages are considered important
+ enough to send an error to the Postmaster (that is, the
+ address specified in the P option). This fix should
+ help problems that cause the df file to be left around
+ sometimes -- unfortunately, I can't seem to reproduce
+ the problem myself.
+ Avoid core dump (null pointer reference) on EXPN command; this
+ only occurred if your log level was set to 10 or higher
+ and the target account was an alias or had a .forward file.
+ Problem noted by Janne Himanka.
+ Avoid "denial of service" attacks by someone who is flooding your
+ SMTP port with bad commands by shutting the connection
+ after 25 bad commands are issued. From Kyle Jones of
+ UUNET.
+ Fix core dump on error messages with very long "to" buffers;
+ fmtmsg overflows the message buffer. Fixed by trimming
+ the to address to 203 characters. Problem reported by
+ John Oleynick.
+ Fix configuration for HASFLOCK -- there were some spots where
+ a #ifndef was incorrectly #ifdef. Pointed out by
+ George Baltz of the University of Maryland.
+ Fix a typo in savemail() that could cause the error message To:
+ lists to be incorrect in some places. From Motonori
+ Nakamura.
+ Fix a glitch that can cause duplicate error messages on split
+ envelopes where an address on one of the lists has a
+ name server failure. Fix from Voradesh Yenbut of the
+ University of Washington.
+ Fix possible bogus pointer reference on ESMTP parameters that
+ don't have an ``=value'' part.
+ CNAME loops caused an error message to be generated, but also
+ re-queued the message. Changed to just re-queue the
+ message (it's really hard to just bounce it because
+ of the wierd way the name server works in the presence
+ of CNAME loops). Problem noted by James M.R.Matheson
+ of Cambridge University.
+ Avoid giving ``warning: foo owned process doing -bs'' messages
+ if they use ``MAIL FROM:<foo>'' where foo is their true
+ user name. Suggested by Andreas Stolcke of ICSI.
+ Change the NAMED_BIND compile flag to be a 0/1 flag so you can
+ override it easily in the Makefile -- that is, you can
+ turn it off using -DNAMED_BIND=0.
+ If a gethostbyname(...) of an address with a trailing dot fails,
+ try it without the trailing dot. This is because if
+ you have a version of gethostbyname() that falls back
+ to NIS or the /etc/hosts file it will fail to find
+ perfectly reasonable names that just don't happen to
+ be dot terminated in the hosts file. You don't want to
+ strip the dot first though because we're trying to ensure
+ that country names that match one of your subdomains get
+ a chance.
+ PRALIASES: fix bogus output on non-null-terminated strings.
+ From Bill Gianopoulos of Raytheon.
+ CONFIG: Avoid rewriting anything that matches $w to be $j.
+ This was in code intended to only catch the self-literal
+ address (that is, [1.2.3.4], where 1.2.3.4 is your
+ IP address), but the code was broken. However, it will
+ still do this if $M is defined; this is necessary to
+ get client configurations to work (sigh). Note that this
+ means that $M overrides :mailname entries in the user
+ database! Problem noted by Paul Southworth.
+ CONFIG: Fix definition of Solaris help file location. From
+ Steve Cliffe <steve@gorgon.cs.uow.edu.au>.
+ CONFIG: Fix bug that broke news.group.USENET mappings.
+ CONFIG: Allow declaration of SMTP_MAILER_MAX, FAX_MAILER_MAX,
+ and USENET_MAILER_MAX to tweak the maximum message
+ size for various mailers.
+ CONFIG: Change definition of USENET_MAILER_ARGS to include argv[0]
+ instead of assuming that it is "inews" for consistency
+ with other mailers. From Michael Corrigan of UC San Diego.
+ CONFIG: When mail is forwarded to a LOCAL_RELAY or a MAIL_HUB,
+ qualify the address in the SMTP envelope as user@{relay|hub}
+ instead of user@$j. From Bill Wisner of The Well.
+ CONFIG: Fix route-addr syntax in nullrelay configuration set.
+ CONFIG: Don't turn off case mapping of user names in the local
+ mailer for IRIX. This was different than most every other
+ system.
+ CONFIG: Avoid infinite loops on certainly list:; syntaxes in
+ envelope. Noted by Thierry Besancon
+ <besancon@excalibur.ens.fr>.
+ CONFIG: Don't include -z by default on uux line -- most systems
+ don't want it set by default. Pointed out by Philippe
+ Michel of Thomson CSF.
+ CONFIG: Fix some bugs with mailertables -- for example, if your
+ host name was foo.bar.ray.com and you matched against
+ ".ray.com", the old implementation bound %1 to "bar"
+ instead of "foo.bar". Also, allow "." in the mailertable
+ to match anything -- essentially, take over SMART_HOST.
+ This also moves matching of explicit local host names
+ before the mailertable so they don't have to be special
+ cased in the mailertable data. Reported by Bill
+ Gianopoulos of Raytheon; the fix for the %1 binding
+ problem was contributed by Nicholas Comanos of the
+ University of Sydney.
+ CONFIG: Don't include "root" in class $=L (users to deliver
+ locally, even if a hub or relay exists) by default.
+ This is because of the known bug where definition of
+ both a LOCAL_RELAY and a MAIL_HUB causes $=L to ignore
+ both and deliver into the local mailbox.
+ CONFIG: Move up bitdomain and uudomain handling so that they
+ are done before .UUCP class matching; uudomain was
+ reported as ineffective before. This also frees up
+ diversion 8 for future use. Problem reported by Kimmo
+ Suominen.
+ CONFIG: Don't try to convert dotted IP address (e.g., [1.2.3.4])
+ into host names. As pointed out by Jonathan Kamens,
+ these are often used because either the forward or reverse
+ mapping is broken; this translation makes it broken again.
+ DOC: Clarify $@ and $: in the Install & Op Guide. From Kimmo
+ Suominen.
+ Portability fixes:
+ Unicos from David L. Kensiski of Sterling Sofware.
+ DomainOS from Don Lewis of Silicon Systems.
+ GNU m4 1.0.3 from Karst Koymans of Utrecht University.
+ Convex from Kimmo Suominen <kim@tac.nyc.ny.us>.
+ NetBSD from Adam Glass <glass@sun-lamp.cs.berkeley.edu>.
+ BSD/386 from Tony Sanders of BSDI.
+ Apollo from Eric Wassenaar.
+ DGUX from Doug Anderson.
+ Sequent DYNIX/ptx 2.0 from Tim Wright of Sequent.
+ NEW FILES:
+ src/Makefile.DomainOS
+ src/Makefile.PTX
+ src/Makefile.SunOS.5.1
+ src/Makefile.SunOS.5.2
+ src/Makefile.SunOS.5.x
+ src/mailq.1
+ cf/ostype/domainos.m4
+ doc/op/Makefile
+ doc/intro/Makefile
+ doc/usenix/Makefile
+
+8.6.5/8.6.5 94/01/13
+ Security fix: /.forward could be owned by anyone (the test
+ to allow root to own any file was backwards). From
+ Bob Campbell at U.C. Berkeley.
+ Security fix: group ids were not completely set when programs
+ were invoked. This caused programs to have group
+ permissions they should not have had (usually group
+ daemon instead of their own group). In particular,
+ Perl scripts would refuse to run.
+ Security: check to make sure files that are written are not
+ symbolic links (at least under some circumstances).
+ Although this does not respond to a specific known
+ attack, it's just a good idea. Suggested by
+ Christian Wettergren.
+ Security fix: if a user had an NFS mounted home directory on
+ a system with a restricted shell listed in their
+ /etc/passwd entry, they could still execute any
+ program by putting that in their .forward file.
+ This fix prevents that by insisting that their shell
+ appear in /etc/shells before allowing a .forward to
+ execute a program or write a file. You can disable
+ this by putting "*" in /etc/shells. It also won't
+ permit world-writable :include: files to reference
+ programs or files (there's no way to disable this).
+ These behaviours are only one level deep -- for
+ example, it is legal for a world-writable :include:
+ file to reference an alias that writes a file, on
+ the assumption that the alias file is well controlled.
+ Security fix: root was not treated suspiciously enough when
+ looking into subdirectories. This would potentially
+ allow a cracker to examine files that were publically
+ readable but in a non-publically searchable directory.
+ Fix a problem that causes an error on QUIT on a cached
+ connection to create problems on the current job.
+ These are typically unrelated, so errors occur in
+ the wrong place.
+ Reset CurrentLA in sendall() -- this makes sendmail queue
+ runs more responsive to load average, and fixes a
+ problem that ignored the load average in locally
+ generated mail. From Eric Wassenaar.
+ Fix possible core dump on aliases with null LHS. From
+ John Orthoefer of BB&N.
+ Revert to using flock() whenever possible -- there are just
+ too many bugs in fcntl() locking, particularly over
+ NFS, that cause sendmail to fail in perverse ways.
+ Fix a bug that causes the connection cache to get confused
+ when sending error messages. This resulted in
+ "unexpected close" messages. It should fix itself
+ on the following queue run. Problem noted by
+ Liudvikas Bukys of the University of Rochester.
+ Include $k in $=k as documented in the Install & Op Guide.
+ This seems odd, but it was documented.... From
+ Michael Corrigan of UCSD.
+ Fix problem that caused :include:s from alias files to be
+ forced to be owned by root instead of daemon
+ (actually DefUid). From Tim Irvin.
+ Diagnose unrecognized I option values -- from Mortin Forssen
+ of the Chalmers University of Technology.
+ Make "error" mailer work consistently when there is no error
+ code associated with it -- previously it returned OK
+ even though there was a real problem. Now it assumes
+ EX_UNAVAILABLE.
+ Fix bug that caused the last header line of messages that had
+ no body and which were terminated with EOF instead of
+ "." to be discarded. Problem noted by Liudvikas Bukys.
+ Fix core dump on SMTP mail to programs that failed -- it tried
+ to go to a "next MX host" when none existed, causing
+ a core dump. From der Mouse at McGill University.
+ Change IDENTPROTO from a defined/not defined to a 0/1 switch;
+ this makes it easier to turn it off (using
+ -DIDENTPROTO=0 in the Makefile). From der Mouse.
+ Fix YP_MASTER_NAME store to use the unupdated result of
+ gethostname() (instead of myhostname(), which tries
+ to fully qualify the name) to be consistent with
+ SunOS. If your hostname is unqualified, this fixes
+ transfers to slave servers. Bug noted by Keith
+ McMillan of Ameritech Services, Inc.
+ Fix Ultrix problem: gethostbyname() can return a very large
+ (> 500) h_length field, which causes the sockaddr
+ to be trashed. Use the size of the sockaddr instead.
+ Fix from Bob Manson of Ohio State.
+ Don't assume "-a." on host lookups if NAMED_BIND is not
+ defined -- this confuses gethostbyname on hosts
+ file lookups, which doesn't understand the trailing
+ dot convention.
+ Log SMTP server subprocesses that die with a signal instead
+ of from a clean exit.
+ If you don't have option "I" set, don't assume that a DNS
+ "host unknown" message is authoritative -- it
+ might still be found in /etc/hosts.
+ Fix a problem that would cause Deferred: messages to be sent
+ as the subject of an error message, even though the
+ actual cause of a message was more severe than that.
+ Problem noted by Chris Seabrook of OSSI.
+ Fix race condition in DBM alias file locking. From Kyle
+ Jones of UUNET.
+ Limit delivery syslog line length to avoid bugs in some
+ versions of syslog(3). This adds a new compile time
+ variable SYSLOG_BUFSIZE. From Jay Plett of Princeton
+ University, which is in turn derived from IDA.
+ Fix quotes inside of comments in addresses -- previously
+ it insisted that they be balanced, but the 822 spec
+ says that they should be ignored.
+ Dump open file state to syslog upon receiving SIGUSR1 (for
+ debugging). This also evaluates ruleset 89, if set
+ (with the null input), and logs the result. This
+ should be used sparingly, since the rewrite process
+ is not reentrant.
+ Change -qI, -qR, and -qS flags to be case-insensitive as
+ documented in the Bat Book.
+ If the mailer returned EX_IOERR or EX_OSERR, sendmail did not
+ return an error message and did not requeue the message.
+ Fix based on code from Roland Dirlewanger of
+ Reseau Regional Aquarel, Bordeaux, France.
+ Fix a problem that caused a seg fault if you got a 421 error
+ code during some parts of connection initialization.
+ I've only seen this when talking to buggy mailers on
+ the other end, but it shouldn't give a seg fault in
+ any case. From Amir Plivatsky.
+ Fix core dump caused by a ruleset call that returns null.
+ Fix from Bryan Costales of ICSI.
+ Full-Name: field was being ignored. Fix from Motonori Nakamura
+ of Kyoto University.
+ Fix a possible problem with very long input lines in setproctitle.
+ From P{r Emanuelsson.
+ Avoid putting "This is a warning message" out on return receipts.
+ Suggested by Douglas Anderson.
+ Detect loops caused by recursive ruleset calls. Suggested by
+ Bryan Costales.
+ Initialize non-alias maps during alias rebuilds -- they may be
+ needed for parsing. Problem noted by Douglas Anderson.
+ Log sender address even if no message was collected in SMTP
+ (e.g., if all RCPTs failed). Suggested by Motonori
+ Nakamura.
+ Don't reflect the owner-list contents into the envelope sender
+ address if the value contains ", :, /, or | (to avoid
+ illegal addresses appearing there).
+ Efficiency hack for toktype macro -- from Craig Partridge of
+ BB&N.
+ Clean up DNS error printing so that a host name is always
+ included.
+ Remember to set $i during queue runs. Reported by Stephen
+ Campbell of Dartmouth University.
+ If ${HOSTALIASES} is set, use it during canonification so that
+ headers are properly mapped. Reported by Anne Bennett
+ of Concordia University.
+ Avoid printing misleading error message if SMTP mailer (not
+ using [IPC]) should die on a core dump.
+ Avoid incorrect diagnosis of "file 1 closed" when it is caused
+ by the other end closing the connection. From
+ Dave Morrison of Oracle.
+ Improve several of the error messages printed by "mailq"
+ to include a host name or other useful information.
+ Add NetInfo preliminary support for NeXT systems. From Vince
+ DeMarco.
+ Fix a glitch that sometimes caused :include:s that pointed to
+ NFS filesystems that were down to give an "aliasing/
+ forwarding loop broken" message instead of queueing
+ the message for retry. Noted by William C Fenner of
+ the NRL Connection Machine Facility.
+ Fix a problem that could cause a core dump if the input sequence
+ had (or somehow acquired) a \231 character.
+ Make sure that route-addrs always have <angle brackets> around
+ them in non-SMTP envelopes (SMTP envelopes already do
+ this properly).
+ Avoid wierd headers on unbalanced punctuation of the form:
+ ``Joe User <user)'' -- this caused reference to the
+ null macro. Fix from Rick McCarty of IO.COM.
+ Fix a problem that caused an alias "user: user@local.host" to
+ not have the QNOTREMOTE bit set; this caused configs
+ to act as if FEATURE(notsticky) was defined even when
+ it was not. The effect of the problem was to make it
+ very hard to to set up satellite sites that had a few
+ local accounts, with everything else forwarded to a
+ corporate hub. Reported by Detlef Drewanz of the
+ University of Rostock and Mark Frost of NCD.
+ Change queuing to not call rulesets 3, {1 or 2}, 4 on header
+ addresses. This is more efficient (fewer name server
+ calls) and fixes certain unusual configurations, such
+ as those that have ruleset 4 do something that is
+ non-idempotent unless a mailer-specific ruleset did
+ something else. Problem reported by Brian J. Coan
+ of the Institute for Global Communications.
+ Fix the "obsolete argument" routine in main to better understand
+ new arguments. For example, if you used ``sendmail
+ -C config -v -q'' it would choke on the -q because
+ the -C would stop looking for old-format arguments.
+ Fix the code that was intended to allow two users to forward their
+ mail to the same program and have them appear unique.
+ Portability fixes for:
+ SCO UNIX from Murray Kucherawy.
+ SCO Open Server 3.2v4 from Philippe Brand.
+ System V Release 4 from Rick Ellis and others.
+ OSF/1 from Steve Campbell.
+ DG/UX from Ben Mesander of the USGS and Bryan Curnutt
+ of Stoner Associates.
+ Motorola SysV88 from Kevin Johnson of Motorola.
+ Solaris 2.3 from Casper H.S. Dik of the University
+ of Amsterdam and John Caruso of University
+ of Maryland.
+ FreeBSD from Ollivier Robert.
+ NetBSD from Adam Glass.
+ TitanOS from Kate Hedstrom of Rutgers University.
+ Irix from Bryan Curnutt.
+ Dynix from Jim Davis of the University of Arizona.
+ RISC/os.
+ Linux from John Kennedy of California State University
+ at Chico.
+ Solaris 2.x from Tony Boner of the U.S. Air Force.
+ NEXTSTEP 3.x from Vince DeMarco.
+ HP-UX from various people. NOTA BENE: the location
+ of the config file has moved to /usr/lib
+ to match the HP-UX version of sendmail.
+ CONFIG: Don't do any recipient rewriting on relay mailer;
+ since this is intended only for internal use, the
+ usual RFC 821/822/1123 rules can be relaxed. The
+ main point of this is to avoid munging (ugh) UUCP
+ addresses when relaying internally.
+ CONFIG: fix typo in mailer/uucp.m4 that mutilates list:;
+ syntax addresses delivered via UUCP. Solution
+ provided by Peter Wemm.
+ CONFIG: fix thumb-fumble in default UUCP relaying in ruleset
+ zero; it caused double @ signs in addresses. From
+ Irving Reid of the University of Toronto.
+ CONFIG: Portability fixes for SCO Unix 3.2 with TCP/IP 1.2.1
+ from Markku Toijala of ICL Personal Systems Oy.
+ CONFIG: Add trailing "." on pseudo-domains for consistency;
+ this fixes a problem (noted by Al Whaley of Sunnyside)
+ that made it hard to recognize your own pseudodomain
+ names.
+ CONFIG: catch "@host" syntax errors (i.e., null local-parts)
+ rather than letting them get "local configuration
+ error"s. Problem noted by John Gardiner Myers.
+ CONFIG: add uucp-uudom mailer variant, based on code posted
+ by Spider Boardman <spider@Orb.Nashua.NH.US>; this
+ has uucp-dom semantics but old UUCP syntax. This
+ also permits "uucp-old" as an alias for "uucp" and
+ "uucp-new" as a synonym for "suucp" for consistency.
+ CONFIG: add POP mailer support (from Kimmo Suominen
+ <kim@grendel.lut.fi>).
+ CONFIG: drop CSNET_RELAY support -- CSNET is long gone.
+ CONFIG: fix bug caused with domain literal addresses (e.g.,
+ ``[128.32.131.12]'') when FEATURE(allmasquerade)
+ was set; it would get an additional @masquerade.host
+ added to the address. Problem noted by Peter Wan
+ of Georgia Tech.
+ CONFIG: make sure that the local UUCP name is in $=w. From
+ Jim Murray of Stratus.
+ CONFIG: changes to UUCP rewriting to simulate IDA-style "V"
+ mailer flag. Briefly, if you are sending to host
+ "foo", then it rewrites "foo!...!baz" to "...!baz",
+ "foo!baz" remains "foo!baz", and anything else has
+ the local name prepended.
+ CONFIG: portability fixes for HP-UX.
+ DOC: several minor problems fixed in the Install & Op Guide.
+ MAKEMAP: fix core dump problem on lines that are too long or
+ which lack newline. From Mark Delany.
+ MAILSTATS: print sums of columns (total messages & kbytes
+ in and out of the system). From Tom Ferrin of UC
+ San Francisco Computer Graphics Lab.
+ SIGNIFICANT USER- OR SYSAD-VISIBLE CHANGES:
+ On HP-UX, /etc/sendmail.cf has been moved to
+ /usr/lib/sendmail.cf to match HP sendmail.
+ Permissions have been tightened up on world-writable
+ :include: files and accounts that have shells
+ that are not listed in /etc/shells. This may
+ cause some .forward files that have worked
+ before to start failing.
+ SIGUSR1 dumps some state to the log.
+ NEW FILES:
+ src/Makefile.DGUX
+ src/Makefile.Dynix
+ src/Makefile.FreeBSD
+ src/Makefile.Mach386
+ src/Makefile.NetBSD
+ src/Makefile.RISCos
+ src/Makefile.SCO
+ src/Makefile.SVR4
+ src/Makefile.Titan
+ cf/mailer/pop.m4
+ cf/ostype/bsdi1.0.m4
+ cf/ostype/dgux.m4
+ cf/ostype/dynix3.2.m4
+ cf/ostype/sco3.2.m4
+ makemap/Makefile.dist
+ praliases/Makefile.dist
+
+8.6.4/8.6.4 93/10/31
+ Repair core-dump problem (write to read-only memory segment)
+ if you fall back to the return-to-Postmaster case in
+ savemail. Problem reported by Richard Liu.
+ Immediately diagnose bogus sender addresses in SMTP. This
+ makes quite certain that crackers can't use this
+ class of attack.
+ Reliability Fix: check return value from fclose() and fsync()
+ in a few critical places.
+ Minor problem in initsys() that reversed a condition for
+ redirecting the output channel on queue runs. It's
+ not clear this code even does anything. From Eric
+ Wassenaar of the Dutch National Institute for Nuclear
+ and High-Energy Physics.
+ Fix some problems that caused queue runs to do "too much work",
+ such as double-reading the Errors-To: header. From
+ Eric Wassenaar.
+ Error messages on writing the temporary file (including the
+ data file) were getting suppressed in SMTP -- this
+ fix causes them to be properly reported. From Eric
+ Wassenaar.
+ Some changes to support AF_UNIX sockets -- this will only
+ really become relevant in the next release, but some
+ people need it for local patches. From Michael
+ Corrigan of UC San Diego.
+ Use dynamically allocated memory (instead of static buffers)
+ for macros defined in initsys() and settime(); since
+ these can have different values depending on which
+ envelope they are in. From Eric Wassenaar.
+ Improve logging to show ctladdr on to= logging; this tells you
+ what uid/gid processes ran as.
+ Fix a problem that caused error messages to be discarded if
+ the sender address was unparseable for some reason;
+ this was supposed to fall back to the "return to
+ postmaster" case.
+ Improve aliaswait backoff algorithm.
+ Portability patches for Linux (8.6.3 required another header
+ file) (from Karl London) and SCO UNIX.
+ CONFIG: patch prog mailer to not strip host name off of envelope
+ addresses (so that it matches local again). From
+ Christopher Davis.
+ CONFIG: change uucp-dom mailer so that "<>" translates to $n;
+ this prevents uux from seeing lines with null names like
+ ``From Sat Oct 30 14:55:31 1993''. From Motonori
+ Nakamura of Kyoto University.
+ CONFIG: handle <list:;> syntax correctly. This isn't legal, but
+ it shouldn't fail miserably. From Motonori Nakamura.
+
+8.6.3/8.6.3 93/10/24
+ IMPORTANT FIX: Fix several problems that caused open files to
+ be "lost" during queue runs; this overflowed the open
+ file table on large runs. An assumption that fdopen
+ always succeeds sometimes resulted in core dumps when
+ this happens; sometimes the message is delivered twice,
+ sometimes (probably) infinite times. This problem in
+ various form was reported by P{r (Pell) Emanuelsson and
+ Robert Campbell of U.C. Berkeley.
+ Special diagnosis of EMFILE error conditions -- it now prints
+ the known open file descriptors so you can figure out
+ what is consuming so much resources.
+ Fix a couple of problems caused by early address parsing
+ errors -- one caused it to return a "this is only a
+ warning" when it really wasn't, and the other started
+ parsing through a random pointer. The first was
+ noted by Eric Wassenaar.
+ Fix an infinite loop problem caused by null components in the
+ host signature. Problem noted by Jan Sorensen.
+ Be sure to reset the "current date" when sending an error
+ message -- PostMasterCopy messages were being sent
+ with an old Date: header.
+ Fix a problem that caused duplicated mail when sendmail was
+ (1) compiled without HASFLOCK, (2) you are sending to
+ an alias that has an owner-* alias, (3) you execute
+ sendmail with -t flag, (4) you run in -odb mode, and
+ (5) the sender specifies both the alias name and
+ another alias [i.e., the envelope is split], then
+ duplicate messages are sent. The problem description
+ and one-line fix are from Motonori Nakamura of Kyoto
+ University.
+ Avoid a problem that causes error messages to be discarded
+ in some cases -- this was the result of a "fix" to
+ avoid duplicate error messages, but two are better
+ than zero. Reported by Tim Rylance.
+ Fix a minor botch in checkfd012() -- fix from Dave Hill of
+ Computervision R&D Ltd.
+ Remove "X-Authentication-Warning: <user> set sender to <address>
+ using -f" entirely -- it is far too eager to include
+ this, and it is confusing folks. I'll try to make it
+ work "right" in 8.7. Problem noted by Yoshitaka
+ Tokugawa of dit Co., Ltd.
+ Fix a race condition with the errno value in tick() and
+ reapchild() -- this caused occasional misdiagnosis
+ of problems. Kyle Jones of UUNET helped this along.
+ Repair rule loop-detection code. From Michael Corrigan of
+ U.C. San Diego.
+ Fix a problem that caused sender domain addition (C mailer
+ flag to be ignored if you use -odq or use -odb with
+ a high load average. Problem reported by Jim Murray
+ of Stratus.
+ Fix ident protocol on multi-homed machines. It was not
+ always using the correct interface. Fix from J.R.
+ Oldroyd of Opal.
+ Previously, sendmail assumed that any SMTP greeting message
+ that wasn't 2xx was a temporary failure -- it should
+ only take 4xx as a temporary failure, and return a
+ solid error message on anything else -- for example,
+ to allow you to reject connections on a workstation
+ that is MXed to a mail server.
+ Portability enhancements for 386BSD/FreeBSD/NetBSD from
+ Ollivier Robert.
+ CONFIG: FEATURE(always_add_domain) didn't always add the domain;
+ in particular, on local mail it modified the header sender
+ but not the header recipient address(es). Reported by
+ Jeffrey Honig of Cornell University. Also, strip
+ any host from envelope recipient address(es), since
+ local mailers don't understand host names -- this is
+ to help mailertable entries. From Christopher Davis.
+ CONFIG: masquerading didn't apply to addresses that already
+ had a domain. This change replaces a local hostname
+ by the masquerade name in the SMTP mailer (previously
+ it only added the masquerade name if it didn't already
+ have a domain name). Several people complained about
+ this.
+
+8.6.2/8.6.2 93/10/15
+ Put a "successful delivery" message in the transcript for
+ addresses that get return-receipts.
+ Put a prominent "this is only a warning" message in warning
+ messages -- some people don't read carefully enough
+ and end up sending the message several times.
+ Include reason for temporary failure in the "warning" return
+ message. Currently, it just says "cannot send for
+ four hours".
+ Fix the "Original message received" time generated for
+ returntosender messages. It was previously listed as
+ the current time. Bug reported by Eric Hagberg of
+ Cornell University Medical College.
+ If there is an error when writing the body of a message,
+ don't send the trailing dot and wait for a response
+ in sender SMTP, as this could cause the connection to
+ hang up under some bizarre circumstances. From Eric
+ Wassenaar.
+ Fix some server SMTP synchronization problems caused when
+ connections fail during message collection. From
+ Eric Wassenaar.
+ Fix a problem that can cause srvrsmtp to reject mail if the
+ name server is down -- it accepts the RCPT but rejects
+ the DATA command. Problem reported by Jim Murray of
+ Stratus.
+ Fix a problem that can cause core dumps if the config file
+ incorrectly resolves to a null hostname. Reported by
+ Allan Johannesen of WPI.
+ Non-root use of -C flag, dangerous -f flags, and use of -oQ
+ by non-root users were not put into
+ X-Authentication-Warning:s as intended because the
+ config file hadn't set the PrivacyFlags yet. Fix
+ from Sven-Ove Westberg of the University of Lulea.
+ Under very odd circumstances, the alias file rebuild code
+ could get confused as to whether a database was
+ open or not.
+ Check "vendor code" on the end of V lines -- this is
+ intended to provide a hook for vendor-specific
+ configuration syntax. (This is a "new feature",
+ but I've made an exception to my rule in a belief
+ that this is a highly exceptional case.)
+ Portability fixes for DG/UX (from Douglas Anderson of NCSC),
+ SCO Unix (from Murray Kucherawy), A/UX, and OSF/1
+ (from Jon Forrest of UC Berkeley)
+ CONFIG: fix ``mailer:host'' form of UUCP relay naming.
+
+8.6.1/8.6 93/10/08
+ Portability fixes for A/UX and Encore UMAX V.
+ Fix error message handling -- if you had a name server down
+ causing an error during parsing, that message was never
+ propogated to the queue file.
+
+8.6/8.6 93/10/05
+ Configuration cleanup: make it easier to undo IDENTPROTO in
+ conf.h (other systems have the same bug).
+ If HASGETDTABLESIZE and _SC_OPEN_MAX are both defined, assume
+ getdtablesize() instead of sysconf(); a disturbingly
+ large number of systems defined _SC_OPEN_MAX in the
+ header files but don't have the syscall.
+ Another patch to really truly ignore MX records in getcanonname
+ if trymx == FALSE.
+ Fix problem that caused the "250 IAA25499 Message accepted for
+ delivery" message to be omitted if there was an error
+ in the header of the message (e.g., a bad Errors-To:
+ line). Pointed out by Michael Corrigan of UCSD.
+ Announce name of host we are chatting when we get errors; this
+ is an IDA-ism suggested by Christophe Wolfhugel.
+ Portability fixes for Alpha OSF/1 (from Anthony Baxter of the
+ Australian Artificial Intelligence Institute), SCO Unix
+ (from Murray Kucherawy of Hookup Communication Corp.),
+ NeXT (from Vince DeMarco and myself), Linux (from
+ Karl London <karl@borg.demon.co.uk>), BSDI (from
+ Christophe Wolfhugel, and SVR4 on Dell (from Kimmo
+ Suominen), AUX 3.0 on Macintosh, and ANSI C compilers.
+ Some changes to get around gcc optimizer bugs. From Takahiro
+ Kanbe.
+ Fix error recovery in queueup if another tf file of the same
+ name already exists. Problem stumbled over by Bill
+ Wisner of The Well.
+ Output YP_MASTER_NAME and YP_LAST_MODIFIED without null bytes.
+ Problem noted by Keith McMillan of Ameritech Services.
+ Deal with group permissions properly when opening .forward and
+ :include: files. This relaxes the 8.1C restrictions
+ slightly more. This includes proper setting of groups
+ when reading :include: files, allowing you to read some
+ files that you should be able to read but have previously
+ been denied unless you owned them or they had "other"
+ read permission.
+ Make certain that $j is in $=w (after the .cf is read) so that
+ if the user is forced to override some silly system,
+ MX suppression will still work.
+ Fix a couple of efficiency problems where newstr was double-
+ calling expensive routines. In at least one case, it
+ wasn't guaranteed that they would always return the
+ same result. Problem noted by Christophe Wolfhugel.
+ Fix null pointer dereference in putoutmsg -- only on an error
+ condition from a non-SMTP mailer. From Motonori
+ Nakamura.
+ Macro expand "C" line class definitions before scanning so that
+ "CX $Z" works.
+ Fix problem that caused error message to be sent while still
+ trying to send the original message if the connection
+ is closed during a DATA command after getting an error
+ on an RCPT command (pretty obscure). Problem reported
+ by John Myers of CMU.
+ Fix reply to NOOP to be 250 instead of 200 -- this is a long
+ term bug.
+ Fix a nasty bug causing core dumps when returning the "warning:
+ cannot deliver for N hours -- will keep trying" message;
+ it only occurred if you had PostMasterCopy set and
+ only on some architectures. Although sendmail would
+ keep trying, it would send error messages on each
+ queue interval. This is an important fix.
+ Allow u and g options to take user and group names respectively.
+ Don't do a chdir into the queue directory in -bt mode to make
+ ruleset testing a bit easier.
+ Don't allow users to turn off logging (using -oL) on the command
+ line -- command line can only raise, not lower, logging
+ level.
+ Set $u to the original recipient on the SMTP transaction or on
+ the command line. This is only done if there is exactly
+ one recipient. Technically, this does not meet the
+ specs, because it does not guarantee a domain on the
+ address.
+ Fix a problem that dumped error messages on bad addresses if
+ you used the -t flag. Problem noted by Josh Smith of
+ Harvey Mudd College.
+ Given an address such as ``<foo> <bar>'', auto-quote the first
+ ``<foo>'' part, giving ``"<foo>" <bar>''. This is to
+ avoid the problem of people who use angle brackets in
+ their full name information.
+ Fix a null pointer dereference if you set option "l", have
+ an Errors-To: header in the message, and have Errors-To:
+ defined in the config file H lines. From J.R. Oldroyd.
+ Put YPCOMPAT on #ifdef NIS instead -- it's one less thing to get
+ wrong when compiling. Suggested by Rick McCarty of TI.
+ Fix a problem that could pass negative SIZE parameter if the
+ df file got lost; this would cause servers to always
+ give a temporary failure, making the problem even worse.
+ Problem noted by Allan Johannesen of WPI.
+ Add "ident" timeout (one of the "r" option selectors) for IDENT
+ protocol timeouts (30s default). Requested by Murray
+ Kucherawy of HookUp Communication Corp. to handle bogus
+ PC TCP/IP implementations.
+ Change $w default definition to be just the first component of
+ the domain name on config level 5. The $j macro defaults
+ to the FQDN; $m remains as before. This lets well-behaved
+ config files use any of the short, long, or subdomain
+ names.
+ Add makesendmail script in src to try to automate multi-architecture
+ builds. I know, this is sub-optimal, but it is still
+ helpful.
+ Fix very obscure race condition that can cause a queue run to
+ get a queue file for an already completed job. This
+ problem has existed for years. Problem noted by the
+ long suffering Allan Johannesen of WPI.
+ Fix a problem that caused the raw sender name to be passed to
+ udbsender instead of the canonified name -- this caused
+ it to sometimes miss records that it should have found.
+ Relax check of name on HELO packet so that a program using -bs
+ that claims to be itself works properly.
+ Restore rewriting of $: part of address through 2, R, 4 in
+ buildaddr -- this requires passing a lot of flags to get
+ it right. Unlike old versions, this ONLY rewrites
+ recipient addresses, not sender addresses.
+ Fix a bug that caused core dumps in config files that cannot
+ resolve /file/name style addresses. Fix from Jonathan
+ Kamens of OpenVision Technologies.
+ Fix problem with fcntl locking that can cause error returns to
+ be lost if the lock is lost; this required fully
+ queueing everything, dropping the envelope (so errors
+ would get returned), and then re-reading the queue from
+ scratch.
+ Fix a problem that caused aliases that redefine an otherwise
+ true address to still send to the original address
+ if and only if the alias failed in certain bizarre
+ ways (e.g, if they pointed at a list:; syntax address).
+ Problem pointed out by Jonathan Kamens.
+ Remove support for frozen configuration files. They caused
+ more trouble than it was worth.
+ Fix problem that can cause error messages to get ignored when
+ using both -odb and -t flags. Problem noted by Rob
+ McNicholas at U.C. Berkeley.
+ Include all "normal" variations on hostname in $=w. For example,
+ if the host name is vangogh.cs.berkeley.edu, $=w will
+ contain vangogh, vangogh.cs, and vangogh.cs.berkeley.edu.
+ Add "restrictqrun" privacy flag -- without this, anyone can run
+ the queue.
+ Reset SmtpPhase global on initial connection creation so that
+ messages don't come out with stale information.
+ Pass an "ext" argument to lockfile so that error/log messages
+ will properly reflect the true filename being locked.
+ Put all [...] address forms into $=w -- this eliminates the need
+ for MAXIPADDR in conf.h. Suggested by John Gardiner
+ Myers of CMU.
+ Fix a bug that can cause qf files to be left around even after
+ an SMTP RSET command. Problem and fix from Michael
+ Corrigan.
+ Don't send a PostMasterCopy to errors when the Precedence: is
+ negative. Error reports still go to the envelope
+ sender address.
+ Add LA_SHORT for load averages.
+ Lock sendmail.st file when posting statistics.
+ Add "SendBufSize" and "RcvBufSize" suboptions to "O" option to
+ set the size of the TCP send and receive buffers; if you
+ run over a slow slip line you may need to set these down
+ (although it would be better to fix the SLIP implementation
+ so that it's not necessary to recompile every program
+ that does bulk data transfer).
+ Allow null defaults on $( ... $) lookups. Problem reported by
+ Amir Plivatsky.
+ Diagnose crufty S and V config lines. This resulted from an
+ observation that some people were using the SITE macro
+ without the SITECONFIG macro first, which was causing
+ bogus config files that were not caught.
+ Fix makemap -f flag to turn off case folding (it was turning it
+ on instead). THIS IS A USER VISIBLE CHANGE!!!
+ Fix a problem that caused multiple error messages to be sent if
+ you used "sendmail -t -oem -odb", your system uses fcntl
+ locking, and one of the recipient addresses is unknown.
+ Reset uid earlier in include() so that recursive .forwards or
+ :include:s don't use the wrong uid.
+ If file descriptor 0, 1, or 2 was closed when sendmail was
+ called, the code to recover the descriptor was broken.
+ This sometimes (only sometimes) caused problems with the
+ alias file. Fix from Motonori Nakamura.
+ Fix a problem that caused aliaswait to go into infinite recursion
+ if the @:@ metasymbol wasn't found in the alias file.
+ Improve error message on newaliases if database files cannot be
+ opened or if running with no database format defined.
+ Do a better estimation of the size of error messages when NoReturn
+ is set. Problem noted by P{r (Pell) Emanuelsson.
+ Fix a problem causing the "c" option (don't connect to expensive
+ mailers) to be ignored in SMTP. Problem noted and the
+ solution suggested by Robert Elz of Munnari University.
+ Improve connection caching algorithm by passing "[host]" to
+ hostsignature, which strips the square brackets and
+ returns the real name. This allows mailertable entries
+ to match regular entries.
+ Re-enable Return-Receipt-To: -- people seem to want this stupid
+ feature, even if it doesn't work right.
+ Catch and log attempts to try the "wiz" command in server SMTP.
+ This also ups the log level from LOG_NOTICE to LOG_CRIT.
+ Be more generous at assigning $z to the home directory -- do this
+ for programs that are specified through a .forward file.
+ Fix from Andrew Chang of Sun Microsystems.
+ Always save a fatal error message in preference to a non-fatal
+ error message so that the "subject" line of return
+ messages is the best possible.
+ CONFIG: reduce the number of quotes needed to quote configuration
+ parameters with commas: two quotes should work now, e.g.,
+ define(ALIAS_FILE, ``/etc/aliases,/etc/aliases.local'').
+ CONFIG: class $=Z is a set of UUCP hosts that use uucp-dom
+ connections (domain-ized UUCP).
+ CONFIG: fix bug in default maps (-o must be before database file
+ name). Pointed out by Christophe Wolfhugel.
+ CONFIG: add FEATURE(nodns) to state that we are not relying on
+ DNS. This would presumably be used in UUCP islands.
+ CONFIG: add OSTYPE(nextstep) and OSTYPE(linux).
+ CONFIG: log $u in Received: line. This is in technical violation
+ of the standards, since it doesn't guarantee a domain
+ on the address.
+ CONFIG: don't assume "m" in local mailer flags -- this means that
+ if you redefine LOCAL_MAILER_FLAGS you will have to include
+ the "m" flag should you want it. Apparently some Solaris 2.2
+ installations can't handle multiple local recipients.
+ Problem noted by Josh Smith.
+ CONFIG: add confDOMAIN_NAME to set $j (if undefined, $j defaults).
+ CONFIG: change default version level from 4 to 5.
+ CONFIG: add FEATURE(nullclient) to create a config file that
+ forwards all mail to a hub without ever looking at the
+ addresses in any detail.
+ CONFIG: properly strip mailer: information off of relays when
+ used to change .BITNET form into %-hack form.
+ CONFIG: fix a problem that caused infinite loops if presented
+ with an address such as "!foo".
+ CONFIG: check for self literal (e.g., [128.32.131.12]) even if
+ the reverse "PTR" mapping is broken. There's a better
+ way to do this, but the change is fairly major and I
+ want to hold it for another release. Problem noted by
+ Bret Marquis.
+
+8.5/8.5 93/07/23
+ Serious bug: if you used a command line recipient that was unknown
+ sendmail would not send a return message (it was treating
+ everything as though it had an SMTP-style client that
+ would do the return itself). Problem noted by Josh Smith.
+ Change "trymx" option in getcanonname() to ignore all MX data,
+ even during a T_ANY query. This actually didn't break
+ anything, because the only time you called getcanonname
+ with !trymx was if you already knew there were no MX
+ records, but it is somewhat cleaner. From Motonori
+ Nakamura.
+ Don't call getcanonname from getmxrr if you already know there
+ are no DNS records matching the name.
+ Fix a problem causing error messages to always include "The
+ original message was received ... from localhost".
+ The correct original host information is now included.
+ Previous change to cf/sh/makeinfo.sh doesn't port to Ultrix (their
+ version of "test" doesn't have the -x flag). Change it
+ to use -f instead. From John Myers.
+ CONFIG: 8.4 mistakenly set the default SMTP-style mailer to
+ esmtp -- it should be smtp.
+ CONFIG: send all relayed mail using confRELAY_MAILER (defaults
+ to "relay" (a variant of "smtp") if MAILER(smtp) is used,
+ else "suucp" if MAILER(uucp) is used, else "unknown");
+ this cleans up the configs somewhat. This fixes a serious
+ problem that caused route-addrs to get mistaken as relays,
+ pointed out by John Myers. WARNING: this also causes
+ the default on SMART_HOST to change from "suucp" to
+ "relay" if you have MAILER(smtp) specified.
+
+8.4/8.4 93/07/22
+ Add option `w'. If you receive a message that comes to you because
+ you are the best (lowest preference) target of an MX, and
+ you haven't explicitly recognized the source MX host in
+ your .cf file, this option will cause you to try the target
+ host directly (as if there were no MX for it at all). If
+ `w' is not set, this case is a configuration error.
+ Beware: if `w' is set, senders may get bogus errors like
+ "message timed out" or "host unknown" for problems that
+ are really configuration errors. This option is
+ disrecommended, provided only for compatibility with
+ UIUC sendmail.
+ Fix a problem that caused the incoming socket to be left open
+ when sendmail forks after the DATA command. This caused
+ calling systems to wait in FIN_WAIT_2 state until the
+ entire list was processed and the child closed -- a
+ potentially prodigious amount of time. Problem noted
+ by Neil Rickert.
+ Fix problem (created in 6.64) that caused mail sent to multiple
+ addresses, one of which was a bad address, to completely
+ suppress the sending of the message. This changes
+ handling of EF_FATALERRS somewhat, and adds an
+ EF_GLOBALERRS flag. This also fixes a potential problem
+ with duplicate error messages if there is a syntax error
+ in the header of a message that isn't noticed until late
+ in processing. Original problem pointed out by Josh Smith
+ of Harvey Mudd College. This release includes quite a bit
+ of dickering with error handling (see below).
+ Back out SMTP transaction if MAIL gets nested 501 error. This
+ will only hurt already-broken software and should help
+ humans.
+ Fix a problem that broke aliases when neither NDBM nor NEWDB were
+ compiled in. It would never read the alias file.
+ Repair unbalanced `)' and `>' (the "open" versions are already
+ repaired).
+ Logging of "done" in dropenvelope() was incorrect: it would
+ log this even when the queue file still existed. Change
+ this to only log "done" (at log level 11) when the
+ queue file is actually removed. From John Myers.
+ Log "lost connection" in server SMTP at log level 20 if there
+ is no pending transaction. Some senders just close the
+ connection rather than sending QUIT.
+ Fix a bug causing getmxrr to add a dot to the end of unqualified
+ domains that do not have MX records -- this would cause
+ the subsequent host name lookup to fail. The problem
+ only occurred if you had FEATURE(nocanonify) set.
+ Problem noted by Rick McCarty of Texas Instruments.
+ Fix invocation of setvbuf when passed a -X flag -- I had
+ unwittingly used an ANSI C extension, and this caused
+ core dumps on some machines.
+ Diagnose self-destructive alias loops on RCPT as well as EXPN.
+ Previously it just gave an empty send queue, which
+ then gave either "Need RCPT (recipient)" at the DATA
+ (confusing, since you had given an RCPT command which
+ returned 250) or just dropped the email, depending on
+ whether you were running VERBose mode. Now it usually
+ diagnoses this case as "aliasing/forwarding loop broken".
+ Unfortunately, it still doesn't adequately diagnose
+ some true error conditions.
+ Add internal concept of "warning messages" using 6xx codes.
+ These are not reported only to Postmaster. Unbalanced
+ parens, brackets, and quotes are printed as 653 codes.
+ They are always mapped to 5xx codes before use in SMTP.
+ Clean up error messages to tell both the actual address that
+ failed and the alias they arose from. This makes it
+ somewhat easier to diagnose problems. Difficulty noted
+ by Motonori Nakamura.
+ Fix a problem that inappropriately added a ctladdr to addresses
+ that shouldn't have had one during a queue run. This
+ caused error messages to be handled differently during
+ a queue run than a direct run.
+ Don't print the qf name and line number if you get errors during
+ the direct run of the queue from srvrsmtp -- this was
+ just extra stuff for users to crawl through.
+ Put command line flags on second line of pid file so you can
+ auto-restart the daemon with all appropriate arguments.
+ Use "kill `head -1 /etc/sendmail.pid`" to stop the
+ daemon, and "eval `tail -1 /etc/sendmail.pid`" to
+ restart it.
+ Remove the ``setuid(getuid())'' in main -- this caused the
+ IDENT daemon to screw up. This required that I change
+ HASSETEUID to HASSETREUID and complicate the mode
+ changing somewhat because both Ultrix and SunOS seem
+ to have a bug causing seteuid() to set the saved uid
+ as well as the effective. The program test/t_setreuid.c
+ will test to see if your implementation of setreuid(2)
+ is appropriately functional.
+ The FallBackMX (option V) handling failed to properly identify
+ fallback to yourself -- most of the code was there,
+ but it wasn't being enabled. Problem noted by Murray
+ Kucherawy of the University of Waterloo.
+ Change :include: open timeout from ETIMEDOUT to an internal
+ code EOPENTIMEOUT; this avoids adding "during SmtpPhase
+ with CurHostName" in error messages, which can be
+ confusing. Reported by Jonathan Kamens of OpenVision
+ Technologies.
+ Back out setpgrp (setpgid on POSIX systems) call to reset the
+ process group id. The original fix was to get around
+ some problems with recalcitrant MUAs, but it breaks
+ any call from a shell that creates a process group id
+ different from the process id. I could try to fix
+ this by diddling the tty owner (using tcsetpgrp or
+ equivalent) but this is too likely to break other
+ things.
+ Portability changes:
+ Support -M as equivalent to -oM on Ultrix -- apparently
+ DECnet calls sendmail with -MrDECnet -Ms<HOST> -bs
+ instead of using standard flags. Oh joy. This
+ behaviour reported by Jon Giltner of University
+ of Colorado.
+ SGI IRIX -- this includes several changes that should
+ help other strict ANSI compilers.
+ SCO Unix -- from Murray Kucherawy of HookUp Communication
+ Corporation.
+ Solaris running the Sun C compiler (which despite the
+ documentation apparently doesn't define
+ __STDC__ by default).
+ ConvexOS from Eric Schnoebelen of Convex.
+ Sony NEWS workstations and Omron LUNA workstations from
+ Motonori Nakamura.
+ CONFIG: add confTRY_NULL_MX_LIST to set option `w'.
+ CONFIG: delete `C' and `e' from default SMTP mailers flags;
+ several people have made a good argument that this
+ creates more problems than it solves (although this
+ may prove painful in the short run).
+ CONFIG: generalize all the relays to accept a "mailer:host"
+ format.
+ CONFIG: move local processing in ruleset 0 into a new ruleset
+ 98 (8 on old sendmail). Domain literal [a.b.c.d]
+ addresses are also passed through this ruleset.
+ CONFIG: if neither SMART_HOST nor MAILER(smtp) were defined,
+ internet-style addresses would "fall off the end" of
+ ruleset zero and be interpreted as local -- however,
+ the angle brackets confused the recursive call.
+ These are now diagnosed as "Unrecognized host name".
+ CONFIG: USENET rules weren't included in S0 because of a mistaken
+ ifdef(`_MAILER_USENET_') instead of
+ ifdef(`_MAILER_usenet_'). Problem found by Rein Tollevik
+ of SINTEF RUNIT, Oslo.
+ CONFIG: move up LOCAL_RULE_0 processing so that it happens very
+ early in ruleset 0; this allows .mc authors to bypass
+ things like the "short circuit" code for local addresses.
+ Prompted by a comment by Bill Wisner of The Well.
+ CONFIG: add confSMTP_MAILER to define the mailer used (smtp or
+ esmtp) to send SMTP mail. This allows you to default
+ to esmtp but use a mailertable or other override to
+ deal with broken servers. This logic was pointed out
+ to me by Bill Wisner. Ditto for confLOCAL_MAILER.
+ Changes to cf/sh/makeinfo.sh to make it portable to SVR4
+ environments. Ugly as sin.
+
+8.3/8.3 93/07/13
+ Fix setuid problems introduced in 8.2 that caused messages
+ like "Cannot create qfXXXXXX: Invalid argument"
+ or "Cannot reopen dfXXXXXX: Permission denied". This
+ involved a new compile flag "HASSETEUID" that takes
+ the place of the old _POSIX_SAVED_IDS -- it turns out
+ that the POSIX interface is broken enough to break
+ some systems badly. This includes some fixes for
+ HP-UX. Also fixes problems where the real uid is
+ not reset properly on startup (from Neil Rickert).
+ Fix a problem that caused timed out messages to not report the
+ addresses that timed out. Error messages are also more
+ "user friendly".
+ Drop required bandwidth on connections from 64 bytes/sec to
+ 16 bytes/sec.
+ Further Solaris portability changes -- doesn't require the BSD
+ compatibility library. This also adds a new
+ "HASGETDTABLESIZE" compile flag which can be used if
+ you want to use getdtablesize(2) instead of sysconf(2).
+ These are loosely based on changes from David Meyer at
+ University of Oregon. This now seems to work, at least
+ for quick test cases.
+ Fix a problem that can cause duplicate error messages to be
+ sent if you are in SMTP, you send to multiple addresses,
+ and at least one of those addresses is good and points
+ to an account that has a .forward file (whew!).
+ Fix a problem causing messages to be discarded if checkcompat()
+ returned EX_TEMPFAIL (because it didn't properly mark
+ the "to" address). Problem noted by John Myers.
+ Fix dfopen to return NULL if the open failed; I was depending
+ on fdopen(-1) returning NULL, which isn't the case. This
+ isn't serious, but does result in wierd error diagnoses.
+ From Michael Corrigan.
+ CONFIG: add UUCP_MAX_SIZE M4 macro to set the maximum size of
+ messages sent through UUCP-family mailers. Suggested
+ by Bill Wisner of The Well.
+ CONFIG: if both MAILER(uucp) and MAILER(smtp) are specified,
+ include a "uucp-dom" mailer that uses domain-style
+ addressing. Suggested by Bill Wisner.
+ CONFIG: Add LOCAL_SHELL_FLAGS and LOCAL_SHELL_ARGS to match
+ LOCAL_MAILER_FLAGS and LOCAL_MAILER_ARGS. Suggested by
+ Christophe Wolfhugel.
+ CONFIG: Add OSTYPE(aix3). From Christophe Wolfhugel.
+
+8.2/8.2 93/07/11
+ Don't drop out on config file parse errors in -bt mode.
+ On older configuration files, assume option "l" (use Errors-To
+ header) for back compatibility. NOTE: this DOES NOT
+ imply an endorsement of the Errors-To: header in any way.
+ Accept -x flag on AIX-3 as well as OSF/1. Why, why, why???
+ Don't log errors on EHLO -- it isn't a "real" error for an old
+ SMTP server to give an error on this command, and
+ logging it in the transcript can be confusing. Fix
+ from Bill Wisner.
+ IRIX compatibility changes provided by Dan Rich
+ <drich@sandman.lerc.nasa.gov>.
+ Solaris 2 compatibility changes. Provided by Bob Cunningham
+ <bob@kahala.soest.hawaii.edu>, John Oleynick
+ <juo@klinzhai.rutgers.edu>
+ Debugging: -d17 was overloaded (hostsignature and usersmtp.c);
+ move usersmtp (smtpinit and smtpmailfrom) to -d18 to
+ match the other flags in that file.
+ Flush transcript before fork in mailfile(). From Eric Wassenaar.
+ Save h_errno in mci struct and improve error message display.
+ Changes from Eric Wassenaar.
+ Open /dev/null for the transcript if the create of the xf file
+ failed; this avoids at least one possible null pointer
+ reference in very wierd cases. From Eric Wassenaar.
+ Clean up statistics gathering; it was over-reporting because of
+ forks. From Eric Wassenaar.
+ Fix problem that causes old Return-Path: line to override new
+ Return-Path: line (conf.c needs H_FORCE to avoid
+ re-using old value). From Motonori Nakamura.
+ Fix broken -m flag in K definition -- even if -m (match only)
+ was specified, it would still replace the key with the
+ value. Noted by Rick McCarty of Texas Instruments.
+ If the name server timed out over several days, no "timed out"
+ message would ever be sent back. The timeout code
+ has been moved from markfailure() to dropenvelope()
+ so that all such failures should be diagnosted. Pointed
+ out by Christophe Wolfhugel and others.
+ Relax safefile() constraints: directories in an include or
+ forward path must be readable by self if the controlling
+ user owns the entry, readable by all otherwise (e.g.,
+ when reading your .forward file, you have to own and
+ have X permssion in it; everyone needs X permission in
+ the root and directories leading up to your home);
+ include files must be readable by anyone, but need not
+ be owned by you.
+ If _POSIX_SAVED_IDS is defined, setuid to the owner before
+ reading a .forward file; this gets around some problems
+ on NFS mounts if root permission is not exported and
+ the user's home directory isn't x'able.
+ Additional NeXT portability enhancements from Axel Zinser.
+ Additional HP-UX portability enhancements from Brian Bullen.
+ Add a timeout around SMTP message writes; this assumes you can
+ get throughput of at least 64 bytes/second. Note that
+ this does not impact the "datafinal" default, which
+ is separate; this is just intended to work around
+ network clogs that will occur before the final dot
+ is sent. From Eric Wassenaar.
+ Change map code to set the "include null" flag adaptively --
+ it initially tries both, but if it finds anything
+ matching without a null it never tries again with a
+ null and vice versa. If -N is specified, it never
+ tries without the null and creates new maps with a
+ null byte. If -O is specified, it never tries with
+ the null (for efficiency). If -N and -O are specified,
+ you get -NO (get it?) lookup at all, so this would
+ be a bad idea. If you don't specify either -N or -O,
+ it adapts.
+ Fix recognition of "same from address" so that MH submissions
+ will insert the appropriate full name information;
+ this used to work and got broken somewhere along the
+ way.
+ Some changes to eliminate some unnecessary SYSERRs in the
+ log. For example, if you lost a connection, don't
+ bother reporting that fact on the connection you lost.
+ Add some "extended debugging" flags to try to track down
+ why we get occassional problems with file descriptor
+ one being closed when execing a mailer; it seems to
+ only happen when there has been another error in the
+ same transaction. This requires XDEBUG, defined
+ by default in conf.h.
+ Add "-X filename" command line flag, which logs both sides of
+ all SMTP transactions. This is intended ONLY for
+ debugging bad implementations of other mailers; start
+ it up, send a message from a mailer that is failing,
+ and then kill it off and examine the indicated log.
+ This output is not intended to be particularly human
+ readable. This also adds the HASSETVBUF compile
+ flag, defaulted on if your compiler defines __STDC__.
+ CONFIG: change SMART_HOST to override an SMTP mailer. If you
+ have a local net that should get direct connects, you
+ will need to use LOCAL_NET_CONFIG to catch these hosts.
+ See cf/README for an example.
+ CONFIG: add LOCAL_MAILER_ARGS (default: `mail -d $u') to handle
+ sites that don't use the -d flag.
+ CONFIG: hide recipient addresses as well as sender addresses
+ behind $M if FEATURE(allmasquerade) is specified; this
+ has been requested by several people, but can break
+ local aliases. For example, if you mail to "localalias"
+ this will be rewritten as "localalias@masqueradehost";
+ although initial delivery will work, replies will be
+ broken. Use it sparingly.
+ CONFIG: add FEATURE(domaintable). This maps unqualified domains
+ to qualified domains in headers. I believe this is
+ largely equivalent to the IDA feature of the same name.
+ CONFIG: use $U as UUCP name instead of $k. This permits you
+ to override the "system name" as your UUCP name --
+ in particular, to use domain-ized UUCP names. From
+ Bill Wisner of The Well.
+ CONFIG: create new mailer "esmtp" that always tries EHLO
+ first. This is currently unused in the config files,
+ but could be used in a mailertable entry.
+
+8.1C/8.1B 93/06/27
+ Serious security bug fix: it was possible to read any file on
+ the system, regardless of ownership and permissions.
+ If a subroutine returns a fully qualified address, return it
+ immediately instead of feeding it back into rewriting.
+ This fixes a problem with mailertable lookups.
+ CONFIG: fix some M4 frotz (concat => CONCAT)
+
+8.1B/8.1A 93/06/12
+ Serious bug fix: pattern matching backup algorithm stepped by
+ two tokens in classes instead of one. Found by Claus
+ Assmann at University of Kiel, Germany.
+
+8.1A/8.1A 93/06/08
+ Another mailertable fix....
+
+8.1/8.1 93/06/07
+ 4.4BSD freeze. No semantic changes.
+
+6.65/6.34 93/06/06
+ Fix some lintish problems.
+ Fix some cases where server SMTP behaved poorly when handed bogus
+ input, pointed out by Eric Wassenaar.
+ CONFIG: fix some more (sigh) mailertable bugs -- thanks to
+ Motonori Nakamura of Kyoto University (again).
+
+6.64/6.33 93/06/05
+ Don't send 050 (-v) information after the 250 response to a QUIT
+ command in srvrsmtp -- clients usually close the connection
+ at this point, and it causes bogus error messages.
+ Don't send messages that have errors on input (such as unbalanced
+ parentheses) during SMTP transactions, since a return
+ message has (probably) already been sent.
+ Give better diagnostics on timeouts during network reads, including
+ information similar to the SMTP phase.
+ Fix bug that caused SMTP messages to deliver synchronously; this
+ happened after the DATA 250, and hence caused reading the
+ next command to be delayed.
+ Ignore Errors-To: header unless 'l' (lower case el) header is
+ specified. The Errors-To: header violates RFC 1123.
+ Errors-To: was only needed to take the place of the
+ envelope sender in the days when most Unix mailers
+ didn't understand about the two kinds of senders.
+ Don't send warning messages in response to automatically generated
+ messages (that is, those From:<>).
+ CONFIG: fix some rather stupid typos in the mailertable code
+ pointed out by Motonori Nakamura of Kyoto University.
+ CONFIG: add confUSE_ERRORS_TO configuration option.
+ CONFIG: if ALWAYS_ADD_DOMAIN is selected, try to use $M
+ (masquerade name) instead of $j.
+ CONFIG: don't add dots to relay names (added in 6.29); it breaks
+ several things, and can be simulated by dot terminating
+ the names of relays. For example, use:
+ DBbit.net.relay.
+ (note the trailing dot).
+
+6.63/6.32 93/06/01
+ Fix prototypes to eliminate chars in argument lists -- some
+ compilers are pissy about this.
+ Log protocol ($r) and body type if set so we can determine if
+ the adaptive algorithms are working.
+ Pessimize on locking of database files (particularly for NEWDB
+ databases) during opens. There were problems with
+ processes opening the file while it was rebuilt; since
+ NEWDB caches heavily, the reader opened an empty file,
+ which is an error. If your system has the ability to
+ lock atomically on open, this works properly; otherwise,
+ there are race conditions.
+ Check mod time on .pag file instead of .dir in NDBM aliases
+ because the .dir file doesn't get updated for small
+ alias files. From John Gardiner Myers of CMU.
+ More Solaris portability -- it now compiles on Solaris, but
+ hangs up in gethostbyname().
+ Move setting of RES_DEBUG flag before first myhostname() call
+ so we can see name server traffic on that call.
+ Fsync() queue files.
+ Fix a problem that causes -bi to try to rebuild maps other than
+ the alias file(s).
+ Fix a problem that caused udb to reject entries from any but
+ the first database listed.
+ Rearrange doc subdirectory for 4.4BSD release tape.
+ CONFIG: put $r into the Received line. This was an oversight.
+ CONFIG: fix typo (call to ruleset 99 should have been rulset 90).
+ CONFIG: move "auxiliary" subroutines to be in ruleset 90-99
+ range -- in the long run, single digit rulesets may
+ become reserved for builtin use by sendmail.
+ CONFIG: fix major problem that causes host aliases (that is,
+ anything in $=w != $j) to not be recognized. This has
+ been around since 6.30.
+
+6.62/6.31 93/05/28
+ BETA RELEASE
+ Fix recursive syserr (if there is an error printing a syserr
+ message). This makes the code much less eager to consider
+ a write error as serious. This also includes some
+ heuristics to be clever about closed connections.
+ Lock NEWDB files during gets. This requires version 1.5 or later
+ of the db library. If you have an older version, you
+ can use -DOLD_NEWDB. This will go away in a few weeks.
+ Fix problem causing aliases that use host maps to get overwritten.
+ Do appropriate byte swapping on port numbers in ident protocol
+ code. Fix from Allan Johannesen of WPI.
+ Defer opening of map files to the same time as alias files so that
+ the daemon will tend to pick up new versions more promptly.
+ Prototype a bunch more functions.
+ Some Solaris 2.1 changes (still doesn't link though).
+ Try to simplify Makefiles by including more subordinate #defines
+ in conf.h (based on OS type).
+ CONFIG: check for domains if FEATURE(mailertable) is defined.
+ For example, if the host name is "knecht.cs.berkeley.edu"
+ it will search the following mailertable keys:
+ knecht.cs.berkeley.edu
+ .cs.berkeley.edu
+ .berkeley.edu
+ .edu
+ This could be used to replace the special relays for bitnet
+ and similar nets.
+
+6.61/6.30 93/05/24
+ Fix problem that prevented appending dots on canonified host
+ names. This breaks tons of config files -- very
+ important fix.
+ Fix improper pointer dereference in response to HELO command.
+ Fix core dump if debugging set in map_rewrite.
+ CONFIG: add FEATURE(always_add_domain) to always attach the
+ local domain (only impacts local mail).
+ CONFIG: try to avoid turning names into $j -- although
+ technically a host can only have one "canonical name",
+ it seems to be common practice to have several.
+
+6.60/6.29 93/05/22
+ Major change: merge alias databases with maps. This expands and
+ changes the map class interface but fixes a bunch of bugs.
+ The important user-visible change is that the file name
+ in a K line now does not include the ".db" extension; this
+ is added automatically. Also, the -d (NIS domain) flag is
+ missing from the K config line; use @domain instead.
+ When compiling, the *_MAP names are gone -- just compile
+ in NDBM, NEWDB, and/or NIS support.
+ Announce mailer/host/user triple on -bv flag -- from Brian
+ Bullen of Stirling University.
+ Don't send more than one line in response to HELO -- it confuses
+ Pony Express, which then behaves very badly. However,
+ this change does send two line 220 greetings, with the
+ second line reading "ESMTP spoken here". The usersmtp
+ module recognizes this and goes into ESMTP mode regardless
+ of the setting of the "a" mailer flag. Thus, "a" means
+ "always try EHLO".
+ AIX portability changes (thanks to Christophe Wolfhugel of
+ Herve Schauer Consultants (Paris) for providing me with
+ an INSA account for this purpose). Lightly tested. Use
+ -D_AIX3. This probably breaks compatibility with some
+ older systems (e.g., 4.2bsd) but still works on SunOS
+ 4.1.2, Ultrix 4.2A, HP-UX 8.07, OSF/1 T1.3, and AIX 3.2.3.
+ Fix a problem causing an error message loop if the output channel
+ is hosed.
+ Add the Makefiles that I use for various environments -- some are
+ Berkeley make versions and some are old make versions.
+ My makefile for the NeXT box has gotten lost, alas!
+ PRALIASES: support for printing NEWDB databases. From
+ Michael J. Corrigan of U.C. San Diego.
+ CONFIG: don't pass pseudo-domains to $[ ... $] (if you have
+ a wildcard MX it can have wierd results). From
+ Christophe Wolfhugel.
+ CONFIG: dot terminate relay hostnames in S0. From Christophe
+ Wolfhugel.
+
+6.59/6.28 93/05/13
+ Log version with SMTP daemon startup message.
+ Adjust setproctitle to work on NetBSD and BSD/386.
+ Fix null pointer reference in MX fallback code.
+ A bunch of minor fixes from Eric Wassenaar:
+ If deliver cannot execv the mailer, return EX_OSERR
+ instead of EX_TEMPFAIL (to give better
+ error messages).
+ Consistently malloc e_message.
+ Catch degenerate case of calling returntosender()
+ with an empty returnq.
+ MIME reformatting.
+
+6.58/6.28 93/05/13
+ Fix bug that can cause incorrect verbose display of user smtp
+ messages.
+ Disable SMTP VERB command if PRIV_NOEXPN is set (since this
+ could reveal the same information.
+ Allow failure when reading SMTP greeting message to go on to
+ next MX host.
+ Add "MIME-Version: 1.0" header if using MIME (this was NOT
+ included in RFC 1344, but Bill King of Allan-Bradley
+ Company forwarded me email from Nathaniel Borenstein
+ claiming that it was an inadvertent omission).
+ Don't use Content-Type: X-message-header. According to John
+ Myers of CMU, many MIME readers will completely ignore
+ the data if they don't recognize it. Instead, just
+ add a blank line to make it a legal (empty) message.
+ Fix problem causing dots to keep getting appended to cached
+ hostnames. This can cause buffer overrun conditions.
+ The problem was found by Erik Forsberg of Retix,
+ although I used a different bug fix than he provided.
+ Fix parsing of split header/envelope rewriting specs -- from
+ Eric Forsberg.
+ Fix from Eric Wassenaar to correct To: lists in error messages.
+
+6.57/6.28 93/05/11
+ Fix minor glitch causing extra ctladdrs to be output to queue
+ file. Just an annoyance.
+ Cache results of name server canonification lookups to avoid
+ backed up queue runs.
+ Major rewrite of alias.c: considerable cleanup, plus sample
+ (untested) support for NIS aliases. The "A" option
+ can now be a comma separated list (or be repeated) --
+ that is, you can have multiple alias databases. Each
+ database can have the syntax ``class:file''; if no class
+ is specified, the "implicit" class is assumed. Implicit
+ searches through a list of compiled in types -- hash,
+ dbm, nis, and stab. Alias files are searched in the
+ order they are listed. For example:
+ OAhash:/etc/aliases.local,/etc/aliases
+ OAnis:mail.aliases@my.nis.domain
+ first searches the hash database /etc/aliases.local,
+ then the regular /etc/aliases database, then the NIS
+ map "mail.aliases" in the NIS domain "my.nis.domain".
+ If in Verbose mode (probably from VERB command) run SMTP job
+ in foreground and don't do RCPT optimizations.
+ Add udb :mailsender as equivalent to owner- for regular aliases.
+ Delete option 8; add option 7 that means the opposite. That is,
+ default to 8-bit mode; a special option is needed to
+ force sendmail into 7 bit mode.
+ Send error messages in encapsulated MIME format.
+ New compile flag "NIS" that turns on NIS alias and NIS map
+ support.
+ Add "j" option to send error messages in MIME (RFC 1341)
+ encapsulated message format per RFC 1344. The
+ syntax is pretty ugly if you don't have MIME-aware
+ user agents.
+ Clean up message handling (for display in mailq output).
+ New setproctitle implementation for 4.4bsd.
+ Create files (such as ~/dead.letter) using mode FileMode (the
+ F option value) instead of 0666.
+ Fix bug causing output of EXPN command to not be fully qualified.
+ This may cause some problems with UUCP addresses that
+ will require some config file assistance -- specifically,
+ the $: part has to include the host name for this output
+ to make sense.
+ Fix a problem that sometimes diagnosed errors and still sent the
+ message if the header syntax was bad.
+ Fix a bug that caused an error message to be emailed when sendmail
+ was operating in -bv mode.
+ Add "ListenQueueSize" keyword to daemon options option (OO) to
+ set the queue size parameter passed to listen(). You
+ will normally have to tweak your kernel to up this.
+ Strip spaces off of beginning of message-id before logging (in
+ case it was folded across lines).
+ Tweak compile flags in daemon.c -- there were some cases where
+ it wouldn't work without NETINET.
+ Change *file* mailer to output all the usual default headers
+ (From, Date, Message-Id). It gets used when sending
+ back error messages.
+ CONFIG: explicitly catch and diagnose list:; syntax in ruleset
+ zero -- this is not a valid recipient syntax according
+ to RFC 821.
+ CONFIG: add confMIME_FORMAT_ERRORS to send error messages in
+ MIME format. Defaults to on.
+ CONFIG: add SMTP_MAILER_FLAGS and UUCP_MAILER_FLAGS to augment
+ the flags for those mailers.
+
+6.56/6.27 93/05/01
+ Fix problem that causes the fallback mail to postmaster
+ (case ESM_POSTMASTER in savemail()) to not look at
+ aliases (ugh).
+ Some more HPUX tweaking (compile flag hpux => __hpux so it
+ still works in ANSI mode).
+ Don't try to flock non-regular files when mailing to a file.
+ In particular, this was a problem if you tried to
+ send to /dev/null.
+ Fix a wierd bug that can cause senders to be queued as
+ recipients if the name server is down when the mail
+ is initially sent. This hack just ignores sender
+ deletion (essentially, it sets the MeToo flag) if there
+ is a TEMPFAIL during processing of the sender address.
+ Obscure.
+ Fix a dangling else problem -- from Brian Bullen from University
+ of Stirling, UK.
+ Add the "b" mailer flag to force a blank line on the end of
+ messages. Some brilliant versions of /bin/mail insist
+ on this but do not add it themselves.
+ Add the "g" mailer flag to prevent user SMTP from sending
+ "MAIL From:<>". This is only intended to be a
+ transitional gesture, and should not be used if at
+ all possible. It appears that Berkeley and IDA
+ config files have always handled this properly; the
+ UK config kit apparently does not.
+ Don't lowercase and then capitalize header field names -- leave
+ them with original capitalization. Fixes from Bill
+ King of Allen-Bradley Company.
+ Further cleanup and improved reporting of error messages,
+ particularly conditions that cause messages to be
+ requeued for future delivery.
+ Tweak syslog priorities in some cases.
+ CONFIG: clean up route-addr on UUCP addresses.
+
+6.55/6.25 93/04/27
+ HPUX 8.07 compatibility changes in getla() -- I had to make
+ these changes to get it to work at Berkeley, although
+ others seem to have been working before (???).
+ Various patches to XLA code.
+ Fix problem that causes setuid bit on files to be ignored from
+ SMTP or in queue runs. Problem noted by Jason Ornstein
+ of Under The Wire, Inc.
+ Fix problem that can cause CNAMEs to be ignored.
+ Generalize getmxrr to match local host in $=w instead of a
+ single name passed in.
+ Some cleanup from Eric Wassenaar:
+ Use FileMailer instead of ProgMailer in two places.
+ Eliminate duplicate 8th-bit stripping in commaize.
+ Fix a problem with mis-parsing of backslash escapes
+ under some circumstances.
+ NIS map fix (was always including trailing null character)
+ from Mike Glendinning of Ingres UK.
+ Add "a" mailer flag to try using ESMTP. It tries the EHLO
+ command and if that fails falls back to regular SMTP.
+ Also parses EHLO option keywords. If host supports
+ SIZE extension, this is added to the MAIL FROM:
+ command.
+ Extend "b" option to include a second value which is the
+ maximum message size this server is willing to accept.
+ For example, a value of "10/1000000" says that there
+ must be ten blocks free, and sendmail will reject
+ any message larger than one megabyte.
+ Some portability hooks for NeXT (this could be applicable
+ to Mach in general). You have to create an empty
+ file called "unistd.h" to get it to compile.
+ Adjust config values (MAXLINE, MAXATOM, and PSBUFSIZE) to
+ be more generous.
+ Add X400-Received: to the list of headers tagged with H_TRACE
+ in conf.c. From Bill King, Allen-Bradley Co.
+
+6.54/6.25 93/04/19
+ Fix problem that caused redefinition of SMTP and QUEUE compile
+ flags. Pointed out by Jon Forrest of the Sequoia 2000
+ project at Berkeley.
+ Properly handle \! hack -- it was treating host\!user as one
+ token (host!user) instead of three (host, !, user).
+ Fix from Eric Wassenaar of NIKHEF-H.
+ Fix compilation problem in getauthinfo() if IDENTPROTO is off.
+ Turn off DEFNAMES and DNSRCH when getting the hostsignature
+ (i.e., MX records) in level 1 configuration files; this
+ matches the old behaviour. From Motonori Nakamura of
+ Kyoto University.
+ Improve error message printing -- if sent through an alias,
+ error messages include the name of the alias in the
+ message. Unfortunately, in order to make this work
+ properly in queue runs, this changes the format of the
+ C line in the qf file. The relatively uselessness of
+ the previous information was pointed out to me by
+ Allan E Johannesen of WPI.
+ Add XLA compile flag to add hooks to Christophe Wolfhugel's
+ extended load average code. This is still in very early
+ form. For information regarding the guts of the xla
+ code, contact Christophe.Wolfhugel@grasp.insa-lyon.fr.
+ Additional hooks for detecting tempfails in rewriting rules
+ (that is, in map lookups).
+
+6.53/6.25 93/04/15
+ Properly diagnose ruleset zero returning null (instead of a mailer
+ triple). From Motonori Nakamura of Kyoto University.
+ More generalization of socket code for other protocols.
+ Shorten timeouts on reverse name lookups -- since they are done
+ during connection establishment, long timeouts here can
+ cause higher level timeouts. This mainly serves to accept
+ mail from hosts that do not have proper reverse (PTR) DNS
+ records set up.
+ Reset e_statmsg before each mailer invocation to avoid bogus
+ messages in the log.
+ Redefine $r, $s, and $_ in error envelopes so you don't get
+ incorrect cruft in the error message. Problem noted by
+ Motonori Nakamura of Kyoto University.
+ Fix a problem that can cause failure to return errors to Postmaster
+ in certain cases. From Motonori Nakamura.
+ Fix a problem that can cause some systems to give duplicate error
+ messages when a bad syntax address such as "<a" is presented
+ to an SMTP server. It doesn't seem to occur on all
+ machines. From Motonori Nakamura.
+ Default IDENTPROTO off for Ultrix and HPUX, which apparently have
+ the interesting "feature" that when they receive a "Host
+ unreachable" message they closes all open connections to
+ that host. However, some firewall gateways send this message
+ if you try to connect to an unauthorized port, such as the
+ IDENT port (113). Thus, no email can be received from such
+ hosts. There is some evidence that versions of Ultrix before
+ 4.3 do not have this problem. Thanks to Tom Ivar Helbekkmo
+ for pointing out this behaviour to me and to Michael Corrigan
+ of U.C. San Diego for informing me about the HPUX problem.
+ Allow IPC mailers to return a colon-separated list of hosts in the
+ $@ clause; these are searched in order as though they were
+ MX records.
+ When sending an error report, print the list of addresses tagged
+ as bad. Requested by Allan E Johannesen of WPI.
+ Change map function calls to return a status code. This gets
+ passed back as the result of rewrite. Parseaddr marks
+ the address as a QUEUEUP address if the return code is
+ EX_TEMPFAIL. All this to queue properly if the name
+ server is down. This code is not well tested. This code
+ changes the interface to map lookup functions (a fifth
+ parameter, int *statp, is added). Feature requested by
+ Dan Oscarsson.
+ Don't delete quotes (in the dequote map) if there are spaces in
+ the string, since this would cause them to be replaced by
+ the SpaceSub character.
+ Accept BODY=8BITMIME on SMTP MAIL command. This isn't advertised
+ because the 8BIT to 7BIT translation doesn't exist yet.
+ This does add a "bodytype" field to both envelope and
+ queue file and a -B command line flag to pass the type in
+ during direct invocations.
+ Discard return error messages only on responses to responses to
+ responses, not on responses to responses. That is, the
+ algorithm is to try return to sender, then return to
+ postmaster, then discard. Previously it discarded
+ immediately if the return to sender pass failed.
+ CONFIG: back out change to hide unqualified hostnames behind %-hack.
+ This screws up local aliases and .forward files.
+ CONFIG: add FEATURE(nocanonify) to turn off calls to $[ ... $];
+ some sites only handle completely canonified names.
+ Requested by John Gardiner Myers of CMU.
+ CONFIG: some UUCP code was still included even if FEATURE(nouucp)
+ was specified.
+
+6.52/6.24 93/04/10
+ Clean up some minor glitches on error return messages pointed out
+ by Motonori Nakamura of Kyoto University.
+ Fix reply() to not reset SmtpReplyBuffer on fatal errors; this
+ was supposed to reset SmtpMsg Buffer. This makes the
+ client side code virtually useless. Reported by Allan
+ E Johannesen of WPI and Phil Brandenberger of Swarthmore.
+ Better debug messages if fuzzy is disabled, suggested by Allan
+ E Johannesen of WPI.
+ Offset SmtpReplyBuffer by four in usersmtp when checking for
+ loopback. From Eric Wassenaar.
+ Don't set $s until after runinchild in srvrsmtp -- otherwise
+ it gets cleared. From Eric Wassenaar.
+ Implement IDA-style $&x for deferred macro expansion.
+ More POSIX compatibility.
+ CONFIG: Hide unqualified hostnames behind %-hack using $s as the
+ actual sender. This is only done if $r is non-null, that
+ is, if this is not locally submitted mail.
+ CONFIG: Add FEATURE(bitdomain) allowing mapping of BITNET host
+ names to internet domains. A program contributed by
+ John Gardiner Myers of CMU to create the maps is included
+ in the contrib directory (in the "misc" tar file).
+ CONFIG: Add FEATURE(uucpdomain) for a similar mapping for UUCP
+ hosts. There is currently no tool to create this map.
+
+6.51/6.23 93/04/04
+ Add D= mailer flag to specify a path of possible working directories
+ in which to execute the mailer. This is intended for the
+ prog mailer; some shells can get upset if they don't have
+ access to the current directory.
+ Add RFC 1413 (IDENT) protocol support. This is only very loosely
+ tested. This adds a $_ macro to be the authenticated
+ info (in ``user@domain [address]'' form) and debug flag
+ 9 to trace the protocol.
+ Check for loopbacks in usersmtp instead of srvrsmtp -- there is no
+ reason for a local agent to not be talking to the localhost
+ (although the inverse is not true).
+ Add a few hooks for automated map rebuilding. This is certainly
+ not done yet.
+ CONFIG: Have prog mailer specify a path of ``D=$z:/'' -- that is,
+ user's home directory then the root.
+ CONFIG: Log RFC 1413 identification in Received: line.
+
+6.50/6.22 93/04/01
+ Fixes to requeueing code to make it compute priority, nrcpts,
+ and the like properly.
+
+6.49/6.22 93/04/01
+ Diagnose incorrect privacy flags. Suggested by Bryan Costales
+ of ICSI.
+ Some ANSI C fixes.
+ Arrange to quote backslashes as well as other special characters
+ in the phrase part of a route-addr.
+ Some fixes to FallBackMX code suggested by Motonori Nakamura of
+ Kyoto University.
+ More vigorous zeroing of CurHostAddr to avoid logging of bogus
+ host addresses when you are actually just printing
+ information from the MCI structure; problem noted by
+ Michael Corrigan of U.C. San Diego.
+ Don't ignore rest of queue if any job is not runnable. This can
+ also cause an incorrect job to be lost. Fix from
+ Eric Wassenaar.
+ Always respond "quickly" to RCPT command; do alias expansion and
+ the like later. This also means that mail for lists that
+ have errors will be acccepted, and an error sent back
+ later. This is done by instantiating the queue file
+ and then immediately running and requeueing it.
+
+6.48/6.22 93/03/30
+ Fix incorrect diagnosis of infinite loop in ruleset. Problem noted
+ by several people.
+ Improve information printed when infinite loops are discovered.
+ Zero CurHostAddr to fix erroneous internet addresses in log when no
+ addresses can be bound. Pointed out by Motonori Nakamura
+ of Kyoto University.
+ "Probe" SMTP connections using RSET instead of NOOP "just in case".
+ Suggested by John Gardiner Myers of CMU.
+ Don't warn about -f if you are setting sender to yourself.
+
+6.47/6.22 93/03/29
+ Fix incompatible call to endmailer in smtpquit which causes core
+ dumps. Noted by Allan E Johannesen of WPI.
+ HPUX portability changes from Michael J. Corrigan of UC San Diego.
+ Require MAIL before RCPT command in srvrsmtp.c. This had been
+ intentional from the 821 draft days when the order wasn't
+ clear, but is silly now.
+ Fix bug in nis_magic routine that was initializing parameters
+ incorrectly. Fix from Takahiro Kanbe of Fuji Xerox
+ Information Systems Co., Ltd.
+ Change default for PrivacyFlags in conf.c to 0 -- since it always
+ "or"s in new values, there was no way to turn off the
+ AuthWarning stuff.
+ Add O option to set SMTP daemon options.
+ Add V option to set fallback MX host. This always sorts at lower
+ priority than anything it gets from the name server. It
+ should only be used for environments with very bad network
+ connectivity. Requested by several people.
+ Log sending info. It's not clear this is a good idea.
+ CONFIG: fix typo in mailertable code. Noted by Phil Brandenberger
+ of Swarthmore.
+ CONFIG: add confDAEMON_OPTIONS and confFALLBACK_MX to set options
+ O and V, respectively.
+
+6.46/6.21 93/03/26
+ Fix botch in server SMTP that broke transactions that did not
+ use HELO first (like MH). Fix from Michael Corrigan
+ of U.C. San Diego.
+ Fall back to other MX records if there is an error anywhere
+ in delivery (actually on MAIL or DATA -- RCPT is harder).
+ Suggested by John Gardiner Myers and Motonori Nakamura.
+ Revert to non-prototypes -- it turns out that our ANSI C
+ compiler is more forgiving than most others about
+ mixing prototyped extern declarations with non-prototyped
+ function definitions.
+ Fix a problem with multi-word class matching pointed out by
+ Neil Rickert. Given:
+ CX b a.b.c
+ R$+ $=X $+ $: $1 < $2 > $3
+ the input "user@a.b.c" failed instead of being properly
+ rewritten as "user@a.<b>.c".
+ Neil also convinced me that it was correct that $~ should match
+ only one token -- the problem is that it's always possible
+ to add another token, so $~ matches far too eagerly.
+
+6.45/6.21 93/03/25
+ Implement multi-word classes (properly!).
+
+6.44/6.21 93/03/25
+ Add X-Authentication-Warning: headers to clue users into possible
+ attempts to forge mail. This is on the authwarnings
+ privacy flag, but is the default. Suggested by Bryan
+ Costales of ICSI.
+ Pass default units for convtime in so they can be more reasonable.
+ Allow config files to always add a new Comments: header (i.e.,
+ they will be added even if an old one already exists).
+ Suggested by Bryan Costales of ICSI.
+ Allow config files to delete an existing Return-Path: header.
+ These should only be added at final delivery. Suggested
+ by Bryan Costales of ICSI.
+ Some debugging additions. Suggested by Bryan Costales of ICSI.
+ Clean up logging of Family 0 addresses. Noted by David Muir
+ Sharnoff and others.
+ Add a "dequote" map class. This allows config files to strip
+ quotes off of addresses. Note that this is not a builtin
+ map, just a class -- so you have to define the map
+ using the K line.
+ Fix a bug in the queueup() loop getting a locked tf where in
+ very odd cases it can fall off the bottom and core dump.
+ Of course, it was P{r Emanuelsson who found it....
+ Open a new transcript when splitting an envelope. Problem found
+ by Allan E Johannesen of WPI.
+ Improved error output in endmailer if the mailer core dumps.
+ CONFIG: Fix typo in UUCP mailer definition.
+ CONFIG: Default several of the new options on: eight bit input,
+ privacy flags set to "authwarnings", and message warning
+ set to 4h.
+ CONFIG: Use dequote map.
+
+6.43/6.20 93/03/23
+ Fix problem with assumption of an sa_len field in a generic
+ sockaddr -- it turns out that most vendors haven't
+ picked up this (very important) fix.
+ Change compilation flags for daemon code -- select one or both
+ of NETINET or NETISO, but don't ever set DAEMON manually.
+ CONFIG: add FEATURE(mailertable) to do IDA-style mailertables.
+
+6.42/6.19 93/03/19
+ Use Postmaster as default fallback return address, not root.
+ POSIX changes for file descriptor handling.
+ Diagnose errors writing new queue file.
+ If you change the owner using an owner- alias, also change the
+ error mode to EM_MAIL so that errors don't get dropped
+ into an inappropriate directory. Problem noted by
+ Allan E Johannesen of WPI.
+ If you are su'ed to root, send email as who you really are, not
+ as root. From Brian Kantor of U.C. San Diego.
+ Allow warning messages to be sent after a configurable interval
+ has passed without delivery. The message is sent only
+ once per envelope. This changes the format of the qf
+ file to have an F line, and the format of the T option
+ to accept take the format "return/warn" (both intervals).
+ Don't force all local names to lower case -- this was left over
+ from the wierd handling of case mapping on aliases. It
+ is now driven (as expected) by the "u" mailer flag.
+ Problem noted by P{r Emanuelsson.
+ Fix problem that caused headers on returned email to be trashed;
+ they were getting freed, but are still accessible via
+ BlankEnvelope.
+ Fix problem that caused bogus ids to be created on returned
+ mail.
+ Add support for ISO and other non-INET networking. This is by
+ no means finished yet. This does assume a lot of other
+ system support, like a version of gethostbyname that
+ returns non-AF_INET addresses.
+ CONFIG: change default on prog mailer to keep upper case in
+ user names (i.e., in the program command line).
+ CONFIG: strip trailing dots off of hosts in uucp mailer before
+ convert to bang format.
+ CONFIG: create new "relay" mailer for $R (LOCAL_RELAY) and $H
+ (MAIL_HUB) delivery that doesn't add local domain. Note
+ that this violates 821, but is probably "more correct"
+ for what we are trying to do. Problem pointed out by
+ Michael Graff of Iowa State.
+
+6.41/6.18 93/03/18
+ Clean up unnecessary creates of queue ids (i.e., empty qf files)
+ when not needed, such as when starting up an SMTP
+ connection.
+ Fix problem where split envelopes aren't instantiated in the queue.
+ This is quite a serious bug.
+ Owner- aliases had problems with leading spaces causing a
+ premature delimitation.
+
+6.40/6.18 93/03/18
+ Have ending 250 (after DATA) include the id; suggested by
+ Brian Kantor of UC San Diego.
+ Add logging on envelope splitting.
+ Change queue ids to have one more letter encoding the hour of
+ the day so that during a single day there is a greater
+ likelihood of uniqueness; requested by Brian Kantor.
+
+6.39/6.18 93/03/18
+ Fix minor compile problem if LOCKF is defined.
+ Define size of tobuf in conf.h. Observed by Toshinari Takahashi
+ of Toshiba.
+ Restore e_sender -- this is equivalent to e_from.q_paddr without
+ decorations such as angle brackets and comments.
+ OSF/1 on Alpha changes from Allan E Johannesen of WPI.
+ CONFIG: fix typo in S3 for list syntax (;: => :;). Thanks to
+ Christopher Hoover for noting the problem.
+
+6.38/6.17 93/03/17
+ Pass envelope to disconnect to avoid another use of CurEnv, which
+ can apparently end up being null at inopportune times.
+ Log "received from" as "relay=" for consistency (suggested by
+ John Gardiner Myers).
+ Fix major bug in header handling: if no From: line existed in
+ the header (so sendmail inserts one), and the sender is
+ an alias that has an owner, the From: line shows the
+ owner (as well as the envelope). Fixed by early binding
+ the headers (which will change debugging output).
+ HPUX portability patches from Michael J. Corrigan of UC San Diego.
+ Some attempts to adapt better to out of open file conditions.
+ Some changes to ctladdr handling in queue files.
+
+6.37/6.17 93/03/16
+ MAJOR CHANGE: delete e_sender and e_returnpath (why are these
+ different from e_from?) and $< macro.
+ Log correct IP address in relay= field even if the connection
+ times out.
+ Log "received from [RESPONSE]" on EF_RESPONSE messages (from
+ John Gardiner Myers).
+ Fixes to SysExMsg logging (sometimes just got "message: %s"
+ instead of "message: error message"), noted by Eric
+ Wassenaar. Also reported by Motonori Nakamura.
+ Improvements to MX piggybacking code, from Motonori Nakamura.
+ Fix case where CurHostName points to an auto variable that has
+ been deallocated (from Motonori Nakamura).
+ Fix bug causing newlines to be included in aliases if option
+ "n" (check alias RHS) is set; bug noted by David Muir
+ Sharnoff.
+ Fix problem causing user names that should be mapped to lower
+ case to not be mapped if they are sent during a queue
+ run. This greatly simplifies the case mapping code.
+ Problem noted by Allan E Johannesen of WPI.
+ Don't do recipient address rewriting in buildaddr. This
+ improperly did recipient rewriting on sender addresses,
+ and just seems bogus in general -- but the change could
+ break some .cf files.
+ Pass TZ envariable to child processes for System V.
+ CONFIG: allow LOCAL_RULE_1 and LOCAL_RULE_2 if you want to
+ define those rulesets.
+ KNOWN PROBLEM: I have seen some problems on SunOS that causes
+ the User Data Base to give errors on some addresses. I
+ have tracked the problem back at least as far as 93.02.15
+ (version 6.22). Running with debugging on makes it
+ go away, so I conclude that it is referencing uninitialized
+ stack data. I haven't been able to track this down yet.
+
+6.36/6.16 93/03/08
+ Allow local mailer to specify $@host -- this lets you assign the
+ "foo" part of jgm+foo to $h for passing in to the local
+ mailer.
+ Additional debug printing in getcanonname (show query type).
+ Don't add the e_fromdomain on sender addresses -- this interacts
+ wierdly with the owner- code.
+ Improve delivery logging to not log obvious or meaningless stuff.
+ Include numeric IP address in Received: lines per RFC 1123 section
+ 5.2.8.
+ Fixed a bug in checking stat() return value if restrictmailq is
+ set. Also, check the entire group set instead of just the
+ primary group. Both from John Gardiner Myers.
+ Don't have usrerr automatically print errno, since this is often
+ misleading.
+ Use transienterror() in makeconnection after connect() fails and
+ in openmailer after execve() fails (from Eric Wassenaar).
+ Also moved transienterror() from util.c to conf.c.
+ Clean up from= logging on response messages.
+ Undo patch allowing prescan to return a null vector -- it breaks
+ too many things.
+ Config: FEATURE(notsticky) lets you use UDB for everything coming
+ in to the machine, even if it is specifically targetted
+ to this machine. Without it, UDB is bypassed if the user
+ name is fully qualified.
+ Config: fix another minor botch with <> (local mailer wasn't
+ mapping them properly).
+
+6.35/6.15 93/03/05
+ Fix getrealhostname to return null if sinlen <= 0 -- this can
+ occur if stdin is a pipe.
+ Avoid infinite loop in getcanonname if name server return
+ NO_DATA (for example).
+ Config: avoid having C flag qualify list syntax and error syntax.
+
+6.34/6.14 93/03/05
+ Fix logging in deliver to not pass too many parameters to Ultrix
+ versions of syslog.
+ Don't write the pid file until after the daemon has actually
+ opened and conditioned the connection.
+ Consider addresses "different" if their q_uids differ (so that
+ two users forwarding to the same program will be seen
+ as different, rather than the same).
+ Fix problem with bad parameters in main() -- they set ExitStat
+ but don't exit.
+ Fix null pointer references through RealHostName -- painfully
+ discovered by Allan E Johannesen of WPI.
+ Fix bug causing user@@localhost to core dump (yuch).
+ Config: don't put two @host.dom.ain on users in $=E in SMTP
+ mailer. Also, catch user@ (no host) in ruleset 0.
+
+6.33/6.13 93/03/03
+ Config: add confCW_FILE as the name of the cw configuration file
+ (defaults to /etc/sendmail.cw). From P{r Emanuelsson.
+ Allow prescan to return a pointer to an empty list -- this is
+ not an error. Also, clean up error reporting to avoid
+ double errors (prescan reports once, then the caller
+ reports again).
+ Changes to avoid trusting T_ANY queries -- run them, but if you
+ don't get the info you expected, do T_A and T_MX queries
+ anyhow. This also fixes an oversight where _res.options
+ bits were being ignored.
+ If PRIV_NOVRFY is set, use 252 response code instead of 502 per
+ RFC 1123 section 5.2.3. It's not 100% clear that this
+ is correct, but it probably works better with stupid
+ mailers that do a VRFY and only check the first digit.
+
+6.32/6.12 93/03/02
+ Fix uninitialized variable "protocol" in smtp code.
+ Include <unistd.h> in sendmail.h -- move towards POSIX/ANSI.
+ Additional hooks for RFC 1427 (ESMTP SIZE extension). This
+ includes requiring that enoughspace() know the system
+ block size, which will undoubtedly break most ports.
+ Trace flag 19 in use for srvrsmtp.c.
+ Additional logging -- notably the sending mailer name. This
+ also changes the delivery logging to strict field=value
+ syntax.
+ Fix some problems with messages getting sent even to addresses
+ that had been marked bad -- from Eric Wassenaar.
+ More WIDE changes: accept host name inside [...] as non-MXed
+ host. This is intended ONLY for use inside firewalled
+ environments, where the MX points at the gateway.
+ Change .cf file conventions so that mapping for <> addresses
+ don't have an @ in them (to avoid confusing the C mailer
+ flag). Pointed out by Neil Rickert.
+ Config extensions for Sam Leffler's FlexFAX software.
+
+6.31/6.10 93/02/28
+ Fix some more bugs in alias owner code -- there were some wierd
+ cases where an error in a non-aliased name would override
+ the return info in an aliased name with an owner.
+ Changes from WIDE Project, forwarded to me by Motonori Nakamura:
+ Log actual delivery host (after MX et al); from
+ yasuhiro@dcl.co.jp.
+ Log daemon startup.
+ Deliver Postmaster copies without a body.
+ Better logging of SMTP senders.
+ Send all program email as daemon even when local.
+ As requested in various forms from many people, accept -qIstring
+ to limit queue runs to jobs with queue-id matching string.
+ Similarly for -qRstring for recipients, -qSstring for
+ senders.
+ Initial hooks for ESMTP support (see RFC 1425).
+ Fixed a syntax error in the UUCP mailer specification that caused
+ core dumps on startup.
+ Check for missing A= or P= arguments in mailer definitions.
+
+6.30/6.10 93/02/27
+ Require FROZENCONFIG compilation flag to include frozen
+ configuration code. Frozen configuration is really
+ not a very good idea any more, particularly in shared
+ library environments.
+ Do better checking of errno after opens of :include: and .forward
+ files to defer delivery on network and other transient
+ errors. Suggestion from Craig Everhart.
+ Fix minor botch in read timeout macro processing.
+ Add FEATURE(nouucp) to config files for sites that know absolutely
+ nothing about UUCP.
+ Add built cf files to distribution tape and clarify how to build
+ them if you don't have the Berkeley make.
+ Some sizeof(long) portability changes for the Alpha, from Allan
+ E Johannesen.
+ Add "restrictmailq" privacy flag -- if set, only people in the same
+ group as your queue directory can print the queue. If you
+ set this, be sure you also restrict access to log files....
+ Fix another bug in owner-list stuff that can cause data files to
+ be "lost".
+ Fix a bug with queue runs that cause forwards to yourself to go
+ into alias/forwarding loops. I'm still iffy about this
+ fix.
+ Fix from Eric Wassenaar for suppression of return message code.
+
+6.29/6.9 93/02/24
+ Fix yet another problem in alias owner code -- put the wrong return
+ address on the enclosed return-to-sender letter.
+
+6.28/6.9 93/02/24
+ Fix botch in alias owner code that caused it to not operate if the
+ error was detected locally.
+
+6.27/6.9 93/02/24
+ M_LOCAL => M_LOCALMAILER to avoid conflict with Ultrix include
+ file <sys/mount.h>.
+ Miscellaneous bug fixes from Eric Wassenaar:
+ sendmail -bv -t logs the from line even though in verify
+ mode only.
+ sendmail -v can go into queue mode if shouldqueue returns
+ TRUE.
+ Add route-addr pruning per RFC 1123 section 5.3.3. This can be
+ disabled using the "R" option.
+ Delete (always undocumented) -R flag (save original recipients);
+ there are ways to syslog(3) these now.
+ Clean up SMTP reply codes -- specify them as needed in the code,
+ instead of in conf.c -- this was needed during the NCP to
+ TCP transition, but seems silly now. This also changes
+ parameters to message and nmessage.
+ Have mailstats read the .cf file to find the sendmail.st file and
+ get text versions of mailer names. An initial version of
+ this code was provided by Tuominen Keijo (although the
+ comments indicate the good bits were written by "E.V.").
+ Add yet more System V compatibility hacks.
+ Fix bug in VRFY code (assumes everything must be a local user).
+ Allow specification of any of the hard-wired pathnames in the
+ Makefile.
+ Delete concept of "trusted users" -- this really didn't provide
+ any security anyway, and caused some problems.
+ Delete last vestige of support for the word "at" as an equivalent
+ to the character "@".
+ Propagate owner-foo alias information into the envelope sender.
+ Based on code from John Gardiner Myers. This is a major
+ semantic change -- beware!
+ Allow $@ on LHS to indicate "match zero" -- this is used to match
+ the null expression.
+
+6.26/6.8 93/02/21
+ Don't "lose" queue runs. Very important fix from (who else?)
+ Eric Wassenaar.
+ Completely reset state on RSET command -- from Eric Wassenaar.
+ Send error messages and return receipts using an envelope sender
+ of <> regardless of the setting of $n. Rewriting rules
+ can undo this if they feel the necessity, as might be
+ needed for networks that don't understand the syntax.
+ This is permitted by RFC 821 section 3.6 and required by
+ RFC 1123 section 5.3.3. THIS REQUIRES VERSION 4 CONFIG
+ FILES because the rulesets must be able to parse <>
+ properly.
+ Don't ever send error messages to "<>" -- they will get sent to
+ the local postmaster or dumped in /usr/tmp/dead.letter
+ instead. Per RFC 1123 section 5.3.3.
+ Explicitly check for email to yourself as a dotted quad. You
+ have to call $[ [ ... ] $] to get this.
+ Up the message timeout to five days per RFC 1123 section 5.3.1.1.
+ Make all read timeouts individually configurable, as strongly
+ recommended by RFC 1123 section 5.3.2.
+ Use f_bavail (blocks available to regular users) instead of f_bfree
+ (blocks available to superuser) in free block checks.
+ Change $d macro to be the current time, not the origination time,
+ since this is consistent with how it is used now.
+ Generalization of enoughspace from Eric Wassenaar covering
+ SGI, Apollo, HPUX, Ultrix, and SunOS.
+ Ignore process group signals -- some front ends can do this if
+ you kill a window too quickly. From Eric Wassenaar.
+ Change umask to 022.
+
+6.25/6.8 93/02/20
+ Close all cached connections before calling mailers and after
+ forking for delivery (caused double closes which resulted
+ in false errors).
+ Add FEATURE(redirect) in config files -- this allows you to alias
+ old addresses to a pointer to the new address that will
+ give a 551 error message, but not deliver the mail.
+ Some code changes to make the 551 errors look pretty.
+ Names of M4 program paths in config files have changed -- they
+ are all XXX_MAILER_PATH now, to match XXX_MAILER_FLAGS.
+ Fix a bug in the QSELFREF code having to do with empty .forward
+ files, reported by Eric Wassenaar.
+ Add option "p" (privacy flags); this allows you to tune how
+ picky the SMTP server will be. This also adds the
+ confPRIVACY_FLAGS M4 macro in the config files.
+ Add option "b" (minimum blocks free). If there are fewer than
+ this number of blocks free on the filesystem containing
+ the queue directory, the SMTP MAIL command will return
+ a 452 response and ask you to try again later. This
+ also adds the confMIN_FREE_BLOCKS M4 macro in the config
+ files.
+ Made VRFY just verify (doesn't expand aliases and .forward files);
+ EXPN does full expansion. RCPT in queue-only mode also
+ doesn't chase aliases and .forward.
+
+6.24/6.7 93/02/19
+ Increase the number of domain search entries in domain.c to allow
+ for the extra "" entry indicating the root domain.
+ Reported by Motonori Nakamura of Kyoto U.
+ Add a "SMART_HOST" in the configs for UUCP-connected sites that
+ want to forward all mail with extra "@"s to that site.
+ Also allows SMART_HOST, LOCAL_RELAY, and MAIL_HUB to
+ be specified as ``mailer:hostname'' to use an alternate
+ mailer.
+ Clarified and updated some wording in the Operations Guide.
+ Add the "c" mailer flag -- this suppresses all comment parts of
+ addresses (requested by John Curran of NEARnet).
+ Have -v print prompts in -bt mode even if stdin is not a terminal
+ (default behaviour is to be silent if not reading from
+ a terminal). Suggested by Bryan Costales, ICSI.
+ Move the metacharacters from C0 space (\001-\037) into C1 space
+ (\201-\237). This also fixes a bunch of potential bugs
+ with G1 characters (\240-\276) in headers relating to
+ negative numbers passed to isspace() et al.
+ Add YP_LAST_MODIFIED and YP_MASTER_NAME to DBM version of alias
+ database if YPCOMPAT is #defined. Enhancement from
+ Takahiro Kanbe of Fuji Xerox Information Systems Co., Ltd.
+ Add "list" Precedence (-30); this can be used with old sendmails
+ which will map to precedence 0 (which will return error
+ messages). Suggested by Stephen R. van den Berg.
+ Many bug fixes from Eric Wassenaar of the National Institute for
+ Nuclear and High-Energy Physics, Amsterdam:
+ Clear timeouts properly on open failures in include().
+ Don't dereference through NULL if no home directory found.
+ Re-establish SIGCHLD signal on System 5 in reapchild().
+ Avoid NULL pointer reference on -pFOO flag.
+ Properly handle backslash escapes in comments.
+ Correctly check reply status on SMTP NOOP command.
+ Properly save SMTP error message if peer gives
+ "Service Shutting Down" message.
+ Avoid writing to the transcript if it couldn't be opened.
+ Signal errors in SMTP children to parent properly.
+ Handle self references in a list more globally (include a
+ QSELFREF bit in the address flags). This enhancement
+ was suggested by Eric Wassenaar.
+ Use initgroups() in hpux, even though it's System-V based. The
+ HASINITGROUPS compile flag can set this on other systems.
+ This HPUX behaviour was pointed out by Eric Wassenaar.
+
+6.23/6.6 93/02/16
+ Clean up handling of LogLevel to make it easier to figure out
+ what's on what level.
+ Change log levels to have some consistency:
+ 1 serious system failures, security problems
+ 2 lost communications, protocol failures
+ 3 other serious failures
+ 4 minor errors
+ 5 message collection
+ 6 vrfy logging, creation of return-to-sender
+ 7 delivery failures
+ 8 delivery successes
+ 9 delivery tempfails (queue ups)
+ 10 database expansion
+ >64 debugging
+ Allow IDA-style separated processing on S= and R= in Mailer
+ definition lines. Note that rulesets 1 and 2 are
+ still used for both addresses as before. Bruce Lilly
+ gave a convincing argument that RFC976 insists on
+ this behaviour.
+ Added some time zones to arpatounix -- they may not be in the
+ standards, but they are in use. However, I may delete
+ arpatounix entirely -- there appears to be no reason
+ for it to exist.
+ Change to UUCP mailer (in cf directory) to try to do a saner job.
+ I'm still not certain about this mailer in general.
+
+6.22/6.5 93/02/15
+ Fix bug that prevents saving letters in ~/dead.letter.
+ Don't add angle brackets in VRFY command if angle brackets already
+ exist in the address.
+ Fix bogus error message in udbexpand.
+ Null terminate host buffers in buildaddr (broken in 6.21) --
+ IMPORTANT FIX!!
+
+6.21/6.5 93/02/15
+ Fix another incorrect error message in alias.c, found by Azuma
+ Okamoto.
+ Fix a couple of problems in the more-configurable config files,
+ found by Tom Ivar Helbekkmo.
+ Fix problem with quoted :include: entries.
+ Don't duplicate the filename on verbose printing of .forward and
+ :include: contents.
+ Extend size of prescan buffer (to allow bigger addresses). Also,
+ detect some buffer overflows.
+ Log user SMTP protocol errors (log level 4).
+
+6.20/6.4 93/02/14
+ Fix another problem in the MCI state machine caused when there
+ were errors generated from the other end to commands
+ other than RCPT.
+
+6.19/6.4 93/02/14
+ Include load average support for DEC Alpha running OSF/1.
+ Fix multiple-response problem with errors in MAIL From: line.
+ Fix SMTP reply codes for invalid address syntaxes (give 501;
+ never give multiple error messages for a single message).
+ Fix problem where a cached connection timeout rejects all
+ later connects to that host.
+ Fix incorrect error message if alias.c is compiled with DBM only.
+ Additional changes to fix nested conditionals (from Bruce Lilly).
+ Recover more gracefully from operating system failures, particularly
+ NULL returns from openmailer (from Noritoshi Demizu,
+ OMRON Corporation).
+ Log forward, alias, and userdb expand operations on log level 10;
+ concept suggested by P{r (Pell) Emanuelsson.
+ Changes for HPUX 8.07 compatibility.
+
+6.18/6.4 93/02/12
+ Allow any config option to be set using an M4 define.
+ Change UNAME compile flag to HASUNAME for IDA compatibility
+ (besides, it's a better name).
+ Note in README that on SunOS it must be linked -Bstatic.
+ Fairly major change in domain.c to handle wildcard MX records
+ more rationally. NOTE: the "w" option (no wildcard MX
+ records match local domain) has been eliminated.
+ Fix some unset variable references pointed out by Bruce Lilly.
+ Fix host name in process titles when using cached connection.
+
+6.17/6.3 93/01/28
+ Fix System 5 compatibility changes to be compatible with the rest
+ of the world.
+
+6.16/6.3 93/01/28
+ Experimental fix for problem handling errors in the SMTP
+ protocol in conjunction with connection caching.
+ System 5 compatibility changes.
+
+6.15/6.3 93/01/26
+ Fix a bug that causes local mail delivered using -odq to be
+ eliminated as a duplicate (because it matched the
+ ctladdr, now passed in as a C line). These changes
+ are pretty tricky......
+
+6.14/6.3 93/01/25
+ Add debugging for some MCI errors.
+
+6.13/6.3 93/01/22
+ Fix -e compatibility flag to take a value.
+ Fix a couple of minor compilation warnings on Sun cc.
+ Improve error messages in a few cases to be more self-explanatory.
+
+6.12/6.3 93/01/21
+ Fix yet-another problem with environment handling, pointed out
+ by Yoshitaka Tokugawa and Tom Ivar Helbekkmo.
+ Some heuristics to try to limit resource exhaustion problems
+ if a downstream host has been down for a long time.
+ Fix problem with incorrect host name being logged in "Connection
+ timed out" messages (from Tom Ivar Helbekkmo).
+ Fix some ANSI C problems (from Takahiro Kanbe).
+ Properly log message sender on returned mail during queue run.
+ Count number of recipients properly.
+ Fix a problem in yp map code.
+ Diagnose "message timed out" (from Motonori Nakamura).
+
+6.11/6.3 93/01/20
+ Fix problem with address delimitor inside quotes.
+ Define $k and $=k to be the UUCP name (from the uname call)
+ based on code from Bruce Lilly.
+
+6.10/6.2 93/01/18
+ Implement arpatounix (largely code from Bruce Lilly).
+ Log more info (suggested by John Myers).
+ Allow nested $?...$|...$. (inspired by code from Bruce Lilly of
+ Sony US).
+ POSIX compatibility (noted by Keith Bostic).
+ Handle SMTP MAIL command errors properly (urged by several people,
+ notably John Myers of CMU).
+ Do early diagnosis of .cf errors (notably referencing a RHS
+ substitution that isn't on the LHS).
+ Adjust checkpointing to better handle batched recipients, suggested
+ by John Myers.
+ Fix miscellaneous bugs.
+ (config files:) Implement MAIL_HUB for all local mail (to handle
+ NFS-mounted directories) as urged by Tom Ivar Helbekkmo
+ of the Norwegian School of Economics.
+
+6.9/6.1 93/01/13
+ Environment handling simplification/bug fix -- child processes
+ get a minimal, fixed environment. This avoids different
+ behaviour in queue runs.
+ Handle commas inside comments properly.
+ Properly limit large messages submitted in -obq mode.
+
+6.8/6.1 93/01/10
+ Check mtime of thaw file against .cf and sendmail binary, based on
+ code from John Myers.
+
+6.7/6.1 93/01/10
+ MX piggybacking, based on code from John Myers@CMU.
+ Allow checkcompat to return -1 to mean tempfail.
+ Bug fix in m_mno computation.
+
+6.6/6.1 93/01/09
+ Tuning of queueing functions as recommended by John Gardiner Myers.
+ Return mail headers (no body) on messages with negative precedence.
+ Minor other bug fixes.
+
+6.5/6.1 93/01/03
+ Fix botch causing queued headers to have ?XX? prefixes.
+
+6.4/6.1 93/01/02
+ Changes to recognize special mailer types (e.g., file) early.
+
+6.3/6.1 93/01/01
+ Pass timeouts to sfgets.
+ Check for control characters in addresses.
+ Fixed deferred error reporting.
+ Report duplicate aliases.
+ Handle mixed case recursive aliases.
+ Misc bug fixes.
+
+6.2/6.1 92/12/30
+ Put return-receipt-to on a conf.c flag (but don't set it).
+ Fix minor syslog problem.
diff --git a/usr.sbin/sendmail/cf/README b/usr.sbin/sendmail/cf/README
new file mode 100644
index 0000000..6ab3b01
--- /dev/null
+++ b/usr.sbin/sendmail/cf/README
@@ -0,0 +1,1232 @@
+
+
+ NEW SENDMAIL CONFIGURATION FILES
+
+ Eric Allman <eric@CS.Berkeley.EDU>
+
+ @(#)README 8.28 (Berkeley) 4/14/94
+
+
+This document describes the sendmail configuration files being used
+at Berkeley. These use features in the new (R8) sendmail, and although
+there is an ``OLDSENDMAIL'' mode, they haven't really been tested on
+old versions of sendmail and cannot be expected to work well.
+
+These configuration files are probably not as general as previous
+versions, and don't handle as many of the weird cases automagically.
+I was able to simplify by them for two reasons. First, the network
+has become more consistent -- for example, at this point, everyone
+on the internet is supposed to be running a name server, so hacks to
+handle NIC-registered hosts can go away. Second, I assumed that a
+subdomain would be running SMTP internally -- UUCP is presumed to be
+a long-haul protocol. I realize that this is not universal, but it
+does describe the vast majority of sites with which I am familiar,
+including those outside the US.
+
+Of course, the downside of this is that if you do live in a weird
+world, things are going to get weirder for you. I'm sorry about that,
+but at the time we at Berkeley had a problem, and it seemed like the
+right thing to do.
+
+This package requires a post-V7 version of m4; if you are running the
+4.2bsd, SysV.2, or 7th Edition version, I suggest finding a friend with
+a newer version. You can m4-expand on their system, then run locally.
+SunOS's /usr/5bin/m4 or BSD-Net/2's m4 both work. GNU m4 version 1.1
+also works. Unfortunately, I'm told that the M4 on BSDI 1.0 doesn't
+work -- you'll have to use a Net/2 or GNU version.
+
+IF YOU DON'T HAVE A BERKELEY MAKE, don't despair! Just run
+"m4 foo.mc > foo.cf" -- that should be all you need. There is also
+a fairly crude (but functional) Makefile.dist that works on the
+old version of make.
+
+To get started, you may want to look at tcpproto.mc (for TCP-only
+sites), uucpproto.mc (for UUCP-only sites), and clientproto.mc (for
+clusters of clients using a single mail host). Others are versions
+that we use at Berkeley, although not all are in current use. For
+example, ucbarpa has gone away, but I've left ucbarpa.mc in because
+it demonstrates some interesting techniques.
+
+I'm not pretending that this README describes everything that these
+configuration files can do; clever people can probably tweak them
+to great effect. But it should get you started.
+
+*******************************************************************
+*** BE SURE YOU CUSTOMIZE THESE FILES! They have some ***
+*** Berkeley-specific assumptions built in, such as the name ***
+*** of our UUCP-relay. You'll want to create your own domain ***
+*** description, and use that in place of domain/Berkeley.m4. ***
+*******************************************************************
+
+
++--------------------------+
+| INTRODUCTION AND EXAMPLE |
++--------------------------+
+
+Configuration files are contained in the subdirectory "cf", with a
+suffix ".mc". They must be run through "m4" to produce a ".cf" file.
+
+Let's examine a typical .mc file (cf/cs-exposed.mc):
+
+ divert(-1)
+ #
+ # Copyright (c) 1983 Eric P. Allman
+ # Copyright (c) 1988 The Regents of the University of California.
+ # All rights reserved.
+ #
+ # Redistribution and use in source and binary forms are permitted
+ # provided that the above copyright notice and this paragraph are
+ # duplicated in all such forms and that any documentation,
+ # advertising materials, and other materials related to such
+ # distribution and use acknowledge that the software was developed
+ # by the University of California, Berkeley. The name of the
+ # University may not be used to endorse or promote products derived
+ # from this software without specific prior written permission.
+ # THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ # IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ # WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ #
+
+The divert(-1) will delete the crud in the resulting output file.
+The copyright notice is what your lawyers require. Our lawyers require
+the one that I've included in my files. A copyleft is a copyright by
+another name.
+
+The next line MUST be
+
+ include(`../m4/cf.m4')
+
+This will pull in the M4 macros you will need to make sense of
+everything else. As the saying goes, don't think about it, just
+do it. If you don't do it, don't bother reading the rest of this
+file.
+
+ VERSIONID(`<SCCS or RCS version id>')
+
+VERSIONID is a macro that stuffs the version information into the
+resulting file. We use SCCS; you could use RCS, something else, or
+omit it completely. This is not the same as the version id included
+in SMTP greeting messages -- this is defined in m4/version.m4.
+
+ DOMAIN(cs.exposed)
+
+This example exposes the host inside of the CS subdomain -- that is,
+it doesn't try to hide the name of the workstation to the outside
+world. Changing this to DOMAIN(cs.hidden) would have made outgoing
+messages refer to "<username>@CS.Berkeley.EDU" instead of using the
+local hostname. Internally this is effected by using
+"MASQUERADE_AS(CS.Berkeley.EDU)".
+
+ MAILER(smtp)
+
+These describe the mailers used at the default CS site site. The
+local mailer is always included automatically.
+
+
++--------+
+| OSTYPE |
++--------+
+
+Note that cf/cs-exposed.mc omits an OSTYPE macro -- this assumes
+default Computer Science Division environment. There are several
+explicit environments available: bsd4.3, bsd4.4, hpux, irix, osf1,
+riscos4.5, sunos3.5, sunos4.1, and ultrix4.1. These change things
+like the location of the alias file and queue directory. Some of
+these files are identical to one another.
+
+Operating system definitions are easy to write. They may define
+the following variables (everything defaults, so an ostype file
+may be empty).
+
+ALIAS_FILE [/etc/aliases] The location of the text version
+ of the alias file(s). It can be a comma-separated
+ list of names (but be sure you quote values with
+ comments in them -- for example, use
+ define(`ALIAS_FILE', `a,b')
+ to get "a" and "b" both listed as alias files;
+ otherwise the define() primitive only sees "a").
+HELP_FILE [/usr/lib/sendmail.hf] The name of the file
+ containing information printed in response to
+ the SMTP HELP command.
+QUEUE_DIR [/var/spool/mqueue] The directory containing
+ queue files.
+STATUS_FILE [/etc/sendmail.st] The file containing status
+ information.
+LOCAL_MAILER_PATH [/bin/mail] The program used to deliver local mail.
+LOCAL_MAILER_FLAGS [rmn] The flags used by the local mailer. The
+ flags lsDFM are always included.
+LOCAL_MAILER_ARGS [mail -d $u] The arguments passed to deliver local
+ mail.
+LOCAL_SHELL_PATH [/bin/sh] The shell used to deliver piped email.
+LOCAL_SHELL_FLAGS [eu] The flags used by the shell mailer. The
+ flags lsDFM are always included.
+LOCAL_SHELL_ARGS [sh -c $u] The arguments passed to deliver "prog"
+ mail.
+USENET_MAILER_PATH [/usr/lib/news/inews] The name of the program
+ used to submit news.
+USENET_MAILER_FLAGS [rlsDFMmn] The mailer flags for the usenet mailer.
+USENET_MAILER_ARGS [-m -h -n] The command line arguments for the
+ usenet mailer.
+USENET_MAILER_MAX [100000] The maximum size of messages that will
+ be accepted by the usenet mailer.
+SMTP_MAILER_FLAGS [undefined] Flags added to SMTP mailer. Default
+ flags are `mDFMUX' (and `a' for esmtp mailer).
+SMTP_MAILER_MAX [undefined] The maximum size of messages that will
+ be transported using the smtp or esmtp mailers.
+UUCP_MAILER_FLAGS [undefined] Flags added to UUCP mailer. Default
+ flags are `DFMhuU' (and `m' for suucp mailer, minus
+ `U' for uucp-dom mailer).
+UUCP_MAILER_ARGS [uux - -r -z -a$f -gC $h!rmail ($u)] The arguments
+ passed to the UUCP mailer.
+UUCP_MAX_SIZE [100000] The maximum size message accepted for
+ transmission by the UUCP mailers.
+FAX_MAILER_PATH [/usr/local/lib/fax/mailfax] The program used to
+ submit FAX messages.
+FAX_MAILER_MAX [100000] The maximum size message accepted for
+ transmission by FAX.
+
++---------+
+| DOMAINS |
++---------+
+
+You will probably want to collect domain-dependent defines into one
+file, referenced by the DOMAIN macro. For example, our Berkeley
+domain file includes definitions for several internal distinguished
+hosts:
+
+UUCP_RELAY The host that will forward UUCP-addressed email.
+ If not defined, all UUCP sites must be directly
+ connected.
+BITNET_RELAY The host that will forward BITNET-addressed email.
+ If not defined, the .BITNET pseudo-domain won't work.
+LOCAL_RELAY The site that will handle unqualified names -- that
+ is, names with out an @domain extension. If not set,
+ they are assumed to belong on this machine. This
+ allows you to have a central site to store a
+ company- or department-wide alias database. This
+ only works at small sites, and there are better
+ methods.
+
+Each of these can be either ``mailer:hostname'' (in which case the
+mailer is the internal mailer name, such as ``suucp'' and the hostname
+is the name of the host as appropriate for that mailer) or just a
+``hostname'', in which case a default mailer type (usually ``relay'',
+a variant on SMTP) is used. WARNING: if you have a wildcard MX
+record matching your domain, you probably want to define these to
+have a trailing dot so that you won't get the mail diverted back
+to yourself.
+
+The domain file can also be used to define a domain name, if needed
+(using "DD<domain>") and set certain site-wide features. If all hosts
+at your site masquerade behind one email name, you could also use
+MASQUERADE_AS here.
+
+You do not have to define a domain -- in particular, if you are a
+single machine sitting off somewhere, it is probably more work than
+it's worth. This is just a mechanism for combining "domain dependent
+knowledge" into one place.
+
++---------+
+| MAILERS |
++---------+
+
+There are fewer mailers supported in this version than the previous
+version, owing mostly to a simpler world.
+
+local The local and prog mailers. You will almost always
+ need these; the only exception is if you relay ALL
+ your mail to another site. This mailer is included
+ automatically.
+
+smtp The Simple Mail Transport Protocol mailer. This does
+ not hide hosts behind a gateway or another other
+ such hack; it assumes a world where everyone is
+ running the name server. This file actually defines
+ three mailers: "smtp" for regular (old-style) SMTP to
+ other servers, "esmtp" for extended SMTP to other
+ servers, and "relay" for transmission to our
+ RELAY_HOST or MAILER_HUB.
+
+uucp The Unix-to-Unix Copy Program mailer. Actually, this
+ defines two mailers, "uucp" and "suucp". The latter
+ is for when you know that the UUCP mailer at the other
+ end can handle multiple recipients in one transfer.
+ When you invoke this, sendmail looks for all names in
+ the $=U class and sends them to the uucp-old mailer; all
+ names in the $=Y class are sent to uucp-new; and all
+ names in the $=Z class are sent to uucp-uudom. Note that
+ this is a function of what version of rmail runs on
+ the receiving end, and hence may be out of your control.
+ If smtp is defined, it also defines "uucp-dom" and
+ "uucp-uudom" mailers that use domain-style rewriting.
+ See the section below describing UUCP mailers in more
+ detail.
+
+usenet Usenet (network news) delivery. If this is specified,
+ an extra rule is added to ruleset 0 that forwards all
+ local email for users named ``group.usenet'' to the
+ ``inews'' program. Note that this works for all groups,
+ and may be considered a security problem.
+
+fax Facsimile transmission. This is experimental and based
+ on Sam Leffler's FlexFAX software. For more information,
+ see below.
+
+pop Post Office Protocol.
+
+
++----------+
+| FEATURES |
++----------+
+
+Special features can be requested using the "FEATURE" macro. For
+example, the .mc line:
+
+ FEATURE(use_cw_file)
+
+tells sendmail that you want to have it read an /etc/sendmail.cw
+file to get values for class $=w. The FEATURE may contain a single
+optional parameter -- for example:
+
+ FEATURE(mailertable, dbm /usr/lib/mailertable)
+
+Available features are:
+
+use_cw_file Read the file /etc/sendmail.cw file to get alternate
+ names for this host. This might be used if you were
+ on a host that MXed for a dynamic set of other
+ hosts. If the set is static, just including the line
+ "Cw<name1> <name2> ..." is probably superior.
+ The actual filename can be overridden by redefining
+ confCW_FILE.
+
+redirect Reject all mail addressed to "address.REDIRECT" with
+ a ``551 User not local; please try <address>'' message.
+ If this is set, you can alias people who have left
+ to their new address with ".REDIRECT" appended.
+
+nouucp Don't do anything special with UUCP addresses at all.
+
+nocanonify Don't pass addresses to $[ ... $] for canonification.
+ This would generally only be used by sites that only
+ act as mail gateways or which have user agents that do
+ full canonification themselves. You may also want to
+ use "define(`confBIND_OPTS',`-DNSRCH -DEFNAMES')" to
+ turn off the usual resolver options that do a similar
+ thing.
+
+notsticky By default, email sent to "user@local.host" are marked
+ as "sticky" -- that is, the local addresses aren't
+ matched against UDB and don't go through ruleset 5.
+ This features disables this treatment. It would
+ normally be used on network gateway machines.
+
+mailertable Include a "mailer table" which can be used to override
+ routing for particular domains. The argument of the
+ FEATURE may be the key definition. If none is specified,
+ the definition used is:
+ hash -o /etc/mailertable
+ Keys in this database are fully qualified domain names
+ or partial domains preceded by a dot -- for example,
+ "vangogh.CS.Berkeley.EDU" or ".CS.Berkeley.EDU".
+ Values must be of the form:
+ mailer:domain
+ where "mailer" is the internal mailer name, and "domain"
+ is where to send the message. These maps are not
+ reflected into the message header.
+
+domaintable Include a "domain table" which can be used to provide
+ full domains on unqualified (single word) hosts. The
+ argument of the FEATURE may be the key definition. If
+ none is specified, the definition used is:
+ hash -o /etc/domaintable
+ The key in this table is the unqualified host name; the
+ value is the fully qualified domain. Anything in the
+ domaintable is reflected into headers; that is, this
+ is done in ruleset 3.
+
+bitdomain Look up bitnet hosts in a table to try to turn them into
+ internet addresses. The table can be built using the
+ bitdomain program contributed by John Gardiner Myers.
+ The argument of the FEATURE may be the key definition; if
+ none is specified, the definition used is:
+ hash -o /etc/bitdomain.db
+ Keys are the bitnet hostname; values are the corresponding
+ internet hostname.
+
+uucpdomain Similar feature for UUCP hosts. The default map definition
+ is:
+ hash -o /etc/uudomain.db
+ At the moment there is no automagic tool to build this
+ database.
+
+always_add_domain
+ Include the local host domain even on locally delivered
+ mail. Normally it is not added unless it is already
+ present.
+
+allmasquerade If masquerading is enabled (using MASQUERADE_AS), this
+ feature will cause recipient addresses to also masquerade
+ as being from the masquerade host. Normally they get
+ the local hostname. Although this may be right for
+ ordinary users, it can break local aliases. For example,
+ if you send to "localalias", the originating sendmail will
+ find that alias and send to all members, but send the
+ message with "To: localalias@masqueradehost". Since that
+ alias likely does not exist, replies will fail. Use this
+ feature ONLY if you can guarantee that the ENTIRE
+ namespace on your masquerade host supersets all the
+ local entries.
+
+nodns We aren't running DNS at our site (for example,
+ we are UUCP-only connected). It's hard to consider
+ this a "feature", but hey, it had to go somewhere.
+
+nullclient This is a special case -- it creates a stripped down
+ configuration file containing nothing but support for
+ forwarding all mail to a central hub via a local
+ SMTP-based network. The argument is the name of that
+ hub.
+
+ The only other feature that should be used in conjunction
+ with this one is "nocanonify" (this causes addresses to
+ be sent unqualified via the SMTP connection; normally
+ they are qualifed with the masquerade name, which
+ defaults to the name of the hub machine). No mailers
+ should be defined. No aliasing or forwarding is done.
+
+
++-------+
+| HACKS |
++-------+
+
+Some things just can't be called features. To make this clear,
+they go in the hack subdirectory and are referenced using the HACK
+macro. These will tend to be site-dependent. The release
+includes the Berkeley-dependent "cssubdomain" hack (that makes
+sendmail accept local names in either Berkeley.EDU or CS.Berkeley.EDU;
+this is intended as a short-term aid while we move hosts into
+subdomains.
+
+
++--------------------+
+| SITE CONFIGURATION |
++--------------------+
+
+Complex sites will need more local configuration information, such as
+lists of UUCP hosts they speak with directly. This can get a bit more
+tricky. For an example of a "complex" site, see cf/ucbvax.mc.
+
+If your host is known by several different names, you need to augment
+the $=w class. This is a list of names by which you are known, and
+anything sent to an address using a host name in this list will be
+treated as local mail. You can do this in two ways: either create
+the file /etc/sendmail.cw containing a list of your aliases (one per
+line), and use ``FEATURE(use_cw_file)'' in the .mc file, or add the
+line:
+
+ Cw alias.host.name
+
+at the end of that file. See the ``vangogh.mc'' file for an example.
+Be sure you use the fully-qualified name of the host, rather than a
+short name.
+
+The SITECONFIG macro allows you to indirectly reference site-dependent
+configuration information stored in the siteconfig subdirectory. For
+example, the line
+
+ SITECONFIG(uucp.ucbvax, ucbvax, U)
+
+reads the file uucp.ucbvax for local connection information. The
+second parameter is the local name (in this case just "ucbvax" since
+it is locally connected, and hence a UUCP hostname). The third
+parameter is the name of both a macro to store the local name (in
+this case, $U) and the name of the class (e.g., $=U) in which to store
+the host information read from the file. Another SITECONFIG line reads
+
+ SITECONFIG(uucp.ucbarpa, ucbarpa.Berkeley.EDU, W)
+
+This says that the file uucp.ucbarpa contains the list of UUCP sites
+connected to ucbarpa.Berkeley.EDU. The $=W class will be used to
+store this list, and $W is defined to be ucbarpa.Berkeley.EDU, that
+is, the name of the relay to which the hosts listed in uucp.ucbarpa
+are connected. [The machine ucbarpa is gone now, but I've left
+this out-of-date configuration file around to demonstrate how you
+might do this.]
+
+Note that the case of SITECONFIG with a third parameter of ``U'' is
+special; the second parameter is assumed to be the UUCP name of the
+local site, rather than the name of a remote site, and the UUCP name
+is entered into $=w (the list of local hostnames) as $U.UUCP.
+
+The siteconfig file (e.g., siteconfig/uucp.ucbvax.m4) contains nothing
+more than a sequence of SITE macros describing connectivity. For
+example:
+
+ SITE(cnmat)
+ SITE(sgi olympus)
+
+The second example demonstrates that you can use two names on the
+same line; these are usually aliases for the same host (or are at
+least in the same company).
+
+
++--------------------+
+| USING UUCP MAILERS |
++--------------------+
+
+It's hard to get UUCP mailers right because of the extremely ad hoc
+nature of UUCP addressing. These config files are really designed
+for domain-based addressing, even for UUCP sites.
+
+There are four UUCP mailers available. The choice of which one to
+use is partly a matter of local preferences and what is running at
+the other end of your UUCP connection. Unlike good protocols that
+define what will go over the wire, UUCP uses the policy that you
+should do what is right for the other end; if they change, you have
+to change. This makes it hard to do the right thing, and discourages
+people from updating their software. In general, if you can avoid
+UUCP, please do.
+
+The major choice is whether to go for a domainized scheme or a
+non-domainized scheme. This depends entirely on what the other
+end will recognize. If at all possible, you should encourage the
+other end to go to a domain-based system -- non-domainized addresses
+don't work entirely properly.
+
+The four mailers are:
+
+ uucp-old (obsolete name: "uucp")
+ This is the oldest, the worst (but the closest to UUCP) way of
+ sending messages accros UUCP connections. It does bangify
+ everything and prepends $U (your UUCP name) to the sender's
+ address (which can already be a bang path itself). It can
+ only send to one address at a time, so it spends a lot of
+ time copying duplicates of messages. Avoid this if at all
+ possible.
+
+ uucp-new (obsolete name: "suucp")
+ The same as above, except that it assumes that in one rmail
+ command you can specify several recipients. It still has a
+ lot of other problems.
+
+ uucp-dom
+ This UUCP mailer keeps everything as domain addresses.
+ Basically, it uses the SMTP mailer rewriting rules.
+
+ Unfortunately, a lot of UUCP mailer transport agents require
+ bangified addresses in the envelope, although you can use
+ domain-based addresses in the message header. (The envelope
+ shows up as the From_ line on UNIX mail.) So....
+
+ uucp-uudom
+ This is a cross between uucp-new (for the envelope addresses)
+ and uucp-dom (for the header addresses). It bangifies the
+ envelope sender (From_ line in messages) without adding the
+ local hostname, unless there is no host name on the address
+ at all (e.g., "wolf") or the host component is a UUCP host name
+ instead of a domain name ("somehost!wolf" instead of
+ "some.dom.ain!wolf").
+
+Examples:
+
+We are on host grasp.insa-lyon.fr (UUCP host name "grasp"). The
+following summarizes the sender rewriting for various mailers.
+
+Mailer sender rewriting in the envelope
+------ ------ -------------------------
+uucp-{old,new} wolf grasp!wolf
+uucp-dom wolf wolf@grasp.insa-lyon.fr
+uucp-uudom wolf grasp.insa-lyon.fr!wolf
+
+uucp-{old,new} wolf@fr.net grasp!fr.net!wolf
+uucp-dom wolf@fr.net wolf@fr.net
+uucp-uudom wolf@fr.net fr.net!wolf
+
+uucp-{old,new} somehost!wolf grasp!somehost!wolf
+uucp-dom somehost!wolf somehost!wolf@grasp.insa-lyon.fr
+uucp-uudom somehost!wolf grasp.insa-lyon.fr!somehost!wolf
+
+If you are using one of the domainized UUCP mailers, you really want
+to convert all UUCP addresses to domain format -- otherwise, it will
+do it for you (and probably not the way you expected). For example,
+if you have the address foo!bar!baz (and you are not sending to foo),
+the heuristics will add the @uucp.relay.name or @local.host.name to
+this address. However, if you map foo to foo.host.name first, it
+will not add the local hostname. You can do this using the uucpdomain
+feature.
+
+
++-------------------+
+| TWEAKING RULESETS |
++-------------------+
+
+For more complex configurations, you can define special rules.
+The macro LOCAL_RULE_3 introduces rules that are used in canonicalizing
+the names. Any modifications made here are reflected in the header.
+
+A common use is to convert old UUCP addreses to SMTP addresses using
+the UUCPSMTP macro. For example:
+
+ LOCAL_RULE_3
+ UUCPSMTP(decvax, decvax.dec.com)
+ UUCPSMTP(research, research.att.com)
+
+will cause addresses of the form "decvax!user" and "research!user"
+to be converted to "user@decvax.dec.com" and "user@research.att.com"
+respectively.
+
+This could also be used to look up hosts in a database map:
+
+ LOCAL_RULE_3
+ R$* < @ $+ > $* $: $1 < @ $(hostmap $2 $) > $3
+
+This map would be defined in the LOCAL_CONFIG portion, as shown below.
+
+Similarly, LOCAL_RULE_0 can be used to introduce new parsing rules.
+For example, new rules are needed to parse hostnames that you accept
+via MX records. For example, you might have:
+
+ LOCAL_RULE_0
+ R$+ <@ host.dom.ain.> $#uucp $@ cnmat $: $1 < @ host.dom.ain.>
+
+You would use this if you had installed an MX record for cnmat.Berkeley.EDU
+pointing at this host; this rule catches the message and forwards it on
+using UUCP.
+
+You can also tweak rulesets 1 and 2 using LOCAL_RULE_1 and LOCAL_RULE_2.
+These rulesets are normally empty.
+
+A similar macro is LOCAL_CONFIG. This introduces lines added after the
+boilerplate option setting but before rulesets, and can be used to
+declare local database maps or whatever. For example:
+
+ LOCAL_CONFIG
+ Khostmap hash /etc/hostmap.db
+ Kyplocal nis -m hosts.byname
+
+
++---------------------------+
+| MASQUERADING AND RELAYING |
++---------------------------+
+
+You can have your host masquerade as another using
+
+ MASQUERADE_AS(host.domain)
+
+This causes outgoing SMTP mail to be labeled as coming from the
+indicated domain, rather than $j. One normally masquerades as one
+of one's own subdomains (for example, it's unlikely that I would
+choose to masquerade as an MIT site).
+
+The masquerade name is not normally canonified, so it is important
+that it be your One True Name, that is, fully qualified and not a
+CNAME.
+
+there are always users that need to be "exposed" -- that is, their
+internal site name should be displayed instead of the masquerade name.
+Root is an example. You can add users to this list using
+
+ EXPOSED_USER(usernames)
+
+This adds users to class E; you could also use something like
+
+ FE/etc/sendmail.cE
+
+You can also arrange to relay all unqualified names (that is, names
+without @host) to a relay host. For example, if you have a central
+email server, you might relay to that host so that users don't have
+to have .forward files or aliases. You can do this using
+
+ define(`LOCAL_RELAY', mailer:hostname)
+
+The ``mailer:'' can be omitted, in which case the mailer defaults to
+"smtp". There are some user names that you don't want relayed, perhaps
+because of local aliases. A common example is root, which may be
+locally aliased. You can add entries to this list using
+
+ LOCAL_USER(usernames)
+
+This adds users to class L; you could also use something like
+
+ FL/etc/sendmail.cL
+
+If you want all incoming mail sent to a centralized hub, as for a
+shared /var/spool/mail scheme, use
+
+ define(`MAIL_HUB', mailer:hostname)
+
+Again, ``mailer:'' defaults to "smtp". If you define both LOCAL_RELAY
+and MAIL_HUB, unqualified names will be sent to the LOCAL_RELAY and
+other local names will be sent to MAIL_HUB. Names in $=L will be
+delivered locally, so you MUST have aliases or .forward files for them.
+
+For example, if are on machine mastodon.CS.Berkeley.EDU, the following
+combinations of settings will have the indicated effects:
+
+email sent to.... eric eric@mastodon.CS.Berkeley.EDU
+
+LOCAL_RELAY set to mail.CS.Berkeley.EDU (delivered locally)
+mail.CS.Berkeley.EDU
+
+MAIL_HUB set to mammoth.CS.Berkeley.EDU mammoth.CS.Berkeley.EDU
+mammoth.CS.Berkeley.EDU
+
+Both LOCAL_RELAY and mail.CS.Berkeley.EDU mammoth.CS.Berkeley.EDU
+MAIL_HUB set as above
+
+If you want all outgoing mail to go to a central relay site, define
+SMART_HOST as well. Briefly:
+
+ LOCAL_RELAY applies to unqualifed names (e.g., "eric").
+ MAIL_HUB applies to names qualified with the name of the
+ local host (e.g., "eric@mastodon.CS.Berkeley.EDU").
+ SMART_HOST applies to names qualified with other hosts.
+
+However, beware that other relays (e.g., UUCP_RELAY, BITNET_RELAY, and
+FAX_RELAY) take precedence over SMART_HOST, so if you really want
+absolutely everything to go to a single central site you will need to
+unset all the other relays -- or better yet, find or build a minimal
+config file that does this.
+
+
++-------------------------------+
+| NON-SMTP BASED CONFIGURATIONS |
++-------------------------------+
+
+These configuration files are designed primarily for use by SMTP-based
+sites. I don't pretend that they are well tuned for UUCP-only or
+UUCP-primarily nodes (the latter is defined as a small local net
+connected to the rest of the world via UUCP). However, there is one
+hook to handle some special cases.
+
+You can define a ``smart host'' that understands a richer address syntax
+using:
+
+ define(`SMART_HOST', mailer:hostname)
+
+In this case, the ``mailer:'' defaults to "relay". Any messages that
+can't be handled using the usual UUCP rules are passed to this host.
+
+If you are on a local SMTP-based net that connects to the outside
+world via UUCP, you can use LOCAL_NET_CONFIG to add appropriate rules.
+For example:
+
+ define(`SMART_HOST', suucp:uunet)
+ LOCAL_NET_CONFIG
+ R$* < @ $* .$m. > $* $#smtp $@ $2.$m. $: $1 < @ $2.$m. > $3
+
+This will cause all names that end in your domain name ($m) via
+SMTP; anything else will be sent via suucp (smart UUCP) to uunet.
+If you have FEATURE(nocanonify), you may need to omit the dots after
+the $m. If you are running a local DNS inside your domain which is
+not otherwise connected to the outside world, you probably want to
+use:
+
+ define(`SMART_HOST', smtp:fire.wall.com)
+ LOCAL_NET_CONFIG
+ R$* < @ $* . > $* $#smtp $@ $2. $: $1 < @ $2. > $3
+
+That is, send directly only to things you found in your DNS lookup;
+anything else goes through SMART_HOST.
+
+If you are not running DNS at all, it is important to use
+FEATURE(nodns) to avoid having sendmail queue everything waiting
+for the name server to come up.
+
+
++-----------+
+| WHO AM I? |
++-----------+
+
+Normally, the $j macro is automatically defined to be your fully
+qualified domain name (FQDN). Sendmail does this by getting your
+host name using gethostname and then calling gethostbyname on the
+result. For example, in some environments gethostname returns
+only the root of the host name (such as "foo"); gethostbyname is
+supposed to return the FQDN ("foo.bar.com"). In some (fairly rare)
+cases, gethostbyname may fail to return the FQDN. In this case
+you MUST define confDOMAIN_NAME to be your fully qualified domain
+name. This is usually done using:
+
+ Dmbar.com
+ define(`confDOMAIN_NAME', `$w.$m')dnl
+
+
++--------------------+
+| USING MAILERTABLES |
++--------------------+
+
+To use FEATURE(mailertable), you will have to create an external
+database containing the routing information for various domains.
+For example, a mailertable file in text format might be:
+
+ .my.domain xnet:%1.my.domain
+ uuhost1.my.domain suucp:uuhost1
+ .bitnet smtp:relay.bit.net
+
+This should normally be stored in /etc/mailertable. The actual
+database version of the mailertable is built using:
+
+ makemap hash /etc/mailertable.db < /etc/mailertable
+
+The semantics are simple. Any LHS entry that does not begin with
+a dot matches the full host name indicated. LHS entries beginning
+with a dot match anything ending with that domain name -- that is,
+they can be thought of as having a leading "*" wildcard. Matching
+is done in order of most-to-least qualified -- for example, even
+though ".my.domain" is listed first in the above example, an entry
+of "uuhost1.my.domain" will match the second entry since it is
+more explicit.
+
+The RHS should always be a "mailer:host" pair. The mailer is the
+configuration name of a mailer (that is, an `M' line in the
+sendmail.cf file). The "host" will be the hostname passed to
+that mailer. In domain-based matches (that is, those with leading
+dots) the "%1" may be used to interpolate the wildcarded part of
+the host name. For example, the first line above sends everything
+addressed to "anything.my.domain" to that same host name, but using
+the (presumably experimental) xnet mailer.
+
+
++--------------------------------+
+| USING USERDB TO MAP FULL NAMES |
++--------------------------------+
+
+The user database was not originally intended for mapping full names
+to login names (e.g., Eric.Allman => eric), but some people are using
+it that way. (I would recommend that you set up aliases for this
+purpose instead -- since you can specify multiple alias files, this
+is fairly easy.) The intent was to locate the default maildrop at
+a site, but allow you to override this by sending to a specific host.
+
+If you decide to set up the user database in this fashion, it is
+imperative that you also specify FEATURE(notsticky) -- otherwise,
+e-mail sent to Full.Name@local.host.name will be rejected.
+
+To build the internal form of the user databae, use:
+
+ makemap btree /usr/data/base.db < /usr/data/base.txt
+
+
++------------------+
+| FlexFAX SOFTWARE |
++------------------+
+
+Sam Leffler's FlexFAX software is still in beta test -- but he expects a
+public version out "later this week" [as of 3/1/93]. The following
+blurb is direct from Sam:
+
+ $Header: /usr/people/sam/fax/RCS/HOWTO,v 1.14 93/05/24 11:42:16 sam Exp $
+
+ How To Obtain This Software (in case all you get is this file)
+ --------------------------------------------------------------
+ The source code is available for public ftp on
+ sgi.com sgi/fax/v2.1.src.tar.Z
+ (192.48.153.1)
+
+ You can also obtain inst'able images for Silicon Graphics machines from
+ sgi.com sgi/fax/v2.1.inst.tar
+ (192.48.153.1)
+
+ For example,
+ % ftp -n sgi.com
+ ....
+ ftp> user anonymous
+ ... <type in password>
+ ftp> cd sgi/fax
+ ftp> binary
+ ftp> get v2.1.src.tar.Z
+
+ In general, the latest version of the 2.1 release of the software is
+ always available as "v2.1.src.tar.Z" or "v2.1.inst.tar" in the ftp
+ directory. This file is a link to the appropriate released version (so
+ don't waste your time retrieving the linked file as well!) Any files of
+ the form v2.1.*.patch are shell scripts that can be used to patch older
+ versions of the source code. For example, the file v2.1.0.patch would
+ contain patches to update v2.1.0.tar.Z. (Note to beta testers: this is
+ different than the naming conventions used during beta testing.) Patch
+ files only work to go between consecutive versions, so if you are
+ multiple versions behind the latest release, you will need to apply
+ each patch file between your current version and the latest.
+
+
+ Obtaining the Software by Electronic Mail
+ -----------------------------------------
+ Do not send me requests for the software; they will be ignored (without
+ response). If you cannot use FTP at all, there is a service called
+ "ftpmail" available from gatekeeper.dec.com: you can send e-mail to
+ this machine and it will use FTP to retrieve files for you and send you
+ the files back again via e-mail. To find out more about the ftpmail
+ service, send a message to "ftpmail@gatekeeper.dec.com" whose body
+ consists of the single line "help".
+
+
+ Obtaining the Software Within Silicon Graphics
+ ----------------------------------------------
+ Internal to Silicon Graphics there are inst'able images on the host
+ flake.asd in the directory /usr/dist. Thus you can do something like:
+
+ % inst -f flake.asd.sgi.com:/usr/dist/flexfax
+
+ to install the latest version of the software on your machine.
+
+
+ What to do Once You've Retrieved Stuff
+ --------------------------------------
+ The external distributions come in a compressed or uncompressed tar
+ file. To extract the source distribution:
+
+ % zcat v2.1.src.tar.Z | tar xf -
+
+ (uncompress and extract individual files in current directory). To
+ unpack and install the client portion of the inst'able distribution:
+
+ % mkdir dist
+ % cd dist; tar xf ../v2.1.inst.tar; cd ..
+ % inst -f dist/flexfax
+ ...
+ inst> go
+
+ (Note, the dist subdirectory is because some versions of inst fail if
+ the files are in the current directory.) Server binaries are also
+ included in the inst'able images as flexfax.server.*. They are not
+ installed by default, so to get them also you need to do:
+
+ % inst -f flexfax
+ ...
+ inst> install flexfax.server.*
+ inst> go
+
+ The SGI binaries were built for Version 4.0.5H of the IRIX operating
+ system. They should work w/o problem on earlier versions of the
+ system, but I have not fully tested this. Also, note that to install a
+ server on an SGI machine, you need to have installed the Display
+ PostScript execution environment product (dps_eoe). Otherwise, the fax
+ server will not be able to convert PostScript to facsimile for
+ transmission.
+
+ If you are working from the source distribution, look at the file
+ README in the top of the source tree. If you are working from the inst
+ images, the subsystem flexfax.man.readme contains the README file and
+ other useful pieces of information--the installed files are placed in
+ the directory /usr/local/doc/flexfax). Basically you will need to run
+ the faxaddmodem script to setup and configure your fax modem. Consult
+ the README file and the manual page for faxaddmodem for information.
+
+
+ FlexFAX Mail List
+ -----------------
+ A mailing list for users of this software is located on sgi.com.
+ If you want to join this mailing list or have a list-related request
+ such as getting your name removed from it, send a request to
+
+ majordomo@whizzer.wpd.sgi.com
+
+ For example, to subscribe, send the line "subscribe flexfax" in
+ the body of your message. The line "help" will return a list of
+ the commands understood by the mailing list management software.
+
+ Submissions (including bug reports) should be directed to:
+
+ flexfax@sgi.com
+
+ When corresponding about this software please always specify what
+ version you have, what system you're running on, and, if the problem is
+ specific to your modem, identify the modem and firmware revision.
+
+
++--------------------------------+
+| TWEAKING CONFIGURATION OPTIONS |
++--------------------------------+
+
+There are a large number of configuration options that don't normally
+need to be changed. However, if you feel you need to tweak them, you
+can define the following M4 variables. This list is shown in four
+columns: the name you define, the default value for that definition,
+the option or macro that is affected (either Ox for an option or Dx
+for a macro), and a brief description. Greater detail of the semantics
+can be found in the Installation and Operations Guide.
+
+Some options are likely to be deprecated in future versions -- that is,
+the option is only included to provide back-compatibility. These are
+marked with "*".
+
+Remember that these options are M4 variables, and hence may need to
+be quoted. In particular, arguments with commas will usually have to
+be ``double quoted, like this phrase'' to avoid having the comma
+confuse things. This is common for alias file definitions and for
+the read timeout.
+
+M4 Variable Name Default Mac/Opt Description
+================ ======= ======= ===========
+confMAILER_NAME MAILER-DAEMON Dn The sender name used for
+ internally generated
+ outgoing messages.
+confFROM_LINE From $g $d Dl The From_ line used when
+ sending to files or programs.
+confFROM_HEADER $?x$x <$g>$|$g$. The format of an internally
+ Dq generated From: address.
+confOPERATORS .:%@!^/[] Do Address operator characters.
+confSMTP_LOGIN_MSG $j Sendmail $v/$Z ready at $b
+ De The initial (spontaneous)
+ SMTP greeting message.
+confSEVEN_BIT_INPUT False O7 Force input to seven bits?
+confALIAS_WAIT 10 Oa Wait (in minutes) for alias
+ file rebuild.
+confMIN_FREE_BLOCKS 4 Ob Minimum number of free blocks
+ on queue filesystem to accept
+ SMTP mail.
+confBLANK_SUB . OB Blank (space) substitution
+ character.
+confCON_EXPENSIVE False Oc Avoid connecting immediately
+ to mailers marked expensive?
+confCHECKPOINT_INTERVAL 10 OC Checkpoint queue files
+ every N recipients.
+confDELIVERY_MODE background Od Default delivery mode.
+confAUTO_REBUILD False OD Automatically rebuild
+ alias file if needed.
+confERROR_MODE (undefined) Oe Error message mode.
+confERROR_MESSAGE (undefined) OE Error message header/file.
+confSAVE_FROM_LINES False Of Save extra leading
+ From_ lines.
+confTEMP_FILE_MODE 0600 OF Temporary file mode.
+confDEF_GROUP_ID 1 Og Default group id.
+confMATCH_GECOS False OG Match GECOS field.
+confMAX_HOP 17 Oh Maximum hop count.
+confIGNORE_DOTS False Oi * Ignore dot as terminator
+ for incoming messages?
+confBIND_OPTS (empty) OI Default options for BIND.
+confMIME_FORMAT_ERRORS True Oj * Send error messages as MIME-
+ encapsulated messages per
+ RFC 1344.
+confFORWARD_PATH (undefined) OJ The colon-separated list of
+ places to search for .forward
+ files.
+confMCI_CACHE_SIZE 2 Ok Size of open connection cache.
+confMCI_CACHE_TIMEOUT 5m OK Open connection cache timeout.
+confUSE_ERRORS_TO False Ol * Use the Errors-To: header to
+ deliver error messages. This
+ should not be necessary because
+ of general acceptance of the
+ envelope/header distinction.
+confLOG_LEVEL 9 OL Log level.
+confME_TOO False Om Include sender in group
+ expansions.
+confCHECK_ALIASES True On Check RHS of aliases when
+ running newaliases.
+confOLD_STYLE_HEADERS True Oo * Assume that headers without
+ special chars are old style.
+confDAEMON_OPTIONS (undefined) OO SMTP daemon options.
+confPRIVACY_FLAGS authwarnings Op Privacy flags.
+confCOPY_ERRORS_TO (undefined) OP Address for additional copies
+ of all error messages.
+confQUEUE_FACTOR (undefined) Oq Slope of queue-only function
+confREAD_TIMEOUT (undefined) Or SMTP read timeouts.
+confSAFE_QUEUE True Os * Commit all messages to disk
+ before forking.
+confMESSAGE_TIMEOUT 5d/4h OT Timeout for messages before
+ sending error/warning message.
+confTIME_ZONE USE_SYSTEM Ot Time zone info -- can be
+ USE_SYSTEM to use the system's
+ idea, USE_TZ to use the user's
+ TZ envariable, or something
+ else to force that value.
+confDEF_USER_ID 1 Ou Default user id.
+confUSERDB_SPEC (undefined) OU User database specification.
+confFALLBACK_MX (undefined) OV Fallback MX host.
+confTRY_NULL_MX_LIST False Ow If we are the best MX for a
+ host and haven't made other
+ arrangements, try connecting
+ to the host directly; normally
+ this would be a config error.
+confQUEUE_LA 8 Ox Load average at which queue-only
+ function kicks in.
+confREFUSE_LA 12 OX Load average at which incoming
+ SMTP connections are refused.
+confWORK_RECIPIENT_FACTOR
+ (undefined) Oy Cost of each recipient.
+confSEPARATE_PROC False OY Run all deliveries in a
+ separate process.
+confWORK_CLASS_FACTOR (undefined) Oz Priority multiplier for class.
+confWORK_TIME_FACTOR (undefined) OZ Cost of each delivery attempt.
+confCW_FILE /etc/sendmail.cw Name of file used to get the
+ Fw local additions to the $=w
+ class.
+confSMTP_MAILER smtp - The mailer name used when
+ SMTP connectivity is required.
+ Either "smtp" or "esmtp".
+confLOCAL_MAILER local - The mailer name used when
+ local connectivity is required.
+ Almost always "local".
+confRELAY_MAILER relay - The default mailer name used
+ for relaying any mail (e.g.,
+ to a BITNET_RELAY, a
+ SMART_HOST, or whatever).
+ This can reasonably be "suucp"
+ if you are on a UUCP-connected
+ site.
+confDOMAIN_NAME (undefined) Dj If defined, sets $j.
+
+
++-----------+
+| HIERARCHY |
++-----------+
+
+Within this directory are several subdirectories, to wit:
+
+m4 General support routines. These are typically
+ very important and should not be changed without
+ very careful consideration.
+
+cf The configuration files themselves. They have
+ ".mc" suffixes, and must be run through m4 to
+ become complete. The resulting output should
+ have a ".cf" suffix.
+
+ostype Definitions describing a particular operating
+ system type. These should always be referenced
+ using the OSTYPE macro in the .mc file. Examples
+ include "bsd4.3", "bsd4.4", "sunos3.5", and
+ "sunos4.1".
+
+domain Definitions describing a particular domain, referenced
+ using the DOMAIN macro in the .mc file. These are
+ site dependent; for example, we contribute "cs.exposed.m4"
+ and "cs.hidden.m4" which both describe hosts in the
+ CS.Berkeley.EDU subdomain; the former displays the local
+ hostname (e.g., mammoth.CS.Berkeley.EDU), whereas the
+ latter does its best to hide the identity of the local
+ workstation inside the CS subdomain.
+
+mailer Descriptions of mailers. These are referenced using
+ the MAILER macro in the .mc file.
+
+sh Shell files used when building the .cf file from the
+ .mc file in the cf subdirectory.
+
+feature These hold special orthogonal features that you might
+ want to include. They should be referenced using
+ the FEATURE macro.
+
+hack Local hacks. These can be referenced using the HACK
+ macro. They shouldn't be of more than voyeuristic
+ interest outside the .Berkeley.EDU domain, but who knows?
+ We've all got our own peccadillos.
+
+siteconfig Site configuration -- e.g., tables of locally connected
+ UUCP sites.
+
+
++------------------------+
+| ADMINISTRATIVE DETAILS |
++------------------------+
+
+The following sections detail usage of certain internal parts of the
+sendmail.cf file. Read them carefully if you are trying to modify
+the current model. If you find the above descriptions adequate, these
+should be {boring, confusing, tedious, ridiculous} (pick one or more).
+
+RULESETS (* means built in to sendmail)
+
+ 0 * Parsing
+ 1 * Sender rewriting
+ 2 * Recipient rewriting
+ 3 * Canonicalization
+ 4 * Post cleanup
+ 5 * Local address rewrite (after aliasing)
+ 1x mailer rules (sender qualification)
+ 2x mailer rules (recipient qualification)
+ 3x mailer rules (sender header qualification)
+ 4x mailer rules (recipient header qualification)
+ 5x mailer subroutines (general)
+ 6x mailer subroutines (general)
+ 7x mailer subroutines (general)
+ 8x reserved
+ 90 Mailertable host stripping
+ 96 Bottom half of Ruleset 3 (ruleset 6 in old sendmail)
+ 97 Hook for recursive ruleset 0 call (ruleset 7 in old sendmail)
+ 98 Local part of ruleset 0 (ruleset 8 in old sendmail)
+
+
+MAILERS
+
+ 0 local, prog local and program mailers
+ 1 [e]smtp, relay SMTP channel
+ 2 uucp-* UNIX-to-UNIX Copy Program
+ 3 netnews Network News delivery
+ 4 fax Sam Leffler's FlexFAX software
+
+
+MACROS
+
+ A
+ B Bitnet Relay
+ C
+ D The local domain -- usually not needed
+ E
+ F FAX Relay
+ G
+ H mail Hub (for mail clusters)
+ I
+ J
+ K
+ L
+ M Masquerade (who I claim to be)
+ N
+ O
+ P
+ Q
+ R Relay (for unqualified names)
+ S Smart Host
+ T
+ U my UUCP name (if I have a UUCP connection)
+ V UUCP Relay (class V hosts)
+ W UUCP Relay (class W hosts)
+ X UUCP Relay (class X hosts)
+ Y UUCP Relay (all other hosts)
+ Z Version number
+
+
+CLASSES
+
+ A
+ B
+ C
+ D
+ E addresses that should not seem to come from $M
+ F hosts we forward for
+ G
+ H
+ I
+ J
+ K
+ L addresses that should not be forwarded to $R
+ M
+ N
+ O operators that indicate network operations (cannot be in local names)
+ P top level pseudo-domains: BITNET, FAX, UUCP, etc.
+ Q
+ R
+ S
+ T
+ U locally connected UUCP hosts
+ V UUCP hosts connected to relay $V
+ W UUCP hosts connected to relay $W
+ X UUCP hosts connected to relay $X
+ Y locally connected smart UUCP hosts
+ Z locally connected domain-ized UUCP hosts
+ . the class containing only a dot
+
+
+M4 DIVERSIONS
+
+ 1 Local host detection and resolution
+ 2 Local Ruleset 3 additions
+ 3 Local Ruleset 0 additions
+ 4 UUCP Ruleset 0 additions
+ 5 locally interpreted names (overrides $R)
+ 6 local configuration (at top of file)
+ 7 mailer definitions
+ 8
+ 9 special local rulesets (1 and 2)
diff --git a/usr.sbin/sendmail/cf/cf/Makefile b/usr.sbin/sendmail/cf/cf/Makefile
new file mode 100644
index 0000000..05613df
--- /dev/null
+++ b/usr.sbin/sendmail/cf/cf/Makefile
@@ -0,0 +1,86 @@
+# @(#)Makefile 8.5 (Berkeley) 12/1/93
+
+M4= m4
+#M4= /usr/src/usr.bin/m4/obj/m4
+CHMOD= chmod
+ROMODE= 444
+RM= rm -f
+
+.SUFFIXES: .mc .cf
+
+.mc.cf:
+ $(RM) $@
+ (cd ${.CURDIR} && $(M4) ${@:R}.mc > obj/$@)
+ $(CHMOD) $(ROMODE) $@
+
+ALL= cs-hidden.cf cs-exposed.cf \
+ hpux-cs-exposed.cf hpux-cs-hidden.cf \
+ riscos-cs-exposed.cf \
+ sunos3.5-cs-exposed.cf sunos3.5-cs-hidden.cf \
+ sunos4.1-cs-exposed.cf sunos4.1-cs-hidden.cf \
+ ultrix4.1-cs-exposed.cf ultrix4.1-cs-hidden.cf \
+ osf1-cs-exposed.cf osf1-cs-hidden.cf \
+ mail.cs.cf mail.eecs.cf ucbvax.cf vangogh.cf \
+ chez.cf knecht.cf cogsci.cf alpha.cf s2k.cf auspex.cf \
+ python.cf \
+ clientproto.cf tcpproto.cf uucpproto.cf
+
+all: $(ALL)
+
+clean cleandir:
+ $(RM) $(ALL) core
+
+depend install:
+
+# this is overkill, but....
+M4FILES=\
+ ../domain/Berkeley.m4 \
+ ../domain/cs.exposed.m4 \
+ ../domain/cs.hidden.m4 \
+ ../domain/eecs.hidden.m4 \
+ ../domain/s2k.m4 \
+ ../feature/allmasquerade.m4 \
+ ../feature/always_add_domain.m4 \
+ ../feature/bitdomain.m4 \
+ ../feature/domaintable.m4 \
+ ../feature/mailertable.m4 \
+ ../feature/nocanonify.m4 \
+ ../feature/nodns.m4 \
+ ../feature/notsticky.m4 \
+ ../feature/nouucp.m4 \
+ ../feature/nullclient.m4 \
+ ../feature/redirect.m4 \
+ ../feature/use_cw_file.m4 \
+ ../feature/uucpdomain.m4 \
+ ../hack/cssubdomain.m4 \
+ ../m4/cf.m4 \
+ ../m4/nullrelay.m4 \
+ ../m4/proto.m4 \
+ ../m4/version.m4 \
+ ../mailer/fax.m4 \
+ ../mailer/local.m4 \
+ ../mailer/smtp.m4 \
+ ../mailer/usenet.m4 \
+ ../mailer/uucp.m4 \
+ ../ostype/aix3.m4 \
+ ../ostype/bsd4.3.m4 \
+ ../ostype/bsd4.4.m4 \
+ ../ostype/hpux.m4 \
+ ../ostype/irix.m4 \
+ ../ostype/linux.m4 \
+ ../ostype/nextstep.m4 \
+ ../ostype/osf1.m4 \
+ ../ostype/riscos4.5.m4 \
+ ../ostype/solaris2.m4 \
+ ../ostype/sunos3.5.m4 \
+ ../ostype/sunos4.1.m4 \
+ ../ostype/svr4.m4 \
+ ../ostype/ultrix4.1.m4 \
+ ../siteconfig/uucp.cogsci.m4 \
+ ../siteconfig/uucp.old.arpa.m4 \
+ ../siteconfig/uucp.ucbarpa.m4 \
+ ../siteconfig/uucp.ucbvax.m4 \
+
+$(ALL): $(M4FILES)
+
+.include <bsd.prog.mk>
diff --git a/usr.sbin/sendmail/cf/cf/Makefile.dist b/usr.sbin/sendmail/cf/cf/Makefile.dist
new file mode 100644
index 0000000..074529e
--- /dev/null
+++ b/usr.sbin/sendmail/cf/cf/Makefile.dist
@@ -0,0 +1,85 @@
+#
+# Makefile for configuration files.
+#
+# @(#)Makefile.dist 8.1 (Berkeley) 8/25/93
+
+M4= m4
+#M4= /usr/src/usr.bin/m4/obj/m4
+CHMOD= chmod
+ROMODE= 444
+RM= rm -f
+
+.SUFFIXES: .mc .cf
+
+.mc.cf:
+ $(RM) $@
+ $(M4) $*.mc > $@
+ $(CHMOD) $(ROMODE) $@
+
+ALL= cs-hidden.cf cs-exposed.cf \
+ hpux-cs-exposed.cf hpux-cs-hidden.cf \
+ sunos3.5-cs-exposed.cf sunos3.5-cs-hidden.cf \
+ sunos4.1-cs-exposed.cf sunos4.1-cs-hidden.cf \
+ ultrix4.1-cs-exposed.cf ultrix4.1-cs-hidden.cf \
+ mail.cs.cf mail.eecs.cf ucbvax.cf vangogh.cf \
+ chez.cf knecht.cf cogsci.cf alpha.cf s2k.cf auspex.cf \
+ python.cf \
+ clientproto.cf tcpproto.cf uucpproto.cf
+
+all: $(ALL)
+
+clean cleandir:
+ $(RM) $(ALL) core
+
+depend install:
+
+# this is overkill, but....
+M4FILES=\
+ ../domain/Berkeley.m4 \
+ ../domain/cs.exposed.m4 \
+ ../domain/cs.hidden.m4 \
+ ../domain/eecs.hidden.m4 \
+ ../domain/s2k.m4 \
+ ../feature/allmasquerade.m4 \
+ ../feature/always_add_domain.m4 \
+ ../feature/bitdomain.m4 \
+ ../feature/domaintable.m4 \
+ ../feature/mailertable.m4 \
+ ../feature/nocanonify.m4 \
+ ../feature/nodns.m4 \
+ ../feature/notsticky.m4 \
+ ../feature/nouucp.m4 \
+ ../feature/nullclient.m4 \
+ ../feature/redirect.m4 \
+ ../feature/use_cw_file.m4 \
+ ../feature/uucpdomain.m4 \
+ ../hack/cssubdomain.m4 \
+ ../m4/cf.m4 \
+ ../m4/nullrelay.m4 \
+ ../m4/proto.m4 \
+ ../m4/version.m4 \
+ ../mailer/fax.m4 \
+ ../mailer/local.m4 \
+ ../mailer/smtp.m4 \
+ ../mailer/usenet.m4 \
+ ../mailer/uucp.m4 \
+ ../ostype/aix3.m4 \
+ ../ostype/bsd4.3.m4 \
+ ../ostype/bsd4.4.m4 \
+ ../ostype/hpux.m4 \
+ ../ostype/irix.m4 \
+ ../ostype/linux.m4 \
+ ../ostype/nextstep.m4 \
+ ../ostype/osf1.m4 \
+ ../ostype/riscos4.5.m4 \
+ ../ostype/solaris2.m4 \
+ ../ostype/sunos3.5.m4 \
+ ../ostype/sunos4.1.m4 \
+ ../ostype/svr4.m4 \
+ ../ostype/ultrix4.1.m4 \
+ ../siteconfig/uucp.cogsci.m4 \
+ ../siteconfig/uucp.old.arpa.m4 \
+ ../siteconfig/uucp.ucbarpa.m4 \
+ ../siteconfig/uucp.ucbvax.m4 \
+
+$(ALL): $(M4FILES)
diff --git a/usr.sbin/sendmail/cf/cf/clientproto.mc b/usr.sbin/sendmail/cf/cf/clientproto.mc
new file mode 100644
index 0000000..902c1eb
--- /dev/null
+++ b/usr.sbin/sendmail/cf/cf/clientproto.mc
@@ -0,0 +1,49 @@
+divert(-1)
+#
+# Copyright (c) 1983 Eric P. Allman
+# Copyright (c) 1988, 1993
+# The Regents of the University of California. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+# 3. All advertising materials mentioning features or use of this software
+# must display the following acknowledgement:
+# This product includes software developed by the University of
+# California, Berkeley and its contributors.
+# 4. Neither the name of the University nor the names of its contributors
+# may be used to endorse or promote products derived from this software
+# without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+#
+
+#
+# This the prototype for a "null client" -- that is, a client that
+# does nothing except forward all mail to a mail hub.
+#
+# To use this, you MUST use the nullclient feature with the name of
+# the mail hub as its argument. You MAY also define an OSTYPE to
+# define the location of the queue directories and the like.
+# Other than these, it should never contain any other lines.
+#
+
+include(`../m4/cf.m4')
+VERSIONID(`@(#)clientproto.mc 8.2 (Berkeley) 8/21/93')
+
+FEATURE(nullclient, mailhost.$m)
diff --git a/usr.sbin/sendmail/cf/cf/knecht.mc b/usr.sbin/sendmail/cf/cf/knecht.mc
new file mode 100644
index 0000000..0cd17fa
--- /dev/null
+++ b/usr.sbin/sendmail/cf/cf/knecht.mc
@@ -0,0 +1,44 @@
+divert(-1)
+#
+# Copyright (c) 1983 Eric P. Allman
+# Copyright (c) 1988, 1993
+# The Regents of the University of California. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+# 3. All advertising materials mentioning features or use of this software
+# must display the following acknowledgement:
+# This product includes software developed by the University of
+# California, Berkeley and its contributors.
+# 4. Neither the name of the University nor the names of its contributors
+# may be used to endorse or promote products derived from this software
+# without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+#
+
+include(`../m4/cf.m4')
+VERSIONID(`@(#)knecht.mc 8.1 (Berkeley) 6/7/93')
+OSTYPE(ultrix4.1)dnl
+DOMAIN(cs.exposed)dnl
+define(`LOCAL_RELAY', CS.Berkeley.EDU)dnl
+MAILER(smtp)dnl
+
+# our local domain
+DDCS.Berkeley.EDU
diff --git a/usr.sbin/sendmail/cf/cf/mail.cs.mc b/usr.sbin/sendmail/cf/cf/mail.cs.mc
new file mode 100644
index 0000000..227e2fe
--- /dev/null
+++ b/usr.sbin/sendmail/cf/cf/mail.cs.mc
@@ -0,0 +1,55 @@
+divert(-1)
+#
+# Copyright (c) 1983 Eric P. Allman
+# Copyright (c) 1988, 1993
+# The Regents of the University of California. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+# 3. All advertising materials mentioning features or use of this software
+# must display the following acknowledgement:
+# This product includes software developed by the University of
+# California, Berkeley and its contributors.
+# 4. Neither the name of the University nor the names of its contributors
+# may be used to endorse or promote products derived from this software
+# without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+#
+
+include(`../m4/cf.m4')
+VERSIONID(`@(#)mail.cs.mc 8.3 (Berkeley) 10/15/93')
+OSTYPE(ultrix4.1)dnl
+DOMAIN(Berkeley)dnl
+MASQUERADE_AS(CS.Berkeley.EDU)dnl
+FEATURE(notsticky)dnl
+MAILER(local)dnl
+MAILER(smtp)dnl
+define(`confUSERDB_SPEC', ``/usr/local/lib/users.cs.db,/usr/local/lib/users.eecs.db'')dnl
+DDBerkeley.EDU
+
+# hosts for which we accept and forward mail (must be in .Berkeley.EDU)
+CF CS
+FF/etc/sendmail.cw
+
+LOCAL_RULE_0
+R< @ $=F . $D . > : $* $@ $>7 $2 @here:... -> ...
+R$* $=O $* < @ $=F . $D . > $@ $>7 $1 $2 $3 ...@here -> ...
+
+R$* < @ $=F . $D . > $#local $: $1 use UDB
diff --git a/usr.sbin/sendmail/cf/cf/mail.eecs.mc b/usr.sbin/sendmail/cf/cf/mail.eecs.mc
new file mode 100644
index 0000000..3b6200c
--- /dev/null
+++ b/usr.sbin/sendmail/cf/cf/mail.eecs.mc
@@ -0,0 +1,54 @@
+divert(-1)
+#
+# Copyright (c) 1983 Eric P. Allman
+# Copyright (c) 1988, 1993
+# The Regents of the University of California. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+# 3. All advertising materials mentioning features or use of this software
+# must display the following acknowledgement:
+# This product includes software developed by the University of
+# California, Berkeley and its contributors.
+# 4. Neither the name of the University nor the names of its contributors
+# may be used to endorse or promote products derived from this software
+# without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+#
+
+include(`../m4/cf.m4')
+VERSIONID(`@(#)mail.eecs.mc 8.1 (Berkeley) 6/7/93')
+OSTYPE(ultrix4.1)dnl
+DOMAIN(eecs.hidden)dnl
+FEATURE(notsticky)dnl
+MAILER(local)dnl
+MAILER(smtp)dnl
+define(`confUSERDB_SPEC', `/usr/local/lib/users.cs.db,/usr/local/lib/users.eecs.db')dnl
+DDBerkeley.EDU
+
+# hosts for which we accept and forward mail (must be in .Berkeley.EDU)
+CF EECS
+FF/etc/sendmail.cw
+
+LOCAL_RULE_0
+R< @ $=F . $D . > : $* $@ $>7 $2 @here:... -> ...
+R$* $=O $* < @ $=F . $D . > $@ $>7 $1 $2 $3 ...@here -> ...
+
+R$* < @ $=F . $D . > $#local $: $1 use UDB
diff --git a/usr.sbin/sendmail/cf/cf/tcpproto.mc b/usr.sbin/sendmail/cf/cf/tcpproto.mc
new file mode 100644
index 0000000..aa31ca1
--- /dev/null
+++ b/usr.sbin/sendmail/cf/cf/tcpproto.mc
@@ -0,0 +1,50 @@
+divert(-1)
+#
+# Copyright (c) 1983 Eric P. Allman
+# Copyright (c) 1988, 1993
+# The Regents of the University of California. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+# 3. All advertising materials mentioning features or use of this software
+# must display the following acknowledgement:
+# This product includes software developed by the University of
+# California, Berkeley and its contributors.
+# 4. Neither the name of the University nor the names of its contributors
+# may be used to endorse or promote products derived from this software
+# without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+#
+
+#
+# This is the prototype file for a configuration that supports nothing
+# but basic SMTP connections via TCP.
+#
+# You may want to add an OSTYPE macro to get the location of various
+# support files for your operating system environment.
+#
+
+include(`../m4/cf.m4')
+VERSIONID(`@(#)tcpproto.mc 8.2 (Berkeley) 8/21/93')
+
+FEATURE(nouucp)
+
+MAILER(local)
+MAILER(smtp)
diff --git a/usr.sbin/sendmail/cf/cf/ucbarpa.mc b/usr.sbin/sendmail/cf/cf/ucbarpa.mc
new file mode 100644
index 0000000..21f35fd
--- /dev/null
+++ b/usr.sbin/sendmail/cf/cf/ucbarpa.mc
@@ -0,0 +1,43 @@
+divert(-1)
+#
+# Copyright (c) 1983 Eric P. Allman
+# Copyright (c) 1988, 1993
+# The Regents of the University of California. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+# 3. All advertising materials mentioning features or use of this software
+# must display the following acknowledgement:
+# This product includes software developed by the University of
+# California, Berkeley and its contributors.
+# 4. Neither the name of the University nor the names of its contributors
+# may be used to endorse or promote products derived from this software
+# without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+#
+
+include(`../m4/cf.m4')
+VERSIONID(`@(#)ucbarpa.mc 8.1 (Berkeley) 6/7/93')
+DOMAIN(cs.exposed)dnl
+OSTYPE(bsd4.4)dnl
+MAILER(local)dnl
+MAILER(smtp)dnl
+MAILER(uucp)dnl
+SITECONFIG(uucp.ucbarpa, ucbarpa, U)
diff --git a/usr.sbin/sendmail/cf/cf/ucbvax.mc b/usr.sbin/sendmail/cf/cf/ucbvax.mc
new file mode 100644
index 0000000..bae55d5
--- /dev/null
+++ b/usr.sbin/sendmail/cf/cf/ucbvax.mc
@@ -0,0 +1,101 @@
+divert(-1)
+#
+# Copyright (c) 1983 Eric P. Allman
+# Copyright (c) 1988, 1993
+# The Regents of the University of California. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+# 3. All advertising materials mentioning features or use of this software
+# must display the following acknowledgement:
+# This product includes software developed by the University of
+# California, Berkeley and its contributors.
+# 4. Neither the name of the University nor the names of its contributors
+# may be used to endorse or promote products derived from this software
+# without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+#
+
+include(`../m4/cf.m4')
+VERSIONID(`@(#)ucbvax.mc 8.1 (Berkeley) 6/7/93')
+OSTYPE(bsd4.3)
+DOMAIN(cs.hidden)
+FEATURE(notsticky)
+MAILER(local)
+MAILER(smtp)
+MAILER(uucp)
+undefine(`UUCP_RELAY')dnl
+DDBerkeley.EDU
+
+# names for which we act as a local forwarding agent
+CF CS
+FF/etc/sendmail.cw
+
+# local UUCP connections, and our local uucp name
+SITECONFIG(uucp.ucbvax, ucbvax, U)
+
+# remote UUCP connections, and the machine they are on
+SITECONFIG(uucp.ucbarpa, ucbarpa.Berkeley.EDU, W)
+
+SITECONFIG(uucp.cogsci, cogsci.Berkeley.EDU, X)
+
+LOCAL_RULE_3
+# map old UUCP names into Internet names
+UUCPSMTP(bellcore, bellcore.com)
+UUCPSMTP(decvax, decvax.dec.com)
+UUCPSMTP(decwrl, decwrl.dec.com)
+UUCPSMTP(hplabs, hplabs.hp.com)
+UUCPSMTP(lbl-csam, lbl-csam.arpa)
+UUCPSMTP(pur-ee, ecn.purdue.edu)
+UUCPSMTP(purdue, purdue.edu)
+UUCPSMTP(research, research.att.com)
+UUCPSMTP(sdcarl, sdcarl.ucsd.edu)
+UUCPSMTP(sdcsvax, sdcsvax.ucsd.edu)
+UUCPSMTP(ssyx, ssyx.ucsc.edu)
+UUCPSMTP(sun, sun.com)
+UUCPSMTP(ucdavis, ucdavis.ucdavis.edu)
+UUCPSMTP(ucivax, ics.uci.edu)
+UUCPSMTP(ucla-cs, cs.ucla.edu)
+UUCPSMTP(ucla-se, seas.ucla.edu)
+UUCPSMTP(ucsbcsl, ucsbcsl.ucsb.edu)
+UUCPSMTP(ucscc, c.ucsc.edu)
+UUCPSMTP(ucsd, ucsd.edu)
+UUCPSMTP(ucsfcgl, cgl.ucsf.edu)
+UUCPSMTP(unmvax, unmvax.cs.unm.edu)
+UUCPSMTP(uwvax, spool.cs.wisc.edu)
+
+LOCAL_RULE_0
+
+# make sure we handle the local domain as absolute
+R$* < @ $* $D > $* $: $1 < @ $2 $D . > $3
+
+# handle names we forward for as though they were local, so we will use UDB
+R< @ $=F . $D . > : $* $@ $>7 $2 @here:... -> ...
+R< @ $D . > : $* $@ $>7 $1 @here:... -> ...
+R$* $=O $* < @ $=F . $D . > $@ $>7 $1 $2 $3 ...@here -> ...
+R$* $=O $* < @ $D . > $@ $>7 $1 $2 $3 ...@here -> ...
+
+R$* < @ $=F . $D . > $#local $: $1 use UDB
+
+# handle local UUCP connections in the Berkeley.EDU domain
+R$+<@cnmat.$D . > $#uucp$@cnmat$:$1
+R$+<@cnmat.CS.$D . > $#uucp$@cnmat$:$1
+R$+<@craig.$D . > $#uucp$@craig$:$1
+R$+<@craig.CS.$D . > $#uucp$@craig$:$1
diff --git a/usr.sbin/sendmail/cf/cf/uucpproto.mc b/usr.sbin/sendmail/cf/cf/uucpproto.mc
new file mode 100644
index 0000000..c460d76
--- /dev/null
+++ b/usr.sbin/sendmail/cf/cf/uucpproto.mc
@@ -0,0 +1,49 @@
+divert(-1)
+#
+# Copyright (c) 1983 Eric P. Allman
+# Copyright (c) 1988, 1993
+# The Regents of the University of California. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+# 3. All advertising materials mentioning features or use of this software
+# must display the following acknowledgement:
+# This product includes software developed by the University of
+# California, Berkeley and its contributors.
+# 4. Neither the name of the University nor the names of its contributors
+# may be used to endorse or promote products derived from this software
+# without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+#
+
+#
+# This is the prototype for a configuration that only supports UUCP.
+#
+# You may want to add an OSTYPE macro to get the location of various
+# support files for your operating system environment.
+#
+
+include(`../m4/cf.m4')
+VERSIONID(`@(#)uucpproto.mc 8.3 (Berkeley) 8/21/93')
+
+FEATURE(nodns)dnl
+
+MAILER(local)dnl
+MAILER(uucp)dnl
diff --git a/usr.sbin/sendmail/cf/feature/allmasquerade.m4 b/usr.sbin/sendmail/cf/feature/allmasquerade.m4
new file mode 100644
index 0000000..c7cbffa
--- /dev/null
+++ b/usr.sbin/sendmail/cf/feature/allmasquerade.m4
@@ -0,0 +1,41 @@
+divert(-1)
+#
+# Copyright (c) 1983 Eric P. Allman
+# Copyright (c) 1988, 1993
+# The Regents of the University of California. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+# 3. All advertising materials mentioning features or use of this software
+# must display the following acknowledgement:
+# This product includes software developed by the University of
+# California, Berkeley and its contributors.
+# 4. Neither the name of the University nor the names of its contributors
+# may be used to endorse or promote products derived from this software
+# without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+#
+
+divert(0)
+VERSIONID(`@(#)allmasquerade.m4 8.2 (Berkeley) 1/22/94')
+divert(-1)
+
+
+define(`_ALL_MASQUERADE_', 1)
diff --git a/usr.sbin/sendmail/cf/feature/always_add_domain.m4 b/usr.sbin/sendmail/cf/feature/always_add_domain.m4
new file mode 100644
index 0000000..dd572c8
--- /dev/null
+++ b/usr.sbin/sendmail/cf/feature/always_add_domain.m4
@@ -0,0 +1,40 @@
+divert(-1)
+#
+# Copyright (c) 1983 Eric P. Allman
+# Copyright (c) 1988, 1993
+# The Regents of the University of California. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+# 3. All advertising materials mentioning features or use of this software
+# must display the following acknowledgement:
+# This product includes software developed by the University of
+# California, Berkeley and its contributors.
+# 4. Neither the name of the University nor the names of its contributors
+# may be used to endorse or promote products derived from this software
+# without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+#
+
+divert(0)
+VERSIONID(`@(#)always_add_domain.m4 8.1 (Berkeley) 6/7/93')
+divert(-1)
+
+define(`_ALWAYS_ADD_DOMAIN_', 1)
diff --git a/usr.sbin/sendmail/cf/feature/bitdomain.m4 b/usr.sbin/sendmail/cf/feature/bitdomain.m4
new file mode 100644
index 0000000..85c8cf0
--- /dev/null
+++ b/usr.sbin/sendmail/cf/feature/bitdomain.m4
@@ -0,0 +1,49 @@
+divert(-1)
+#
+# Copyright (c) 1983 Eric P. Allman
+# Copyright (c) 1988, 1993
+# The Regents of the University of California. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+# 3. All advertising materials mentioning features or use of this software
+# must display the following acknowledgement:
+# This product includes software developed by the University of
+# California, Berkeley and its contributors.
+# 4. Neither the name of the University nor the names of its contributors
+# may be used to endorse or promote products derived from this software
+# without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+#
+
+divert(0)
+VERSIONID(`@(#)bitdomain.m4 8.6 (Berkeley) 2/19/94')
+divert(-1)
+
+
+PUSHDIVERT(6)
+Kbitdomain ifelse(_ARG_, `', `hash -o /etc/bitdomain', `_ARG_')
+POPDIVERT
+
+
+PUSHDIVERT(2)
+# handle BITNET mapping
+R$* < @ $+ .BITNET > $* $: $1 < @ $(bitdomain $2 $: $2.BITNET $) > $3
+POPDIVERT
diff --git a/usr.sbin/sendmail/cf/feature/domaintable.m4 b/usr.sbin/sendmail/cf/feature/domaintable.m4
new file mode 100644
index 0000000..bfad1bc
--- /dev/null
+++ b/usr.sbin/sendmail/cf/feature/domaintable.m4
@@ -0,0 +1,40 @@
+divert(-1)
+#
+# Copyright (c) 1983 Eric P. Allman
+# Copyright (c) 1988, 1993
+# The Regents of the University of California. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+# 3. All advertising materials mentioning features or use of this software
+# must display the following acknowledgement:
+# This product includes software developed by the University of
+# California, Berkeley and its contributors.
+# 4. Neither the name of the University nor the names of its contributors
+# may be used to endorse or promote products derived from this software
+# without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+#
+
+divert(0)
+VERSIONID(`@(#)domaintable.m4 8.2 (Berkeley) 8/9/93')
+divert(-1)
+
+define(`DOMAIN_TABLE', ifelse(_ARG_, `', `hash -o /etc/domaintable', `_ARG_'))dnl
diff --git a/usr.sbin/sendmail/cf/feature/mailertable.m4 b/usr.sbin/sendmail/cf/feature/mailertable.m4
new file mode 100644
index 0000000..fa39997
--- /dev/null
+++ b/usr.sbin/sendmail/cf/feature/mailertable.m4
@@ -0,0 +1,40 @@
+divert(-1)
+#
+# Copyright (c) 1983 Eric P. Allman
+# Copyright (c) 1988, 1993
+# The Regents of the University of California. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+# 3. All advertising materials mentioning features or use of this software
+# must display the following acknowledgement:
+# This product includes software developed by the University of
+# California, Berkeley and its contributors.
+# 4. Neither the name of the University nor the names of its contributors
+# may be used to endorse or promote products derived from this software
+# without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+#
+
+divert(0)
+VERSIONID(`@(#)mailertable.m4 8.3 (Berkeley) 8/7/93')
+divert(-1)
+
+define(`MAILER_TABLE', ifelse(_ARG_, `', `hash -o /etc/mailertable', `_ARG_'))dnl
diff --git a/usr.sbin/sendmail/cf/feature/nocanonify.m4 b/usr.sbin/sendmail/cf/feature/nocanonify.m4
new file mode 100644
index 0000000..0157e6b
--- /dev/null
+++ b/usr.sbin/sendmail/cf/feature/nocanonify.m4
@@ -0,0 +1,40 @@
+divert(-1)
+#
+# Copyright (c) 1983 Eric P. Allman
+# Copyright (c) 1988, 1993
+# The Regents of the University of California. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+# 3. All advertising materials mentioning features or use of this software
+# must display the following acknowledgement:
+# This product includes software developed by the University of
+# California, Berkeley and its contributors.
+# 4. Neither the name of the University nor the names of its contributors
+# may be used to endorse or promote products derived from this software
+# without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+#
+
+divert(0)
+VERSIONID(`@(#)nocanonify.m4 8.1 (Berkeley) 6/7/93')
+divert(-1)
+
+define(`_NO_CANONIFY_', 1)
diff --git a/usr.sbin/sendmail/cf/feature/nodns.m4 b/usr.sbin/sendmail/cf/feature/nodns.m4
new file mode 100644
index 0000000..465a5ae
--- /dev/null
+++ b/usr.sbin/sendmail/cf/feature/nodns.m4
@@ -0,0 +1,40 @@
+divert(-1)
+#
+# Copyright (c) 1983 Eric P. Allman
+# Copyright (c) 1988, 1993
+# The Regents of the University of California. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+# 3. All advertising materials mentioning features or use of this software
+# must display the following acknowledgement:
+# This product includes software developed by the University of
+# California, Berkeley and its contributors.
+# 4. Neither the name of the University nor the names of its contributors
+# may be used to endorse or promote products derived from this software
+# without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+#
+
+divert(0)
+VERSIONID(`@(#)nodns.m4 8.1 (Berkeley) 8/6/93')
+divert(-1)
+
+undefine(`confBIND_OPTS')dnl
diff --git a/usr.sbin/sendmail/cf/feature/notsticky.m4 b/usr.sbin/sendmail/cf/feature/notsticky.m4
new file mode 100644
index 0000000..5118923
--- /dev/null
+++ b/usr.sbin/sendmail/cf/feature/notsticky.m4
@@ -0,0 +1,40 @@
+divert(-1)
+#
+# Copyright (c) 1983 Eric P. Allman
+# Copyright (c) 1988, 1993
+# The Regents of the University of California. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+# 3. All advertising materials mentioning features or use of this software
+# must display the following acknowledgement:
+# This product includes software developed by the University of
+# California, Berkeley and its contributors.
+# 4. Neither the name of the University nor the names of its contributors
+# may be used to endorse or promote products derived from this software
+# without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+#
+
+divert(0)
+VERSIONID(`@(#)notsticky.m4 8.1 (Berkeley) 6/7/93')
+divert(-1)
+
+define(`_LOCAL_NOT_STICKY_', 1)
diff --git a/usr.sbin/sendmail/cf/feature/nouucp.m4 b/usr.sbin/sendmail/cf/feature/nouucp.m4
new file mode 100644
index 0000000..8723437
--- /dev/null
+++ b/usr.sbin/sendmail/cf/feature/nouucp.m4
@@ -0,0 +1,40 @@
+divert(-1)
+#
+# Copyright (c) 1983 Eric P. Allman
+# Copyright (c) 1988, 1993
+# The Regents of the University of California. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+# 3. All advertising materials mentioning features or use of this software
+# must display the following acknowledgement:
+# This product includes software developed by the University of
+# California, Berkeley and its contributors.
+# 4. Neither the name of the University nor the names of its contributors
+# may be used to endorse or promote products derived from this software
+# without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+#
+
+divert(0)
+VERSIONID(`@(#)nouucp.m4 8.1 (Berkeley) 6/7/93')
+divert(-1)
+
+define(`_NO_UUCP_', 1)
diff --git a/usr.sbin/sendmail/cf/feature/nullclient.m4 b/usr.sbin/sendmail/cf/feature/nullclient.m4
new file mode 100644
index 0000000..930f265
--- /dev/null
+++ b/usr.sbin/sendmail/cf/feature/nullclient.m4
@@ -0,0 +1,61 @@
+PUSHDIVERT(-1)
+#
+# Copyright (c) 1983 Eric P. Allman
+# Copyright (c) 1988, 1993
+# The Regents of the University of California. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+# 3. All advertising materials mentioning features or use of this software
+# must display the following acknowledgement:
+# This product includes software developed by the University of
+# California, Berkeley and its contributors.
+# 4. Neither the name of the University nor the names of its contributors
+# may be used to endorse or promote products derived from this software
+# without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+#
+ifdef(`SMTP_MAILER_FLAGS',,
+ `define(`SMTP_MAILER_FLAGS',
+ `ifdef(`_OLD_SENDMAIL_', `L', `')')')
+define(_NULL_CLIENT_ONLY_, `1')
+ifelse(_ARG_, `', `errprint(`Feature "nullclient" requires argument')',
+ `define(`MAIL_HUB', _ARG_)')
+POPDIVERT
+
+#
+# This is used only for relaying mail from a client to a hub when
+# that client does absolutely nothing else -- i.e., it is a "null
+# mailer". In this sense, it acts like the "R" option in Sun
+# sendmail.
+#
+
+VERSIONID(`@(#)nullclient.m4 8.2 (Berkeley) 8/21/93')
+
+PUSHDIVERT(7)
+############################################
+### Null Client Mailer specification ###
+############################################
+
+ifdef(`confRELAY_MAILER',,
+ `define(`confRELAY_MAILER', `nullclient')')dnl
+
+Mnullclient, P=[IPC], F=CONCAT(mDFMuXa, SMTP_MAILER_FLAGS), A=IPC $h
+POPDIVERT
diff --git a/usr.sbin/sendmail/cf/feature/redirect.m4 b/usr.sbin/sendmail/cf/feature/redirect.m4
new file mode 100644
index 0000000..0f2199c
--- /dev/null
+++ b/usr.sbin/sendmail/cf/feature/redirect.m4
@@ -0,0 +1,48 @@
+divert(-1)
+#
+# Copyright (c) 1983 Eric P. Allman
+# Copyright (c) 1988, 1993
+# The Regents of the University of California. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+# 3. All advertising materials mentioning features or use of this software
+# must display the following acknowledgement:
+# This product includes software developed by the University of
+# California, Berkeley and its contributors.
+# 4. Neither the name of the University nor the names of its contributors
+# may be used to endorse or promote products derived from this software
+# without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+#
+
+divert(0)
+VERSIONID(`@(#)redirect.m4 8.2 (Berkeley) 12/27/93')
+divert(-1)
+
+
+PUSHDIVERT(3)
+# addresses sent to foo@host.REDIRECT will give a 551 error code
+R$* < @ $+ .REDIRECT. > $# error $@ NOUSER $: "551 User not local; please try " <$1@$2>
+POPDIVERT
+
+PUSHDIVERT(6)
+CPREDIRECT
+POPDIVERT
diff --git a/usr.sbin/sendmail/cf/feature/use_cw_file.m4 b/usr.sbin/sendmail/cf/feature/use_cw_file.m4
new file mode 100644
index 0000000..33b5ad5
--- /dev/null
+++ b/usr.sbin/sendmail/cf/feature/use_cw_file.m4
@@ -0,0 +1,46 @@
+divert(-1)
+#
+# Copyright (c) 1983 Eric P. Allman
+# Copyright (c) 1988, 1993
+# The Regents of the University of California. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+# 3. All advertising materials mentioning features or use of this software
+# must display the following acknowledgement:
+# This product includes software developed by the University of
+# California, Berkeley and its contributors.
+# 4. Neither the name of the University nor the names of its contributors
+# may be used to endorse or promote products derived from this software
+# without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+#
+
+divert(0)
+VERSIONID(`@(#)use_cw_file.m4 8.1 (Berkeley) 6/7/93')
+divert(-1)
+
+# if defined, the sendmail.cf will read the /etc/sendmail.cw file
+# to find alternate names for this host. Typically only used when
+# several hosts have been squashed into one another at high speed.
+
+define(`USE_CW_FILE', `')
+
+divert(0)
diff --git a/usr.sbin/sendmail/cf/feature/uucpdomain.m4 b/usr.sbin/sendmail/cf/feature/uucpdomain.m4
new file mode 100644
index 0000000..77cc97b
--- /dev/null
+++ b/usr.sbin/sendmail/cf/feature/uucpdomain.m4
@@ -0,0 +1,49 @@
+divert(-1)
+#
+# Copyright (c) 1983 Eric P. Allman
+# Copyright (c) 1988, 1993
+# The Regents of the University of California. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+# 3. All advertising materials mentioning features or use of this software
+# must display the following acknowledgement:
+# This product includes software developed by the University of
+# California, Berkeley and its contributors.
+# 4. Neither the name of the University nor the names of its contributors
+# may be used to endorse or promote products derived from this software
+# without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+#
+
+divert(0)
+VERSIONID(`@(#)uucpdomain.m4 8.6 (Berkeley) 2/19/94')
+divert(-1)
+
+
+PUSHDIVERT(6)
+Kuudomain ifelse(_ARG_, `', `hash -o /etc/uudomain', `_ARG_')
+POPDIVERT
+
+
+PUSHDIVERT(2)
+# handle UUCP mapping
+R$* < @ $+ .UUCP > $* $: $1 < @ $(uudomain $2 $: $2.UUCP $) > $3
+POPDIVERT
diff --git a/usr.sbin/sendmail/cf/hack/cssubdomain.m4 b/usr.sbin/sendmail/cf/hack/cssubdomain.m4
new file mode 100644
index 0000000..4f270c0
--- /dev/null
+++ b/usr.sbin/sendmail/cf/hack/cssubdomain.m4
@@ -0,0 +1,44 @@
+divert(-1)
+#
+# Copyright (c) 1983 Eric P. Allman
+# Copyright (c) 1988, 1993
+# The Regents of the University of California. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+# 3. All advertising materials mentioning features or use of this software
+# must display the following acknowledgement:
+# This product includes software developed by the University of
+# California, Berkeley and its contributors.
+# 4. Neither the name of the University nor the names of its contributors
+# may be used to endorse or promote products derived from this software
+# without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+#
+divert(0)
+VERSIONID(`@(#)cssubdomain.m4 8.1 (Berkeley) 6/7/93')
+
+divert(2)
+# find possible (old & new) versions of our name via short circuit hack
+# (this code should exist ONLY during the transition from .Berkeley.EDU
+# names to .CS.Berkeley.EDU names -- probably not more than a few months)
+R$* < @ $=w .CS.Berkeley.EDU > $* $: $1 < @ $j > $3
+R$* < @ $=w .Berkeley.EDU> $* $: $1 < @ $j > $3
+divert(0)
diff --git a/usr.sbin/sendmail/cf/m4/cf.m4 b/usr.sbin/sendmail/cf/m4/cf.m4
new file mode 100644
index 0000000..528cbff
--- /dev/null
+++ b/usr.sbin/sendmail/cf/m4/cf.m4
@@ -0,0 +1,149 @@
+divert(0)dnl
+#
+# Copyright (c) 1983 Eric P. Allman
+# Copyright (c) 1988, 1993
+# The Regents of the University of California. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+# 3. All advertising materials mentioning features or use of this software
+# must display the following acknowledgement:
+# This product includes software developed by the University of
+# California, Berkeley and its contributors.
+# 4. Neither the name of the University nor the names of its contributors
+# may be used to endorse or promote products derived from this software
+# without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+#
+
+
+######################################################################
+######################################################################
+#####
+##### SENDMAIL CONFIGURATION FILE
+#####
+define(`TEMPFILE', maketemp(/tmp/cfXXXXXX))dnl
+syscmd(sh ../sh/makeinfo.sh > TEMPFILE)dnl
+include(TEMPFILE)dnl
+syscmd(rm -f TEMPFILE)dnl
+#####
+######################################################################
+######################################################################
+
+divert(-1)
+
+changecom()
+undefine(`format')
+undefine(`hpux')
+ifdef(`pushdef', `',
+ `errprint(`You need a newer version of M4, at least as new as
+System V or GNU')
+ include(NoSuchFile)')
+define(`PUSHDIVERT', `pushdef(`__D__', divnum)divert($1)')
+define(`POPDIVERT', `divert(__D__)popdef(`__D__')')
+define(`OSTYPE', `PUSHDIVERT(-1)define(`_ARG_', $2)include(../ostype/$1.m4)POPDIVERT`'')
+define(`MAILER',
+`ifdef(`_MAILER_$1_', `dnl`'',
+`define(`_MAILER_$1_', `')PUSHDIVERT(7)include(../mailer/$1.m4)POPDIVERT`'')')
+define(`DOMAIN', `PUSHDIVERT(-1)define(`_ARG_', $2)include(../domain/$1.m4)POPDIVERT`'')
+define(`FEATURE', `PUSHDIVERT(-1)define(`_ARG_', $2)include(../feature/$1.m4)POPDIVERT`'')
+define(`HACK', `PUSHDIVERT(-1)define(`_ARG_', $2)include(../hack/$1.m4)POPDIVERT`'')
+define(`OLDSENDMAIL', `define(`_OLD_SENDMAIL_', `')')
+define(`VERSIONID', ``##### $1 #####'')
+define(`LOCAL_RULE_0', `divert(3)')
+define(`LOCAL_RULE_1',
+`divert(9)dnl
+#######################################
+### Ruleset 1 -- Sender Rewriting ###
+#######################################
+
+S1
+')
+define(`LOCAL_RULE_2',
+`divert(9)dnl
+##########################################
+### Ruleset 2 -- Recipient Rewriting ###
+##########################################
+
+S2
+')
+define(`LOCAL_RULE_3', `divert(2)')
+define(`LOCAL_CONFIG', `divert(6)')
+define(`LOCAL_NET_CONFIG', `define(`_LOCAL_RULES_', 1)divert(1)')
+define(`UUCPSMTP', `R DOL(*) < @ $1 .UUCP > DOL(*) DOL(1) < @ $2 > DOL(2)')
+define(`CONCAT', `$1$2$3$4$5$6$7')
+define(`DOL', ``$'$1')
+define(`SITECONFIG',
+`CONCAT(D, $3, $2)
+define(`_CLASS_$3_', `')dnl
+ifelse($3, U, Cw$2 $2.UUCP, `dnl')
+define(`SITE', `ifelse(CONCAT($'2`, $3), SU,
+ CONCAT(CY, $'1`),
+ CONCAT(C, $3, $'1`))')
+sinclude(../siteconfig/$1.m4)')
+define(`EXPOSED_USER', `PUSHDIVERT(5)CE$1
+POPDIVERT`'dnl')
+define(`LOCAL_USER', `PUSHDIVERT(5)CL$1
+POPDIVERT`'dnl')
+define(`MASQUERADE_AS', `define(`MASQUERADE_NAME', $1)')
+
+m4wrap(`include(`../m4/proto.m4')')
+
+# set up default values for options
+define(`confMAILER_NAME', ``MAILER-DAEMON'')
+define(`confFROM_LINE', `From $g $d')
+define(`confOPERATORS', `.:%@!^/[]')
+define(`confSMTP_LOGIN_MSG', `$j Sendmail $v/$Z ready at $b')
+define(`confSEVEN_BIT_INPUT', `False')
+define(`confALIAS_WAIT', `10')
+define(`confMIN_FREE_BLOCKS', `4')
+define(`confBLANK_SUB', `.')
+define(`confCON_EXPENSIVE', `False')
+define(`confCHECKPOINT_INTERVAL', `10')
+define(`confDELIVERY_MODE', `background')
+define(`confAUTO_REBUILD', `False')
+define(`confSAVE_FROM_LINES', `False')
+define(`confTEMP_FILE_MODE', `0600')
+define(`confMATCH_GECOS', `False')
+define(`confDEF_GROUP_ID', `1')
+define(`confMAX_HOP', `17')
+define(`confIGNORE_DOTS', `False')
+define(`confBIND_OPTS', `')
+define(`confMCI_CACHE_SIZE', `2')
+define(`confMCI_CACHE_TIMEOUT', `5m')
+define(`confUSE_ERRORS_TO', `False')
+define(`confLOG_LEVEL', `9')
+define(`confME_TOO', `False')
+define(`confCHECK_ALIASES', `True')
+define(`confOLD_STYLE_HEADERS', `True')
+define(`confPRIVACY_FLAGS', `authwarnings')
+define(`confSAFE_QUEUE', `True')
+define(`confMESSAGE_TIMEOUT', `5d/4h')
+define(`confTIME_ZONE', `USE_SYSTEM')
+define(`confDEF_USER_ID', `1')
+define(`confQUEUE_LA', `8')
+define(`confREFUSE_LA', `12')
+define(`confSEPARATE_PROC', `False')
+define(`confCW_FILE', `/etc/sendmail.cw')
+define(`confMIME_FORMAT_ERRORS', `True')
+define(`confTRY_NULL_MX_LIST', `False')
+
+divert(0)dnl
+VERSIONID(`@(#)cf.m4 8.4 (Berkeley) 12/24/93')
diff --git a/usr.sbin/sendmail/cf/m4/nullrelay.m4 b/usr.sbin/sendmail/cf/m4/nullrelay.m4
new file mode 100644
index 0000000..c79d179
--- /dev/null
+++ b/usr.sbin/sendmail/cf/m4/nullrelay.m4
@@ -0,0 +1,302 @@
+divert(-1)
+#
+# Copyright (c) 1983 Eric P. Allman
+# Copyright (c) 1988, 1993
+# The Regents of the University of California. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+# 3. All advertising materials mentioning features or use of this software
+# must display the following acknowledgement:
+# This product includes software developed by the University of
+# California, Berkeley and its contributors.
+# 4. Neither the name of the University nor the names of its contributors
+# may be used to endorse or promote products derived from this software
+# without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+#
+divert(0)
+
+VERSIONID(`@(#)nullrelay.m4 8.5 (Berkeley) 2/1/94')
+
+#
+# This configuration applies only to relay-only hosts. They send
+# all mail to a hub without consideration of the address syntax
+# or semantics, except for adding the hub qualification to the
+# addresses.
+#
+# This is based on a prototype done by Bryan Costales of ICSI.
+#
+
+# hub host (to which all mail is sent)
+DH`'ifdef(`MAIL_HUB', MAIL_HUB,
+ `errprint(`MAIL_HUB not defined for nullclient feature')')
+
+# name from which everyone will appear to come
+DM`'ifdef(`MASQUERADE_NAME', MASQUERADE_NAME, MAIL_HUB)
+
+# route-addr separators
+C: : ,
+
+undivert(6)dnl
+
+######################
+# Special macros #
+######################
+
+# SMTP initial login message
+De`'confSMTP_LOGIN_MSG
+
+# UNIX initial From header format
+Dl`'confFROM_LINE
+
+# my name for error messages
+Dn`'confMAILER_NAME
+
+# delimiter (operator) characters
+Do`'confOPERATORS
+
+# format of a total name
+Dq<$g>
+include(`../m4/version.m4')
+
+###############
+# Options #
+###############
+
+# strip message body to 7 bits on input?
+O7`'confSEVEN_BIT_INPUT
+
+# no aliases here
+
+# substitution for space (blank) characters
+OB`'confBLANK_SUB
+
+# default delivery mode
+Od`'confDELIVERY_MODE
+
+# error message header/file
+ifdef(`confERROR_MESSAGE',
+ OE`'confERROR_MESSAGE,
+ #OE/etc/sendmail.oE)
+
+# error mode
+ifdef(`confERROR_MODE',
+ Oe`'confERROR_MODE,
+ #Oep)
+
+# save Unix-style "From_" lines at top of header?
+Of`'confSAVE_FROM_LINES
+
+# temporary file mode
+OF`'confTEMP_FILE_MODE
+
+# default GID
+Og`'confDEF_GROUP_ID
+
+# maximum hop count
+Oh`'confMAX_HOP
+
+# location of help file
+OH`'ifdef(`HELP_FILE', HELP_FILE, /usr/lib/sendmail.hf)
+
+# ignore dots as terminators in incoming messages?
+Oi`'confIGNORE_DOTS
+
+# Insist that the BIND name server be running to resolve names
+ifdef(`confBIND_OPTS',
+ OI`'confBIND_OPTS,
+ #OI)
+
+# deliver MIME-encapsulated error messages?
+Oj`'confMIME_FORMAT_ERRORS
+
+# open connection cache size
+Ok`'confMCI_CACHE_SIZE
+
+# open connection cache timeout
+OK`'confMCI_CACHE_TIMEOUT
+
+# use Errors-To: header?
+Ol`'confUSE_ERRORS_TO
+
+# log level
+OL`'confLOG_LEVEL
+
+# send to me too, even in an alias expansion?
+Om`'confME_TOO
+
+# default messages to old style headers if no special punctuation?
+Oo`'confOLD_STYLE_HEADERS
+
+# SMTP daemon options
+ifdef(`confDAEMON_OPTIONS',
+ OO`'confDAEMON_OPTIONS,
+ #OOPort=esmtp)
+
+# privacy flags
+Op`'confPRIVACY_FLAGS
+
+# who (if anyone) should get extra copies of error messages
+ifdef(`confCOPY_ERRORS_TO',
+ OP`'confCOPY_ERRORS_TO,
+ #OPPostmaster)
+
+# slope of queue-only function
+ifdef(`confQUEUE_FACTOR',
+ Oq`'confQUEUE_FACTOR,
+ #Oq600000)
+
+# queue directory
+OQ`'ifdef(`QUEUE_DIR', QUEUE_DIR, /var/spool/mqueue)
+
+# read timeout -- now OK per RFC 1123 section 5.3.2
+ifdef(`confREAD_TIMEOUT',
+ Or`'confREAD_TIMEOUT,
+ #Ordatablock=10m)
+
+# queue up everything before forking?
+Os`'confSAFE_QUEUE
+
+# status file
+OS`'ifdef(`STATUS_FILE', STATUS_FILE, /etc/sendmail.st)
+
+# default message timeout interval
+OT`'confMESSAGE_TIMEOUT
+
+# time zone handling:
+# if undefined, use system default
+# if defined but null, use TZ envariable passed in
+# if defined and non-null, use that info
+ifelse(confTIME_ZONE, `USE_SYSTEM', `#Ot',
+ confTIME_ZONE, `USE_TZ', `Ot',
+ `Ot`'confTIME_ZONE')
+
+# default UID
+Ou`'confDEF_USER_ID
+
+# deliver each queued job in a separate process?
+OY`'confSEPARATE_PROC
+
+# work class factor
+ifdef(`confWORK_CLASS_FACTOR',
+ Oz`'confWORK_CLASS_FACTOR,
+ #Oz1800)
+
+# work time factor
+ifdef(`confWORK_TIME_FACTOR',
+ OZ`'confWORK_TIME_FACTOR,
+ #OZ90000)
+
+###########################
+# Message precedences #
+###########################
+
+Pfirst-class=0
+Pspecial-delivery=100
+Plist=-30
+Pbulk=-60
+Pjunk=-100
+
+#####################
+# Trusted users #
+#####################
+
+Troot
+Tdaemon
+Tuucp
+
+#########################
+# Format of headers #
+#########################
+
+H?P?Return-Path: $g
+HReceived: $?sfrom $s $.$?_($_) $.by $j ($v/$Z)$?r with $r$. id $i$?u for $u$.; $b
+H?D?Resent-Date: $a
+H?D?Date: $a
+H?F?Resent-From: $q
+H?F?From: $q
+H?x?Full-Name: $x
+HSubject:
+# HPosted-Date: $a
+# H?l?Received-Date: $b
+H?M?Resent-Message-Id: <$t.$i@$j>
+H?M?Message-Id: <$t.$i@$j>
+#
+######################################################################
+######################################################################
+#####
+##### REWRITING RULES
+#####
+######################################################################
+######################################################################
+
+###########################################
+### Rulset 3 -- Name Canonicalization ###
+###########################################
+S3
+
+# handle null input and list syntax (translate to <@> special case)
+R$@ $@ <@>
+R$*:;$* $@ $1 :; <@>
+
+# basic textual canonicalization -- note RFC733 heuristic here
+R$*<$*>$*<$*>$* $2$3<$4>$5 strip multiple <> <>
+R$*<$*<$+>$*>$* <$3>$5 2-level <> nesting
+R$*<>$* $@ <@> MAIL FROM:<> case
+R$*<$+>$* $2 basic RFC821/822 parsing
+
+ifdef(`_NO_CANONIFY_', `dnl',
+`# eliminate local host if present
+R@ $=w $=: $+ $@ @ $M $2 $3 @thishost ...
+R@ $+ $@ @ $1 @somewhere ...
+
+R$+ @ $=w $@ $1 @ $M ...@thishost
+R$+ @ $+ $@ $1 @ $2 ...@somewhere
+
+R$=w ! $+ $@ $2 @ $M thishost!...
+R$+ ! $+ $@ $1 ! $2 @ $M somewhere ! ...
+
+R$+ % $=w $@ $1 @ $M ...%thishost
+R$+ % $+ $@ $1 @ $2 ...%somewhere
+
+R$+ $@ $1 @ $M unadorned user')
+
+
+######################################
+### Ruleset 0 -- Parse Address ###
+######################################
+
+S0
+
+R$*:;<@> $#error $@ USAGE $: "list:; syntax illegal for recipient addresses"
+
+# pass everything else to a relay host
+R$* $#_RELAY_ $@ $H $: $1
+
+#
+######################################################################
+######################################################################
+#####
+`##### MAILER DEFINITIONS'
+#####
+######################################################################
+######################################################################
+undivert(7)dnl
diff --git a/usr.sbin/sendmail/cf/m4/proto.m4 b/usr.sbin/sendmail/cf/m4/proto.m4
new file mode 100644
index 0000000..2845729
--- /dev/null
+++ b/usr.sbin/sendmail/cf/m4/proto.m4
@@ -0,0 +1,689 @@
+divert(-1)
+#
+# Copyright (c) 1983 Eric P. Allman
+# Copyright (c) 1988, 1993
+# The Regents of the University of California. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+# 3. All advertising materials mentioning features or use of this software
+# must display the following acknowledgement:
+# This product includes software developed by the University of
+# California, Berkeley and its contributors.
+# 4. Neither the name of the University nor the names of its contributors
+# may be used to endorse or promote products derived from this software
+# without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+#
+divert(0)
+
+VERSIONID(`@(#)proto.m4 8.45 (Berkeley) 3/4/94')
+
+MAILER(local)dnl
+
+ifdef(`_OLD_SENDMAIL_',
+`define(`_SET_95_', 5)dnl
+define(`_SET_96_', 6)dnl
+define(`_SET_97_', 7)dnl
+define(`_SET_98_', 8)dnl
+define(`confDOMAIN_NAME',
+ `ifdef(`NEED_DOMAIN', `$w.$d', `$w')')dnl',
+`# level 5 config file format
+V5
+define(`_SET_95_', 95)dnl
+define(`_SET_96_', 96)dnl
+define(`_SET_97_', 97)dnl
+define(`_SET_98_', 98)dnl')
+ifdef(`confSMTP_MAILER',, `define(`confSMTP_MAILER', `smtp')')dnl
+ifdef(`confLOCAL_MAILER',, `define(`confLOCAL_MAILER', `local')')dnl
+ifdef(`confRELAY_MAILER',,
+ `define(`confRELAY_MAILER',
+ `ifdef(`_MAILER_smtp_', `relay',
+ `ifdef(`_MAILER_uucp', `suucp', `unknown')')')')dnl
+define(`_SMTP_', `confSMTP_MAILER')dnl for readability only
+define(`_LOCAL_', `confLOCAL_MAILER')dnl for readability only
+define(`_RELAY_', `confRELAY_MAILER')dnl for readability only
+
+##################
+# local info #
+##################
+
+Cwlocalhost
+ifdef(`USE_CW_FILE',
+`# file containing names of hosts for which we receive email
+Fw`'confCW_FILE',
+ `dnl')
+ifdef(`confDOMAIN_NAME', `
+# my official domain name
+Dj`'confDOMAIN_NAME',
+ `dnl')
+
+ifdef(`_NULL_CLIENT_ONLY_',
+`include(../m4/nullrelay.m4)m4exit',
+ `dnl')
+
+CP.
+
+ifdef(`UUCP_RELAY',
+`# UUCP relay host
+DY`'UUCP_RELAY
+CPUUCP
+
+')dnl
+ifdef(`BITNET_RELAY',
+`# BITNET relay host
+DB`'BITNET_RELAY
+CPBITNET
+
+')dnl
+ifdef(`FAX_RELAY',
+`# FAX relay host
+DF`'FAX_RELAY
+CPFAX
+
+')dnl
+# "Smart" relay host (may be null)
+DS`'ifdef(`SMART_HOST', SMART_HOST)
+
+ifdef(`MAILER_TABLE',
+`# Mailer table (overriding domains)
+Kmailertable MAILER_TABLE
+
+')dnl
+ifdef(`DOMAIN_TABLE',
+`# Domain table (adding domains)
+Kdomaintable DOMAIN_TABLE
+
+')dnl
+# who I send unqualified names to (null means deliver locally)
+DR`'ifdef(`LOCAL_RELAY', LOCAL_RELAY)
+
+# who gets all local email traffic ($R has precedence for unqualified names)
+DH`'ifdef(`MAIL_HUB', MAIL_HUB)
+
+# who I masquerade as (null for no masquerading)
+DM`'ifdef(`MASQUERADE_NAME', MASQUERADE_NAME)
+
+# class L: names that should be delivered locally, even if we have a relay
+# class E: names that should be exposed as from this host, even if we masquerade
+#CLroot
+CEroot
+undivert(5)dnl
+
+# operators that cannot be in local usernames (i.e., network indicators)
+CO @ % ifdef(`_NO_UUCP_', `', `!')
+
+# a class with just dot (for identifying canonical names)
+C..
+
+ifdef(`_OLD_SENDMAIL_', `dnl',
+`# dequoting map
+Kdequote dequote')
+
+undivert(6)dnl
+
+######################
+# Special macros #
+######################
+
+# SMTP initial login message
+De`'confSMTP_LOGIN_MSG
+
+# UNIX initial From header format
+Dl`'confFROM_LINE
+
+# my name for error messages
+Dn`'confMAILER_NAME
+
+# delimiter (operator) characters
+Do`'confOPERATORS
+
+# format of a total name
+Dq`'ifdef(`confFROM_HEADER', confFROM_HEADER,
+ ifdef(`_OLD_SENDMAIL_', `$g$?x ($x)$.', `$?x$x <$g>$|$g$.'))
+include(`../m4/version.m4')
+
+###############
+# Options #
+###############
+
+# strip message body to 7 bits on input?
+O7`'confSEVEN_BIT_INPUT
+
+# wait (in minutes) for alias file rebuild
+Oa`'confALIAS_WAIT
+
+# location of alias file
+OA`'ifdef(`ALIAS_FILE', `ALIAS_FILE', /etc/aliases)
+
+# minimum number of free blocks on filesystem
+Ob`'confMIN_FREE_BLOCKS
+
+# substitution for space (blank) characters
+OB`'confBLANK_SUB
+
+# avoid connecting to "expensive" mailers on initial submission?
+Oc`'confCON_EXPENSIVE
+
+# checkpoint queue runs after every N successful deliveries
+OC`'confCHECKPOINT_INTERVAL
+
+# default delivery mode
+Od`'confDELIVERY_MODE
+
+# automatically rebuild the alias database?
+OD`'confAUTO_REBUILD
+
+# error message header/file
+ifdef(`confERROR_MESSAGE',
+ OE`'confERROR_MESSAGE,
+ #OE/etc/sendmail.oE)
+
+# error mode
+ifdef(`confERROR_MODE',
+ Oe`'confERROR_MODE,
+ #Oep)
+
+# save Unix-style "From_" lines at top of header?
+Of`'confSAVE_FROM_LINES
+
+# temporary file mode
+OF`'confTEMP_FILE_MODE
+
+# match recipients against GECOS field?
+OG`'confMATCH_GECOS
+
+# default GID
+Og`'confDEF_GROUP_ID
+
+# maximum hop count
+Oh`'confMAX_HOP
+
+# location of help file
+OH`'ifdef(`HELP_FILE', HELP_FILE, /usr/lib/sendmail.hf)
+
+# ignore dots as terminators in incoming messages?
+Oi`'confIGNORE_DOTS
+
+# Insist that the BIND name server be running to resolve names
+ifdef(`confBIND_OPTS',
+ OI`'confBIND_OPTS,
+ #OI)
+
+# deliver MIME-encapsulated error messages?
+Oj`'confMIME_FORMAT_ERRORS
+
+# Forward file search path
+ifdef(`confFORWARD_PATH',
+ OJ`'confFORWARD_PATH,
+ #OJ/var/forward/$u:$z/.forward.$w:$z/.forward)
+
+# open connection cache size
+Ok`'confMCI_CACHE_SIZE
+
+# open connection cache timeout
+OK`'confMCI_CACHE_TIMEOUT
+
+# use Errors-To: header?
+Ol`'confUSE_ERRORS_TO
+
+# log level
+OL`'confLOG_LEVEL
+
+# send to me too, even in an alias expansion?
+Om`'confME_TOO
+
+# verify RHS in newaliases?
+On`'confCHECK_ALIASES
+
+# default messages to old style headers if no special punctuation?
+Oo`'confOLD_STYLE_HEADERS
+
+# SMTP daemon options
+ifdef(`confDAEMON_OPTIONS',
+ OO`'confDAEMON_OPTIONS,
+ #OOPort=esmtp)
+
+# privacy flags
+Op`'confPRIVACY_FLAGS
+
+# who (if anyone) should get extra copies of error messages
+ifdef(`confCOPY_ERRORS_TO',
+ OP`'confCOPY_ERRORS_TO,
+ #OPPostmaster)
+
+# slope of queue-only function
+ifdef(`confQUEUE_FACTOR',
+ Oq`'confQUEUE_FACTOR,
+ #Oq600000)
+
+# queue directory
+OQ`'ifdef(`QUEUE_DIR', QUEUE_DIR, /var/spool/mqueue)
+
+# read timeout -- now OK per RFC 1123 section 5.3.2
+ifdef(`confREAD_TIMEOUT',
+ Or`'confREAD_TIMEOUT,
+ #Ordatablock=10m)
+
+# queue up everything before forking?
+Os`'confSAFE_QUEUE
+
+# status file
+OS`'ifdef(`STATUS_FILE', STATUS_FILE, /etc/sendmail.st)
+
+# default message timeout interval
+OT`'confMESSAGE_TIMEOUT
+
+# time zone handling:
+# if undefined, use system default
+# if defined but null, use TZ envariable passed in
+# if defined and non-null, use that info
+ifelse(confTIME_ZONE, `USE_SYSTEM', `#Ot',
+ confTIME_ZONE, `USE_TZ', `Ot',
+ `Ot`'confTIME_ZONE')
+
+# default UID
+Ou`'confDEF_USER_ID
+
+# list of locations of user database file (null means no lookup)
+OU`'ifdef(`confUSERDB_SPEC', `confUSERDB_SPEC')
+
+# fallback MX host
+ifdef(`confFALLBACK_MX',
+ OV`'confFALLBACK_MX,
+ #OVfall.back.host.net)
+
+# if we are the best MX host for a site, try it directly instead of config err
+Ow`'confTRY_NULL_MX_LIST
+
+# load average at which we just queue messages
+Ox`'confQUEUE_LA
+
+# load average at which we refuse connections
+OX`'confREFUSE_LA
+
+# work recipient factor
+ifdef(`confWORK_RECIPIENT_FACTOR',
+ Oy`'confWORK_RECIPIENT_FACTOR,
+ #Oy30000)
+
+# deliver each queued job in a separate process?
+OY`'confSEPARATE_PROC
+
+# work class factor
+ifdef(`confWORK_CLASS_FACTOR',
+ Oz`'confWORK_CLASS_FACTOR,
+ #Oz1800)
+
+# work time factor
+ifdef(`confWORK_TIME_FACTOR',
+ OZ`'confWORK_TIME_FACTOR,
+ #OZ90000)
+
+###########################
+# Message precedences #
+###########################
+
+Pfirst-class=0
+Pspecial-delivery=100
+Plist=-30
+Pbulk=-60
+Pjunk=-100
+
+#####################
+# Trusted users #
+#####################
+
+Troot
+Tdaemon
+Tuucp
+
+#########################
+# Format of headers #
+#########################
+
+H?P?Return-Path: $g
+HReceived: $?sfrom $s $.$?_($?s$|from $.$_) $.by $j ($v/$Z)$?r with $r$. id $i$?u for $u$.; $b
+H?D?Resent-Date: $a
+H?D?Date: $a
+H?F?Resent-From: $q
+H?F?From: $q
+H?x?Full-Name: $x
+HSubject:
+# HPosted-Date: $a
+# H?l?Received-Date: $b
+H?M?Resent-Message-Id: <$t.$i@$j>
+H?M?Message-Id: <$t.$i@$j>
+#
+######################################################################
+######################################################################
+#####
+##### REWRITING RULES
+#####
+######################################################################
+######################################################################
+
+undivert(9)dnl
+
+###########################################
+### Rulset 3 -- Name Canonicalization ###
+###########################################
+S3
+
+# handle null input (translate to <@> special case)
+R$@ $@ <@>
+
+# basic textual canonicalization -- note RFC733 heuristic here
+R$*<$*>$*<$*>$* $2$3<$4>$5 strip multiple <> <>
+R$*<$*<$+>$*>$* <$3>$5 2-level <> nesting
+R$*<>$* $@ <@> MAIL FROM:<> case
+R$*<$+>$* $2 basic RFC821/822 parsing
+
+# handle list:; syntax as special case
+R$*:;$* $@ $1 :; <@>
+
+# make sure <@a,@b,@c:user@d> syntax is easy to parse -- undone later
+R@ $+ , $+ @ $1 : $2 change all "," to ":"
+
+# localize and dispose of route-based addresses
+R@ $+ : $+ $@ $>_SET_96_ < @$1 > : $2 handle <route-addr>
+
+# find focus for list syntax
+R $+ : $* ; @ $+ $@ $>_SET_96_ $1 : $2 ; < @ $3 > list syntax
+R $+ : $* ; $@ $1 : $2; list syntax
+
+# find focus for @ syntax addresses
+R$+ @ $+ $: $1 < @ $2 > focus on domain
+R$+ < $+ @ $+ > $1 $2 < @ $3 > move gaze right
+R$+ < @ $+ > $@ $>_SET_96_ $1 < @ $2 > already canonical
+
+# do some sanity checking
+R$* < @ $* : $* > $* $1 < @ $2 $3 > $4 nix colons in addrs
+
+ifdef(`_NO_UUCP_', `dnl',
+`# convert old-style addresses to a domain-based address
+R$- ! $+ $@ $>_SET_96_ $2 < @ $1 .UUCP > resolve uucp names
+R$+ . $- ! $+ $@ $>_SET_96_ $3 < @ $1 . $2 > domain uucps
+R$+ ! $+ $@ $>_SET_96_ $2 < @ $1 .UUCP > uucp subdomains')
+
+# if we have % signs, take the rightmost one
+R$* % $* $1 @ $2 First make them all @s.
+R$* @ $* @ $* $1 % $2 @ $3 Undo all but the last.
+R$* @ $* $@ $>_SET_96_ $1 < @ $2 > Insert < > and finish
+
+# else we must be a local name
+
+
+################################################
+### Ruleset _SET_96_ -- bottom half of ruleset 3 ###
+################################################
+
+# At this point, everything should be in a "local_part<@domain>extra" format.
+S`'_SET_96_
+
+# handle special cases for local names
+R$* < @ localhost > $* $: $1 < @ $j . > $2 no domain at all
+R$* < @ localhost . $m > $* $: $1 < @ $j . > $2 local domain
+ifdef(`_NO_UUCP_', `dnl',
+`R$* < @ localhost . UUCP > $* $: $1 < @ $j . > $2 .UUCP domain')
+R$* < @ [ $+ ] > $* $: $1 < @@ [ $2 ] > $3 mark [a.b.c.d]
+R$* < @@ $=w > $* $: $1 < @ $j . > $3 self-literal
+R$* < @@ $+ > $* $@ $1 < @ $2 > $3 canon IP addr
+ifdef(`DOMAIN_TABLE', `
+# look up unqualified domains in the domain table
+R$* < @ $- > $* $: $1 < @ $(domaintable $2 $) > $3',
+`dnl')
+undivert(2)dnl
+
+ifdef(`_NO_UUCP_', `dnl',
+`ifdef(`UUCP_RELAY',
+`# pass UUCP addresses straight through
+R$* < @ $+ . UUCP > $* $@ $1 < @ $2 . UUCP . > $3',
+`# if really UUCP, handle it immediately
+ifdef(`_CLASS_U_',
+`R$* < @ $=U . UUCP > $* $@ $1 < @ $2 . UUCP . > $3', `dnl')
+ifdef(`_CLASS_V_',
+`R$* < @ $=V . UUCP > $* $@ $1 < @ $2 . UUCP . > $3', `dnl')
+ifdef(`_CLASS_W_',
+`R$* < @ $=W . UUCP > $* $@ $1 < @ $2 . UUCP . > $3', `dnl')
+ifdef(`_CLASS_X_',
+`R$* < @ $=X . UUCP > $* $@ $1 < @ $2 . UUCP . > $3', `dnl')
+ifdef(`_CLASS_Y_',
+`R$* < @ $=Y . UUCP > $* $@ $1 < @ $2 . UUCP . > $3', `dnl')
+
+# try UUCP traffic as a local address
+R$* < @ $+ . UUCP > $* $: $1 < @ $[ $2 $] . UUCP . > $3
+ifdef(`_OLD_SENDMAIL_',
+`R$* < @ $+ . $+ . UUCP . > $* $@ $1 < @ $2 . $3 . > $4',
+`R$* < @ $+ . . UUCP . > $* $@ $1 < @ $2 . > $3')')
+')
+ifdef(`_NO_CANONIFY_', `dnl',
+`# pass to name server to make hostname canonical
+R$* < @ $* $~P > $* $: $1 < @ $[ $2 $3 $] > $4')
+
+# local host aliases and pseudo-domains are always canonical
+R$* < @ $=w > $* $: $1 < @ $2 . > $3
+R$* < @ $* $=P > $* $: $1 < @ $2 $3 . > $4
+R$* < @ $* . . > $* $1 < @ $2 . > $3
+
+# if this is the local hostname, make sure we treat is as canonical
+R$* < @ $j > $* $: $1 < @ $j . > $2
+
+
+##################################################
+### Ruleset 4 -- Final Output Post-rewriting ###
+##################################################
+S4
+
+R$*<@> $@ $1 handle <> and list:;
+
+# strip trailing dot off possibly canonical name
+R$* < @ $+ . > $* $1 < @ $2 > $3
+
+# externalize local domain info
+R$* < $+ > $* $1 $2 $3 defocus
+R@ $+ : @ $+ : $+ @ $1 , @ $2 : $3 <route-addr> canonical
+R@ $* $@ @ $1 ... and exit
+
+ifdef(`_NO_UUCP_', `dnl',
+`# UUCP must always be presented in old form
+R$+ @ $- . UUCP $2!$1 u@h.UUCP => h!u')
+
+# delete duplicate local names
+R$+ % $=w @ $=w $1 @ $j u%host@host => u@host
+
+
+
+##############################################################
+### Ruleset _SET_97_ -- recanonicalize and call ruleset zero ###
+### (used for recursive calls) ###
+##############################################################
+
+S`'_SET_97_
+R$* $: $>3 $1
+R$* $@ $>0 $1
+
+
+######################################
+### Ruleset 0 -- Parse Address ###
+######################################
+
+S0
+
+R<@> $#_LOCAL_ $: <> special case error msgs
+R$* : $* ; $#error $@ USAGE $: "list:; syntax illegal for recipient addresses"
+R<@ $+> $#error $@ USAGE $: "user address required"
+R<$* : $* > $#error $@ USAGE $: "colon illegal in host name part"
+
+ifdef(`_MAILER_smtp_',
+`# handle numeric address spec
+R$* < @ [ $+ ] > $* $: $>_SET_98_ $1 < @ [ $2 ] > $3 numeric internet spec
+R$* < @ [ $+ ] > $* $#_SMTP_ $@ [$2] $: $1 < @ [$2] > $3 still numeric: send',
+ `dnl')
+
+# now delete the local info -- note $=O to find characters that cause forwarding
+R$* < @ > $* $@ $>_SET_97_ $1 user@ => user
+R< @ $=w . > : $* $@ $>_SET_97_ $2 @here:... -> ...
+R$* $=O $* < @ $=w . > $@ $>_SET_97_ $1 $2 $3 ...@here -> ...
+
+# handle local hacks
+R$* $: $>_SET_98_ $1
+
+# short circuit local delivery so forwarded email works
+ifdef(`_LOCAL_NOT_STICKY_',
+`R$=L < @ $=w . > $#_LOCAL_ $: @ $1 special local names
+R$+ < @ $=w . > $#_LOCAL_ $: $1 dispose directly',
+`R$+ < @ $=w . > $: $1 < @ $2 . @ $H > first try hub
+ifdef(`_OLD_SENDMAIL_',
+`R$+ < $+ @ $-:$+ > $# $3 $@ $4 $: $1 < $2 > yep ....
+R$+ < $+ @ $+ > $#relay $@ $3 $: $1 < $2 > yep ....
+R$+ < $+ @ > $#_LOCAL_ $: $1 nope, local address',
+`R$+ < $+ @ $+ > $#_LOCAL_ $: $1 yep ....
+R$+ < $+ @ > $#_LOCAL_ $: @ $1 nope, local address')')
+ifdef(`MAILER_TABLE',
+`
+# not local -- try mailer table lookup
+R$* <@ $+ > $* $: < $2 > $1 < @ $2 > $3 extract host name
+R< $+ . > $* $: < $1 > $2 strip trailing dot
+R< $+ > $* $: < $(mailertable $1 $) > $2 lookup
+R< $- : $+ > $* $# $1 $@ $2 $: $3 check -- resolved?
+R< $+ > $* $: $>90 <$1> $2 try domain',
+`dnl')
+undivert(4)dnl
+
+ifdef(`_NO_UUCP_', `dnl',
+`# resolve remotely connected UUCP links (if any)
+ifdef(`_CLASS_V_',
+`R$* < @ $=V . UUCP . > $* $: $>_SET_95_ < $V > $1 <@$2.UUCP.> $3',
+ `dnl')
+ifdef(`_CLASS_W_',
+`R$* < @ $=W . UUCP . > $* $: $>_SET_95_ < $W > $1 <@$2.UUCP.> $3',
+ `dnl')
+ifdef(`_CLASS_X_',
+`R$* < @ $=X . UUCP . > $* $: $>_SET_95_ < $X > $1 <@$2.UUCP.> $3',
+ `dnl')')
+
+# resolve fake top level domains by forwarding to other hosts
+ifdef(`BITNET_RELAY',
+`R$*<@$+.BITNET.>$* $: $>_SET_95_ < $B > $1 <@$2.BITNET.> $3 user@host.BITNET',
+ `dnl')
+ifdef(`_MAILER_pop_',
+`R$+ < @ POP. > $#pop $: $1 user@POP',
+ `dnl')
+ifdef(`_MAILER_fax_',
+`R$+ < @ $+ .FAX. > $#fax $@ $2 $: $1 user@host.FAX',
+`ifdef(`FAX_RELAY',
+`R$*<@$+.FAX.>$* $: $>_SET_95_ < $F > $1 <@$2.FAX.> $3 user@host.FAX',
+ `dnl')')
+
+ifdef(`UUCP_RELAY',
+`# forward non-local UUCP traffic to our UUCP relay
+R$*<@$*.UUCP.>$* $: $>_SET_95_ < $Y > $1 <@$2.UUCP.> $3 uucp mail',
+`ifdef(`_MAILER_uucp_',
+`# forward other UUCP traffic straight to UUCP
+R$* < @ $+ .UUCP. > $* $#uucp $@ $2 $: $1 < @ $2 .UUCP. > $3 user@host.UUCP',
+ `dnl')')
+ifdef(`_MAILER_usenet_', `
+# addresses sent to net.group.USENET will get forwarded to a newsgroup
+R$+ . USENET $#usenet $: $1',
+ `dnl')
+
+ifdef(`_LOCAL_RULES_',
+`# figure out what should stay in our local mail system
+undivert(1)', `dnl')
+
+# pass names that still have a host to a smarthost (if defined)
+R$* < @ $* > $* $: $>_SET_95_ < $S > $1 < @ $2 > $3 glue on smarthost name
+
+# deal with other remote names
+ifdef(`_MAILER_smtp_',
+`R$* < @$* > $* $#_SMTP_ $@ $2 $: $1 < @ $2 > $3 user@host.domain',
+`R$* < @$* > $* $#error $@NOHOST $: Unrecognized host name $2')
+
+ifdef(`_OLD_SENDMAIL_',
+`# forward remaining names to local relay, if any
+R$=L $#_LOCAL_ $: $1 special local names
+R$+ $: $>_SET_95_ < $R > $1 try relay
+R$+ $: $>_SET_95_ < $H > $1 try hub
+R$+ $#_LOCAL_ $: $1 no relay or hub: local',
+
+`# if this is quoted, strip the quotes and try again
+R$+ $: $(dequote $1 $) strip quotes
+R$+ $=O $+ $@ $>_SET_97_ $1 $2 $3 try again
+
+# handle locally delivered names
+R$=L $#_LOCAL_ $: @ $1 special local names
+R$+ $#_LOCAL_ $: $1 regular local names
+
+###########################################################################
+### Ruleset 5 -- special rewriting after aliases have been expanded ###
+### (new sendmail only) ###
+###########################################################################
+
+S5
+
+# see if we have a relay or a hub
+R$+ $: < $R > $1 try relay
+R< > $+ $: < $H > $1 try hub
+R< > $+ $@ $1 nope, give up
+R< $- : $+ > $+ $: $>_SET_95_ < $1 : $2 > $3 < @ $2 >
+R< $+ > $+ $@ $>_SET_95_ < $1 > $2 < @ $1 >')
+ifdef(`MAILER_TABLE',
+`
+
+###################################################################
+### Ruleset 90 -- try domain part of mailertable entry ###
+### (new sendmail only) ###
+###################################################################
+
+S90
+R$* <$- . $+ > $* $: $1$2 < $(mailertable .$3 $@ $1$2 $@ $2 $) > $4
+R$* <$- : $+ > $* $# $2 $@ $3 $: $4 check -- resolved?
+R$* < . $+ > $* $@ $>90 $1 . <$2> $3 no -- strip & try again
+R$* < $* > $* $: < $(mailertable . $@ $1$2 $) > $3 try "."
+R<$- : $+ > $* $# $1 $@ $2 $: $3 "." found?
+R< $* > $* $@ $2 no mailertable match',
+`dnl')
+
+###################################################################
+### Ruleset _SET_95_ -- canonify mailer:host syntax to triple ###
+###################################################################
+
+S`'_SET_95_
+R< > $* $@ $1 strip off null relay
+R< $- : $+ > $* $# $1 $@ $2 $: $3 try qualified mailer
+R< $=w > $* $@ $2 delete local host
+R< $+ > $* $#_RELAY_ $@ $1 $: $2 use unqualified mailer
+
+###################################################################
+### Ruleset _SET_98_ -- local part of ruleset zero (can be null) ###
+###################################################################
+
+S`'_SET_98_
+undivert(3)dnl
+#
+######################################################################
+######################################################################
+#####
+`##### MAILER DEFINITIONS'
+#####
+######################################################################
+######################################################################
+undivert(7)dnl
diff --git a/usr.sbin/sendmail/cf/m4/version.m4 b/usr.sbin/sendmail/cf/m4/version.m4
new file mode 100644
index 0000000..19806ff
--- /dev/null
+++ b/usr.sbin/sendmail/cf/m4/version.m4
@@ -0,0 +1,39 @@
+divert(-1)
+#
+# Copyright (c) 1983 Eric P. Allman
+# Copyright (c) 1988, 1993
+# The Regents of the University of California. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+# 3. All advertising materials mentioning features or use of this software
+# must display the following acknowledgement:
+# This product includes software developed by the University of
+# California, Berkeley and its contributors.
+# 4. Neither the name of the University nor the names of its contributors
+# may be used to endorse or promote products derived from this software
+# without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+#
+VERSIONID(`@(#)version.m4 8.6.9.1 (Berkeley) 4/18/94')
+#
+divert(0)
+# Configuration version number
+DZ8.6.9
diff --git a/usr.sbin/sendmail/cf/mailer/fax.m4 b/usr.sbin/sendmail/cf/mailer/fax.m4
new file mode 100644
index 0000000..0c98a3b
--- /dev/null
+++ b/usr.sbin/sendmail/cf/mailer/fax.m4
@@ -0,0 +1,50 @@
+PUSHDIVERT(-1)
+#
+# Copyright (c) 1983 Eric P. Allman
+# Copyright (c) 1988, 1993
+# The Regents of the University of California. All rights reserved.
+#
+# This assumes you already have Sam Leffler's FAX software.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+# 3. All advertising materials mentioning features or use of this software
+# must display the following acknowledgement:
+# This product includes software developed by the University of
+# California, Berkeley and its contributors.
+# 4. Neither the name of the University nor the names of its contributors
+# may be used to endorse or promote products derived from this software
+# without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+#
+
+ifdef(`FAX_MAILER_PATH',,
+ `define(`FAX_MAILER_PATH', /usr/local/lib/fax/mailfax)')
+ifdef(`FAX_MAILER_MAX',,
+ `define(`FAX_MAILER_MAX', 100000)')
+POPDIVERT
+####################################
+### FAX Mailer specification ###
+####################################
+
+VERSIONID(`@(#)fax.m4 8.2 (Berkeley) 1/24/94')
+
+Mfax, P=FAX_MAILER_PATH, F=DFMhu, S=14, R=24, M=FAX_MAILER_MAX,
+ A=mailfax $u $h $f
diff --git a/usr.sbin/sendmail/cf/mailer/local.m4 b/usr.sbin/sendmail/cf/mailer/local.m4
new file mode 100644
index 0000000..24a8204
--- /dev/null
+++ b/usr.sbin/sendmail/cf/mailer/local.m4
@@ -0,0 +1,66 @@
+PUSHDIVERT(-1)
+#
+# Copyright (c) 1983 Eric P. Allman
+# Copyright (c) 1988, 1993
+# The Regents of the University of California. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+# 3. All advertising materials mentioning features or use of this software
+# must display the following acknowledgement:
+# This product includes software developed by the University of
+# California, Berkeley and its contributors.
+# 4. Neither the name of the University nor the names of its contributors
+# may be used to endorse or promote products derived from this software
+# without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+#
+ifdef(`LOCAL_MAILER_FLAGS',, `define(`LOCAL_MAILER_FLAGS', `rmn')')
+ifdef(`LOCAL_MAILER_PATH',, `define(`LOCAL_MAILER_PATH', /bin/mail)')
+ifdef(`LOCAL_MAILER_ARGS',, `define(`LOCAL_MAILER_ARGS', `mail -d $u')')
+ifdef(`LOCAL_SHELL_FLAGS',, `define(`LOCAL_SHELL_FLAGS', `eu')')
+ifdef(`LOCAL_SHELL_PATH',, `define(`LOCAL_SHELL_PATH', /bin/sh)')
+ifdef(`LOCAL_SHELL_ARGS',, `define(`LOCAL_SHELL_ARGS', `sh -c $u')')
+POPDIVERT
+
+##################################################
+### Local and Program Mailer specification ###
+##################################################
+
+VERSIONID(`@(#)local.m4 8.6 (Berkeley) 10/24/93')
+
+Mlocal, P=LOCAL_MAILER_PATH, F=CONCAT(`lsDFM', LOCAL_MAILER_FLAGS), S=10, R=20/40,
+ A=LOCAL_MAILER_ARGS
+Mprog, P=LOCAL_SHELL_PATH, F=CONCAT(`lsDFM', LOCAL_SHELL_FLAGS), S=10, R=20/40, D=$z:/,
+ A=LOCAL_SHELL_ARGS
+
+S10
+R<@> $n errors to mailer-daemon
+R$+ $: $>40 $1
+
+S20
+R$+ < @ $* > $: $1 strip host part
+
+S40
+ifdef(`_ALWAYS_ADD_DOMAIN_',
+`R$* < @ $* > $* $@ $1 < @ $2 > $3 already fully qualified
+R$* $: $1 @ $M add local qualification
+R$* @ $: $1 @ $j if $M not defined',
+`dnl')
diff --git a/usr.sbin/sendmail/cf/mailer/pop.m4 b/usr.sbin/sendmail/cf/mailer/pop.m4
new file mode 100644
index 0000000..92bcff9
--- /dev/null
+++ b/usr.sbin/sendmail/cf/mailer/pop.m4
@@ -0,0 +1,53 @@
+PUSHDIVERT(-1)
+#
+# Copyright (c) 1983 Eric P. Allman
+# Copyright (c) 1988, 1993
+# The Regents of the University of California. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+# 3. All advertising materials mentioning features or use of this software
+# must display the following acknowledgement:
+# This product includes software developed by the University of
+# California, Berkeley and its contributors.
+# 4. Neither the name of the University nor the names of its contributors
+# may be used to endorse or promote products derived from this software
+# without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+#
+
+ifdef(`POP_MAILER_PATH',, `define(`POP_MAILER_PATH', /usr/lib/mh/spop)')
+ifdef(`POP_MAILER_FLAGS',, `define(`POP_MAILER_FLAGS', `eu')')
+ifdef(`POP_MAILER_ARGS',, `define(`POP_MAILER_ARGS', `pop $u')')
+
+POPDIVERT
+
+####################################
+### POP Mailer specification ###
+####################################
+
+VERSIONID(`@(#)pop.m4 8.2 (Berkeley) 2/19/94')
+
+Mpop, P=POP_MAILER_PATH, F=CONCAT(`lsDFM', POP_MAILER_FLAGS), S=10, R=20/40,
+ A=POP_MAILER_ARGS
+
+LOCAL_CONFIG
+# POP mailer is a pseudo-domain
+CPPOP
diff --git a/usr.sbin/sendmail/cf/mailer/smtp.m4 b/usr.sbin/sendmail/cf/mailer/smtp.m4
new file mode 100644
index 0000000..45efbd6
--- /dev/null
+++ b/usr.sbin/sendmail/cf/mailer/smtp.m4
@@ -0,0 +1,126 @@
+PUSHDIVERT(-1)
+#
+# Copyright (c) 1983 Eric P. Allman
+# Copyright (c) 1988, 1993
+# The Regents of the University of California. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+# 3. All advertising materials mentioning features or use of this software
+# must display the following acknowledgement:
+# This product includes software developed by the University of
+# California, Berkeley and its contributors.
+# 4. Neither the name of the University nor the names of its contributors
+# may be used to endorse or promote products derived from this software
+# without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+#
+ifdef(`SMTP_MAILER_FLAGS',,
+ `define(`SMTP_MAILER_FLAGS',
+ `ifdef(`_OLD_SENDMAIL_', `L', `')')')
+POPDIVERT
+#####################################
+### SMTP Mailer specification ###
+#####################################
+
+VERSIONID(`@(#)smtp.m4 8.15 (Berkeley) 2/14/94')
+
+Msmtp, P=[IPC], F=CONCAT(mDFMuX, SMTP_MAILER_FLAGS), S=11/31, R=ifdef(`_ALL_MASQUERADE_', `11/31', `21'), E=\r\n,
+ ifdef(`_OLD_SENDMAIL_',, `L=990, ')ifdef(`SMTP_MAILER_MAX', `M=SMTP_MAILER_MAX, ')A=IPC $h
+Mesmtp, P=[IPC], F=CONCAT(mDFMuXa, SMTP_MAILER_FLAGS), S=11/31, R=ifdef(`_ALL_MASQUERADE_', `11/31', `21'), E=\r\n,
+ ifdef(`_OLD_SENDMAIL_',, `L=990, ')ifdef(`SMTP_MAILER_MAX', `M=SMTP_MAILER_MAX, ')A=IPC $h
+Mrelay, P=[IPC], F=CONCAT(mDFMuXa, SMTP_MAILER_FLAGS), S=11/31, R=61, E=\r\n,
+ ifdef(`_OLD_SENDMAIL_',, `L=2040, ')A=IPC $h
+
+#
+# envelope sender and masquerading recipient rewriting
+#
+S11
+R$+ $: $>51 $1 sender/recipient common
+R$* :; <@> $@ $1 :; list:; special case
+R$* $@ $>61 $1 qualify unqual'ed names
+
+
+#
+# header recipient rewriting if not masquerading recipients
+#
+S21
+
+# do sender/recipient common rewriting
+R$+ $: $>51 $1
+
+# unqualified names (e.g., "eric") are qualified by local host
+R$* < @ $* > $* $@ $1 < @ $2 > $3 already qualified
+R$+ $: $1 < @ $j > add local domain
+
+
+#
+# header sender and masquerading recipient rewriting
+#
+S31
+R$+ $: $>51 $1 sender/recipient common
+R$* :; <@> $@ $1 :; list:; special case
+
+# do special header rewriting
+R$* <@> $* $@ $1 <@> $2 pass null host through
+R< @ $* > $* $@ < @ $1 > $2 pass route-addr through
+R$=E < @ $=w . > $@ $1 < @ $2 > exposed user as is
+R$* < @ $=w . > $: $1 < @ $2 @ $M > masquerade as domain
+R$* < @ $+ @ > $@ $1 < @ $2 > in case $M undefined
+R$* < @ $+ @ $+ > $@ $1 < @ $3 > $M is defined -- use it
+R$* $@ $>61 $1 qualify unqual'ed names
+
+
+#
+# convert pseudo-domain addresses to real domain addresses
+#
+S51
+
+# pass <route-addr>s through
+R< @ $+ > $* $@ < @ $1 > $2 resolve <route-addr>
+
+# output fake domains as user%fake@relay
+ifdef(`BITNET_RELAY',
+`R$+ <@ $+ .BITNET. > $: $1 % $2 .BITNET < @ $B > user@host.BITNET
+R$+.BITNET <@ $+:$+ > $: $1 .BITNET < @ $3 > strip mailer: part',
+ `dnl')
+ifdef(`_NO_UUCP_', `dnl', `
+# do UUCP heuristics; note that these are shared with UUCP mailers
+R$+ < @ $+ .UUCP. > $: < $2 ! > $1 convert to UUCP form
+R$+ < @ $* > $* $@ $1 < @ $2 > $3 not UUCP form
+
+# leave these in .UUCP form to avoid further tampering
+R< $&h ! > $- ! $+ $@ $2 < @ $1 .UUCP. >
+R< $&h ! > $-.$+ ! $+ $@ $3 < @ $1.$2 >
+R< $&h ! > $+ $@ $1 < @ $&h .UUCP. >
+R< $+ ! > $+ $: $1 ! $2 < @ $Y >
+R$+ < @ > $: $1 < @ $j > in case $Y undefined
+R$+ < @ $+ : $+ > $: $1 < @ $3 > strip mailer: part')
+
+
+#
+# common sender and masquerading recipient rewriting
+#
+S61
+
+R$* < @ $* > $* $@ $1 < @ $2 > $3 already qualified
+R$=E $@ $1 < @ $j> show exposed names
+R$+ $: $1 < @ $M > user w/o host
+R$+ <@> $: $1 < @ $j > in case $M undefined
diff --git a/usr.sbin/sendmail/cf/mailer/usenet.m4 b/usr.sbin/sendmail/cf/mailer/usenet.m4
new file mode 100644
index 0000000..fe6ee30
--- /dev/null
+++ b/usr.sbin/sendmail/cf/mailer/usenet.m4
@@ -0,0 +1,47 @@
+PUSHDIVERT(-1)
+#
+# Copyright (c) 1983 Eric P. Allman
+# Copyright (c) 1988, 1993
+# The Regents of the University of California. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+# 3. All advertising materials mentioning features or use of this software
+# must display the following acknowledgement:
+# This product includes software developed by the University of
+# California, Berkeley and its contributors.
+# 4. Neither the name of the University nor the names of its contributors
+# may be used to endorse or promote products derived from this software
+# without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+#
+
+ifdef(`USENET_MAILER_PATH',, `define(`USENET_MAILER_PATH', /usr/lib/news/inews)')
+ifdef(`USENET_MAILER_FLAGS',, `define(`USENET_MAILER_FLAGS', `rlsDFMmn')')
+ifdef(`USENET_MAILER_ARGS',, `define(`USENET_MAILER_ARGS', `inews -m -h -n')')
+POPDIVERT
+####################################
+### USENET Mailer specification ###
+####################################
+
+VERSIONID(`@(#)usenet.m4 8.3 (Berkeley) 1/24/94')
+
+Musenet, P=USENET_MAILER_PATH, F=USENET_MAILER_FLAGS, S=10, R=20,ifdef(`USENET_MAILER_MAX', ` M=USENET_MAILER_MAX,')
+ A=USENET_MAILER_ARGS $u
diff --git a/usr.sbin/sendmail/cf/mailer/uucp.m4 b/usr.sbin/sendmail/cf/mailer/uucp.m4
new file mode 100644
index 0000000..dd7aa87
--- /dev/null
+++ b/usr.sbin/sendmail/cf/mailer/uucp.m4
@@ -0,0 +1,172 @@
+PUSHDIVERT(-1)
+#
+# Copyright (c) 1983 Eric P. Allman
+# Copyright (c) 1988, 1993
+# The Regents of the University of California. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+# 3. All advertising materials mentioning features or use of this software
+# must display the following acknowledgement:
+# This product includes software developed by the University of
+# California, Berkeley and its contributors.
+# 4. Neither the name of the University nor the names of its contributors
+# may be used to endorse or promote products derived from this software
+# without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+#
+
+ifdef(`UUCP_MAILER_PATH',, `define(`UUCP_MAILER_PATH', /usr/bin/uux)')
+ifdef(`UUCP_MAILER_ARGS',, `define(`UUCP_MAILER_ARGS', `uux - -r -a$f -gC $h!rmail ($u)')')
+ifdef(`UUCP_MAILER_FLAGS',, `define(`UUCP_MAILER_FLAGS', `')')
+ifdef(`UUCP_MAX_SIZE',, `define(`UUCP_MAX_SIZE', 100000)')
+POPDIVERT
+#####################################
+### UUCP Mailer specification ###
+#####################################
+
+VERSIONID(`@(#)uucp.m4 8.16 (Berkeley) 4/14/94')
+
+#
+# There are innumerable variations on the UUCP mailer. It really
+# is rather absurd.
+#
+
+# old UUCP mailer (two names)
+Muucp, P=UUCP_MAILER_PATH, F=CONCAT(DFMhuU, UUCP_MAILER_FLAGS), S=12, R=22/42, M=UUCP_MAX_SIZE,
+ A=UUCP_MAILER_ARGS
+Muucp-old, P=UUCP_MAILER_PATH, F=CONCAT(DFMhuU, UUCP_MAILER_FLAGS), S=12, R=22/42, M=UUCP_MAX_SIZE,
+ A=UUCP_MAILER_ARGS
+
+# smart UUCP mailer (handles multiple addresses) (two names)
+Msuucp, P=UUCP_MAILER_PATH, F=CONCAT(mDFMhuU, UUCP_MAILER_FLAGS), S=12, R=22/42, M=UUCP_MAX_SIZE,
+ A=UUCP_MAILER_ARGS
+Muucp-new, P=UUCP_MAILER_PATH, F=CONCAT(mDFMhuU, UUCP_MAILER_FLAGS), S=12, R=22/42, M=UUCP_MAX_SIZE,
+ A=UUCP_MAILER_ARGS
+
+ifdef(`_MAILER_smtp_',
+`# domain-ized UUCP mailer
+Muucp-dom, P=UUCP_MAILER_PATH, F=CONCAT(mDFMhu, UUCP_MAILER_FLAGS), S=52/31, R=ifdef(`_ALL_MASQUERADE_', `11/31', `21'), M=UUCP_MAX_SIZE,
+ A=UUCP_MAILER_ARGS
+
+# domain-ized UUCP mailer with UUCP-style sender envelope
+Muucp-uudom, P=UUCP_MAILER_PATH, F=CONCAT(mDFMhu, UUCP_MAILER_FLAGS), S=72/31, R=ifdef(`_ALL_MASQUERADE_', `11/31', `21'), M=UUCP_MAX_SIZE,
+ A=UUCP_MAILER_ARGS')
+
+
+#
+# envelope and header sender rewriting
+#
+S12
+
+# handle error address as a special case
+R<@> $n errors to mailer-daemon
+
+# do not qualify list:; syntax
+R$* :; <@> $@ $1 :;
+
+R$* < @ $* . > $1 < @ $2 > strip trailing dots
+R$* < @ $=w > $1 strip local name
+R<@ $- . UUCP > : $+ $1 ! $2 convert to UUCP format
+R<@ $+ > : $+ $1 ! $2 convert to UUCP format
+R$* < @ $- . UUCP > $2 ! $1 convert to UUCP format
+R$* < @ $+ > $2 ! $1 convert to UUCP format
+R$&h ! $+ ! $+ $@ $1 ! $2 $h!...!user => ...!user
+R$&h ! $+ $@ $&h ! $1 $h!user => $h!user
+R$+ $: $U ! $1 prepend our name
+R! $+ $: $k ! $1 in case $U undefined
+
+#
+# envelope recipient rewriting
+#
+S22
+
+# don't touch list:; syntax
+R$* :; <@> $@ $1 :;
+
+R$* < @ $* . > $1 < @ $2 > strip trailing dots
+R$* < @ $j > $1 strip local name
+R<@ $- . UUCP > : $+ $1 ! $2 convert to UUCP format
+R<@ $+ > : $+ $1 ! $2 convert to UUCP format
+R$* < @ $- . UUCP > $2 ! $1 convert to UUCP format
+R$* < @ $+ > $2 ! $1 convert to UUCP format
+
+#
+# header recipient rewriting
+#
+S42
+
+# don't touch list:; syntax
+R$* :; <@> $@ $1 :;
+
+R$* < @ $* . > $1 < @ $2 > strip trailing dots
+R$* < @ $j > $1 strip local name
+R<@ $- . UUCP > : $+ $1 ! $2 convert to UUCP format
+R<@ $+ > : $+ $1 ! $2 convert to UUCP format
+R$* < @ $- . UUCP > $2 ! $1 convert to UUCP format
+R$* < @ $+ > $2 ! $1 convert to UUCP format
+R$&h ! $+ ! $+ $@ $1 ! $2 $h!...!user => ...!user
+R$&h ! $+ $@ $&h ! $1 $h!user => $h!user
+R$+ $: $U ! $1 prepend our name
+R! $+ $: $k ! $1 in case $U undefined
+
+
+ifdef(`_MAILER_smtp_',
+`#
+# envelope sender rewriting for uucp-dom mailer
+#
+S52
+
+# handle error address as a special case
+R<@> $n errors to mailer-daemon
+
+# pass everything to standard SMTP mailer rewriting
+R$* $@ $>11 $1
+
+#
+# envelope sender rewriting for uucp-uudom mailer
+#
+S72
+
+# handle error address as a special case
+R<@> $n errors to mailer-daemon
+
+# do not qualify list:; syntax
+R$* :; <@> $@ $1 :;
+
+R$* < @ $* . > $1 < @ $2 > strip trailing dots
+R$* < @ $=w > $1 strip local name
+R<@ $- . UUCP > : $+ $1 ! $2 convert to UUCP format
+R<@ $+ > : $+ $1 ! $2 convert to UUCP format
+R$* < @ $- . UUCP > $2 ! $1 convert to UUCP format
+R$* < @ $+ > $@ $2 ! $1 convert to UUCP format
+
+R$&h ! $+ ! $+ $@ $1 ! $2 $h!...!user => ...!user
+R$&h ! $+ $@ $&h ! $1 $h!user => $h!user
+R$+ $: $M ! $1 prepend masquerade name
+R! $+ $: $j ! $1 in case $M undefined')
+
+
+PUSHDIVERT(4)
+# resolve locally connected UUCP links
+R$* < @ $=Z . UUCP. > $* $#uucp-uudom $@ $2 $: $1 < @ $2 .UUCP. > $3
+R$* < @ $=Y . UUCP. > $* $#uucp-new $@ $2 $: $1 < @ $2 .UUCP. > $3
+R$* < @ $=U . UUCP. > $* $#uucp-old $@ $2 $: $1 < @ $2 .UUCP. > $3
+POPDIVERT
diff --git a/usr.sbin/sendmail/cf/ostype/aix3.m4 b/usr.sbin/sendmail/cf/ostype/aix3.m4
new file mode 100644
index 0000000..4411fd0
--- /dev/null
+++ b/usr.sbin/sendmail/cf/ostype/aix3.m4
@@ -0,0 +1,40 @@
+divert(-1)
+#
+# Copyright (c) 1983 Eric P. Allman
+# Copyright (c) 1988, 1993
+# The Regents of the University of California. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+# 3. All advertising materials mentioning features or use of this software
+# must display the following acknowledgement:
+# This product includes software developed by the University of
+# California, Berkeley and its contributors.
+# 4. Neither the name of the University nor the names of its contributors
+# may be used to endorse or promote products derived from this software
+# without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+#
+
+divert(0)
+VERSIONID(`@(#)aix3.m4 8.3 (Berkeley) 8/8/93')
+define(`LOCAL_MAILER_PATH', /bin/bellmail)dnl
+define(`LOCAL_MAILER_ARGS', mail $u)dnl
+define(`LOCAL_MAILER_FLAGS', `mn')dnl
diff --git a/usr.sbin/sendmail/cf/ostype/aux.m4 b/usr.sbin/sendmail/cf/ostype/aux.m4
new file mode 100644
index 0000000..b7ea47b
--- /dev/null
+++ b/usr.sbin/sendmail/cf/ostype/aux.m4
@@ -0,0 +1,43 @@
+divert(-1)
+#
+# Copyright (c) 1983 Eric P. Allman
+# Copyright (c) 1988, 1993
+# The Regents of the University of California. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+# 3. All advertising materials mentioning features or use of this software
+# must display the following acknowledgement:
+# This product includes software developed by the University of
+# California, Berkeley and its contributors.
+# 4. Neither the name of the University nor the names of its contributors
+# may be used to endorse or promote products derived from this software
+# without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+#
+
+divert(0)
+VERSIONID(`@(#)aux.m4 8.1 (Berkeley) 9/2/93')
+define(`ALIAS_FILE', /usr/lib/aliases)dnl
+define(`QUEUE_DIR', /usr/spool/mqueue)dnl
+define(`STATUS_FILE', /usr/lib/sendmail.st)dnl
+define(`UUCP_MAILER_PATH', /usr/bin/uux)dnl
+define(`LOCAL_MAILER_FLAGS', mn)dnl
+define(`LOCAL_MAILER_ARGS', `mail -d -r $f $u')dnl
diff --git a/usr.sbin/sendmail/cf/ostype/bsd4.3.m4 b/usr.sbin/sendmail/cf/ostype/bsd4.3.m4
new file mode 100644
index 0000000..32aac4d
--- /dev/null
+++ b/usr.sbin/sendmail/cf/ostype/bsd4.3.m4
@@ -0,0 +1,39 @@
+divert(-1)
+#
+# Copyright (c) 1983 Eric P. Allman
+# Copyright (c) 1988, 1993
+# The Regents of the University of California. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+# 3. All advertising materials mentioning features or use of this software
+# must display the following acknowledgement:
+# This product includes software developed by the University of
+# California, Berkeley and its contributors.
+# 4. Neither the name of the University nor the names of its contributors
+# may be used to endorse or promote products derived from this software
+# without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+#
+
+divert(0)
+VERSIONID(`@(#)bsd4.3.m4 8.2 (Berkeley) 2/10/94')
+define(`QUEUE_DIR', /usr/spool/mqueue)dnl
+define(`UUCP_MAILER_ARGS', `uux - -r -z -a$f $h!rmail ($u)')dnl
diff --git a/usr.sbin/sendmail/cf/ostype/bsd4.4.m4 b/usr.sbin/sendmail/cf/ostype/bsd4.4.m4
new file mode 100644
index 0000000..1950528
--- /dev/null
+++ b/usr.sbin/sendmail/cf/ostype/bsd4.4.m4
@@ -0,0 +1,42 @@
+divert(-1)
+#
+# Copyright (c) 1983 Eric P. Allman
+# Copyright (c) 1988, 1993
+# The Regents of the University of California. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+# 3. All advertising materials mentioning features or use of this software
+# must display the following acknowledgement:
+# This product includes software developed by the University of
+# California, Berkeley and its contributors.
+# 4. Neither the name of the University nor the names of its contributors
+# may be used to endorse or promote products derived from this software
+# without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+#
+#
+
+divert(0)
+VERSIONID(`@(#)bsd4.4.m4 8.2 (Berkeley) 2/10/94')
+define(`HELP_FILE', /usr/share/misc/sendmail.hf)dnl
+define(`STATUS_FILE', /var/log/sendmail.st)dnl
+define(`LOCAL_MAILER_PATH', /usr/libexec/mail.local)dnl
+define(`UUCP_MAILER_ARGS', `uux - -r -z -a$f $h!rmail ($u)')dnl
diff --git a/usr.sbin/sendmail/cf/ostype/bsdi1.0.m4 b/usr.sbin/sendmail/cf/ostype/bsdi1.0.m4
new file mode 100644
index 0000000..28088f0
--- /dev/null
+++ b/usr.sbin/sendmail/cf/ostype/bsdi1.0.m4
@@ -0,0 +1,38 @@
+divert(-1)
+#
+# Copyright (c) 1983 Eric P. Allman
+# Copyright (c) 1988, 1993
+# The Regents of the University of California. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+# 3. All advertising materials mentioning features or use of this software
+# must display the following acknowledgement:
+# This product includes software developed by the University of
+# California, Berkeley and its contributors.
+# 4. Neither the name of the University nor the names of its contributors
+# may be used to endorse or promote products derived from this software
+# without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+#
+
+divert(0)
+VERSIONID(`@(#)bsdi1.0.m4 8.1 (Berkeley) 12/11/93')dnl
+OSTYPE(bsd4.4)
diff --git a/usr.sbin/sendmail/cf/ostype/dgux.m4 b/usr.sbin/sendmail/cf/ostype/dgux.m4
new file mode 100644
index 0000000..38c1c1a
--- /dev/null
+++ b/usr.sbin/sendmail/cf/ostype/dgux.m4
@@ -0,0 +1,39 @@
+divert(-1)
+#
+# Copyright (c) 1983 Eric P. Allman
+# Copyright (c) 1988, 1993
+# The Regents of the University of California. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+# 3. All advertising materials mentioning features or use of this software
+# must display the following acknowledgement:
+# This product includes software developed by the University of
+# California, Berkeley and its contributors.
+# 4. Neither the name of the University nor the names of its contributors
+# may be used to endorse or promote products derived from this software
+# without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+#
+
+divert(0)
+VERSIONID(`@(#)dgux.m4 8.1 (Berkeley) 11/27/93')
+define(`LOCAL_MAILER_FLAGS', m)dnl
+define(`confTIME_ZONE', `USE_TZ')dnl
diff --git a/usr.sbin/sendmail/cf/ostype/domainos.m4 b/usr.sbin/sendmail/cf/ostype/domainos.m4
new file mode 100644
index 0000000..6c214e6
--- /dev/null
+++ b/usr.sbin/sendmail/cf/ostype/domainos.m4
@@ -0,0 +1,42 @@
+divert(-1)
+#
+# Copyright (c) 1983 Eric P. Allman
+# Copyright (c) 1988, 1993
+# The Regents of the University of California. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+# 3. All advertising materials mentioning features or use of this software
+# must display the following acknowledgement:
+# This product includes software developed by the University of
+# California, Berkeley and its contributors.
+# 4. Neither the name of the University nor the names of its contributors
+# may be used to endorse or promote products derived from this software
+# without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+#
+
+divert(0)
+VERSIONID(`@(#)domainos.m4 8.1 (Berkeley) 1/23/94')
+divert(-1)
+
+define(`ALIAS_FILE', /usr/lib/aliases)
+define(`STATUS_FILE', /usr/lib/sendmail.st)
+define(`QUEUE_DIR', /usr/spool/mqueue)
diff --git a/usr.sbin/sendmail/cf/ostype/dynix3.2.m4 b/usr.sbin/sendmail/cf/ostype/dynix3.2.m4
new file mode 100644
index 0000000..a4d6e52
--- /dev/null
+++ b/usr.sbin/sendmail/cf/ostype/dynix3.2.m4
@@ -0,0 +1,39 @@
+divert(-1)
+#
+# Copyright (c) 1983 Eric P. Allman
+# Copyright (c) 1988, 1993
+# The Regents of the University of California. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+# 3. All advertising materials mentioning features or use of this software
+# must display the following acknowledgement:
+# This product includes software developed by the University of
+# California, Berkeley and its contributors.
+# 4. Neither the name of the University nor the names of its contributors
+# may be used to endorse or promote products derived from this software
+# without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+#
+
+divert(0)
+VERSIONID(`@(#)dynix3.2.m4 8.1 (Berkeley) 11/27/93')
+define(`ALIAS_FILE', /usr/lib/aliases)dnl
+define(`QUEUE_DIR', /usr/spool/mqueue)dnl
diff --git a/usr.sbin/sendmail/cf/ostype/linux.m4 b/usr.sbin/sendmail/cf/ostype/linux.m4
new file mode 100644
index 0000000..527b6fa
--- /dev/null
+++ b/usr.sbin/sendmail/cf/ostype/linux.m4
@@ -0,0 +1,38 @@
+divert(-1)
+#
+# Copyright (c) 1983 Eric P. Allman
+# Copyright (c) 1988, 1993
+# The Regents of the University of California. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+# 3. All advertising materials mentioning features or use of this software
+# must display the following acknowledgement:
+# This product includes software developed by the University of
+# California, Berkeley and its contributors.
+# 4. Neither the name of the University nor the names of its contributors
+# may be used to endorse or promote products derived from this software
+# without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+#
+
+divert(0)
+VERSIONID(`@(#)linux.m4 8.2 (Berkeley) 8/21/93')
+define(`LOCAL_MAILER_PATH', /bin/mail.local)dnl
diff --git a/usr.sbin/sendmail/cf/ostype/nextstep.m4 b/usr.sbin/sendmail/cf/ostype/nextstep.m4
new file mode 100644
index 0000000..8144c3e
--- /dev/null
+++ b/usr.sbin/sendmail/cf/ostype/nextstep.m4
@@ -0,0 +1,44 @@
+divert(-1)
+#
+# Copyright (c) 1983 Eric P. Allman
+# Copyright (c) 1988, 1993
+# The Regents of the University of California. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+# 3. All advertising materials mentioning features or use of this software
+# must display the following acknowledgement:
+# This product includes software developed by the University of
+# California, Berkeley and its contributors.
+# 4. Neither the name of the University nor the names of its contributors
+# may be used to endorse or promote products derived from this software
+# without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+#
+
+divert(0)
+VERSIONID(`@(#)nextstep.m4 8.4 (Berkeley) 11/30/93')
+define(`ALIAS_FILE', /etc/sendmail/aliases)dnl
+define(`HELP_FILE', /usr/lib/sendmail.hf)dnl
+define(`STATUS_FILE', /etc/sendmail/sendmail.st)dnl
+define(`UUCP_MAILER_PATH', /usr/bin/uux)dnl
+define(`QUEUE_DIR', /usr/spool/mqueue)dnl
+define(`LOCAL_MAILER_FLAGS', `rmnP')dnl
+define(`LOCAL_SHELL_FLAGS', `euP')dnl
diff --git a/usr.sbin/sendmail/cf/ostype/osf1.m4 b/usr.sbin/sendmail/cf/ostype/osf1.m4
new file mode 100644
index 0000000..fbc4832
--- /dev/null
+++ b/usr.sbin/sendmail/cf/ostype/osf1.m4
@@ -0,0 +1,41 @@
+divert(-1)
+#
+# Copyright (c) 1983 Eric P. Allman
+# Copyright (c) 1988, 1993
+# The Regents of the University of California. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+# 3. All advertising materials mentioning features or use of this software
+# must display the following acknowledgement:
+# This product includes software developed by the University of
+# California, Berkeley and its contributors.
+# 4. Neither the name of the University nor the names of its contributors
+# may be used to endorse or promote products derived from this software
+# without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+#
+
+divert(0)
+VERSIONID(`@(#)osf1.m4 8.1 (Berkeley) 6/7/93')
+ifdef(`_OLD_SENDMAIL_', `define(`NEED_DOMAIN', `')')dnl
+define(`ALIAS_FILE', /usr/adm/sendmail/aliases)dnl
+define(`STATUS_FILE', /usr/adm/sendmail/sendmail.st)dnl
+define(`HELP_FILE', /usr/share/lib/sendmail.hf)dnl
diff --git a/usr.sbin/sendmail/cf/ostype/riscos4.5.m4 b/usr.sbin/sendmail/cf/ostype/riscos4.5.m4
new file mode 100644
index 0000000..b45b252
--- /dev/null
+++ b/usr.sbin/sendmail/cf/ostype/riscos4.5.m4
@@ -0,0 +1,42 @@
+divert(-1)
+#
+# Copyright (c) 1983 Eric P. Allman
+# Copyright (c) 1988, 1993
+# The Regents of the University of California. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+# 3. All advertising materials mentioning features or use of this software
+# must display the following acknowledgement:
+# This product includes software developed by the University of
+# California, Berkeley and its contributors.
+# 4. Neither the name of the University nor the names of its contributors
+# may be used to endorse or promote products derived from this software
+# without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+#
+
+divert(0)
+VERSIONID(`@(#)riscos4.5.m4 8.2 (Berkeley) 12/1/93')
+
+define(`LOCAL_MAILER_ARGS', `rmail -d $u')dnl
+define(`ALIAS_FILE', `/usr/lib/aliases')dnl
+define(`QUEUE_DIR', `/usr/spool/mqueue')dnl
+define(`HELP_FILE', `/usr/lib/sendmail.hf')dnl
diff --git a/usr.sbin/sendmail/cf/ostype/sco3.2.m4 b/usr.sbin/sendmail/cf/ostype/sco3.2.m4
new file mode 100644
index 0000000..08ed0fd
--- /dev/null
+++ b/usr.sbin/sendmail/cf/ostype/sco3.2.m4
@@ -0,0 +1,45 @@
+divert(-1)
+#
+# Copyright (c) 1983 Eric P. Allman
+# Copyright (c) 1988, 1993
+# The Regents of the University of California. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+# 3. All advertising materials mentioning features or use of this software
+# must display the following acknowledgement:
+# This product includes software developed by the University of
+# California, Berkeley and its contributors.
+# 4. Neither the name of the University nor the names of its contributors
+# may be used to endorse or promote products derived from this software
+# without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+#
+
+divert(0)
+VERSIONID(`@(#)sco32.m4 8.1 (Berkeley) 11/27/93')
+define(`ALIAS_FILE', /usr/lib/mail/aliases)dnl
+define(`QUEUE_DIR', /usr/spool/mqueue)dnl
+define(`STATUS_FILE', /usr/lib/sendmail.st)dnl
+define(`UUCP_MAILER_PATH', /usr/bin/uux)dnl
+define(`LOCAL_MAILER_PATH', /usr/bin/lmail)dnl
+define(`LOCAL_MAILER_FLAGS', PuhCE)dnl
+define(`LOCAL_MAILER_ARGS', `lmail $u')dnl
+define(`LOCAL_SHELL_FLAGS', Peu)dnl
diff --git a/usr.sbin/sendmail/cf/ostype/solaris2.m4 b/usr.sbin/sendmail/cf/ostype/solaris2.m4
new file mode 100644
index 0000000..5e87027
--- /dev/null
+++ b/usr.sbin/sendmail/cf/ostype/solaris2.m4
@@ -0,0 +1,43 @@
+divert(-1)
+#
+# Copyright (c) 1983 Eric P. Allman
+# Copyright (c) 1988, 1993
+# The Regents of the University of California. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+# 3. All advertising materials mentioning features or use of this software
+# must display the following acknowledgement:
+# This product includes software developed by the University of
+# California, Berkeley and its contributors.
+# 4. Neither the name of the University nor the names of its contributors
+# may be used to endorse or promote products derived from this software
+# without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+#
+
+divert(0)
+VERSIONID(`@(#)solaris2.m4 8.2 (Berkeley) 1/23/94')
+divert(-1)
+
+define(`ALIAS_FILE', /etc/mail/aliases)
+define(`HELP_FILE', /etc/mail/sendmail.hf)
+define(`STATUS_FILE', /etc/mail/sendmail.st)
+define(`LOCAL_MAILER_FLAGS', `fSn')
diff --git a/usr.sbin/sendmail/cf/ostype/sunos3.5.m4 b/usr.sbin/sendmail/cf/ostype/sunos3.5.m4
new file mode 100644
index 0000000..fe76931
--- /dev/null
+++ b/usr.sbin/sendmail/cf/ostype/sunos3.5.m4
@@ -0,0 +1,37 @@
+divert(-1)
+#
+# Copyright (c) 1983 Eric P. Allman
+# Copyright (c) 1988, 1993
+# The Regents of the University of California. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+# 3. All advertising materials mentioning features or use of this software
+# must display the following acknowledgement:
+# This product includes software developed by the University of
+# California, Berkeley and its contributors.
+# 4. Neither the name of the University nor the names of its contributors
+# may be used to endorse or promote products derived from this software
+# without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+#
+
+divert(0)
+VERSIONID(`@(#)sunos3.5.m4 8.1 (Berkeley) 6/7/93')
diff --git a/usr.sbin/sendmail/cf/ostype/sunos4.1.m4 b/usr.sbin/sendmail/cf/ostype/sunos4.1.m4
new file mode 100644
index 0000000..cfa7a9a
--- /dev/null
+++ b/usr.sbin/sendmail/cf/ostype/sunos4.1.m4
@@ -0,0 +1,37 @@
+divert(-1)
+#
+# Copyright (c) 1983 Eric P. Allman
+# Copyright (c) 1988, 1993
+# The Regents of the University of California. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+# 3. All advertising materials mentioning features or use of this software
+# must display the following acknowledgement:
+# This product includes software developed by the University of
+# California, Berkeley and its contributors.
+# 4. Neither the name of the University nor the names of its contributors
+# may be used to endorse or promote products derived from this software
+# without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+#
+
+divert(0)
+VERSIONID(`@(#)sunos4.1.m4 8.1 (Berkeley) 6/7/93')
diff --git a/usr.sbin/sendmail/cf/ostype/svr4.m4 b/usr.sbin/sendmail/cf/ostype/svr4.m4
new file mode 100644
index 0000000..dd50127
--- /dev/null
+++ b/usr.sbin/sendmail/cf/ostype/svr4.m4
@@ -0,0 +1,45 @@
+divert(-1)
+#
+# Copyright (c) 1983 Eric P. Allman
+# Copyright (c) 1988, 1993
+# The Regents of the University of California. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+# 3. All advertising materials mentioning features or use of this software
+# must display the following acknowledgement:
+# This product includes software developed by the University of
+# California, Berkeley and its contributors.
+# 4. Neither the name of the University nor the names of its contributors
+# may be used to endorse or promote products derived from this software
+# without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+#
+
+divert(0)
+VERSIONID(`@(#)svr4.m4 8.1 (Berkeley) 8/24/93')
+
+ifdef(`ALIAS_FILE',,`define(`ALIAS_FILE', /usr/ucblib/aliases)')dnl
+ifdef(`HELP_FILE',,`define(`HELP_FILE', /usr/ucblib/sendmail.hf)')dnl
+ifdef(`STATUS_FILE',,`define(`STATUS_FILE', /usr/ucblib/sendmail.st)')dnl
+define(`LOCAL_MAILER_PATH', `/usr/ucblib/binmail')dnl
+define(`LOCAL_MAILER_FLAGS', `rmn')dnl
+define(`LOCAL_SHELL_FLAGS', `ehuP')dnl
+define(`UUCP_MAILER_ARGS', `uux - -r -a$f -gmedium $h!rmail ($u)')dnl
diff --git a/usr.sbin/sendmail/cf/sh/makeinfo.sh b/usr.sbin/sendmail/cf/sh/makeinfo.sh
new file mode 100644
index 0000000..dd5044a
--- /dev/null
+++ b/usr.sbin/sendmail/cf/sh/makeinfo.sh
@@ -0,0 +1,77 @@
+#!/bin/sh
+#
+# Copyright (c) 1983 Eric P. Allman
+# Copyright (c) 1988, 1993
+# The Regents of the University of California. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+# 3. All advertising materials mentioning features or use of this software
+# must display the following acknowledgement:
+# This product includes software developed by the University of
+# California, Berkeley and its contributors.
+# 4. Neither the name of the University nor the names of its contributors
+# may be used to endorse or promote products derived from this software
+# without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+#
+# @(#)makeinfo.sh 8.4 (Berkeley) 3/4/94
+#
+
+usewhoami=0
+usehostname=0
+for p in `echo $PATH | sed 's/:/ /g'`
+do
+ if [ "x$p" = "x" ]
+ then
+ p="."
+ fi
+ if [ -f $p/whoami ]
+ then
+ usewhoami=1
+ if [ $usehostname -ne 0 ]
+ then
+ break;
+ fi
+ fi
+ if [ -f $p/hostname ]
+ then
+ usehostname=1
+ if [ $usewhoami -ne 0 ]
+ then
+ break;
+ fi
+ fi
+done
+if [ $usewhoami -ne 0 ]
+then
+ user=`whoami`
+else
+ user=$LOGNAME
+fi
+
+if [ $usehostname -ne 0 ]
+then
+ host=`hostname`
+else
+ host=`uname -n`
+fi
+echo '#####' built by $user@$host on `date`
+echo '#####' in `pwd` | sed 's/\/tmp_mnt//'
diff --git a/usr.sbin/sendmail/cf/siteconfig/uucp.cogsci.m4 b/usr.sbin/sendmail/cf/siteconfig/uucp.cogsci.m4
new file mode 100644
index 0000000..33c7151
--- /dev/null
+++ b/usr.sbin/sendmail/cf/siteconfig/uucp.cogsci.m4
@@ -0,0 +1,6 @@
+SITE(contessa)
+SITE(emind)
+SITE(hoptoad)
+SITE(nkainc)
+SITE(well)
+SITE(ferdy)
diff --git a/usr.sbin/sendmail/cf/siteconfig/uucp.old.arpa.m4 b/usr.sbin/sendmail/cf/siteconfig/uucp.old.arpa.m4
new file mode 100644
index 0000000..81d5e94
--- /dev/null
+++ b/usr.sbin/sendmail/cf/siteconfig/uucp.old.arpa.m4
@@ -0,0 +1,4 @@
+SITE(endotsew)
+SITE(fateman)
+SITE(interlan)
+SITE(metron)
diff --git a/usr.sbin/sendmail/cf/siteconfig/uucp.ucbarpa.m4 b/usr.sbin/sendmail/cf/siteconfig/uucp.ucbarpa.m4
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/usr.sbin/sendmail/cf/siteconfig/uucp.ucbarpa.m4
@@ -0,0 +1 @@
+
diff --git a/usr.sbin/sendmail/cf/siteconfig/uucp.ucbvax.m4 b/usr.sbin/sendmail/cf/siteconfig/uucp.ucbvax.m4
new file mode 100644
index 0000000..ee2c34f
--- /dev/null
+++ b/usr.sbin/sendmail/cf/siteconfig/uucp.ucbvax.m4
@@ -0,0 +1,73 @@
+SITE(Padova)
+SITE(Shasta)
+SITE(alice)
+SITE(allegra)
+SITE(amdcad)
+SITE(att)
+SITE(attunix)
+SITE(avsd)
+SITE(bellcore bellcor)
+SITE(calma)
+SITE(cithep)
+SITE(cnmat)
+SITE(craig)
+SITE(craylab)
+SITE(decusj)
+SITE(decvax, S)
+SITE(decwrl)
+SITE(dssovax)
+SITE(eagle)
+SITE(ecovax)
+SITE(floyd)
+SITE(franz)
+SITE(geoff)
+SITE(harpo)
+SITE(ho3e2)
+SITE(hpda)
+SITE(hplabs)
+SITE(ibmsupt ibmuupa ibmpa)
+SITE(iiasa70)
+SITE(imagen)
+SITE(isunix menlo70)
+SITE(kentmth)
+SITE(lbl-csam lbl-csa)
+SITE(lime)
+SITE(mothra)
+SITE(mseonyx)
+SITE(mtxinu)
+SITE(pixar)
+SITE(pur-ee)
+SITE(purdue)
+SITE(pwbd)
+SITE(sdcarl)
+SITE(sftig)
+SITE(sgi olympus)
+SITE(sii)
+SITE(srivisi)
+SITE(ssyx)
+SITE(sun)
+SITE(trwrb)
+SITE(twg)
+SITE(ucivax)
+SITE(ucla-se)
+SITE(ucla-cs)
+SITE(ucsbcsl ucsbhub)
+SITE(ucscc)
+SITE(ucsd)
+SITE(ucsfcgl)
+SITE(ucsfmis)
+SITE(ulysses)
+SITE(unisoft)
+SITE(unmvax)
+SITE(usenix)
+SITE(uw)
+SITE(uwvax)
+SITE(vax135)
+SITE(voder)
+SITE(wheps)
+SITE(whuxle)
+SITE(whuxlj)
+SITE(xicomp)
+SITE(xprin)
+SITE(zehntel)
+SITE(zilog)
diff --git a/usr.sbin/sendmail/contrib/README b/usr.sbin/sendmail/contrib/README
new file mode 100644
index 0000000..dcf5c8f
--- /dev/null
+++ b/usr.sbin/sendmail/contrib/README
@@ -0,0 +1,10 @@
+Everything in this directory (except this file) has been contributed.
+We will not fix bugs in these programs. Contact the original author
+for assistance.
+
+Some of these are patches to sendmail itself. You may need to take
+care -- some of the patches may be out of date with the latest release
+of sendmail. Also, the previous comment applies -- patches belong to
+the original author, not to me.
+
+Eric Allman, 26 May 1993
diff --git a/usr.sbin/sendmail/contrib/bitdomain.c b/usr.sbin/sendmail/contrib/bitdomain.c
new file mode 100644
index 0000000..4fad761
--- /dev/null
+++ b/usr.sbin/sendmail/contrib/bitdomain.c
@@ -0,0 +1,409 @@
+/*
+ * By John G. Myers, jgm+@cmu.edu
+ * Version 1.1
+ *
+ * Process a BITNET "internet.listing" file, producing output
+ * suitable for input to makemap.
+ *
+ * The input file can be obtained via anonymous FTP to bitnic.educom.edu.
+ * Change directory to "netinfo" and get the file internet.listing
+ * The file is updated monthly.
+ *
+ * Feed the output of this program to "makemap hash /etc/bitdomain.db"
+ * to create the table used by the "FEATURE(bitdomain)" config file macro.
+ * If your sendmail does not have the db library compiled in, you can instead
+ * use "makemap dbm /etc/bitdomain" and
+ * "FEATURE(bitdomain,`dbm -o /etc/bitdomain')"
+ *
+ * The bitdomain table should be rebuilt monthly.
+ */
+
+#include <stdio.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <netinet/in.h>
+#include <arpa/nameser.h>
+#include <resolv.h>
+#include <netdb.h>
+#include <ctype.h>
+#include <string.h>
+
+/* don't use sizeof because sizeof(long) is different on 64-bit machines */
+#define SHORTSIZE 2 /* size of a short (really, must be 2) */
+#define LONGSIZE 4 /* size of a long (really, must be 4) */
+
+typedef union
+{
+ HEADER qb1;
+ char qb2[PACKETSZ];
+} querybuf;
+
+extern int h_errno;
+extern char *malloc();
+extern char *optarg;
+extern int optind;
+
+char *lookup();
+
+main(argc, argv)
+int argc;
+char **argv;
+{
+ int opt;
+
+ while ((opt = getopt(argc, argv, "o:")) != EOF) {
+ switch (opt) {
+ case 'o':
+ if (!freopen(optarg, "w", stdout)) {
+ perror(optarg);
+ exit(1);
+ }
+ break;
+
+ default:
+ fprintf(stderr, "usage: %s [-o outfile] [internet.listing]\n",
+ argv[0]);
+ exit(1);
+ }
+ }
+
+ if (optind < argc) {
+ if (!freopen(argv[optind], "r", stdin)) {
+ perror(argv[optind]);
+ exit(1);
+ }
+ }
+ readfile(stdin);
+ finish();
+ exit(0);
+}
+
+/*
+ * Parse and process an input file
+ */
+readfile(infile)
+FILE *infile;
+{
+ int skippingheader = 1;
+ char buf[1024], *node, *hostname, *p;
+
+ while (fgets(buf, sizeof(buf), infile)) {
+ for (p = buf; *p && isspace(*p); p++);
+ if (!*p) {
+ skippingheader = 0;
+ continue;
+ }
+ if (skippingheader) continue;
+
+ node = p;
+ for (; *p && !isspace(*p); p++) {
+ if (isupper(*p)) *p = tolower(*p);
+ }
+ if (!*p) {
+ fprintf(stderr, "%-8s: no domain name in input file\n", node);
+ continue;
+ }
+ *p++ = '\0';
+
+ for (; *p && isspace(*p); p++) ;
+ if (!*p) {
+ fprintf(stderr, "%-8s no domain name in input file\n", node);
+ continue;
+ }
+
+ hostname = p;
+ for (; *p && !isspace(*p); p++) {
+ if (isupper(*p)) *p = tolower(*p);
+ }
+ *p = '\0';
+
+ /* Chop off any trailing .bitnet */
+ if (strlen(hostname) > 7 &&
+ !strcmp(hostname+strlen(hostname)-7, ".bitnet")) {
+ hostname[strlen(hostname)-7] = '\0';
+ }
+ entry(node, hostname, sizeof(buf)-(hostname - buf));
+ }
+}
+
+/*
+ * Process a single entry in the input file.
+ * The entry tells us that "node" expands to "domain".
+ * "domain" can either be a domain name or a bitnet node name
+ * The buffer pointed to by "domain" may be overwritten--it
+ * is of size "domainlen".
+ */
+entry(node, domain, domainlen)
+char *node;
+char *domain;
+char *domainlen;
+{
+ char *otherdomain, *p, *err;
+
+ /* See if we have any remembered information about this node */
+ otherdomain = lookup(node);
+
+ if (otherdomain && strchr(otherdomain, '.')) {
+ /* We already have a domain for this node */
+ if (!strchr(domain, '.')) {
+ /*
+ * This entry is an Eric Thomas FOO.BITNET kludge.
+ * He doesn't want LISTSERV to do transitive closures, so we
+ * do them instead. Give the the domain expansion for "node"
+ * (which is in "otherdomian") to FOO (which is in "domain")
+ * if "domain" doesn't have a domain expansion already.
+ */
+ p = lookup(domain);
+ if (!p || !index(p, '.')) remember(domain, otherdomain);
+ }
+ }
+ else {
+ if (!strchr(domain, '.') || valhost(domain, domainlen)) {
+ remember(node, domain);
+ if (otherdomain) {
+ /*
+ * We previously mapped the node "node" to the node
+ * "otherdomain". If "otherdomain" doesn't already
+ * have a domain expansion, give it the expansion "domain".
+ */
+ p = lookup(otherdomain);
+ if (!p || !index(p, '.')) remember(otherdomain, domain);
+ }
+ }
+ else {
+ switch (h_errno) {
+ case HOST_NOT_FOUND:
+ err = "not registered in DNS";
+ break;
+
+ case TRY_AGAIN:
+ err = "temporary DNS lookup failure";
+ break;
+
+ case NO_RECOVERY:
+ err = "non-recoverable nameserver error";
+ break;
+
+ case NO_DATA:
+ err = "registered in DNS, but not mailable";
+ break;
+
+ default:
+ err = "unknown nameserver error";
+ break;
+ }
+
+ fprintf(stderr, "%-8s %s %s\n", node, domain, err);
+ }
+ }
+}
+
+/*
+ * Validate whether the mail domain "host" is registered in the DNS.
+ * If "host" is a CNAME, it is expanded in-place if the expansion fits
+ * into the buffer of size "hbsize". Returns nonzero if it is, zero
+ * if it is not. A BIND error code is left in h_errno.
+ */
+int
+valhost(host, hbsize)
+ char *host;
+ int hbsize;
+{
+ register u_char *eom, *ap;
+ register int n;
+ HEADER *hp;
+ querybuf answer;
+ int ancount, qdcount;
+ int ret;
+ int type;
+ int qtype;
+ char nbuf[1024];
+
+ if ((_res.options & RES_INIT) == 0 && res_init() == -1)
+ return (0);
+
+ _res.options &= ~(RES_DNSRCH|RES_DEFNAMES);
+ _res.retrans = 30;
+ _res.retry = 10;
+
+ qtype = T_ANY;
+
+ for (;;) {
+ h_errno = NO_DATA;
+ ret = res_querydomain(host, "", C_IN, qtype,
+ &answer, sizeof(answer));
+ if (ret <= 0)
+ {
+ if (errno == ECONNREFUSED || h_errno == TRY_AGAIN)
+ {
+ /* the name server seems to be down */
+ h_errno = TRY_AGAIN;
+ return 0;
+ }
+
+ if (h_errno != HOST_NOT_FOUND)
+ {
+ /* might have another type of interest */
+ if (qtype == T_ANY)
+ {
+ qtype = T_A;
+ continue;
+ }
+ else if (qtype == T_A)
+ {
+ qtype = T_MX;
+ continue;
+ }
+ }
+
+ /* otherwise, no record */
+ return 0;
+ }
+
+ /*
+ ** This might be a bogus match. Search for A, MX, or
+ ** CNAME records.
+ */
+
+ hp = (HEADER *) &answer;
+ ap = (u_char *) &answer + sizeof(HEADER);
+ eom = (u_char *) &answer + ret;
+
+ /* skip question part of response -- we know what we asked */
+ for (qdcount = ntohs(hp->qdcount); qdcount--; ap += ret + QFIXEDSZ)
+ {
+ if ((ret = dn_skipname(ap, eom)) < 0)
+ {
+ return 0; /* ???XXX??? */
+ }
+ }
+
+ for (ancount = ntohs(hp->ancount); --ancount >= 0 && ap < eom; ap += n)
+ {
+ n = dn_expand((u_char *) &answer, eom, ap,
+ (u_char *) nbuf, sizeof nbuf);
+ if (n < 0)
+ break;
+ ap += n;
+ GETSHORT(type, ap);
+ ap += SHORTSIZE + LONGSIZE;
+ GETSHORT(n, ap);
+ switch (type)
+ {
+ case T_MX:
+ case T_A:
+ return 1;
+
+ case T_CNAME:
+ /* value points at name */
+ if ((ret = dn_expand((u_char *)&answer,
+ eom, ap, (u_char *)nbuf, sizeof(nbuf))) < 0)
+ break;
+ if (strlen(nbuf) < hbsize) {
+ (void)strcpy(host, nbuf);
+ }
+ return 1;
+
+ default:
+ /* not a record of interest */
+ continue;
+ }
+ }
+
+ /*
+ ** If this was a T_ANY query, we may have the info but
+ ** need an explicit query. Try T_A, then T_MX.
+ */
+
+ if (qtype == T_ANY)
+ qtype = T_A;
+ else if (qtype == T_A)
+ qtype = T_MX;
+ else
+ return 0;
+ }
+}
+
+struct entry {
+ struct entry *next;
+ char *node;
+ char *domain;
+};
+struct entry *firstentry;
+
+/*
+ * Find any remembered information about "node"
+ */
+char *lookup(node)
+char *node;
+{
+ struct entry *p;
+
+ for (p = firstentry; p; p = p->next) {
+ if (!strcmp(node, p->node)) {
+ return p->domain;
+ }
+ }
+ return 0;
+}
+
+/*
+ * Mark the node "node" as equivalent to "domain". "domain" can either
+ * be a bitnet node or a domain name--if it is the latter, the mapping
+ * will be written to stdout.
+ */
+remember(node, domain)
+char *node;
+char *domain;
+{
+ struct entry *p;
+
+ if (strchr(domain, '.')) {
+ fprintf(stdout, "%-8s %s\n", node, domain);
+ }
+
+ for (p = firstentry; p; p = p->next) {
+ if (!strcmp(node, p->node)) {
+ p->domain = malloc(strlen(domain)+1);
+ if (!p->domain) {
+ goto outofmemory;
+ }
+ strcpy(p->domain, domain);
+ return;
+ }
+ }
+
+ p = (struct entry *)malloc(sizeof(struct entry));
+ if (!p) goto outofmemory;
+
+ p->next = firstentry;
+ firstentry = p;
+ p->node = malloc(strlen(node)+1);
+ p->domain = malloc(strlen(domain)+1);
+ if (!p->node || !p->domain) goto outofmemory;
+ strcpy(p->node, node);
+ strcpy(p->domain, domain);
+ return;
+
+ outofmemory:
+ fprintf(stderr, "Out of memory\n");
+ exit(1);
+}
+
+/*
+ * Walk through the database, looking for any cases where we know
+ * node FOO is equivalent to node BAR and node BAR has a domain name.
+ * For those cases, give FOO the same domain name as BAR.
+ */
+finish()
+{
+ struct entry *p;
+ char *domain;
+
+ for (p = firstentry; p; p = p->next) {
+ if (!strchr(p->domain, '.') && (domain = lookup(p->domain))) {
+ remember(p->node, domain);
+ }
+ }
+}
+
diff --git a/usr.sbin/sendmail/contrib/converting.sun.configs b/usr.sbin/sendmail/contrib/converting.sun.configs
new file mode 100644
index 0000000..0fcd919
--- /dev/null
+++ b/usr.sbin/sendmail/contrib/converting.sun.configs
@@ -0,0 +1,446 @@
+
+ Converting Standard Sun Config
+ Files to Sendmail Version 8
+
+ Rick McCarty
+ Texas Instruments Inc.
+ Latest Update: 08/25/93 - RJMc
+
+This document details the changes necessary to continue using your
+current SunOS sendmail.cf with sendmail version 8. In the longer term,
+it is recommended that one move to using an m4 based configuration such
+as those shipped with sendmail, but if you're like me and have made
+enough modifications to your .cf file that you'd rather put that task
+off until later, here's the sum total of my experience to get you to
+version 8 with minimal pain. I'll cover .cf as well as build issues.
+
+Some background - as many are surely aware, Sun has some "special"
+features in the sendmail they ship ($%x, %y LHS lookup, NIS alias DB
+search, etc.). (Some of those features can be had in alternative forms
+in IDA sendmail, but v8 has picked up some IDA capabilities as well as
+new ones, making it IMHO a most desirable version to go to.) What I
+will explain below includes v8 functional "equivalences" to these Sun
+sendmail features.
+
+So with that out of the way, let's begin.
+
+First, some assumptions:
+
+ 1) I'm going to assume you've got sendmail version 8.6 or
+ later in hand - if not, grab it from ftp.cs.berkeley.edu
+ in the ucb/sendmail directory. There are bugs in earlier
+ versions which affect some of the needed functionality.
+
+ 2) Second, I'm going to detail this based upon the
+ "sendmail.main.cf" configuration. (BTW, if you attempt
+ to move to using an m4 generated config in the future,
+ MAIL_HUB is the feature which should provide similar
+ functionality).
+
+ In general, the changes will be similar for a subsidiary
+ file, but since we (my TI group) funnel all non-local mail
+ through our mailhost, we're not as interested in getting v8
+ to run on such systems and I haven't tried it.
+
+ 3) You're using DNS and sendmail.mx. If you're not, you ought
+ to be, even if you're also running it along with NIS (which
+ we do - except for gethostbyxxx() lookups, which I'll be
+ talking about later). I would imagine you could get things
+ running OK without DNS support, but I haven't tried it myself.
+
+ 4) You're not mounting /var/spool/mail from other systems.
+ I haven't found a v8 feature to guarantee this will work
+ correctly. Anyway, in the past, we've tried doing that
+ here and found it to be a rather "ugly" feature, though
+ Sun ostensibly supports it ("R" option). Perhaps v8
+ will one day have a similar feature, but for now, bottom
+ line, I would recommend against it.
+
+ 5) You're not on Solaris or using NIS+. I'm on 4.1.3. I've
+ looked at Solaris briefly and have noted that things are
+ pretty much similar there except that they've moved some
+ things into the /etc/mail directory. I'd guess the
+ executables aren't functionally all that different from
+ what they had before - the configs are roughly the same.
+ So I'd bet most of what I say in here will apply to
+ Solaris.
+
+OK, let's configure our sendmail.cf! I'll just go from the top down...
+
+ VARIOUS DECLARATIONS
+
+1) For v8, you need to define your .cf as AT LEAST a version level 4
+ configuration. Add the following line:
+
+ V4
+
+ There are some issues regarding certain predefined macros - $w, $j, and
+ $m. With a V4 configuration:
+
+ $w is defined to be the hostname, which will usually be fully
+ qualified (i.e. "firefly.add.itg.ti.com").
+
+ $j should have the same value as $w.
+
+ $m will be predefined as the domain portion of $w
+ (ex. "add.itg.ti.com").
+
+ One note about this - if your configuration relies on the "w" macro to
+ be the "simple" hostname (as mine does)...
+
+ If the configuration version is 5 or larger:
+
+ $w is supposed to be the "simple" name (ex. "firefly")
+
+ $j should be the fully qualified name (i.e. "firefly.add.itg.ti.com")
+
+ $m will be predefined as the domain portion of $j
+ (ex. "add.itg.ti.com").
+
+ I have not experimented with the various combinations, so I cannot
+ guarantee you that the above definitions will always come out as
+ expected. Bottom line: if your sendmail.cf depends on $w being the
+ simple hostname, test it carefully or define the name explicitly,
+ for example:
+
+ Dwfirefly
+
+2) To replace the Sun's "%y" feature, we must use a hostname mapping
+ feature in v8. If you want to do similar lookups with v8, you need
+ to define the following map (we'll go over the rules that use this
+ map later):
+
+ Khostlookup host -f -m -a.
+
+ This will define a "lookup only" map that is otherwise the same as
+ sendmail version 8's built-in "host" map (see the "Sendmail
+ Installation and Operation Guide" for details on this map.).
+
+ An important note: Whether or not these lookups will be done via
+ NIS is a function of what gethostbyxxx() functions you link into
+ your sendmail. DO NOT redefine your host mapping to use NIS
+ explicitly within sendmail - there can be unexpected behaviour if
+ you do so (if you do any canonicalization in your .cf, you can get
+ incorrect results, for one thing).
+
+ For example, DO NOT TRY:
+
+ Khost nis -f -a. hosts.byname
+
+3) If you're doing reverse alias mapping as done in ruleset 22, instead of:
+
+ DZmail.byaddr
+
+ you'll need to declare the following:
+
+ Kaliasrev nis -f -N mail.byaddr
+
+4) If you are doing any other NIS map lookups, you'll need to define the
+ map as done in the below example. I have a "mailhosts" map, which I
+ use to distinguish between local and non-local hosts. Look at the
+ sendmail doc for details on this stuff.
+
+ Kmailhosts nis -f -m -a. mailhosts
+
+5) You might wish to add the following line to support Errors-To: headers.
+ I don't.
+
+ Ol
+
+6) Comment out/remove the following line:
+
+ OR
+
+ The R option means something different under v8 - check the documentation
+ if you're interested in using it.
+
+7) If you're running NIS and have a separate alias map, BELOW the
+ following line where the alias file is declared:
+
+ OA/etc/aliases
+
+ ADD the following:
+
+ OAnis:mail.aliases
+
+ This will set things up so v8 will look at the local alias DB first,
+ then the NIS map, just as Sun sendmail does.
+
+8) Though you don't have to, I'd suggest changing:
+
+ OT3d
+
+ to use v8's warning feature, which allows a warning message to be
+ sent if a message cannot be delivered within a specified period.
+ I use:
+
+ OT5d/4h
+
+ which says - bounce after 5 days, warn after 4 hours.
+
+9) I set the following option to be explicit about how I want DNS
+ handled:
+
+ OI +DNSRCH +DEFNAMES
+
+10) The following line:
+
+ T root daemon uucp
+
+ may be deleted, though it will be ignored if you leave it around.
+
+11) It would probably be good to change the version macro value (which
+ shows up in "Received:" headers) so no one debugging mail problems
+ gets the wrong idea about what config you're running under. Look
+ for something like:
+
+ DVSMI-4.1
+
+ Mine, for example is:
+
+ DVADD-HUB-2.1
+
+ RULESETS
+
+1) In ruleset 3, BELOW this rule:
+
+ # basic textual canonicalization
+ R$*<$+>$* $2 basic RFC822 parsing
+
+
+I add the following rule to remove a trailing dot in the domain spec so
+it won't interfere with v8 mapping features, etc. (Having a trailing dot is
+not RFC-compliant anyway.):
+
+ R$+. $1
+
+2) Because ruleset 5 is special in v8, I rename it to S95 and also change
+ all RHS expressions containing ">5" to use ">95" instead. In v8,
+ 5 is executed against addresses which resolve to the local mailer and
+ are not an alias. If you don't change S5 to something else, you might
+ get a surprise!
+
+3) If you're doing any lookups via the generalized NIS "$%x/$!x"
+ mechanisms (such as with the mailhost map I referred to earlier) it's
+ done differently under v8. For example:
+
+ DMmailhosts
+ ...
+ R$*<@$%M.uucp>$* $#ether $@$2 $:$1<@$2>$3
+
+ takes a different map definition and two rules under version 8:
+
+ Kmailhosts nis -f -m -a. mailhosts
+ ...
+ R$*<@$+.uucp>$* $: $1<@$(mailhosts $2 $).uucp>$3
+ R$*<@$+..uucp>$* $#ether $@$2 $:$1<@$2>$3
+
+4) Sun has a special case of the "$%x" feature for host lookups - "%y" is
+ automagically defined to do an NIS "hosts.byname" search with no other
+ definition, as done in the below example:
+
+ R$*<@$%y.LOCAL>$* $#ether $@$2 $:$1<@$2>$3
+
+ (Sun does this in more than one place. But the above syntax is almost
+ identical in each - mostly a case of changing names to protect the
+ innocent.)
+
+ In version 8, the predefined "host" map can be used to do essentially
+ the same thing. (However, whether or not it does an NIS lookup is
+ a function of what gethostbyxxx() functions are linked in.)
+
+ Recall the map definition I mentioned earlier in the DECLARATIONS
+ section:
+
+ Khostlookup host -f -m -a.
+
+ Here's where we will use it. It will take two rules:
+
+ R$*<@$+.LOCAL>$* $: $1<@$(hostlookup $2 $).LOCAL>$3
+ R$*<@$+..LOCAL>$* $#ether $@$2 $:$1<@$2>$3
+
+ Note that this is almost verbatim the same change as was used in the
+ previous "mailhosts" example.
+
+5) Although Sun's default configs don't do this, because I mentioned
+ canonicalization earlier, it deserves an example, as it's illustrative
+ of the functional difference in the map definitions I discussed before.
+ This stuff is also convered in the "Sendmail Installation and Operation
+ Guide".
+
+ Remember the built-in "host" map definition? As you'll recall, unlike
+ the "hostlookup" map we defined, "host" will actually CHANGE the
+ hostname in addition to appending a dot. "hostlookup" only appends a
+ dot if the name is found and doesn't change it otherwise. Anyway,
+ here's the example:
+
+ R$*<@$+>$* $: $1<@$(host $2 $)>$3 canonicalize
+ R$*<@$+.>$* $1<@$2>$3 remove trailing dot
+
+ Using the above, say you had input of:
+
+ joe<@tilde>
+
+ OR
+
+ joe<@[128.247.160.56]>
+
+ Assuming "tilde" or the IP address is found, it might be
+ canonicalized as:
+
+ joe<@tilde.csc.ti.com>
+
+6) As another instance of the NIS lookup feature, with a slightly
+ different twist, Sun implements reverse alias mapping in ruleset 22
+ with the below:
+
+ DZmail.byaddr
+ ...
+ R$-<@$-> $:$>3${Z$1@$2$} invert aliases
+
+ To use this feature under v8, change the above rule a (remember to
+ define the alias map as I showed earlier):
+
+ R$-<@$-> $:$>3$(aliasrev $1@$2 $) invert aliases
+
+
+ MAILER DEFINITIONS
+
+1) Where "TCP" is defined in the "P=" and "A=" parameters of mailers, I
+ changed it to "IPC". Version 8 will accept "TCP", but "IPC" is
+ preferred.
+
+2) On all IPC mailers, I also defined "E=\r\n" and added an "L=1000" as
+ in the below example:
+
+ Mether, P=[IPC], F=mDFMuCX, S=11, R=21, L=1000, E=\r\n, A=IPC $h
+
+ The "E=\r\n" will save you headaches interoperating with such things as
+ VMS TCP products.
+
+ The "L=1000" is for RFC821 compatibility. Not strictly necessary.
+
+ I also removed the "s" (strip quotes) mailer flag Sun puts in for
+ these mailers. Stripping quotes violates protocols, which say
+ clearly that you can't touch the local-part (left hand side of
+ the @) until you are on the delivering host.
+
+NOW. If I haven't left anything out, you should be able to run through
+your Sun sendmail.cf file and convert it to run under v8.
+
+ BUILD ISSUES
+
+Some important notes on building v8 on SunOS:
+
+Makefile
+
+The default makefile in the version 8 source (src) directory assumes the
+new Berkeley make. Unless you want to go to the trouble of building it,
+you can use your regular make, but you need to use a different makefile.
+You can use "Makefile.dist" or "Makefile.SunOS" in the src directory. I
+made changes to get it to build so it is as compatible as possible with
+the file/directory locations Sun uses. Here are some relevant sections
+out of my makefile:
+
+ CC=gcc
+
+ # use O=-O (usual) or O=-g (debugging)
+ O= -O
+
+ # define the database mechanisms available for map & alias lookups:
+ # -DNDBM -- use new DBM
+ # -DNEWDB -- use new Berkeley DB
+ # -DNDBM -DNEWDB -DYPCOMPAT -- use both plus YP compatility
+ # -DNIS -- include client NIS support
+ # The really old (V7) DBM library is no longer supported.
+ # See READ_ME for a description of how these flags interact.
+ #DBMDEF= -DNDBM -DNEWDB
+ DBMDEF= -DNDBM -DNIS
+
+ # environment definitions (e.g., -D_AIX3)
+ ENVDEF=
+
+ # see also conf.h for additional compilation flags
+
+ # library directories
+ LIBDIRS=-L/usr/local/lib
+
+ # libraries required on your system
+ #LIBS= -ldb -ldbm
+ LIBS= -ldbm -lresolv
+
+ # location of sendmail binary (usually /usr/sbin or /usr/lib)
+ BINDIR= ${DESTDIR}/usr/lib
+
+ # location of sendmail.st file (usually /var/log or /usr/lib)
+ STDIR= ${DESTDIR}/etc
+
+ # location of sendmail.hf file (usually /usr/share/misc or /usr/lib)
+ HFDIR= ${DESTDIR}/usr/lib
+
+For the resolver library, you can use the one shipped with Sun if you
+want. But I'd recommend using another version of the resolver library
+(such as the one with Bind 4.8.3 or 4.9). Sun's resolver stuff (at
+least with 4.1.x) is quite old - I believe it is of 4.3.1 vintage. (Do
+you get the impression I don't TRUST what Sun ships with their systems?)
+
+If you want NIS host lookup while maintaining DNS capability, you might
+take a look at resolv+, which has NIS capable gethostbyxxx() functions
+in it. My recommendation, however, is to avoid doing NIS host lookups
+in sendmail altogether, and to use a "pure" version of the resolver
+library.
+
+There are probably no situations (at least I think so) where it makes
+any sense to link in Sun's NIS gethostbyxxx() functions from libc.
+You could, I guess do it (I haven't tried it) and wind up with a
+sendmail equivalent to the non-mx version Sun ships. You'd need to
+insure that NAMED_BIND is not defined in the build. (If you do
+this and have the "-b" DNS passthru option set in NIS, remember that
+while you have some DNS functionality you'll not have any MX support.
+(This, IMO, is what makes this a non-optimal choice.)
+
+ INSTALLATION/TESTING ISSUES
+
+The sendmail.hf file in the src directory should replace the one currently
+in /usr/lib. You also might choose to edit it a bit to "localize" what it
+says.
+
+The sendmail executable goes, of course, in /usr/lib in place of the current
+one. What I did was create a subdirectory in /usr/lib and put all of the
+Sun sendmail stuff in there. I named the v8 sendmail executable to be
+sendmail.v8.mx and then symbolically linked it to sendmail.
+
+One other thing. If you use address test mode, keep in mind that
+Version 8 is like IDA in that it does not automatically execute ruleset
+3 first. So say you're playing around with things testing addresses and
+you're used to things like:
+
+ 0 jimbob@good.old.boy.com
+
+under v8 you need to say instead:
+
+ 3,0 jimbob@good.old.boy.com
+
+ INTEROPERABILITY ISSUES YOU MIGHT ENCOUNTER
+
+Be aware that sendmail v8 issues a multi-line SMTP welcome (220)
+response upon a client connection. Most systems in your network should
+handle it OK, but there are some that choke on it, because whoever wrote
+the clients assumed only a single line. THIS IS NOT SENDMAIL's FAULT.
+A multi-line 220 response is perfectly valid. A likely place you'll
+encounter this problem is with non-Un*x SMTP clients. If you do run
+into it, you should report it to the vendor.
+
+A final note about version 8 - if you follow the above configuration
+scenario, you'll notice it doesn't like to get envelope sender
+addresses it doesn't know how to get back to. Sun sendmail would take
+anything, even though it might not be able to bounce the message back
+should something happen downstream. So if another sendmail on a host
+that's not locally known is trying to pump mail through your v8 host,
+the ENVELOPE sender it gives had better be fully qualified. This is
+a GREAT thing, because it helps clear up problems we've had with not
+being able to get things back to the sender, resulting in an
+overburdened postmaster.
+
+I hope this helps those running Sun sendmail feel more at ease with moving
+on to v8. It's really worth going to.
diff --git a/usr.sbin/sendmail/contrib/expn.pl b/usr.sbin/sendmail/contrib/expn.pl
new file mode 100755
index 0000000..495db73
--- /dev/null
+++ b/usr.sbin/sendmail/contrib/expn.pl
@@ -0,0 +1,1365 @@
+#!/usr/local/bin/perl
+'di ';
+'ds 00 \\"';
+'ig00 ';
+#
+# THIS PROGRAM IS ITS OWN MANUAL PAGE. INSTALL IN man & bin.
+#
+
+# hardcoded constants, should work fine for BSD-based systems
+$AF_INET = 2;
+$SOCK_STREAM = 1;
+$sockaddr = 'S n a4 x8';
+
+# system requirements:
+# must have 'nslookup' and 'hostname' programs.
+
+# $Header: /home/muir/bin/RCS/expn,v 3.6 1994/02/23 22:26:19 muir Exp muir $
+
+# TODO:
+# less magic should apply to command-line addresses
+# less magic should apply to local addresses
+# add magic to deal with cross-domain cnames
+
+# Checklist: (hard addresses)
+# 250 Kimmo Suominen <"|/usr/local/mh/lib/slocal -user kim"@grendel.tac.nyc.ny.us>
+# harry@hofmann.cs.Berkeley.EDU -> harry@tenet (.berkeley.edu) [dead]
+# bks@cs.berkeley.edu -> shiva.CS (.berkeley.edu) [dead]
+# dan@tc.cornell.edu -> brown@tiberius (.tc.cornell.edu)
+
+#############################################################################
+#
+# Copyright (c) 1993 David Muir Sharnoff
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+# 3. All advertising materials mentioning features or use of this software
+# must display the following acknowledgement:
+# This product includes software developed by the David Muir Sharnoff.
+# 4. The name of David Sharnoff may not be used to endorse or promote products
+# derived from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE DAVID MUIR SHARNOFF ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL DAVID MUIR SHARNOFF BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+#
+# This copyright notice derrived from material copyrighted by the Regents
+# of the University of California.
+#
+# Contributions accepted.
+#
+#############################################################################
+
+# overall structure:
+# in an effort to not trace each address individually, but rather
+# ask each server in turn a whole bunch of questions, addresses to
+# be expanded are queued up.
+#
+# This means that all account w.r.t. an address must be stored in
+# various arrays. Generally these arrays are indexed by the
+# string "$addr *** $server" where $addr is the address to be
+# expanded "foo" or maybe "foo@bar" and $server is the hostname
+# of the SMTP server to contact.
+#
+
+# important global variables:
+#
+# @hosts : list of servers still to be contacted
+# $server : name of the current we are currently looking at
+# @users = $users{@hosts[0]} : addresses to expand at this server
+# $u = $users[0] : the current address being expanded
+# $names{"$users[0] *** $server"} : the 'name' associated with the address
+# $mxbacktrace{"$users[0] *** $server"} : record of mx expansion
+# $mx_secondary{$server} : other mx relays at the same priority
+# $domainify_fallback{"$users[0] *** $server"} : alternative names to try
+# instead of $server if $server doesn't work
+# $temporary_redirect{"$users[0] *** $server"} : when trying alternates,
+# temporarily channel all tries along current path
+# $giveup{$server} : do not bother expanding addresses at $server
+# $verbose : -v
+# $watch : -w
+# $vw : -v or -w
+# $debug : -d
+# $valid : -a
+# $levels : -1
+# S : the socket connection to $server
+
+$have_nslookup = 1; # we have the nslookup program
+$port = 'smtp';
+$av0 = $0;
+$0 = "$av0 - running hostname";
+$ENV{'PATH'} .= ":/usr/etc" unless $ENV{'PATH'} =~ m,/usr/etc,;
+chop($hostname = `hostname`);
+select(STDERR);
+
+$usage = "Usage: $av0 [-1avwd] user[@host] [user2[host2] ...]";
+$0 = "$av0 - parsing args";
+for $a (@ARGV) {
+ die $usage if $a eq "-";
+ while ($a =~ s/^(-.*)([1avwd])/$1/) {
+ eval '$'."flag_$2 += 1";
+ }
+ next if $a eq "-";
+ die $usage if $a =~ /^-/;
+ &expn(&parse($a,$hostname,undef,1));
+}
+$verbose = $flag_v;
+$watch = $flag_w;
+$vw = $flag_v + $flag_w;
+$debug = $flag_d;
+$valid = $flag_a;
+$levels = $flag_1;
+
+die $usage unless @hosts;
+if ($valid) {
+ if ($valid == 1) {
+ $validRequirement = 0.8;
+ } elsif ($valid == 2) {
+ $validRequirement = 1.0;
+ } elsif ($valid == 3) {
+ $validRequirement = 0.9;
+ } else {
+ $validRequirement = (1 - (1/($valid-3)));
+ print "validRequirement = $validRequirement\n" if $debug;
+ }
+}
+
+$0 = "$av0 - building local socket";
+($name,$aliases,$proto) = getprotobyname('tcp');
+($name,$aliases,$port) = getservbyname($port,'tcp')
+ unless $port =~ /^\d+/;
+($name,$aliases,$type,$len,$thisaddr) = gethostbyname($hostname);
+$this = pack($sockaddr, $AF_INET, 0, $thisaddr);
+
+HOST:
+while (@hosts) {
+ $server = shift(@hosts);
+ @users = split(' ',$users{$server});
+ delete $users{$server};
+
+ # is this server already known to be bad?
+ $0 = "$av0 - looking up $server";
+ if ($giveup{$server}) {
+ &giveup('mx domainify',$giveup{$server});
+ next;
+ }
+
+ # do we already have an mx record for this host?
+ next HOST if &mxredirect($server,*users);
+
+ # look it up, or try for an mx.
+ $0 = "$av0 - gethostbyname($server)";
+
+ ($name,$aliases,$type,$len,$thataddr) = gethostbyname($server);
+ # if we can't get an A record, try for an MX record.
+ unless($thataddr) {
+ &mxlookup(1,$server,"$server: could not resolve name",*users);
+ next HOST;
+ }
+
+ # get a connection, or look for an mx
+ $0 = "$av0 - socket to $server";
+ $that = pack($sockaddr, $AF_INET, $port, $thataddr);
+ socket(S, $AF_INET, $SOCK_STREAM, $proto)
+ || die "socket: $!";
+ $0 = "$av0 - bind to $server";
+ bind(S, $this)
+ || die "bind $hostname,0: $!";
+ $0 = "$av0 - connect to $server";
+ print "debug = $debug server = $server\n" if $debug > 8;
+ if (! connect(S, $that) || ($debug == 10 && $server =~ /relay\d.UU.NET$/i)) {
+ $0 = "$av0 - $server: could not connect: $!\n";
+ $emsg = $!;
+ unless (&mxlookup(0,$server,"$server: could not connect: $!",*users)) {
+ &giveup('mx',"$server: Could not connect: $emsg");
+ }
+ next HOST;
+ }
+ select((select(S),$| = 1)[0]); # don't buffer output to S
+
+ # read the greeting
+ $0 = "$av0 - talking to $server";
+ &alarm("greeting with $server",'');
+ while(<S>) {
+ alarm(0);
+ print if $watch;
+ if (/^(\d+)([- ])/) {
+ if ($1 != 220) {
+ $0 = "$av0 - bad numeric responce from $server";
+ &alarm("giving up after bet responce from $server",'');
+ &read_response($2,$watch);
+ alarm(0);
+ print STDERR "$server: NOT 220 greeting: $_"
+ if ($debug || $vw);
+ if (&mxlookup(0,$server,"$server: did not respond with a 220 greeting",*users)) {
+ close(S);
+ next HOST;
+ }
+ }
+ last if ($2 eq " ");
+ } else {
+ $0 = "$av0 - bad responce from $server";
+ print STDERR "$server: NOT 220 greeting: $_"
+ if ($debug || $vw);
+ unless (&mxlookup(0,$server,"$server: did not respond with SMTP codes",*users)) {
+ &giveup('',"$server: did not talk SMTP");
+ }
+ close(S);
+ next HOST;
+ }
+ &alarm("greeting with $server",'');
+ }
+ alarm(0);
+
+ # if this causes problems, remove it
+ $0 = "$av0 - sending helo to $server";
+ &alarm("sending helo to $server","");
+ &ps("helo $hostname");
+ while(<S>) {
+ print if $watch;
+ last if /^\d+ /;
+ }
+ alarm(0);
+
+ # try the users, one by one
+ USER:
+ while(@users) {
+ $u = shift(@users);
+ $0 = "$av0 - expanding $u [\@$server]";
+
+ # do we already have a name for this user?
+ $oldname = $names{"$u *** $server"};
+
+ print &compact($u,$server)." ->\n" if ($verbose && ! $valid);
+ if ($valid) {
+ #
+ # when running with -a, we delay taking any action
+ # on the results of our query until we have looked
+ # at the complete output. @toFinal stores expansions
+ # that will be final if we take them. @toExpn stores
+ # expnansions that are not final. @isValid keeps
+ # track of our ability to send mail to each of the
+ # expansions.
+ #
+ @isValid = ();
+ @toFinal = ();
+ @toExpn = ();
+ }
+
+ ($ecode,@expansion) = &expn_vrfy($u,$server);
+ if ($ecode) {
+ &giveup('',$ecode,$u);
+ last USER;
+ }
+
+ for $s (@expansion) {
+ $s =~ s/[\n\r]//g;
+ $0 = "$av0 - parsing $server: $s";
+
+ $skipwatch = $watch;
+
+ if ($s =~ /^[25]51([- ]).*<(.+)>/) {
+ print "$s" if $watch;
+ print "(pretending 250$1<$2>)" if ($debug && $watch);
+ print "\n" if $watch;
+ $s = "250$1<$2>";
+ $skipwatch = 0;
+ }
+
+ if ($s =~ /^250([- ])(.+)/) {
+ print "$s\n" if $skipwatch;
+ ($done,$addr) = ($1,$2);
+ ($newhost, $newaddr, $newname) = &parse($addr,$server,$oldname, $#expansion == 0);
+ print "($newhost, $newaddr, $newname) = &parse($addr, $server, $oldname)\n" if $debug;
+ if (! $newhost) {
+ # no expansion is possible w/o a new server to call
+ if ($valid) {
+ push(@isValid, &validAddr($newaddr));
+ push(@toFinal,$newaddr,$server,$newname);
+ } else {
+ &verbose(&final($newaddr,$server,$newname));
+ }
+ } else {
+ $newmxhost = &mx($newhost,$newaddr);
+ print "$newmxhost = &mx($newhost)\n"
+ if ($debug && $newhost ne $newmxhost);
+ $0 = "$av0 - parsing $newaddr [@$newmxhost]";
+ print "levels = $levels, level{$u *** $server} = ".$level{"$u *** $server"}."\n" if ($debug > 1);
+ # If the new server is the current one,
+ # it would have expanded things for us
+ # if it could have. Mx records must be
+ # followed to compare server names.
+ # We are also done if the recursion
+ # count has been exceeded.
+ if (&trhost($newmxhost) eq &trhost($server) || ($levels && $level{"$u *** $server"} >= $levels)) {
+ if ($valid) {
+ push(@isValid, &validAddr($newaddr));
+ push(@toFinal,$newaddr,$newmxhost,$newname);
+ } else {
+ &verbose(&final($newaddr,$newmxhost,$newname));
+ }
+ } else {
+ # more work to do...
+ if ($valid) {
+ push(@isValid, &validAddr($newaddr));
+ push(@toExpn,$newmxhost,$newaddr,$newname,$level{"$u *** $server"});
+ } else {
+ &verbose(&expn($newmxhost,$newaddr,$newname,$level{"$u *** $server"}));
+ }
+ }
+ }
+ last if ($done eq " ");
+ next;
+ }
+ # 550 is a known code... Should the be
+ # included in -a output? Might be a bug
+ # here. Does it matter? Can assume that
+ # there won't be UNKNOWN USER responces
+ # mixed with valid users?
+ if ($s =~ /^(550)([- ])/) {
+ if ($valid) {
+ print STDERR "\@$server:$u ($oldname) USER UNKNOWN\n";
+ } else {
+ &verbose(&final($u,$server,$oldname,"USER UNKNOWN"));
+ }
+ last if ($2 eq " ");
+ next;
+ }
+ # 553 is a known code...
+ if ($s =~ /^(553)([- ])/) {
+ if ($valid) {
+ print STDERR "\@$server:$u ($oldname) USER AMBIGUOUS\n";
+ } else {
+ &verbose(&final($u,$server,$oldname,"USER AMBIGUOUS"));
+ }
+ last if ($2 eq " ");
+ next;
+ }
+ # 252 is a known code...
+ if ($s =~ /^(252)([- ])/) {
+ if ($valid) {
+ print STDERR "\@$server:$u ($oldname) REFUSED TO VRFY\n";
+ } else {
+ &verbose(&final($u,$server,$oldname,"REFUSED TO VRFY"));
+ }
+ last if ($2 eq " ");
+ next;
+ }
+ &giveup('',"$server: did not grok '$s'",$u);
+ last USER;
+ }
+
+ if ($valid) {
+ #
+ # now we decide if we are going to take these
+ # expansions or roll them back.
+ #
+ $avgValid = &average(@isValid);
+ print "avgValid = $avgValid\n" if $debug;
+ if ($avgValid >= $validRequirement) {
+ print &compact($u,$server)." ->\n" if $verbose;
+ while (@toExpn) {
+ &verbose(&expn(splice(@toExpn,0,4)));
+ }
+ while (@toFinal) {
+ &verbose(&final(splice(@toFinal,0,3)));
+ }
+ } else {
+ print "Tossing some valid to avoid invalid ".&compact($u,$server)."\n" if ($avgValid > 0.0 && ($vw || $debug));
+ print &compact($u,$server)." ->\n" if $verbose;
+ &verbose(&final($u,$server,$newname));
+ }
+ }
+ }
+
+ &alarm("sending 'quit' to $server",'');
+ $0 = "$av0 - sending 'quit' to $server";
+ &ps("quit");
+ while(<S>) {
+ print if $watch;
+ last if /^\d+ /;
+ }
+ close(S);
+ alarm(0);
+}
+
+$0 = "$av0 - printing final results";
+print "----------\n" if $vw;
+select(STDOUT);
+for $f (sort @final) {
+ print "$f\n";
+}
+unlink("/tmp/expn$$");
+exit(0);
+
+
+# abandon all attempts deliver to $server
+# register the current addresses as the final ones
+sub giveup
+{
+ local($redirect_okay,$reason,$user) = @_;
+ local($us,@so,$nh,@remaining_users);
+
+ $0 = "$av0 - giving up on $server: $reason";
+ #
+ # add back a user if we gave up in the middle
+ #
+ push(@users,$user) if $user;
+ #
+ # don't bother with this system anymore
+ #
+ unless ($giveup{$server}) {
+ $giveup{$server} = $reason;
+ print STDERR "$reason\n";
+ }
+ print "Giveup!!! redirect okay = $redirect_okay; $reason\n" if $debug;
+ #
+ # Wait!
+ # Before giving up, see if there is a chance that
+ # there is another host to redirect to!
+ # (Kids, don't do this at home! Hacking is a dangerous
+ # crime and you could end up behind bars.)
+ #
+ for $u (@users) {
+ if ($redirect_okay =~ /\bmx\b/) {
+ next if &try_fallback('mx',$u,*server,
+ *mx_secondary,
+ *already_mx_fellback);
+ }
+ if ($redirect_okay =~ /\bdomainify\b/) {
+ next if &try_fallback('domainify',$u,*server,
+ *domainify_fallback,
+ *already_domainify_fellback);
+ }
+ push(@remaining_users,$u);
+ }
+ @users = @remaining_users;
+ for $u (@users) {
+ print &compact($u,$server)." ->\n" if ($verbose && $valid && $u);
+ &verbose(&final($u,$server,$names{"$u *** $server"},$reason));
+ }
+}
+#
+# This routine is used only within &giveup. It checks to
+# see if we really have to giveup or if there is a second
+# chance because we did something before that can be
+# backtracked.
+#
+# %fallback{"$user *** $host"} tracks what is able to fallback
+# %fellback{"$user *** $host"} tracks what has fallen back
+#
+# If there is a valid backtrack, then queue up the new possibility
+#
+sub try_fallback
+{
+ local($method,$user,*host,*fall_table,*fellback) = @_;
+ local($us,$fallhost,$oldhost,$ft,$i);
+
+ if ($debug > 8) {
+ print "Fallback table $method:\n";
+ for $i (sort keys %fall_table) {
+ print "\t'$i'\t\t'$fall_table{$i}'\n";
+ }
+ print "Fellback table $method:\n";
+ for $i (sort keys %fellback) {
+ print "\t'$i'\t\t'$fellback{$i}'\n";
+ }
+ print "U: $user H: $host\n";
+ }
+
+ $us = "$user *** $host";
+ if (defined $fellback{$us}) {
+ #
+ # Undo a previous fallback so that we can try again
+ # Nest fallbacks are avoided because they could
+ # lead to infinite loops
+ #
+ $fallhost = $fellback{$us};
+ print "Already $method fell back from $us -> \n" if $debug;
+ $us = "$user *** $fallhost";
+ $oldhost = $fallhost;
+ } elsif (($method eq 'mx') && (defined $mxbacktrace{$us}) && (defined $mx_secondary{$mxbacktrace{$us}})) {
+ print "Fallback an MX expansion $us -> \n" if $debug;
+ $oldhost = $mxbacktrace{$us};
+ } else {
+ print "Oldhost($host, $us) = " if $debug;
+ $oldhost = $host;
+ }
+ print "$oldhost\n" if $debug;
+ if (((defined $fall_table{$us}) && ($ft = $us)) || ((defined $fall_table{$oldhost}) && ($ft = $oldhost))) {
+ print "$method Fallback = ".$fall_table{$ft}."\n" if $debug;
+ local(@so,$newhost);
+ @so = split(' ',$fall_table{$ft});
+ $newhost = shift(@so);
+ print "Falling back ($method) $us -> $newhost (from $oldhost)\n" if $debug;
+ if ($method eq 'mx') {
+ if (! defined ($mxbacktrace{"$user *** $newhost"})) {
+ if (defined $mxbacktrace{"$user *** $oldhost"}) {
+ print "resetting oldhost $oldhost to the original: " if $debug;
+ $oldhost = $mxbacktrace{"$user *** $oldhost"};
+ print "$oldhost\n" if $debug;
+ }
+ $mxbacktrace{"$user *** $newhost"} = $oldhost;
+ print "mxbacktrace $user *** $newhost -> $oldhost\n" if $debug;
+ }
+ $mx{&trhost($oldhost)} = $newhost;
+ } else {
+ $temporary_redirect{$us} = $newhost;
+ }
+ if (@so) {
+ print "Can still $method $us: @so\n" if $debug;
+ $fall_table{$ft} = join(' ',@so);
+ } else {
+ print "No more fallbacks for $us\n" if $debug;
+ delete $fall_table{$ft};
+ }
+ if (defined $create_host_backtrack{$us}) {
+ $create_host_backtrack{"$user *** $newhost"}
+ = $create_host_backtrack{$us};
+ }
+ $fellback{"$user *** $newhost"} = $oldhost;
+ &expn($newhost,$user,$names{$us},$level{$us});
+ return 1;
+ }
+ delete $temporary_redirect{$us};
+ $host = $oldhost;
+ return 0;
+}
+# return 1 if you could send mail to the address as is.
+sub validAddr
+{
+ local($addr) = @_;
+ $res = &do_validAddr($addr);
+ print "validAddr($addr) = $res\n" if $debug;
+ $res;
+}
+sub do_validAddr
+{
+ local($addr) = @_;
+ local($urx) = "[-A-Za-z_.0-9+]+";
+
+ # \u
+ return 0 if ($addr =~ /^\\/);
+ # ?@h
+ return 1 if ($addr =~ /.\@$urx$/);
+ # @h:?
+ return 1 if ($addr =~ /^\@$urx\:./);
+ # h!u
+ return 1 if ($addr =~ /^$urx!./);
+ # u
+ return 1 if ($addr =~ /^$urx$/);
+ # ?
+ print "validAddr($addr) = ???\n" if $debug;
+ return 0;
+}
+# Some systems use expn and vrfy interchangeably. Some only
+# implement one or the other. Some check expn against mailing
+# lists and vrfy against users. It doesn't appear to be
+# consistent.
+#
+# So, what do we do? We try everything!
+#
+#
+# Ranking of result codes: good: 250, 251/551, 252, 550, anything else
+#
+# Ranking of inputs: best: user@host.domain, okay: user
+#
+# Return value: $error_string, @responces_from_server
+sub expn_vrfy
+{
+ local($u,$server) = @_;
+ local(@c) = ('expn', 'vrfy');
+ local(@try_u) = $u;
+ local(@ret,$code);
+
+ if (($u =~ /(.+)@(.+)/) && (&trhost($2) eq &trhost($server))) {
+ push(@try_u,$1);
+ }
+
+ TRY:
+ for $c (@c) {
+ for $try_u (@try_u) {
+ &alarm("$c'ing $try_u on $server",'',$u);
+ &ps("$c $try_u");
+ alarm(0);
+ $s = <S>;
+ if ($s eq '') {
+ return "$server: lost connection";
+ }
+ if ($s !~ /^(\d+)([- ])/) {
+ return "$server: garbled reply to '$c $try_u'";
+ }
+ if ($1 == 250) {
+ $code = 250;
+ @ret = ("",$s);
+ push(@ret,&read_response($2,$debug));
+ return @ret;
+ }
+ if ($1 == 551 || $1 == 251) {
+ $code = $1;
+ @ret = ("",$s);
+ push(@ret,&read_response($2,$debug));
+ next;
+ }
+ if ($1 == 252 && ($code == 0 || $code == 550)) {
+ $code = 252;
+ @ret = ("",$s);
+ push(@ret,&read_response($2,$watch));
+ next;
+ }
+ if ($1 == 550 && $code == 0) {
+ $code = 550;
+ @ret = ("",$s);
+ push(@ret,&read_response($2,$watch));
+ next;
+ }
+ &read_response($2,$watch);
+ }
+ }
+ return "$server: expn/vrfy not implemented" unless @ret;
+ return @ret;
+}
+# sometimes the old parse routine (now parse2) didn't
+# reject funky addresses.
+sub parse
+{
+ local($oldaddr,$server,$oldname,$one_to_one) = @_;
+ local($newhost, $newaddr, $newname, $um) = &parse2($oldaddr,$server,$oldname,$one_to_one);
+ if ($newaddr =~ m,^["/],) {
+ return (undef, $oldaddr, $newname) if $valid;
+ return (undef, $um, $newname);
+ }
+ return ($newhost, $newaddr, $newname);
+}
+
+# returns ($new_smtp_server,$new_address,$new_name)
+# given a responce from a SMTP server ($newaddr), the
+# current host ($server), the old "name" and a flag that
+# indicates if it is being called during the initial
+# command line parsing ($parsing_args)
+sub parse2
+{
+ local($newaddr,$context_host,$old_name,$parsing_args) = @_;
+ local(@names) = $old_name;
+ local($urx) = "[-A-Za-z_.0-9+]+";
+ local($unmangle);
+
+ #
+ # first, separate out the address part.
+ #
+
+ #
+ # [NAME] <ADDR [(NAME)]>
+ # [NAME] <[(NAME)] ADDR
+ # ADDR [(NAME)]
+ # (NAME) ADDR
+ # [(NAME)] <ADDR>
+ #
+ if ($newaddr =~ /^\<(.*)\>$/) {
+ print "<A:$1>\n" if $debug;
+ $newaddr = &trim($1);
+ print "na = $newaddr\n" if $debug;
+ }
+ if ($newaddr =~ /^([^\<\>]*)\<([^\<\>]*)\>([^\<\>]*)$/) {
+ # address has a < > pair in it.
+ print "N:$1 <A:$2> N:$3\n" if $debug;
+ $newaddr = &trim($2);
+ unshift(@names, &trim($3,$1));
+ print "na = $newaddr\n" if $debug;
+ }
+ if ($newaddr =~ /^([^\(\)]*)\(([^\(\)]*)\)([^\(\)]*)$/) {
+ # address has a ( ) pair in it.
+ print "A:$1 (N:$2) A:$3\n" if $debug;
+ unshift(@names,&trim($2));
+ local($f,$l) = (&trim($1),&trim($3));
+ if (($f && $l) || !($f || $l)) {
+ # address looks like:
+ # foo (bar) baz or (bar)
+ # not allowed!
+ print STDERR "Could not parse $newaddr\n" if $vw;
+ return(undef,$newaddr,&firstname(@names));
+ }
+ $newaddr = $f if $f;
+ $newaddr = $l if $l;
+ print "newaddr now = $newaddr\n" if $debug;
+ }
+ #
+ # @foo:bar
+ # j%k@l
+ # a@b
+ # b!a
+ # a
+ #
+ $unmangle = $newaddr;
+ if ($newaddr =~ /^\@($urx)\:(.+)$/) {
+ print "(\@:)" if $debug;
+ # this is a bit of a cheat, but it seems necessary
+ return (&domainify($1,$context_host,$2),$2,&firstname(@names),$unmangle);
+ }
+ if ($newaddr =~ /^(.+)\@($urx)$/) {
+ print "(\@)" if $debug;
+ return (&domainify($2,$context_host,$newaddr),$newaddr,&firstname(@names),$unmangle);
+ }
+ if ($parsing_args) {
+ if ($newaddr =~ /^($urx)\!(.+)$/) {
+ return (&domainify($1,$context_host,$newaddr),$newaddr,&firstname(@names),$unmangle);
+ }
+ if ($newaddr =~ /^($urx)$/) {
+ return ($context_host,$newaddr,&firstname(@names),$unmangle);
+ }
+ print STDERR "Could not parse $newaddr\n";
+ }
+ print "(?)" if $debug;
+ return(undef,$newaddr,&firstname(@names),$unmangle);
+}
+# return $u (@$server) unless $u includes reference to $server
+sub compact
+{
+ local($u, $server) = @_;
+ local($se) = $server;
+ local($sp);
+ $se =~ s/(\W)/\\$1/g;
+ $sp = " (\@$server)";
+ if ($u !~ /$se/i) {
+ return "$u$sp";
+ }
+ return $u;
+}
+# remove empty (spaces don't count) members from an array
+sub trim
+{
+ local(@v) = @_;
+ local($v,@r);
+ for $v (@v) {
+ $v =~ s/^\s+//;
+ $v =~ s/\s+$//;
+ push(@r,$v) if ($v =~ /\S/);
+ }
+ return(@r);
+}
+# using the host part of an address, and the server name, add the
+# servers' domain to the address if it doesn't already have a
+# domain. Since this sometimes failes, save a back reference so
+# it can be unrolled.
+sub domainify
+{
+ local($host,$domain_host,$u) = @_;
+ local($domain,$newhost);
+
+ # cut of trailing dots
+ $host =~ s/\.$//;
+ $domain_host =~ s/\.$//;
+
+ if ($domain_host !~ /\./) {
+ #
+ # domain host isn't, keep $host whatever it is
+ #
+ print "domainify($host,$domain_host) = $host\n" if $debug;
+ return $host;
+ }
+
+ #
+ # There are several weird situtations that need to be
+ # accounted for. They have to do with domain relay hosts.
+ #
+ # Examples:
+ # host server "right answer"
+ #
+ # shiva.cs cs.berkeley.edu shiva.cs.berkeley.edu
+ # shiva cs.berkeley.edu shiva.cs.berekley.edu
+ # cumulus reed.edu @reed.edu:cumulus.uucp
+ # tiberius tc.cornell.edu tiberius.tc.cornell.edu
+ #
+ # The first try must always be to cut the domain part out of
+ # the server and tack it onto the host.
+ #
+ # A reasonable second try is to tack the whole server part onto
+ # the host and for each possible repeated element, eliminate
+ # just that part.
+ #
+ # These extra "guesses" get put into the %domainify_fallback
+ # array. They will be used to give addresses a second chance
+ # in the &giveup routine
+ #
+
+ local(%fallback);
+
+ local($long);
+ $long = "$host $domain_host";
+ $long =~ tr/A-Z/a-z/;
+ print "long = $long\n" if $debug;
+ if ($long =~ s/^([^ ]+\.)([^ ]+) \2(\.[^ ]+\.[^ ]+)/$1$2$3/) {
+ # matches shiva.cs cs.berkeley.edu and returns shiva.cs.berkeley.edu
+ print "condensed fallback $host $domain_host -> $long\n" if $debug;
+ $fallback{$long} = 9;
+ }
+
+ local($fh);
+ $fh = $domain_host;
+ while ($fh =~ /\./) {
+ print "FALLBACK $host.$fh = 1\n" if $debug > 7;
+ $fallback{"$host.$fh"} = 1;
+ $fh =~ s/^[^\.]+\.//;
+ }
+
+ $fallback{"$host.$domain_host"} = 2;
+
+ ($domain = $domain_host) =~ s/^[^\.]+//;
+ $fallback{"$host$domain"} = 6
+ if ($domain =~ /\./);
+
+ if ($host =~ /\./) {
+ #
+ # Host is already okay, but let's look for multiple
+ # interpretations
+ #
+ print "domainify($host,$domain_host) = $host\n" if $debug;
+ delete $fallback{$host};
+ $domainify_fallback{"$u *** $host"} = join(' ',sort {$fallback{$b} <=> $fallback{$a};} keys %fallback) if %fallback;
+ return $host;
+ }
+
+ $domain = ".$domain_host"
+ if ($domain !~ /\..*\./);
+ $newhost = "$host$domain";
+
+ $create_host_backtrack{"$u *** $newhost"} = $domain_host;
+ print "domainify($host,$domain_host) = $newhost\n" if $debug;
+ delete $fallback{$newhost};
+ $domainify_fallback{"$u *** $newhost"} = join(' ',sort {$fallback{$b} <=> $fallback{$a};} keys %fallback) if %fallback;
+ if ($debug) {
+ print "fallback = ";
+ print $domainify_fallback{"$u *** $newhost"}
+ if defined($domainify_fallback{"$u *** $newhost"});
+ print "\n";
+ }
+ return $newhost;
+}
+# return the first non-empty element of an array
+sub firstname
+{
+ local(@names) = @_;
+ local($n);
+ while(@names) {
+ $n = shift(@names);
+ return $n if $n =~ /\S/;
+ }
+ return undef;
+}
+# queue up more addresses to expand
+sub expn
+{
+ local($host,$addr,$name,$level) = @_;
+ if ($host) {
+ $host = &trhost($host);
+
+ if (($debug > 3) || (defined $giveup{$host})) {
+ unshift(@hosts,$host) unless $users{$host};
+ } else {
+ push(@hosts,$host) unless $users{$host};
+ }
+ $users{$host} .= " $addr";
+ $names{"$addr *** $host"} = $name;
+ $level{"$addr *** $host"} = $level + 1;
+ print "expn($host,$addr,$name)\n" if $debug;
+ return "\t$addr\n";
+ } else {
+ return &final($addr,'NONE',$name);
+ }
+}
+# compute the numerical average value of an array
+sub average
+{
+ local(@e) = @_;
+ return 0 unless @e;
+ local($e,$sum);
+ for $e (@e) {
+ $sum += $e;
+ }
+ $sum / @e;
+}
+# print to the server (also to stdout, if -w)
+sub ps
+{
+ local($p) = @_;
+ print ">>> $p\n" if $watch;
+ print S "$p\n";
+}
+# return case-adjusted name for a host (for comparison purposes)
+sub trhost
+{
+ # treat foo.bar as an alias for Foo.BAR
+ local($host) = @_;
+ local($trhost) = $host;
+ $trhost =~ tr/A-Z/a-z/;
+ if ($trhost{$trhost}) {
+ $host = $trhost{$trhost};
+ } else {
+ $trhost{$trhost} = $host;
+ }
+ $trhost{$trhost};
+}
+# re-queue users if an mx record dictates a redirect
+# don't allow a user to be redirected more than once
+sub mxredirect
+{
+ local($server,*users) = @_;
+ local($u,$nserver,@still_there);
+
+ $nserver = &mx($server);
+
+ if (&trhost($nserver) ne &trhost($server)) {
+ $0 = "$av0 - mx redirect $server -> $nserver\n";
+ for $u (@users) {
+ if (defined $mxbacktrace{"$u *** $nserver"}) {
+ push(@still_there,$u);
+ } else {
+ $mxbacktrace{"$u *** $nserver"} = $server;
+ print "mxbacktrace{$u *** $nserver} = $server\n"
+ if ($debug > 1);
+ &expn($nserver,$u,$names{"$u *** $server"});
+ }
+ }
+ @users = @still_there;
+ if (! @users) {
+ return $nserver;
+ } else {
+ return undef;
+ }
+ }
+ return undef;
+}
+# follow mx records, return a hostname
+# also follow temporary redirections comming from &domainify and
+# &mxlookup
+sub mx
+{
+ local($h,$u) = @_;
+
+ for (;;) {
+ if (defined $mx{&trhost($h)} && $h ne $mx{&trhost($h)}) {
+ $0 = "$av0 - mx expand $h";
+ $h = $mx{&trhost($h)};
+ return $h;
+ }
+ if ($u) {
+ if (defined $temporary_redirect{"$u *** $h"}) {
+ $0 = "$av0 - internal redirect $h";
+ print "Temporary redirect taken $u *** $h -> " if $debug;
+ $h = $temporary_redirect{"$u *** $h"};
+ print "$h\n" if $debug;
+ next;
+ }
+ $htr = &trhost($h);
+ if (defined $temporary_redirect{"$u *** $htr"}) {
+ $0 = "$av0 - internal redirect $h";
+ print "temporary redirect taken $u *** $h -> " if $debug;
+ $h = $temporary_redirect{"$u *** $htr"};
+ print "$h\n" if $debug;
+ next;
+ }
+ }
+ return $h;
+ }
+}
+# look up mx records with the name server.
+# re-queue expansion requests if possible
+# optionally give up on this host.
+sub mxlookup
+{
+ local($lastchance,$server,$giveup,*users) = @_;
+ local(*T);
+ local(*NSLOOKUP);
+ local($nh, $pref,$cpref);
+ local($o0) = $0;
+ local($nserver);
+ local($name,$aliases,$type,$len,$thataddr);
+ local(%fallback);
+
+ return 1 if &mxredirect($server,*users);
+
+ if ((defined $mx{$server}) || (! $have_nslookup)) {
+ return 0 unless $lastchance;
+ &giveup('mx domainify',$giveup);
+ return 0;
+ }
+
+ $0 = "$av0 - nslookup of $server";
+ open(T,">/tmp/expn$$") || die "open > /tmp/expn$$: $!\n";
+ print T "set querytype=MX\n";
+ print T "$server\n";
+ close(T);
+ $cpref = 1.0E12;
+ undef $nserver;
+ open(NSLOOKUP,"nslookup < /tmp/expn$$ 2>&1 |") || die "open nslookup: $!";
+ while(<NSLOOKUP>) {
+ print if ($debug > 2);
+ if (/mail exchanger = ([-A-Za-z_.0-9+]+)/) {
+ $nh = $1;
+ if (/preference = (\d+)/) {
+ $pref = $1;
+ if ($pref < $cpref) {
+ $nserver = $nh;
+ $cpref = $pref;
+ } elsif ($pref) {
+ $fallback{$pref} .= " $nh";
+ }
+ }
+ }
+ if (/Non-existent domain/) {
+ #
+ # These addresss are hosed. Kaput! Dead!
+ # However, if we created the address in the
+ # first place then there is a chance of
+ # salvation.
+ #
+ 1 while(<NSLOOKUP>);
+ close(NSLOOKUP);
+ return 0 unless $lastchance;
+ &giveup('domainify',"$server: Non-existent domain",undef,1);
+ return 0;
+ }
+
+ }
+ close(NSLOOKUP);
+ unlink("/tmp/expn$$");
+ unless ($nserver) {
+ $0 = "$o0 - finished mxlookup";
+ return 0 unless $lastchance;
+ &giveup('mx domainify',"$server: Could not resolve address");
+ return 0;
+ }
+
+ # provide fallbacks in case $nserver doesn't work out
+ if (defined $fallback{$cpref}) {
+# for $u (@users) {
+# print "mx_secondary{$u *** $nserver} = ".$fallback{$cpref}."\n"
+# if $debug;
+# $mx_secondary{"$u *** $nserver"} = $fallback{$cpref};
+# }
+ $mx_secondary{$server} = $fallback{$cpref};
+ }
+
+ $0 = "$av0 - gethostbyname($nserver)";
+ ($name,$aliases,$type,$len,$thataddr) = gethostbyname($nserver);
+
+ unless ($thataddr) {
+ $0 = $o0;
+ return 0 unless $lastchance;
+ &giveup('mx domainify',"$nserver: could not resolve address");
+ return 0;
+ }
+ print "MX($server) = $nserver\n" if $debug;
+ print "$server -> $nserver\n" if $vw && !$debug;
+ $mx{&trhost($server)} = $nserver;
+ # redeploy the users
+ unless (&mxredirect($server,*users)) {
+ return 0 unless $lastchance;
+ &giveup('mx domainify',"$nserver: only one level of mx redirect allowed");
+ return 0;
+ }
+ $0 = "$o0 - finished mxlookup";
+ return 1;
+}
+# if mx expansion did not help to resolve an address
+# (ie: foo@bar became @baz:foo@bar, then undo the
+# expansion).
+# this is only used by &final
+sub mxunroll
+{
+ local(*host,*addr) = @_;
+ local($r) = 0;
+ print "looking for mxbacktrace{$addr *** $host}\n"
+ if ($debug > 1);
+ while (defined $mxbacktrace{"$addr *** $host"}) {
+ print "Unrolling MX expnasion: \@$host:$addr -> "
+ if ($debug || $verbose);
+ $host = $mxbacktrace{"$addr *** $host"};
+ print "\@$host:$addr\n"
+ if ($debug || $verbose);
+ $r = 1;
+ }
+ return 1 if $r;
+ $addr = "\@$host:$addr"
+ if ($host =~ /\./);
+ return 0;
+}
+# register a completed expnasion. Make the final address as
+# simple as possible.
+sub final
+{
+ local($addr,$host,$name,$error) = @_;
+ local($he);
+ local($hb,$hr);
+ local($au,$ah);
+
+ if ($error =~ /Non-existent domain/) {
+ #
+ # If we created the domain, then let's undo the
+ # damage...
+ #
+ if (defined $create_host_backtrack{"$addr *** $host"}) {
+ while (defined $create_host_backtrack{"$addr *** $host"}) {
+ print "Un&domainifying($host) = " if $debug;
+ $host = $create_host_backtrack{"$addr *** $host"};
+ print "$host\n" if $debug;
+ }
+ $error = "$host: could not locate";
+ } else {
+ #
+ # If we only want valid addresses, toss out
+ # bad host names.
+ #
+ if ($valid) {
+ print STDERR "\@$host:$addr ($name) Non-existent domain\n";
+ return "";
+ }
+ }
+ }
+
+ MXUNWIND: {
+ $0 = "$av0 - final parsing of \@$host:$addr";
+ ($he = $host) =~ s/(\W)/\\$1/g;
+ if ($addr !~ /@/) {
+ # addr does not contain any host
+ $addr = "$addr@$host";
+ } elsif ($addr !~ /$he/i) {
+ # if host part really something else, use the something
+ # else.
+ if ($addr =~ m/(.*)\@([^\@]+)$/) {
+ ($au,$ah) = ($1,$2);
+ print "au = $au ah = $ah\n" if $debug;
+ if (defined $temporary_redirect{"$addr *** $ah"}) {
+ $addr = "$au\@".$temporary_redirect{"$addr *** $ah"};
+ print "Rewrite! to $addr\n" if $debug;
+ next MXUNWIND;
+ }
+ }
+ # addr does not contain full host
+ if ($valid) {
+ if ($host =~ /^([^\.]+)(\..+)$/) {
+ # host part has a . in it - foo.bar
+ ($hb, $hr) = ($1, $2);
+ if ($addr =~ /\@([^\.\@]+)$/ && ($1 eq $hb)) {
+ # addr part has not .
+ # and matches beginning of
+ # host part -- tack on a
+ # domain name.
+ $addr .= $hr;
+ } else {
+ &mxunroll(*host,*addr)
+ && redo MXUNWIND;
+ }
+ } else {
+ &mxunroll(*host,*addr)
+ && redo MXUNWIND;
+ }
+ } else {
+ $addr = "${addr}[\@$host]"
+ if ($host =~ /\./);
+ }
+ }
+ }
+ $name = "$name " if $name;
+ $error = " $error" if $error;
+ if ($valid) {
+ push(@final,"$name<$addr>");
+ } else {
+ push(@final,"$name<$addr>$error");
+ }
+ "\t$name<$addr>$error\n";
+}
+
+sub alarm
+{
+ local($alarm_action,$alarm_redirect,$alarm_user) = @_;
+ alarm(3600);
+ $SIG{ALRM} = 'handle_alarm';
+}
+# this involves one GREAT hack.
+# the "next HOST" has to unwind the stack!
+sub handle_alarm
+{
+ &giveup($alarm_redirect,"Timed out during $alarm_action",$alarm_user);
+ next HOST;
+}
+
+# read the rest of the current smtp daemon's responce (and toss it away)
+sub read_response
+{
+ local($done,$watch) = @_;
+ local(@resp);
+ print $s if $watch;
+ while(($done eq "-") && ($s = <S>) && ($s =~ /^\d+([- ])/)) {
+ print $s if $watch;
+ $done = $1;
+ push(@resp,$s);
+ }
+ return @resp;
+}
+# print args if verbose. Return them in any case
+sub verbose
+{
+ local(@tp) = @_;
+ print "@tp" if $verbose;
+}
+# to pass perl -w:
+@tp;
+$flag_a;
+$flag_d;
+$flag_1;
+%already_domainify_fellback;
+%already_mx_fellback;
+&handle_alarm;
+################### BEGIN PERL/TROFF TRANSITION
+.00;
+
+'di \\ " finish diversion--previous line must be blank
+.nr nl 0-1 \\ " fake up transition to first page again
+.nr % 0 \\ " start at page 1
+.\\"'; __END__
+.\" ############## END PERL/TROFF TRANSITION
+.TH EXPN 1 "March 11, 1993"
+.AT 3
+.SH NAME
+expn \- recursively expand mail aliases
+.SH SYNOPSIS
+.B expn
+.RI [ -a ]
+.RI [ -v ]
+.RI [ -w ]
+.RI [ -d ]
+.RI [ -1 ]
+.IR user [@ hostname ]
+.RI [ user [@ hostname ]]...
+.SH DESCRIPTION
+.B expn
+will use the SMTP
+.B expn
+and
+.B vrfy
+commands to expand mail aliases.
+It will first look up the addresses you provide on the command line.
+If those expand into addresses on other systems, it will
+connect to the other systems and expand again. It will keep
+doing this until no further expansion is possible.
+.SH OPTIONS
+The default output of
+.B expn
+can contain many lines which are not valid
+email addresses. With the
+.I -aa
+flag, only expansions that result in legal addresses
+are used. Since many mailing lists have an illegal
+address or two, the single
+.IR -a ,
+address, flag specifies that a few illegal addresses can
+be mixed into the results. More
+.I -a
+flags vary the ratio. Read the source to track down
+the formula. With the
+.I -a
+option, you should be able to construct a new mailing
+list out of an existing one.
+.LP
+If you wish to limit the number of levels deep that
+.B expn
+will recurse as it traces addresses, use the
+.I -1
+option. For each
+.I -1
+another level will be traversed. So,
+.I -111
+will traverse no more than three levels deep.
+.LP
+The normal mode of operation for
+.B expn
+is to do all of its work silently.
+The following options make it more verbose.
+It is not necessary to make it verbose to see what it is
+doing because as it works, it changes its
+.BR argv [0]
+variable to reflect its current activity.
+To see how it is expanding things, the
+.IR -v ,
+verbose, flag will cause
+.B expn
+to show each address before
+and after translation as it works.
+The
+.IR -w ,
+watch, flag will cause
+.B expn
+to show you its conversations with the mail daemons.
+Finally, the
+.IR -d ,
+debug, flag will expose many of the inner workings so that
+it is possible to eliminate bugs.
+.SH ENVIRONMENT
+No enviroment variables are used.
+.SH FILES
+.PD 0
+.B /tmp/expn$$
+.B temporary file used as input to
+.BR nslookup .
+.SH SEE ALSO
+.BR aliases (5),
+.BR sendmail (8),
+.BR nslookup (8),
+RFC 823, and RFC 1123.
+.SH BUGS
+Not all mail daemons will implement
+.B expn
+or
+.BR vrfy .
+It is not possible to verify addresses that are served
+by such daemons.
+.LP
+When attempting to connect to a system to verify an address,
+.B expn
+only tries one IP address. Most mail daemons
+will try harder.
+.LP
+It is assumed that you are running domain names and that
+the
+.BR nslookup (8)
+program is available. If not,
+.B expn
+will not be able to verify many addresses. It will also pause
+for a long time unless you change the code where it says
+.I $have_nslookup = 1
+to read
+.I $have_nslookup =
+.IR 0 .
+.LP
+Lastly,
+.B expn
+does not handle every valid address. If you have an example,
+please submit a bug report.
+.SH CREDITS
+In 1986 or so, Jon Broome wrote a program of the same name
+that did about the same thing. It has since suffered bit rot
+and Jon Broome has dropped off the face of the earth!
+(Jon, if you are out there, drop me a line)
+.SH AVAILABILITY
+The latest version of
+.B expn
+is available through anonymous ftp to
+.IR idiom.berkeley.ca.us .
+.SH AUTHOR
+.I David Muir Sharnoff\ \ \ \ <muir@idiom.berkeley.ca.us>
diff --git a/usr.sbin/sendmail/contrib/mail.local.linux b/usr.sbin/sendmail/contrib/mail.local.linux
new file mode 100644
index 0000000..42d2c3c
--- /dev/null
+++ b/usr.sbin/sendmail/contrib/mail.local.linux
@@ -0,0 +1,205 @@
+From: Karl London <karl@borg.demon.co.uk>
+Message-Id: <199308111712.SAA05454@borg.demon.co.uk>
+Subject: Final port of mail.local to Linux
+To: eric@cs.berkeley.edu
+Date: Wed, 11 Aug 1993 18:12:27 +0100 (BST)
+X-Mailer: ELM [version 2.4 PL21]
+MIME-Version: 1.0
+Content-Type: text/plain; charset=US-ASCII
+Content-Transfer-Encoding: 7bit
+Content-Length: 11415
+
+Hi,
+ Sorry about this.. This is a final version of mail.local for
+linux..
+
+This is what I would like to see distributed with 8.6 if poss...
+
+Karl
+
+--------------
+
+begin 600 mail.local.linux.tar.Z
+M'YV0;<*D8>."S9LQ8=B\`,"PH<.'$"-*G$BQHL6*(&C`N`$#!@@`($#$N%'#
+M(TB1)$V&7,D2A$<0-6C,D$%3QHT8+V/HI$$#9(V+0(,*'4HT8ITY=,+("0E@
+MC5(V12<ZE0,UJM6K6+-JW<KU:L"!!0\F?`$G#!TT;L*T*3/'!9JN<*WBA*%1
+M)<J2'T..Q'NRY0P;,6:$+`DC!@V:,VK(T#MCQDV0,.)*GFP4J5*F4ZMNS4RY
+ML^?/H#^_4-%"`0@5((:\@9-'3IHS:.B`0#$FA<@<.3Q205,&A)0R9\JXH3,'
+MQ!LS(,[VKN(FC9TR<N:DH9/'./(A"=.8>2.G>1@7IE$'8<,&A&O8Q,VSA?Z<
+M#/C3X7V7(9,&J6LQ=>BD>>,&1!@W9(!P5&]I]#?'&W7(,49O_P4H1H%*5;>=
+M'&W,P0((=TR'AG%+97@6@G3$U\8;])F1!D+Z\7>A4KW!`5T;T]$Q'PAPR/&&
+M'6F0,>-99B7'&PC;D?=&AFZ<`<(8_-&7HAMSQ,<B"&O1H4-\,;@@'WWVI8'?
+MDL4=!\*!"2YX)(F]M7&4;'*4D52!/C(HQHV](<G:>;'%MY(;;^BWX(5GU0<"
+M&_7)YB62`$ZW'Y/^`=@FD&\(2:216([!AD!KR?$>:C)8^1N6=-R7WZ'%L?E@
+M6G)(R%T;4)ZI7HTDUB&F<OZ]^=R8<[Y6YVDLX:EG&7RBX2>@2%DW9J%<)AH@
+MK$$:]"@(D4Z:1J4@L*F<G2&1<5`=:PUGUJ'&OL"=<<HM%9",KB54'*LXZAB@
+MAQO"RJFG2UX*P@Q6CE=>&&0\)X=^TA4)I5G0I6$NE,(M6:"19I1A5H)L<2C@
+M'+UYV6=Q!YI!QQTL4IMJL%C",6EUR#:J[,'^C;$&GG>P,5]PV4H97@*[^<DJ
+M&:[*5J"D=>A(\7$7/ZGC<P:YZ"#(/S+G''3246?=R]@!.J%W%PH!W1IEJ%Q=
+M@]&F1VBG6N;'75OQT6"E$V5H"-VB::TE+*Q&ZYMT=7@N!6O:#7LY77%;P_NU
+MQ@%5)T9O`Q[[!@C"61M=Q$NQ.J*,--I(\QCIZ>A:>T#:B.K$7_*,<9H:LPOB
+MERZ.H=V)C>_7H6MTR-B?BQ36)QU_E\9'!1))3`'"%$\80<4504A1!`BU@P"%
+M%$]8D00111`!@A!9@##[[[X?48035-@>A!/*#_$$]5(D(4055#PAA>U@@!&$
+M[;6?<`((UQ,1W_7-%X'%\$5,8;OXP#<!!1-))`\"[U*0PO6HT+\I7"@)3A@"
+M$ZI`!`0>(6K@`X$3GD`%$/"O"4F@@O_"=Z'GQ2<)^N.?_P`H0.H5$`2Y`T$3
+MBB"%(2!A@$$00A+X1X7FM0\$1LB@$^IG.R/@+PC"ZQT!AU`%)O1.>%60`A2>
+M,(4BO,]W(&C@%!08!!`FSTK`<X($GP""(EAA>A6<P@N9P`3G(0%Z19`>]>XG
+MA=1LCPK=^U[XQK>\W_$OADQP(JY\V$;X13$)OAL"%0Z(/4`609"$',+QP!@$
+M)EQH"E`X9!(:>2'Y%2&$O<O"A?"G/2<T,0I5`.,DF1`?(@2A"4&0GNU0@$`%
+M,M"!$*S@!"MXP0QN\`D7&MX3B.B[%5(/A4:X716$,`4"4@%\OSO"$YY`A"G$
+M!W]-E(+QAE"_'5B0B?<+9A6:>"%34B$(FVRC+G-8/6OB[WM30"`/LZC!`%8!
+M"@3<7@KB@X0G7,&++$Q-$+;IOQMNCWU.:-[SQ->\%-Y1AC34Y/_.^+PV(M"-
+MW`L"(F\'QR0(,CX'G6$&%8J_.5:0E0E<8`.=<`0)II%_:J0F"MM(P3-*X0JU
+M*X)M>E<[!V81H,WC71:>&<$4/@\$_`2F&8.'.]T!L`B5_*(6DQ#,(!#!>$U4
+MGD_/*#QL>D^C-01F?*90!1=&\92I+$+L3I,`(*!@!"DHRUGHUA8T)*`&+A`,
+M"J0F!ZI9S38Q>,%(7I"#&(3G!0H8P<W8D+/>\$"M:&BK#Q006!V9R`V]^0(4
+M@C"[+S!AEU307P)$\`(ZM`$.+S`(0@B"A=*:5@0*"(UJ5_L5@HAV+*T-RVA=
+M,(;5@F8N=<G+7>RR%[NP9"0PJ$$-!B.3FMBD(XSAR0T@8]OF#N5,E_D(9[@R
+M7>=:][K8E<QH2H,KU=0*/;.IS6URX[P?_28XP^D2<MC6'+=-ISI>:IIVN.,=
+M>=G+/+9*3YH@)H?VC!4UFPH4O+B%M0%%RT`(4A"#%#6J"#&*0A;"D(8<YKG\
+MB(A$HT/1H5:4)AJ]*$8S0E>.=H2&'H7,420CE))`Y:0.1VE*N*K2E03<M6)Y
+M"4P*'I..-H8F-0FD/[`*@ZSBM)K6Y%=CNCH1KWSTJT`)2\6&XD]QL';BD?FK
+M692"CKPR->,L;0E4!P9!@TOU8%29*5AIFIFK>A/D(=/*R.A!<IZ4W*LF!VM0
+M28HRHJC\HV0-B618?M;9I,4;C5EK#-@JV+;XTZUOY8DWX@)8N=AP+ANE:T;L
+M6M2[:GPH>=&+?>3Q3[Z@PR^2C2M@`VO9H4B6L(7MUV$&EIBO=F:QS96!;ZKJ
+MV,<6Y>=EA<%D*%,9&5A6,!BK`&:S;ERK('=@G.DL<[7V61F`MIH9B8%HRVDO
+MTMZ[-++*]VD"B]K4JE:&JRGJ;L/BVI:^)B^Q2;!LX4*;6B*VWJ)I.SK<CIN\
+MUZ+>K.&-/^KV6G3X%@:_`0YB@B,<@+Z&.&4OKD6.JUEQ)'>T`)G!<DRF=<\X
+MAZN55%@V<PA=ADOWK3N@3G4>;MT<7N>&_P[5=D7=7>]^%SQ=&@]YRF.>&=&H
+MQNH!-'MOC"/XQ$<^\Z%O"NK[^?L"VL7Y^<Y^*\W?_OJG/!(.L(")%"DLEQ?!
+M65H0A+94'@=W_L$04OU_O2LA`>LGU!6V\(74BR%6;8@]'.IPG7QD7Q"E,,0B
+M'A$*25QB$Y_X.RE2T8I$P.)#)]A%I89QC&7\:?3`R$:(5E2.1*_CU_&H1]3D
+MW8\-#.0@LQCZ0XZ^E8N,NR-O%TE%4K+IE]Q?)L,)T4^&TH2-+"5853F;5FJ=
+MI+'<(BW!KD&QXU)XQ./E)<$H5*X2TYC(!($RF>E,7$&3A=.LYC6AGD)^=I.R
+MX(SZ.#,X!7.V$9WJA#H"VRF%=\;3"?/$53WO^<4V#F&?4?TY"K7HQX%*H:#!
+ME%$)=2%7P%`N=5.=!$<2-7K%U#T7A2L"N%&TYU&]%U*O1%(F=00H-3TJA3\M
+MQ4(PU40SU3WIA($/Y4<ZQ5,5-%6_$U13152Y(W.^DU33`SQ-]50Q)57!]%."
+METX(M5%:A2M<Y56FA$K2<RF`%5C:`2!E@!R`,AP*,`8EMA1R`F>QL05=``(]
+MH``B8%9HE1I%1B>R01MXA1NZ85[`43#]QEY'@V]*$U_9`6[?P05NP`6F<5]B
+M6!S[Q1[SX0)T*`([$%B%HQT@,!H@H"M_4B"RH0))*%AFP(1.J(@*8!EZ<B13
+M^"5C,`;20098J(4@T(5GE0*Q]5H$,09OY0(V,!MT95?E9ALVH%<YP%<Q`(B"
+M6"C(88B(^(2+V(B#55@@P`-SD`=S0!9*H19NL5B"Y0;.9EC!.(R4>(Q*J(R$
+MM6/`*(PO<"`FHR;0F(S+^(O-^`(FHC+;V(O4"%GZ88XO4"#C*(V^6(US8!!G
+ML([=R`-F,`;#01!H@(SD:%CF2`9B((_3:%AP<`?ND8_1.(_ZL18`V8YUT!Q(
+M49#ZR([4"!W=\08+28T/N1\7R8QT0`:`\H\&R8T!Z8U<4R0;^8F(Q59N@5J-
+MU80%4@8)8`3@QP0)D`!^-0*.]9(),$LR^4TT"0.,I8@)H".`HB\@\`62A0(H
+MH(@7(H67H0(ID`*!:`=OD",)0)%'F91+.1Q-*66RX91+H0(7X@)D&953695D
+MD`!)9@9Y\"!F@!Q("05*"9:G898*()1(P1V1I95T"952J0!4:95'$0;!D95R
+MB0*!209VJ0!?X08HH!1G,`8<=@9V,$\)H(C^(0>1&8@)T)<J`)EV$(A[H`!7
+MB0?DTA^8N1KG2`:<60:F"1W]T9>J"9F<:1\U0R-AL'($>1H#R9F8*8478@9D
+M<"'3EA"<60<Y\@6R@9RL29I]>7%OT`:!2)K5Y@;PB`(B,(IBP08B<"&7=022
+MQ4+$(P7>^03@B4HS])>D"9VHT@,25$1,P)EWX"LJ,QNTL2'N&1QTH)J/J9F2
+MF9F4>2$B0`9FH`-RH`,B$)4@$`+N602Y8YD),`<>(H7W:1NC69,(`3$@<`)D
+M<`(Z4).&*`:_M@:;$R!(\EG;(@;UR8BD69-BD"9AL`:<V9FYV1LG8`8>VJ(9
+M:J-RX*$@BAHB:C(E.B8HJA\JVALL6I.7B1PHP)X0F@`L09$HT).OEYUUP`;Z
+MX3&]T0+(H9J@DJ`SF@#LZ8FSJ9EA^J(*(Z,Z6J,;^@,Y6I..%097ZC)*.IC!
+M@0)_69-]0)J0.08@T`+NZ:4`PIF@"0(K$*APL)K3N:2S$0*?J9F5V:)V6@9X
+MNJBC09JXD@3(,::(&')E(#HF,A\78F!S,V^5$YT@H)_P6"!X&BWU=FM0BAK,
+M^2]T((5L<2&/!AT9`C&CJJ&EJC9C"BMEH9O<87$#`:NX@B1RL%]PD&?^LI^+
+MPIS@$:N`E0"SFI]JPIR52IJ$B`(A,*8F8`*-VJ08AZUTL*J.J:!\P`>8NA(A
+M@`(#Z8GZ.9!I0Z[1J:Y\0"-WT`(^,)!?,*L,*B`Y$I4M.J;N":]W(*]J,I#:
+MRIP*^@/ZRJ_^2C<@H`.?^`,82XOK&2#NF9=I8J]MD*<3,AO%61[N"0/6]*B4
+M:4TKL`*@":$E"P)\X)Y$V89-.IRG\;*MB0?3@0(E^Y=[.HG[^;%.ZIR7J`+L
+M*9JDF4-Y=!IF``><F9!EH)S)80?&R:W#`20X6S4OR9E]20=N<"%/6`9;(`-T
+M@0-=L*A@ZXGV03-P@`*215E(8%F8I3]YVJTWZXEML`9(40:?A0)@JZ`]X)XM
+M$`,RFZ_O^K2>*)S5>;,">@<KD*`$6Y-22J6K)P(-*63U":W5F1Q^VZQRX&#A
+M6`9@2IJ(B98IT)!/N`:`ZP8BFR:4&KB+>KH#*[4H8`)T8+5LD*>TJYA/ZQK#
+M809-"@<":@085P+%@;S=>:IMT)2VB[NZNY@),+9;``-9Z)XGP`4P<`*<.;(^
+M.[:>&`/69`;Z.0<H,+87(AUZ4`;'<;XOF0+IVY$%(I46VJ+=2KW6JX782X<G
+M\*1<"UGA.Z-5HZ$76I/=^K^]$:Z)"%G5>[W8:P3KH\`A(`9C\+?H^XG&BZK+
+M6P.3JZ2]FU;Y,08H<`(^<`+!"0=Y2KG@>[(SNJ<U^<&_JXC"^[0"JKQB^[XS
+MVJT)LZS<,;P=G`!H&J.<&;0)8(B:2C`K1YB]@8B0E3(OZ;FMDQ8R@K.0-2/_
+M03BF&;I6DJ3=&@(%HB-XX+Z0=2'9ZP;]"Z$?#`<A/,+\>\)Y:HA/D!]J+!MA
+M<(AEX,2094VZLF2?JS3\-@=*/&4=EA#*TH>G4:UIO,9E;,)`@L*SFY@I\):$
+M-0=HX,.^R:0[;"-RX,,PNZQ3.I,"*B.?Q1VB>ZP8@CJ]09'<4;H)D"9TD"".
+M*9Q`RU@UJR^.>XCS9IF8*9Q>>[1TH[01VBFW28E?(@:U*<S,-JP2&B`JT)M8
+M^Y4P.L47T@9B()P7X@9R<,UW@*MO>2']=;6=>8EN:085<@9;,!==<"'X809;
+M@`,J@!,R0`/IC)MGL06H-#]RFT=.D+;4^994BV@VTLU_`C%EP+KJ6<0J@*FH
+M003U0<A#PBQ<JR\@,S@->3)#TA]L]:<M`#J?*C#ET5IO@@<-@Q#]\3<*#0(E
+M!B#"%F:P`C$`TEK^`2@U6ARC.ZV'S*U,^J[Q:J[TJA8H0#=16;^4Z\D\"<J?
+M6-$H@]'S9K$VC,MKD<*N#,LH$`-Y2L0?''+`2P?"BU@U/(Q-';>5A9Y,$'K7
+MG,N+VL6T$<TSXIZ4EA1T`*]F@0878@)S(`8*&J[M&A(H4-<N@!1?8)T%L@8+
+MZIZ&NZZW\P6UPP1.L`1[_8]^/2(Z$M0@4,!26M0^V=46N[HS,KK+BUA0G:W=
+M,=55S5@(?=*[`1UE<`)39AZ_UAN0MJ4;?3&#PRH+LG(-TR=N(-C*X3>/=B1J
+M308GC2S'BD4Q4QQK\1_%(=SU2=*(^#<"`MBYW8<*7:UX2\W"J85Y;1PNXIA<
+MC4)?$`10$$G8PP=/\`5#X#N41=Y?<`7$XP1,H%!3@-CM-P52P`?QG017L$U2
+MH*`\X!)"?95$34&6B]D@T-3=;1^JO,D4B2=V69-1'=I4/<2D_<TFZQ*<:8BF
+M9;%/L-U?@@8(P@8!XM`):P:BM08G0#+*70;61-`9X0(T0$R)=].,VJ0EC@+6
+MC;.7-01+\`7RHZ"4'>!4,."?B+Q,/0>='=?QFR8\K.#+RN!0K;L!W*)GD">#
+M(Z+-F0!$#-#'@1QL3="L>^,7`@.KUT1%L./30P2\"\E8+<,H,,[EW-5`4`(@
+M_H=EO19-F2!;?K=,2FEE4-"W+.:/5`1E_@5-1`6V,;BSL>7*F0*%^]^5:]0B
+M(,J@6\HJ4^3+B^!+[K--_@8-WLI03M@S.N70:N423IKS:<I*B<V>"*-D<,OK
+MG+YIL+[MN\Z2[0/^7;#?@@);[HDH:QW(T=_8K,=+`:B'N,V^;JCNZ09W\*1X
+MJ^R>:'+30:E@+F9U@!PKX.O7+`?\[=^3W:)#O<F67:5$7N!&?B$'WBD)KND5
+MV>DU*>J#(\S*&*8NW*VJWM\PX.B>+.21_KFD3&:C:^E)GNX+SNE_">]C\*$)
+M`,,&#S`V7LTXJ^5O^>0)$>583MJ7&JNWHR:+<M%G@S5G8"-U``=8A`2!PATG
+M0LAYH,X%`M-IIC!3G''^$2(8KS!2^"\#`=%%"1UY@$57L,2#8Q!%<C;6DG$K
+MLG+8@N(E9C.O>M(<'QV^`@<.PSHPLG)@=@>H;8G_$1S'\MH8DIO^H1ZYR6@C
+M:RT'<]('8M,L:N4?VJUC\-NVT:(P+(47W?#6'+']>@?_FB/FOJ]W_P5G,+"/
+MC+IF$(S*2/>*N0,_&D7\<0*R@3'3\6`"`@=D`#!;C,B0+"EO`#&&+Y6)GP2?
+M!2BBLYS6>1!K4/FDW<44#J%KV9;:(;QN/@=GD*</[IBI'XA!FY@*L/KC;..P
+M;YE]6<[`3(FD8YO,AHU.009D(`=?P";XDOS'O"U^NLN>6+C'+`>WZ>%]F[4J
+M@`902YK$#W)\J/TAYYM9JS)N<-8YW?R6TB]?8`9J,1!Y\-^&*#5?<JQ92XCC
+M_"7LH62'F"?^8;4#07.5`=-GP'+:7H-ZYHJ_V(%K0S>PTSA;7IB+#,`!R?6D
+M9E\.,X#<3V%]"*3``.<-=B)%V(\.4,!NIZ0JFX"#="`P\TD)<G?IT%VF&WCL
+MS@*V*!>6`-1?7RL0[>_]L8'JX)ZX'[]"`U]`_5$'%S&C*%B100$^T`<`0?4W
+MUVP@^V."*`T._,`O8/[.P%E(84X0!X(NV="QI*`/F`-?8`M*N!GWZUP""%!@
+M38IMD3XU@0*"@!%`;#N$`>V2'4<$CH``:0)A3G`1+JI&`@$<N#N!E^T3&3\U
+M`?"^A`O49.K.R<TH&5CQII=P8%N=POSQOMAGJ$3")9L-+HT,[*<F-<U@G]@2
+M#F'N0NPU9`9R2)_ZJTLF``JJ+_8EO-3?Y&()`<O\=;(_&.0@728<=:VO$&(Z
+M1`@#9QE@0DL*8%+A*05PH1Y=(,1<@"PX6"SM-%I`P!;@4LPK"PV(I4"67$#I
+M"EJ.*"L5$R(P!)#201I)P*@C0:9M-,!NC4AJ1U8K=&DFQ5*+2@1CP7W9$"EM
+MPV[X!12`E,),]<'])04VT)68Q%<Z6N2,#HRELB2(^)P]]&3YT"PDA.#4!NB`
+M+KM_<T`?@K/GU!`YD]7Z`F1`4K1#[4`,2=-%!!9TK/O%0T)'!;BA-TP`%]$R
+M[(O'1+R`1$/\2R.@''K$,/`%5.);"P..;".:`8_8C*[3=^)Q`80A"D3_D!-1
+M(DTL'"Q1S\V&A+@/81;/>FL13@'LJ>Q"%:NB5;R*6#$K:L6M*!&8X5AH`C'*
+M):D,KJ@5<`MR.0F]1;>DQ;[0$F2`3B`N,Z$F<(2<(`-L@&)@+F2QN4"7I2!=
+MGD)7J"YY,3`*1LDP`LI**`*+5&-TG2*YLHK(3?P3"7KE!L@BQJ)+CD`/2`!>
+MD0TH`%3B!'#`9<R,+@`HR9`)<@6<P&6T$7E"`8S&)L!,BD`/H`'"I0:H1@02
+M>GK`"Q@5C,4%[*-?)`;F@'M@%?%H;RV6P4@<BZ-Q/(Z",3.^`-"(`Y!C13"+
+MO"4EJ$7IR!97@@VP`3>`!@R&CF`#8*,,4`RI2"0TAL?@$IPC9=B+F,$O4A?U
+M:![;HWMD"'Y(!("A[Q(;PDL9(B^G33Z@E_0@:[)-&WH;PN+;T!>!`1[B(Z@I
+M#WE(/2A`Z18?%8"!##!>YE,PF@*CH=@$CA$36&/,F`H(<R$R3<G1$"#"07(!
+M^0C9,LRB"5N9J45\F-018BS-B-EZ)J;/B(P_XR^@#)<0D?+Q2;P8'"D2-,5\
+MH#%?1LH(BPM)9';,F>DQ:P+(_`@A`R?>C!CBD7=BSNP)F`<2GTR>*19\IC?T
+M&D!3'R1%EK$4/)++0,B`4RQ$!83P=Z>"QZR*B/,JEJ2;J4)/TD!&R5U19XI#
+ME<0SQ`+,9$E&@6*N3)=T%M""T-P:.5DMKD7+.)&-9BGDJDA#+CQ:I;D1+U+"
+MG`5-`R0E9,OAD9_FON`+?5%J_,6IF33&K6"L&G_1:E[9J_D6L:;>^(F*L7$&
+MY8AD"4>26=0'CU%P>,V,]#7`9D@(&V(S'*9$?$0V,H--V@R)U#!8I:V!:-1&
+M:(@9;`-4[@V`/`XX,@$(R.X0;I;'N+$:QL+?I!N]$1T*Y*MT-V3#;,B-'T&Q
+M^F.S_(_YYEO\JKJ!'-!-WJ@Q>X-0_@N#\S!VQ.`H'`PGZEF./`%QEDWD"!B4
+M(U@E&V.9,>3EQ^%HH(ITU`C3<<I`S.KX,%0/=N!('CD[8)!1F3G`PW;8G$62
+M<P0*59D\:T3_)""A,T>*SOG(F$FG??!(/R(_Z`?W<2AF9X2DG:M3/[+.!7H@
+M7$>64)"O@T&*C_,X/A[$0(*0J2,S`PC-S"8JA(6X$!CR@[+*#2$G.P3J?)Z]
+MTW>,B#@)/$S$B1A(C&EXC`CB43Q:A/'@DU\B1AI)Y/F8:83R1)V1Z3V&#AT1
+M`G9DD@B!/,(C/P_3*3T3A38:DKR90%)/((0DDN3U6!),\G]H3R>Q/:(D]QC(
+M(A165HGON9G!Q^O4$I\Y=G2)\O$E*RB8.)]BDD&BS_1I)CSR^D@3BZ)]+@OW
+MT2;<Y*M\$]HS?LI)U$$_41-]4`_QY'Z2@#SAD?,'G]@?_--/ZLX_Z3]GA*`(
+ME0A40PB0`<HG#V5D+J!'4E$NBH$DGAREC5`@D.)*1DI)V2$:*`FDE-_A@1I*
+M")(I[(,$V903Q'12D(%\`CUE!U$5%Z0^+:8,0BJ-IP8Q%?:!@_(/"ZHJ]N.J
+M)!2M8B"'$!+X*D9(K$S,7^F%1)%`<"W;R07@@`1@`Q2H*KJ6K2@CO`";,!D;
+MI`L@`@$B""S,\F`3+D0,P`U^Y8+*!K'F`G)<(P$!.,!!/H$FX0*FP(9P`J=$
+M:SH!,W-`94M"<)!.($!XK#)Q0,-,'0-I;P`/.$@7>CNRP`2!`NG$F;B`&6KS
+M$.AH4:%0SPB4!^00!)8">W*05;1>4D.R-$0W!/*8(MT#GMA.)X!#4058!`ND
+M2`&PNN3V(RP#@%`*`:)`S+'(EQP&QQ4K'"W@.'`I4X8U<.)V(P.A0C9`*YJ'
+M!K#H4IB&&XJ%0H$?>D`50$U3`*?-D&I1QJ0JG%L=TUTY0HLZM0'H(*$`'("D
+M/\)+"<DGX?5ZS1SPE4*@/+2`I&`D6D"&T(0;`@_(TBOJ`I*`;)"B0()]6%'+
+MH0"F@,AA2XLB$T('U;9)"V01T(PNP),J@"10*-)%'9AX,.V/!3*6]B.`*!Y(
+MD3CO642[H9$H",=GH0X*`'SU&FMS-198;_@;?\\--`=_D6E:6DDR$N4C@Z$*
+M]0$>@`CXVAH_!NGUABSA+^(IQE$?O6*?%HYA6APH5A]-#H+&$*J%3QHLR\`?
+MM9>$X]=LB%J&V@)$-&4+R9"3`A$5]1\$&_CR$WYTH"8<0HK$,FH]355J30ZL
+MTI2&]4(7Y#@;**!\E+#^%2TJC4,5J74T452'CZHDRP1&56(*X-35/"1QI1Q$
+MF0@48;$_C*PZYD]15=*I63""7)C3`JE,\R-,&UV"+)7A`9PA'8#&3EV#ZV+"
+M.$@L8$5+'`B0`4&5/O'0FP=2X<!#=0^=]),>,5A1/L99TE&`_,]/S#YR.E:7
+M0OEB#QU0;0@&%J``8$7^6Y!+P4^LI30P([P$14T3%K6&QE50.BB9:&8,AOH!
+M4"@-UX1N/`*CF0.NHK9%&*SA`SP"(;JC2\XX9*($`39:Z(:8'L:CO6%.!YE*
+M_Q0K_5.O=%)^L8+A(&UI%[$#SD,+*(`J@'!R*L00I$O2K=J(A0DP$*K:T`/\
+M(6+T5.?*%I+"9S&FR)2(,JWZ05M5Z6UUI3EB4G:6SQ):$JAI,2U_ZD25!<C1
+M6V7#(BU$G@6TD"(7<%Y+2V'E=^I00APK%NI;W^L+2(?+\8"^@&D8#/D+,;6F
+MLC)-0`[ND`<<Y#'MHK=#T+$/)H`[^FH3%0D@@+#2UZ6`!S(AAM6P9!5(F-7%
+M`&+]JII0@(&U-PQ6"WNB`)ELP`$9UL)F0IB60ETK"*`=Q82@*``@`EI9QW%=
+M&DN4AJ+1[:0`D&"#>$)&`L&R.I+A]:Q>J/%Z,.VQQC\%$%)91!QU`UA4-MB!
+M&P`"P(/7$U8VXN.IA3)Z8<'#>SRS:#;-JMDURV;;K)M]LW`VSLK9.4MGZZR=
+HO;-X-L_JV3W+9_NLG_VS@#;0"MI!2V@+K:$]M(@VT2K:1<MH&^UD`$MG
+`
+end
diff --git a/usr.sbin/sendmail/contrib/mh.patch b/usr.sbin/sendmail/contrib/mh.patch
new file mode 100644
index 0000000..7b23a5b
--- /dev/null
+++ b/usr.sbin/sendmail/contrib/mh.patch
@@ -0,0 +1,193 @@
+Message-Id: <199309031900.OAA19417@ignatz.acs.depaul.edu>
+To: bug-mh@ics.uci.edu
+cc: mh-users@ics.uci.edu, eric@cs.berkeley.edu
+Subject: MH-6.8.1/Sendmail 8.X (MH patch) updated
+Date: Fri, 03 Sep 1993 14:00:46 -0500
+From: Dave Nelson <dcn@ignatz.acs.depaul.edu>
+
+
+ This patch will fix the "X-auth..." warnings from the newer
+Sendmails (8.X) while continuing to work with the old sendmails.
+
+ I think the following patch will make everyone happy.
+
+ 1) Anybody with MH-6.8.1 can install this. It doesn't matter
+ what version of sendmail you're running. It doesn't matter
+ if you're not running sendmail (but it won't fix anything
+ for you).
+
+ 2) No configuration file hacks. If the -client switch is
+ absent (the default), the new sendmails will get an EHLO
+ using what LocalName() returns as the hostname. On my systems,
+ this returns the FQDN. If the EHLO fails with a result between
+ 500 and 599 and the -client switch is not set, we give up on
+ sending EHLO/HELO and just go deliver the mail.
+
+ 3) No new configuration options.
+
+ 4) Retains the undocumented -client switch. One warning: it
+ is possible using the -client switch to cause the old sendmails
+ to return "I refuse to talk to myself". You could do this under
+ the old code as well. This will happen if you claim to be the
+ same system as the sendmail you're sending to is running on.
+ That's pointless, but possible. If you do this, just like under
+ the old code, you will get an error.
+
+ 5) If you're running a site with both old and new sendmails, you only
+ have to build MH once. The code's the same; works with them
+ both.
+
+ If you decide to install this, make sure that you look the patch
+over and that you agree with what it is doing. It works for me, but I
+can't test it on every possible combination. Make sure that it works
+before you really install it for your users, if any. No promises.
+
+ To install this, save this to a file in the mts/sendmail directory.
+Feed it to patch. Patch will ignore the non-patch stuff. You should have
+"mts sendmail/smtp" in your configuration file. This works with old and
+new sendmails. Using "mts sendmail" will cause the new sendmails to
+print an "X-auth..." warning about who owns the process piping the mail
+message. I don't know of anyway of getting rid of these.
+
+ mh-config (if necessary), make, make inst-all.
+
+
+I hope this helps people.
+
+/dcn
+
+Dave Nelson
+Academic Computer Services
+DePaul University, Chicago
+
+*** smail.c Fri Sep 3 11:58:05 1993
+--- smail.c Fri Sep 3 11:57:27 1993
+***************
+*** 239,261 ****
+ return RP_RPLY;
+ }
+
+! if (client && *client) {
+! doingEHLO = 1;
+! result = smtalk (SM_HELO, "EHLO %s", client);
+! doingEHLO = 0;
+
+! if (500 <= result && result <= 599)
+ result = smtalk (SM_HELO, "HELO %s", client);
+!
+! switch (result) {
+ case 250:
+! break;
+
+ default:
+ (void) sm_end (NOTOK);
+ return RP_RPLY;
+ }
+ }
+
+ #ifndef ZMAILER
+ if (onex)
+--- 239,276 ----
+ return RP_RPLY;
+ }
+
+! doingEHLO = 1;
+! result = smtalk (SM_HELO, "EHLO %s",
+! (client && *client) ? client : LocalName());
+! doingEHLO = 0;
+!
+! switch (result)
+! {
+! case 250:
+! break;
+
+! default:
+! if (!(500 <= result && result <= 599))
+! {
+! (void) sm_end (NOTOK);
+! return RP_RPLY;
+! }
+!
+! if (client && *client)
+! {
+ result = smtalk (SM_HELO, "HELO %s", client);
+! switch (result)
+! {
+ case 250:
+! break;
+
+ default:
+ (void) sm_end (NOTOK);
+ return RP_RPLY;
++ }
+ }
+ }
++
+
+ #ifndef ZMAILER
+ if (onex)
+***************
+*** 357,380 ****
+ return RP_RPLY;
+ }
+
+! if (client && *client) {
+! doingEHLO = 1;
+! result = smtalk (SM_HELO, "EHLO %s", client);
+! doingEHLO = 0;
+
+! if (500 <= result && result <= 599)
+ result = smtalk (SM_HELO, "HELO %s", client);
+!
+! switch (result) {
+! case 250:
+ break;
+
+! default:
+ (void) sm_end (NOTOK);
+ return RP_RPLY;
+ }
+ }
+!
+ send_options: ;
+ if (watch && EHLOset ("XVRB"))
+ (void) smtalk (SM_HELO, "VERB on");
+--- 372,409 ----
+ return RP_RPLY;
+ }
+
+! doingEHLO = 1;
+! result = smtalk (SM_HELO, "EHLO %s",
+! (client && *client) ? client : LocalName());
+! doingEHLO = 0;
+!
+! switch (result)
+! {
+! case 250:
+! break;
+!
+! default:
+! if (!(500 <= result && result <= 599))
+! {
+! (void) sm_end (NOTOK);
+! return RP_RPLY;
+! }
+
+! if (client && *client)
+! {
+ result = smtalk (SM_HELO, "HELO %s", client);
+! switch (result)
+! {
+! case 250:
+ break;
+
+! default:
+ (void) sm_end (NOTOK);
+ return RP_RPLY;
++ }
+ }
+ }
+!
+ send_options: ;
+ if (watch && EHLOset ("XVRB"))
+ (void) smtalk (SM_HELO, "VERB on");
diff --git a/usr.sbin/sendmail/contrib/mmuegel b/usr.sbin/sendmail/contrib/mmuegel
new file mode 100644
index 0000000..6db4a45
--- /dev/null
+++ b/usr.sbin/sendmail/contrib/mmuegel
@@ -0,0 +1,2079 @@
+From: "Michael S. Muegel" <mmuegel@cssun6.corp.mot.com>
+Message-Id: <199307280818.AA08111@cssun6.corp.mot.com>
+Subject: Re: contributed software
+To: eric@cs.berkeley.edu (Eric Allman)
+Date: Wed, 28 Jul 1993 03:18:02 -0500 (CDT)
+In-Reply-To: <199307221853.LAA04266@mastodon.CS.Berkeley.EDU> from "Eric Allman" at Jul 22, 93 11:53:47 am
+X-Mailer: ELM [version 2.4 PL22]
+Mime-Version: 1.0
+Content-Type: text/plain; charset=US-ASCII
+Content-Transfer-Encoding: 7bit
+Content-Length: 69132
+
+OK. Here is a new shell archive.
+
+Cheers,
+-Mike
+
+---- Cut Here and feed the following to sh ----
+#!/bin/sh
+# This is a shell archive (produced by shar 3.49)
+# To extract the files from this archive, save it to a file, remove
+# everything above the "!/bin/sh" line above, and type "sh file_name".
+#
+# made 07/28/1993 08:13 UTC by mmuegel@mot.com (Michael S. Muegel)
+# Source directory /home/ustart/NeXT/src/mail-tools/dist/foo
+#
+# existing files will NOT be overwritten unless -c is specified
+#
+# This shar contains:
+# length mode name
+# ------ ---------- ------------------------------------------
+# 4308 -r--r--r-- README
+# 12339 -r--r--r-- libs/date.pl
+# 3198 -r--r--r-- libs/elapsed.pl
+# 4356 -r--r--r-- libs/mail.pl
+# 6908 -r--r--r-- libs/mqueue.pl
+# 7024 -r--r--r-- libs/newgetopts.pl
+# 4687 -r--r--r-- libs/strings1.pl
+# 1609 -r--r--r-- libs/timespec.pl
+# 5212 -r--r--r-- man/cqueue.1
+# 2078 -r--r--r-- man/postclip.1
+# 6647 -r-xr-xr-x src/cqueue
+# 1836 -r-xr-xr-x src/postclip
+#
+# ============= README ==============
+if test -f 'README' -a X"$1" != X"-c"; then
+ echo 'x - skipping README (File already exists)'
+else
+echo 'x - extracting README (Text)'
+sed 's/^X//' << 'SHAR_EOF' > 'README' &&
+-------------------------------------------------------------------------------
+Document Revision Control Information:
+X mmuegel
+X /usr/local/ustart/src/mail-tools/dist/foo/README,v
+X 1.1 of 1993/07/28 08:12:53
+-------------------------------------------------------------------------------
+X
+1. Introduction
+---------------
+X
+These tools may be of use to those sites using sendmail. Both are written in
+Perl. Our site, Mot.COM, receives a ton of mail being a top-level domain
+gateway. We have over 24 domains under us. Needless to say, we must have
+a robust mail system or my head, and others, would be on the chopping block.
+X
+2. Description
+--------------
+X
+The first tool, cqueue, checks the sendmail queue for problems. We use
+it to flag problems with subdomain mail servers (and even our own servers
+once in a while ;-). We run it via a cron job every hour during the day.
+You may find this too frequent, however.
+X
+The other program, postclip, is used to "filter" non-deliverable NDNs that
+get sent to our Postmaster account now and then. This ensures privacy of
+e-mail and helps avoid disk problems from huge NDNs. It is different than
+a brute force "just keep the header" approach because it tries hard to keep
+other parts of the message that look like non-delivery information.
+X
+Both have been used for some time at our site with no problems. Everything
+you need should be in this distribution: source, manual pages, and support
+libs. See the manual pages for a complete description of each tool.
+X
+3. Installation
+---------------
+X
+No fancy Makefile simply because these tools are all under a large
+hierarchy at my site. Installation should be a snap, however. Install
+the nroff(1) man(5) manual pages from the man subdirectory to the
+appropriate directory on your system. This might be something like
+/usr/local/man/man1.
+X
+Next, install all of the Perl libraries located in the lib subdirectory
+to your Perl library area. /usr/local/lib/perl is a good bet. The person
+who installed Perl at your site will be able to tell you for sure.
+X
+Finally, you need to install the programs. Note that cqueue wants to
+run setuid root by default. This is because the sendmail queue is normally
+only readable by root or some special group. In order to let any user
+run this suidperl is used. suidperl allows a Perl program to run with the
+privileges of another user.
+X
+You will have to edit both the cqueue and postclip programs to change
+the #! line at the top of each. Just change the pathname to whatever is
+appropriate on your system. Note that Larry Wall's fixin program from
+the Camel book can also be used to do this. It is very handy. It changes
+#! lines by looking at your PATH.
+X
+If you do not have suidperl on your system change the #! line in cqueue
+to reference perl instead of suidperl.
+X
+You may also wish to change some constants in cqueue. $DEF_QUEUE should be
+changed to your queue directory if it is not /usr/spool/mqueue. $DEF_TIME
+could be changed easy enough also. It is the time spec for the time duration
+after which a mail message will be reported on if the -a option has not been
+specified. See the manual page for more information and the format of this
+constant (same as the -t argument). Then again, neither of these has to
+be changed. Command line options are there to override their default
+values.
+X
+After you have edited the programs as necessary, all that remains is to
+install them to some executable directory. Install postclip mode 555
+and cqueue mode 4555 with owner root (if using suidperl) or mode 555
+(if not using suidperl).
+X
+4. Gripes, Comments, Etc
+------------------------
+X
+If you start using either of these let me know. I have other mail tools I
+will likely post in the future if these prove useful. Also, if you think
+something is just plain dumb/wrong/stupid let me know!
+X
+Cheers,
+-Mike
+X
+--
++----------------------------------------------------------------------------+
+| Michael S. Muegel | Internet E-Mail: mmuegel@mot.com |
+| UNIX Applications Startup Group | Moto Dist E-Mail: X10090 |
+| Corporate Information Office | Voice: (708) 576-0507 |
+| Motorola | Fax: (708) 576-4153 |
++----------------------------------------------------------------------------+
+SHAR_EOF
+chmod 0444 README ||
+echo 'restore of README failed'
+Wc_c="`wc -c < 'README'`"
+test 4308 -eq "$Wc_c" ||
+ echo 'README: original size 4308, current size' "$Wc_c"
+fi
+# ============= libs/date.pl ==============
+if test ! -d 'libs'; then
+ echo 'x - creating directory libs'
+ mkdir 'libs'
+fi
+if test -f 'libs/date.pl' -a X"$1" != X"-c"; then
+ echo 'x - skipping libs/date.pl (File already exists)'
+else
+echo 'x - extracting libs/date.pl (Text)'
+sed 's/^X//' << 'SHAR_EOF' > 'libs/date.pl' &&
+;#
+;# Name
+;# date.pl - Perl emulation of (the output side of) date(1)
+;#
+;# Synopsis
+;# require "date.pl";
+;# $Date = &date(time);
+;# $Date = &date(time, $format);
+;#
+;# Description
+;# This package implements the output formatting functions of date(1) in
+;# Perl. The format options are based on those supported by Ultrix 4.0
+;# plus a couple of additions from SunOS 4.1.1 and elsewhere:
+;#
+;# %a abbreviated weekday name - Sun to Sat
+;# %A full weekday name - Sunday to Saturday
+;# %b abbreviated month name - Jan to Dec
+;# %B full month name - January to December
+;# %c date and time in local format [+]
+;# %C date and time in long local format [+]
+;# %d day of month - 01 to 31
+;# %D date as mm/dd/yy
+;# %e day of month (space padded) - ` 1' to `31'
+;# %E day of month (with suffix: 1st, 2nd, 3rd...)
+;# %f month of year (space padded) - ` 1' to `12'
+;# %h abbreviated month name - Jan to Dec
+;# %H hour - 00 to 23
+;# %i hour (space padded) - ` 1' to `12'
+;# %I hour - 01 to 12
+;# %j day of the year (Julian date) - 001 to 366
+;# %k hour (space padded) - ` 0' to `23'
+;# %l date in ls(1) format
+;# %m month of year - 01 to 12
+;# %M minute - 00 to 59
+;# %n insert a newline character
+;# %p ante-meridiem or post-meridiem indicator (AM or PM)
+;# %r time in AM/PM notation
+;# %R time as HH:MM
+;# %S second - 00 to 59
+;# %t insert a tab character
+;# %T time as HH:MM:SS
+;# %u date/time in date(1) required format
+;# %U week number, Sunday as first day of week - 00 to 53
+;# %V date-time in SysV touch format (mmddHHMMyy)
+;# %w day of week - 0 (Sunday) to 6
+;# %W week number, Monday as first day of week - 00 to 53
+;# %x date in local format [+]
+;# %X time in local format [+]
+;# %y last 2 digits of year - 00 to 99
+;# %Y all 4 digits of year ~ 1700 to 2000 odd ?
+;# %z time zone from TZ environment variable w/ a trailing space
+;# %Z time zone from TZ environment variable
+;# %% insert a `%' character
+;# %+ insert a `+' character
+;#
+;# [+]: These may need adjustment to fit local conventions, see below.
+;#
+;# For the sake of compatibility, a leading `+' in the format
+;# specificaiton is removed if present.
+;#
+;# Remarks
+;# This is version 3.4 of date.pl
+;#
+;# An extension of `ctime.pl' by Waldemar Kebsch (kebsch.pad@nixpbe.UUCP),
+;# as modified by Marion Hakanson (hakanson@ogicse.ogi.edu).
+;#
+;# Unlike date(1), unknown format tags are silently replaced by "".
+;#
+;# defaultTZ is a blatant hack, but I wanted to be able to get date(1)
+;# like behaviour by default and there does'nt seem to be an easy (read
+;# portable) way to get the local TZ name back...
+;#
+;# For a cheap date, try...
+;#
+;# #!/usr/local/bin/perl
+;# require "date.pl";
+;# exit print (&date(time, shift @ARGV) . "\n") ? 0 : 1;
+;#
+;# This package is redistributable under the same terms as apply to
+;# the Perl 4.0 release. See the COPYING file in your Perl kit for
+;# more information.
+;#
+;# Please send any bug reports or comments to tmcgonigal@gallium.com
+;#
+;# Modification History
+;# Nmemonic Version Date Who
+;#
+;# NONE 1.0 02feb91 Terry McGonigal (tmcgonigal@gallium.com)
+;# Created from ctime.pl
+;#
+;# NONE 2.0 07feb91 tmcgonigal
+;# Added some of Marion Hakanson (hakanson@ogicse.ogi.edu)'s ctime.pl
+;# TZ handling changes.
+;#
+;# NONE 2.1 09feb91 tmcgonigal
+;# Corrected week number calculations.
+;#
+;# NONE 2.2 21oct91 tmcgonigal
+;# Added ls(1) date format, `%l'.
+;#
+;# NONE 2.3 06nov91 tmcgonigal
+;# Added SysV touch(1) date-time format, `%V' (pretty thin as
+;# mnemonics go, I know, but `t' and `T' were both gone already!)
+;#
+;# NONE 2.4 05jan92 tmcgonigal
+;# Corrected slight (cosmetic) problem with %V replacment string
+;#
+;# NONE 3.0 09jul92 tmcgonigal
+;# Fixed a couple of problems with &ls as pointed out by
+;# Thomas Richter (richter@ki1.chemie.fu-berlin.de), thanks Thomas!
+;# Also added a couple of SunOS 4.1.1 strftime-ish formats, %i and %k
+;# for space padded hours (` 1' to `12' and ` 0' to `23' respectivly),
+;# and %C for locale long date/time format. Changed &ampmH to take a
+;# pad char parameter to make to evaled code for %i and %k simpler.
+;# Added %E for suffixed day-of-month (ie 1st, 3rd, 4th etc).
+;#
+;# NONE 3.1 16jul92 tmcgonigal
+;# Added `%u' format to generate date/time in date(1) required
+;# format (ie '%y%m%d%H%M.%S').
+;#
+;# NONE 3.2 23jan93 tmcgonigal
+;# Added `%f' format to generate space padded month numbers, added
+;# `%E' to the header comments, it seems to have been left out (and
+;# I'm sure I wanted to use it at some point in the past...).
+;#
+;# NONE 3.3 03feb93 tmcgonigal
+;# Corrected some problems with AM/PM handling pointed out by
+;# Michael S. Muegel (mmuegel@mot.com). Thanks Michael, I hope
+;# this is the behaviour you were looking for, it seems more
+;# correct to me...
+;#
+;# NONE 3.4 26jul93 tmcgonigal
+;# Incorporated some fixes provided by DaviD W. Sanderson
+;# (dws@ssec.wisc.edu): February was spelled incorrectly and
+;# &wkno() was always using the current year while calculating
+;# week numbers, regardless of year implied by the time value
+;# passed to &date(). DaviD also contributed an improved &date()
+;# test script, thanks DaviD, I appreciate the effort. Finally,
+;# changed my mailling address from @gvc.com to @gallium.com
+;# to reflect, well, my new address!
+;#
+;# SccsId = "%W% %E%"
+;#
+require 'timelocal.pl';
+package date;
+X
+# Months of the year
+@MoY = ('January', 'February', 'March', 'April', 'May', 'June',
+X 'July', 'August', 'September','October', 'November', 'December');
+X
+# days of the week
+@DoW = ('Sunday', 'Monday', 'Tuesday', 'Wednesday',
+X 'Thursday', 'Friday', 'Saturday');
+X
+# CUSTOMIZE - defaults
+$defaultTZ = 'CST'; # time zone (hack!)
+$defaultFMT = '%a %h %e %T %z%Y'; # format (ala date(1))
+X
+# CUSTOMIZE - `local' formats
+$locTF = '%T'; # time (as HH:MM:SS)
+$locDF = '%D'; # date (as mm/dd/yy)
+$locDTF = '%a %b %d %T %Y'; # date/time (as dow mon dd HH:MM:SS yyyy)
+$locLDTF = '%i:%M:%S %p %A %B %E %Y'; # long date/time (as HH:MM:SS a/p day month dom yyyy)
+X
+# Time zone info
+$TZ; # wkno needs this info too
+X
+# define the known format tags as associative keys with their associated
+# replacement strings as values. Each replacement string should be
+# an eval-able expresion assigning a value to $rep. These expressions are
+# eval-ed, then the value of $rep is substituted into the supplied
+# format (if any).
+%Tags = ( '%a', q|($rep = $DoW[$wday])=~ s/^(...).*/\1/|, # abbr. weekday name - Sun to Sat
+X '%A', q|$rep = $DoW[$wday]|, # full weekday name - Sunday to Saturday
+X '%b', q|($rep = $MoY[$mon]) =~ s/^(...).*/\1/|, # abbr. month name - Jan to Dec
+X '%B', q|$rep = $MoY[$mon]|, # full month name - January to December
+X '%c', q|$rep = $locDTF; 1|, # date/time in local format
+X '%C', q|$rep = $locLDTF; 1|, # date/time in local long format
+X '%d', q|$rep = &date'pad($mday, 2, "0")|, # day of month - 01 to 31
+X '%D', q|$rep = '%m/%d/%y'|, # date as mm/dd/yy
+X '%e', q|$rep = &date'pad($mday, 2, " ")|, # day of month (space padded) ` 1' to `31'
+X '%E', q|$rep = &date'dsuf($mday)|, # day of month (w/suffix) `1st' to `31st'
+X '%f', q|$rep = &date'pad($mon+1, 2, " ")|, # month of year (space padded) ` 1' to `12'
+X '%h', q|$rep = '%b'|, # abbr. month name (same as %b)
+X '%H', q|$rep = &date'pad($hour, 2, "0")|, # hour - 00 to 23
+X '%i', q|$rep = &date'ampmH($hour, " ")|, # hour (space padded ` 1' to `12'
+X '%I', q|$rep = &date'ampmH($hour, "0")|, # hour - 01 to 12
+X '%j', q|$rep = &date'pad($yday+1, 3, "0")|, # Julian date 001 - 366
+X '%k', q|$rep = &date'pad($hour, 2, " ")|, # hour (space padded) ` 0' to `23'
+X '%l', q|$rep = '%b %d ' . &date'ls($year)|, # ls(1) style date
+X '%m', q|$rep = &date'pad($mon+1, 2, "0")|, # month of year - 01 to 12
+X '%M', q|$rep = &date'pad($min, 2, "0")|, # minute - 00 to 59
+X '%n', q|$rep = "\n"|, # insert a newline
+X '%p', q|$rep = &date'ampmD($hour)|, # insert `AM' or `PM'
+X '%r', q|$rep = '%I:%M:%S %p'|, # time in AM/PM notation
+X '%R', q|$rep = '%H:%M'|, # time as HH:MM
+X '%S', q|$rep = &date'pad($sec, 2, "0")|, # second - 00 to 59
+X '%t', q|$rep = "\t"|, # insert a tab
+X '%T', q|$rep = '%H:%M:%S'|, # time as HH:MM:SS
+X '%u', q|$rep = '%y%m%d%H%M.%S'|, # daaate/time in date(1) required format
+X '%U', q|$rep = &date'wkno($year, $yday, 0)|, # week number (weeks start on Sun) - 00 to 53
+X '%V', q|$rep = '%m%d%H%M%y'|, # SysV touch(1) date-time format (mmddHHMMyy)
+X '%w', q|$rep = $wday; 1|, # day of week - Sunday = 0
+X '%W', q|$rep = &date'wkno($year, $yday, 1)|, # week number (weeks start on Mon) - 00 to 53
+X '%x', q|$rep = $locDF; 1|, # date in local format
+X '%X', q|$rep = $locTF; 1|, # time in local format
+X '%y', q|($rep = $year) =~ s/..(..)/\1/|, # last 2 digits of year - 00 to 99
+X '%Y', q|$rep = "$year"; 1|, # full year ~ 1700 to 2000 odd
+X '%z', q|$rep = $TZ eq "" ? "" : "$TZ "|, # time zone from TZ env var (w/trail. space)
+X '%Z', q|$rep = $TZ; 1|, # time zone from TZ env. var.
+X '%%', q|$rep = '%'; $adv=1|, # insert a `%'
+X '%+', q|$rep = '+'| # insert a `+'
+);
+X
+sub main'date {
+X local($time, $format) = @_;
+X local($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst);
+X local($pos, $tag, $rep, $adv) = (0, "", "", 0);
+X
+X # default to date/ctime format or strip leading `+'...
+X if ($format eq "") {
+X $format = $defaultFMT;
+X } elsif ($format =~ /^\+/) {
+X $format = $';
+X }
+X
+X # Use local time if can't find a TZ in the environment
+X $TZ = defined($ENV{'TZ'}) ? $ENV{'TZ'} : $defaultTZ;
+X ($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst) =
+X &gettime ($TZ, $time);
+X
+X # Hack to deal with 'PST8PDT' format of TZ
+X # Note that this can't deal with all the esoteric forms, but it
+X # does recognize the most common: [:]STDoff[DST[off][,rule]]
+X if ($TZ =~ /^([^:\d+\-,]{3,})([+-]?\d{1,2}(:\d{1,2}){0,2})([^\d+\-,]{3,})?/) {
+X $TZ = $isdst ? $4 : $1;
+X }
+X
+X # watch out in 2070...
+X $year += ($year < 70) ? 2000 : 1900;
+X
+X # now loop throught the supplied format looking for tags...
+X while (($pos = index ($format, '%')) != -1) {
+X
+X # grab the format tag
+X $tag = substr($format, $pos, 2);
+X $adv = 0; # for `%%' processing
+X
+X # do we have a replacement string?
+X if (defined $Tags{$tag}) {
+X
+X # trap dead evals...
+X if (! eval $Tags{$tag}) {
+X print STDERR "date.pl: internal error: eval for $tag failed: $@\n";
+X return "";
+X }
+X } else {
+X $rep = "";
+X }
+X
+X # do the substitution
+X substr ($format, $pos, 2) =~ s/$tag/$rep/;
+X $pos++ if ($adv);
+X }
+X
+X $format;
+}
+X
+# dsuf - add `st', `nd', `rd', `th' to a date (ie 1st, 22nd, 29th)
+sub dsuf {
+X local ($mday) = @_;
+X
+X return $mday . 'st' if ($mday =~ m/.*1$/);
+X return $mday . 'nd' if ($mday =~ m/.*2$/);
+X return $mday . 'rd' if ($mday =~ m/.*3$/);
+X return $mday . 'th';
+}
+X
+# weekno - figure out week number
+sub wkno {
+X local ($year, $yday, $firstweekday) = @_;
+X local ($jan1, @jan1, $wks);
+X
+X # figure out the `time' value for January 1 of the given year
+X $jan1 = &maketime ($TZ, 0, 0, 0, 1, 0, $year-1900);
+X
+X # figure out what day of the week January 1 was
+X @jan1= &gettime ($TZ, $jan1);
+X
+X # and calculate the week number
+X $wks = (($yday + ($jan1[6] - $firstweekday)) + 1)/ 7;
+X $wks += (($wks - int($wks) > 0.0) ? 1 : 0);
+X
+X # supply zero padding
+X &pad (int($wks), 2, "0");
+}
+X
+# ampmH - figure out am/pm (1 - 12) mode hour value, padded with $p (0 or ' ')
+sub ampmH { local ($h, $p) = @_; &pad($h>12 ? $h-12 : ($h ? $h : 12), 2, $p); }
+X
+# ampmD - figure out am/pm designator
+sub ampmD { shift @_ >= 12 ? "PM" : "AM"; }
+X
+# gettime - get the time via {local,gmt}time
+sub gettime { ((shift @_) eq 'GMT') ? gmtime(shift @_) : localtime(shift @_); }
+X
+# maketime - make a time via time{local,gmt}
+sub maketime { ((shift @_) eq 'GMT') ? &main'timegm(@_) : &main'timelocal(@_); }
+X
+# ls - generate the time/year portion of an ls(1) style date
+sub ls {
+X return ((&gettime ($TZ, time))[5] == @_[0]) ? "%R" : " %Y";
+}
+X
+# pad - pad $in with leading $pad until lenght $len
+sub pad {
+X local ($in, $len, $pad) = @_;
+X local ($out) = "$in";
+X
+X $out = $pad . $out until (length ($out) == $len);
+X return $out;
+}
+X
+1;
+SHAR_EOF
+chmod 0444 libs/date.pl ||
+echo 'restore of libs/date.pl failed'
+Wc_c="`wc -c < 'libs/date.pl'`"
+test 12339 -eq "$Wc_c" ||
+ echo 'libs/date.pl: original size 12339, current size' "$Wc_c"
+fi
+# ============= libs/elapsed.pl ==============
+if test -f 'libs/elapsed.pl' -a X"$1" != X"-c"; then
+ echo 'x - skipping libs/elapsed.pl (File already exists)'
+else
+echo 'x - extracting libs/elapsed.pl (Text)'
+sed 's/^X//' << 'SHAR_EOF' > 'libs/elapsed.pl' &&
+;# NAME
+;# elapsed.pl - convert seconds to elapsed time format
+;#
+;# AUTHOR
+;# Michael S. Muegel <mmuegel@mot.com>
+;#
+;# RCS INFORMATION
+;# mmuegel
+;# /usr/local/ustart/src/mail-tools/dist/foo/libs/elapsed.pl,v
+;# 1.1 of 1993/07/28 08:07:19
+X
+package elapsed;
+X
+# Time field types
+$DAYS = 1;
+$HOURS = 2;
+$MINUTES = 3;
+$SECONDS = 4;
+X
+# The array contains four records each with four fields. The fields are,
+# in order:
+#
+# Type Specifies what kind of time field this is. Once of
+# $DAYS, $HOURS, $MINUTES, or $SECONDS.
+#
+# Multiplier Specifies what time field this is via the minimum
+# number of seconds this time field may specify. For
+# example, the minutes field would be non-zero
+# when there are 60 or more seconds.
+#
+# Separator How to separate this time field from the next
+# *greater* field.
+#
+# Format sprintf() format specifier on how to print this
+# time field.
+@MULT_AND_SEPS = ($DAYS, 60 * 60 * 24, "+", "%d",
+X $HOURS, 60 * 60, ":", "%d",
+X $MINUTES, 60, ":", "%02d",
+X $SECONDS, 1, "", "%02d"
+X );
+X
+;###############################################################################
+;# Seconds_To_Elapsed
+;#
+;# Coverts a seconds count to form [d+]h:mm:ss. If $Collapse
+;# is true then the result is compacted somewhat. The string returned
+;# will be of the form [d+][[h:]mm]:ss.
+;#
+;# Arguments:
+;# $Seconds, $Collapse
+;#
+;# Examples:
+;# &Seconds_To_Elapsed (0, 0) -> 0:00:00
+;# &Seconds_To_Elapsed (0, 1) -> :00
+;#
+;# &Seconds_To_Elapsed (119, 0) -> 0:01:59
+;# &Seconds_To_Elapsed (119, 1) -> 01:59
+;#
+;# &Seconds_To_Elapsed (3601, 0) -> 1:00:01
+;# &Seconds_To_Elapsed (3601, 1) -> 1:00:01
+;#
+;# &Seconds_To_Elapsed (86401, 0) -> 1+0:00:01
+;# &Seconds_To_Elapsed (86401, 1) -> 1+:01
+;#
+;# Returns:
+;# $Elapsed
+;###############################################################################
+sub main'Seconds_To_Elapsed
+{
+X local ($Seconds, $Collapse) = @_;
+X local ($Type, $Multiplier, @Multipliers, $Separator, $DHMS_Used,
+X $Elapsed, @Mult_And_Seps, $Print_Field);
+X
+X $Multiplier = 1;
+X @Mult_And_Seps = @MULT_AND_SEPS;
+X
+X # Keep subtracting the number of seconds corresponding to a time field
+X # from the number of seconds passed to the function.
+X while (1)
+X {
+X ($Type, $Multiplier, $Separator, $Format) = splice (@Mult_And_Seps, 0, 4);
+X last if (! $Multiplier);
+X $Seconds -= $DHMS_Used * $Multiplier
+X if ($DHMS_Used = int ($Seconds / $Multiplier));
+X
+X # Figure out if we should print this field
+X if ($Type == $DAYS)
+X {
+X $Print_Field = $DHMS_Used;
+X }
+X
+X elsif ($Collapse)
+X {
+X if ($Type == $HOURS)
+X {
+X $Print_Field = $DHMS_Used;
+X }
+X elsif ($Type == $MINUTES)
+X {
+X $Print_Field = $DHMS_Used || $Printed_Field {$HOURS};
+X }
+X else
+X {
+X $Format = ":%02d"
+X if (! $Printed_Field {$MINUTES});
+X $Print_Field = 1;
+X };
+X }
+X
+X else
+X {
+X $Print_Field = 1;
+X };
+X
+X $Printed_Field {$Type} = $Print_Field;
+X $Elapsed .= sprintf ("$Format%s", $DHMS_Used, $Separator)
+X if ($Print_Field);
+X };
+X
+X return ($Elapsed);
+};
+X
+1;
+SHAR_EOF
+chmod 0444 libs/elapsed.pl ||
+echo 'restore of libs/elapsed.pl failed'
+Wc_c="`wc -c < 'libs/elapsed.pl'`"
+test 3198 -eq "$Wc_c" ||
+ echo 'libs/elapsed.pl: original size 3198, current size' "$Wc_c"
+fi
+# ============= libs/mail.pl ==============
+if test -f 'libs/mail.pl' -a X"$1" != X"-c"; then
+ echo 'x - skipping libs/mail.pl (File already exists)'
+else
+echo 'x - extracting libs/mail.pl (Text)'
+sed 's/^X//' << 'SHAR_EOF' > 'libs/mail.pl' &&
+;# NAME
+;# mail.pl - perl function(s) to handle mail processing
+;#
+;# AUTHOR
+;# Michael S. Muegel (mmuegel@mot.com)
+;#
+;# RCS INFORMATION
+;# mmuegel
+;# /usr/local/ustart/src/mail-tools/dist/foo/libs/mail.pl,v 1.1 1993/07/28 08:07:19 mmuegel Exp
+X
+package mail;
+X
+# Mailer statement to eval. $Users, $Subject, and $Verbose are substituted
+# via eval
+$BIN_MAILER = "/usr/ucb/mail \$Verbose -s '\$Subject' \$Users";
+X
+# Sendmail command to use when $Use_Sendmail is true.
+$SENDMAIL = '/usr/lib/sendmail $Verbose $Users';
+X
+;###############################################################################
+;# Send_Mail
+;#
+;# Sends $Message to $Users with a subject of $Subject. If $Message_Is_File
+;# is true then $Message is assumed to be a filename pointing to the mail
+;# message. This is a new option and thus the backwards-compatible hack.
+;# $Users should be a space separated list of mail-ids.
+;#
+;# If everything went OK $Status will be 1 and $Error_Msg can be ignored;
+;# otherwise, $Status will be 0 and $Error_Msg will contain an error message.
+;#
+;# If $Use_Sendmail is 1 then sendmail is used to send the message. Normally
+;# a mailer such as Mail is used. By specifiying this you can include
+;# headers in addition to text in either $Message or $Message_Is_File.
+;# If either $Message or $Message_Is_File contain a Subject: header then
+;# $Subject is ignored; otherwise, a Subject: header is automatically created.
+;# Similar to the Subject: header, if a To: header does not exist one
+;# is automatically created from the $Users argument. The mail is still
+;# sent, however, to the recipients listed in $Users. This is keeping with
+;# normal sendmail usage (header vs. envelope).
+;#
+;# In both bin mailer and sendmail modes $Verbose will turn on verbose mode
+;# (normally just sendmail verbose mode output).
+;#
+;# Arguments:
+;# $Users, $Subject, $Message, $Message_Is_File, $Verbose, $Use_Sendmail
+;#
+;# Returns:
+;# $Status, $Error_Msg
+;###############################################################################
+sub main'Send_Mail
+{
+X local ($Users, $Subject, $Message, $Message_Is_File, $Verbose,
+X $Use_Sendmail) = @_;
+X local ($BIN_MAILER_HANDLE, $Mailer_Command, $Header_Found, %Header_Map,
+X $Header_Extra, $Mailer);
+X
+X # If the message is contained in a file read it in so we can have one
+X # consistent interface
+X if ($Message_Is_File)
+X {
+X undef $/;
+X $Message_Is_File = 0;
+X open (Message) || return (0, "error reading $Message: $!");
+X $Message = <Message>;
+X close (Message);
+X };
+X
+X # If sendmail mode see if we need to add some headers
+X if ($Use_Sendmail)
+X {
+X # Determine if a header block is included in the message and what headers
+X # are there
+X foreach (split (/\n/, $Message))
+X {
+X last if ($_ eq "");
+X $Header_Found = $Header_Map {$1} = 1 if (/^([A-Z]\S*): /);
+X };
+X
+X # Add some headers?
+X if (! $Header_Map {"To"})
+X {
+X $Header_Extra .= "To: " . join (", ", $Users) . "\n";
+X };
+X if (($Subject ne "") && (! $Header_Map {"Subject"}))
+X {
+X $Header_Extra .= "Subject: $Subject\n";
+X };
+X
+X # Add the required blank line between header/body if there where no
+X # headers to begin with
+X if ($Header_Found)
+X {
+X $Message = "$Header_Extra$Message";
+X }
+X else
+X {
+X $Message = "$Header_Extra\n$Message";
+X };
+X };
+X
+X # Get a string that is the mail command
+X $Verbose = ($Verbose) ? "-v" : "";
+X $Mailer = ($Use_Sendmail) ? $SENDMAIL : $BIN_MAILER;
+X eval "\$Mailer = \"$Mailer\"";
+X return (0, "error setting \$Mailer: $@") if ($@);
+X
+X # need to catch SIGPIPE in case the $Mailer call fails
+X $SIG {'PIPE'} = "mail'Cleanup";
+X
+X # Open mailer
+X return (0, "can not open mail program: $Mailer") if (! open (MAILER, "| $Mailer"));
+X
+X # Send off the mail!
+X print MAILER $Message;
+X close (MAILER);
+X return (0, "error running mail program: $Mailer") if ($?);
+X
+X # Everything must have went AOK
+X return (1);
+};
+X
+;###############################################################################
+;# Cleanup
+;#
+;# Simply here so we can catch SIGPIPE and not exit.
+;#
+;# Globals:
+;# None
+;#
+;# Arguments:
+;# None
+;#
+;# Returns:
+;# Nothing exciting
+;###############################################################################
+sub Cleanup
+{
+};
+X
+1;
+SHAR_EOF
+chmod 0444 libs/mail.pl ||
+echo 'restore of libs/mail.pl failed'
+Wc_c="`wc -c < 'libs/mail.pl'`"
+test 4356 -eq "$Wc_c" ||
+ echo 'libs/mail.pl: original size 4356, current size' "$Wc_c"
+fi
+# ============= libs/mqueue.pl ==============
+if test -f 'libs/mqueue.pl' -a X"$1" != X"-c"; then
+ echo 'x - skipping libs/mqueue.pl (File already exists)'
+else
+echo 'x - extracting libs/mqueue.pl (Text)'
+sed 's/^X//' << 'SHAR_EOF' > 'libs/mqueue.pl' &&
+;# NAME
+;# mqueue.pl - functions to work with the sendmail queue
+;#
+;# DESCRIPTION
+;# Both Get_Queue_IDs and Parse_Control_File are available to get
+;# information about the sendmail queue. The cqueue program is a good
+;# example of how these functions work.
+;#
+;# AUTHOR
+;# Michael S. Muegel (mmuegel@mot.com)
+;#
+;# RCS INFORMATION
+;# mmuegel
+;# /usr/local/ustart/src/mail-tools/dist/foo/libs/mqueue.pl,v
+;# 1.1 of 1993/07/28 08:07:19
+X
+package mqueue;
+X
+;###############################################################################
+;# Get_Queue_IDs
+;#
+;# Will figure out the queue IDs in $Queue that have both control and data
+;# files. They are returned in @Valid_IDs. Those IDs that have a
+;# control file and no data file are saved to the array globbed by
+;# *Missing_Control_IDs. Likewise, those IDs that have a data file and no
+;# control file are saved to the array globbed by *Missing_Data_IDs.
+;#
+;# If $Skip_Locked is true they a message that has a lock file is skipped
+;# and will not show up in any of the arrays.
+;#
+;# If everything went AOK then $Status is 1; otherwise, $Status is 0 and
+;# $Msg tells what went wrong.
+;#
+;# Globals:
+;# None
+;#
+;# Arguments:
+;# $Queue, $Skip_Locked, *Missing_Control_IDs, *Missing_Data_IDs
+;#
+;# Returns:
+;# $Status, $Msg, @Valid_IDs
+;###############################################################################
+sub main'Get_Queue_IDs
+{
+X local ($Queue, $Skip_Locked, *Missing_Control_IDs,
+X *Missing_Data_IDs) = @_;
+X local (*QUEUE, @Files, %Lock_IDs, %Data_IDs, %Control_IDs, $_);
+X
+X # Make sure that the * argument @arrays ar empty
+X @Missing_Control_IDs = @Missing_Data_IDs = ();
+X
+X # Save each data, lock, and queue file in @Files
+X opendir (QUEUE, $Queue) || return (0, "error getting directory listing of $Queue");
+X @Files = grep (/^(df|lf|qf)/, readdir (QUEUE));
+X closedir (QUEUE);
+X
+X # Create indexed list of data and control files. IF $Skip_Locked is true
+X # then skip either if there is a lock file present.
+X if ($Skip_Locked)
+X {
+X grep ((s/^lf//) && ($Lock_IDs {$_} = 1), @Files);
+X grep ((s/^df//) && (! $Lock_IDs {$_}) && ($Data_IDs {$_} = 1), @Files);
+X grep ((s/^qf//) && (! $Lock_IDs {$_}) && ($Control_IDs {$_} = 1), @Files);
+X }
+X else
+X {
+X grep ((s/^df//) && ($Data_IDs {$_} = 1), @Files);
+X grep ((s/^qf//) && ($Control_IDs {$_} = 1), @Files);
+X };
+X
+X # Find missing control and data files and remove them from the lists of each
+X @Missing_Control_IDs = sort (grep ((! $Control_IDs {$_}) && (delete $Data_IDs {$_}), keys (%Data_IDs)));
+X @Missing_Data_IDs = sort (grep ((! $Data_IDs {$_} && (delete $Control_IDs {$_})), keys (%Control_IDs)));
+X
+X
+X # Return the IDs in an appartently random order
+X return (1, "", keys (%Control_IDs));
+};
+X
+X
+;###############################################################################
+;# Parse_Control_File
+;#
+;# Will pase a sendmail queue control file for useful information. See the
+;# Sendmail Installtion and Operation Guide (SMM:07) for a complete
+;# explanation of each field.
+;#
+;# The following globbed variables are set (or cleared) by this function:
+;#
+;# $Sender The sender's address.
+;#
+;# @Recipients One or more addresses for the recipient of the mail.
+;#
+;# @Errors_To One or more addresses for addresses to which mail
+;# delivery errors should be sent.
+;#
+;# $Creation_Time The job creation time in time(3) format. That is,
+;# seconds since 00:00:00 GMT 1/1/70.
+;#
+;# $Priority An integer representing the current message priority.
+;# This is used to order the queue. Higher numbers mean
+;# lower priorities.
+;#
+;# $Status_Message The status of the mail message. It can contain any
+;# text.
+;#
+;# @Headers Message headers unparsed but in their original order.
+;# Headers that span multiple lines are not mucked with,
+;# embedded \ns will be evident.
+;#
+;# In all e-mail addresses bounding <> pairs are stripped.
+;#
+;# If everything went AOK then $Status is 1. If the message with queue ID
+;# $Queue_ID just does not exist anymore -1 is returned. This is very
+;# possible and should be allowed for. Otherwise, $Status is 0 and $Msg
+;# tells what went wrong.
+;#
+;# Globals:
+;# None
+;#
+;# Arguments:
+;# $Queue, $Queue_ID, *Sender, *Recipients, *Errors_To, *Creation_Time,
+;# *Priority, *Status_Message, *Headers
+;#
+;# Returns:
+;# $Status, $Msg
+;###############################################################################
+sub main'Parse_Control_File
+{
+X local ($Queue, $Queue_ID, *Sender, *Recipients, *Errors_To, *Creation_Time,
+X *Priority, *Status_Message, *Headers) = @_;
+X local (*Control, $_, $Not_Empty);
+X
+X # Required variables and the associated control. If empty at the end of
+X # parsing we return a bad status.
+X @REQUIRED_INFO = ('$Creation_Time', 'T', '$Sender', 'S', '@Recipients', 'R',
+X '$Priority', 'P');
+X
+X # Open up the control file for read
+X $Control = "$Queue/qf$Queue_ID";
+X if (! open (Control))
+X {
+X return (-1) if ((-x $Queue) && (! -f "$Queue/qf$Queue_ID") &&
+X (! -f "$Queue/df$Queue_ID"));
+X return (0, "error opening $Control for read: $!");
+X };
+X
+X # Reset the globbed variables just in case
+X $Sender = $Creation_Time = $Priority = $Status_Message = "";
+X @Recipients = @Errors_To = @Headers = ();
+X
+X # Look for a few things in the control file
+X READ: while (<Control>)
+X {
+X $Not_Empty = 1;
+X chop;
+X
+X PARSE:
+X {
+X if (/^T(\d+)$/)
+X {
+X $Creation_Time = $1;
+X }
+X elsif (/^S(<)?([^>]+)/)
+X {
+X $Sender = $2;
+X }
+X elsif (/^R(<)?([^>]+)/)
+X {
+X push (@Recipients, $2);
+X }
+X elsif (/^E(<)?([^>]+)/)
+X {
+X push (@Errors_To, $2);
+X }
+X elsif (/^M(.*)/)
+X {
+X $Status_Message = $1;
+X }
+X elsif (/^P(\d+)$/)
+X {
+X $Priority = $1;
+X }
+X elsif (/^H(.*)/)
+X {
+X $Header = $1;
+X while (<Control>)
+X {
+X chop;
+X last if (/^[A-Z]/);
+X $Header .= "\n$_";
+X };
+X push (@Headers, $Header);
+X redo PARSE if ($_);
+X last if (eof);
+X };
+X };
+X };
+X
+X # If the file was empty scream bloody murder
+X return (0, "empty control file") if (! $Not_Empty);
+X
+X # Yell if we could not find a required field
+X while (($Var, $Control) = splice (@REQUIRED_INFO, 0, 2))
+X {
+X eval "return (0, 'required control field $Control not found')
+X if (! $Var)";
+X return (0, "error checking \$Var: $@") if ($@);
+X };
+X
+X # Everything went AOK
+X return (1);
+};
+X
+1;
+SHAR_EOF
+chmod 0444 libs/mqueue.pl ||
+echo 'restore of libs/mqueue.pl failed'
+Wc_c="`wc -c < 'libs/mqueue.pl'`"
+test 6908 -eq "$Wc_c" ||
+ echo 'libs/mqueue.pl: original size 6908, current size' "$Wc_c"
+fi
+# ============= libs/newgetopts.pl ==============
+if test -f 'libs/newgetopts.pl' -a X"$1" != X"-c"; then
+ echo 'x - skipping libs/newgetopts.pl (File already exists)'
+else
+echo 'x - extracting libs/newgetopts.pl (Text)'
+sed 's/^X//' << 'SHAR_EOF' > 'libs/newgetopts.pl' &&
+;# NAME
+;# newgetopts.pl - a better newgetopt (which is a better getopts which is
+;# a better getopt ;-)
+;#
+;# AUTHOR
+;# Mike Muegel (mmuegel@mot.com)
+;#
+;# mmuegel
+;# /usr/local/ustart/src/mail-tools/dist/foo/libs/newgetopts.pl,v 1.1 1993/07/28 08:07:19 mmuegel Exp
+X
+;###############################################################################
+;# New_Getopts
+;#
+;# Does not care about order of switches, options, and arguments like
+;# getopts.pl. Thus all non-switches/options will be kept in ARGV even if they
+;# are not at the end. If $Pass_Invalid is set all unkown options will be
+;# passed back to the caller by keeping them in @ARGV. This is useful when
+;# parsing a command line for your script while ignoring options that you
+;# may pass to another script. If this is set New_Getopts tries to maintain
+;# the switch clustering on the unkown switches.
+;#
+;# Accepts the special argument -usage to print the Usage string. Also accepts
+;# the special option -version which prints the contents of the string
+;# $VERSION. $VERSION may or may not have an embeded \n in it. If -usage
+;# or -version are specified a status of -1 is returned. Note that the usage
+;# option is only accepted if the usage string is not null.
+;#
+;# $Switches is just like the formal arguemnt of getopts.pl. $Usage is a usage
+;# string with or without a trailing \n. *Switch_To_Order is an optional
+;# pointer to the name of an associative array which will contain a mapping of
+;# switch names to the order in which (if at all) the argument was entered.
+;#
+;# For example, if @ARGV contains -v, -x, test:
+;#
+;# $Switch_To_Order {"v"} = 1;
+;# $Switch_To_Order {"x"} = 2;
+;#
+;# Note that in the case of multiple occurances of an option $Switch_To_Order
+;# will store each occurance of the argument via a string that emulates
+;# an array. This is done by using join ($;, ...). You can retrieve the
+;# array by using split (/$;/, ...).
+;#
+;# *Split_ARGV is an optional pointer to an array which will conatin the
+;# original switches along with their values. For the example used above
+;# Split_ARGV would contain:
+;#
+;# @Split_ARGV = ("v", "", "x", "test");
+;#
+;# Another exciting ;-) feature that newgetopts has. Along with creating the
+;# normal $opt_ scalars for the last value of an argument the list @opt_ is
+;# created. It is an array which contains all the values of arguments to the
+;# basename of the variable. They are stored in the order which they occured
+;# on the command line starting with $[. Note that blank arguments are stored
+;# as "". Along with providing support for multiple options on the command
+;# line this also provides a method of counting the number of times an option
+;# was specified via $#opt_.
+;#
+;# Automatically resets all $opt_, @opt_, %Switch_To_Order, and @Split_ARGV
+;# variables so that New_Getopts may be called more than once from within
+;# the same program. Thus, if $opt_v is set upon entry to New_Getopts and
+;# -v is not in @ARGV $opt_v will not be set upon exit.
+;#
+;# Arguments:
+;# $Switches, $Usage, $Pass_Invalid, *Switch_To_Order, *Split_ARGV
+;#
+;# Returns:
+;# -1, 0, or 1 depending on status (printed Usage/Version, OK, not OK)
+;###############################################################################
+sub New_Getopts
+{
+X local($taint_argumentative, $Usage, $Pass_Invalid, *Switch_To_Order,
+X *Split_ARGV) = @_;
+X local(@args,$_,$first,$rest,$errs, @leftovers, @current_leftovers,
+X %Switch_Found);
+X local($[, $*, $Script_Name, $argumentative);
+X
+X # Untaint the argument cluster so that we can use this with taintperl
+X $taint_argumentative =~ /^(.*)$/;
+X $argumentative = $1;
+X
+X # Clear anything that might still be set from a previous New_Getopts
+X # call.
+X @Split_ARGV = ();
+X
+X # Get the basename of the calling script
+X ($Script_Name = $0) =~ s/.*\///;
+X
+X # Make Usage have a trailing \n
+X $Usage .= "\n" if ($Usage !~ /\n$/);
+X
+X @args = split( / */, $argumentative );
+X
+X # Clear anything that might still be set from a previous New_Getopts call.
+X foreach $first (@args)
+X {
+X next if ($first eq ":");
+X delete $Switch_Found {$first};
+X delete $Switch_To_Order {$first};
+X eval "undef \@opt_$first; undef \$opt_$first;";
+X };
+X
+X while (@ARGV)
+X {
+X # Let usage through
+X if (($ARGV[0] eq "-usage") && ($Usage ne "\n"))
+X {
+X print $Usage;
+X exit (-1);
+X }
+X
+X elsif ($ARGV[0] eq "-version")
+X {
+X if ($VERSION)
+X {
+X print $VERSION;
+X print "\n" if ($VERSION !~ /\n$/);
+X }
+X else
+X {
+X warn "${Script_Name}: no version information available, sorry\n";
+X }
+X exit (-1);
+X }
+X
+X elsif (($_ = $ARGV[0]) =~ /^-(.)(.*)/)
+X {
+X ($first,$rest) = ($1,$2);
+X $pos = index($argumentative,$first);
+X
+X $Switch_To_Order {$first} = join ($;, split (/$;/, $Switch_To_Order {$first}), ++$Order);
+X
+X if($pos >= $[)
+X {
+X if($args[$pos+1] eq ':')
+X {
+X shift(@ARGV);
+X if($rest eq '')
+X {
+X $rest = shift(@ARGV);
+X }
+X
+X eval "\$opt_$first = \$rest;";
+X eval "push (\@opt_$first, \$rest);";
+X push (@Split_ARGV, $first, $rest);
+X }
+X else
+X {
+X eval "\$opt_$first = 1";
+X eval "push (\@opt_$first, '');";
+X push (@Split_ARGV, $first, "");
+X
+X if($rest eq '')
+X {
+X shift(@ARGV);
+X }
+X else
+X {
+X $ARGV[0] = "-$rest";
+X }
+X }
+X }
+X
+X else
+X {
+X # Save any other switches if $Pass_Valid
+X if ($Pass_Invalid)
+X {
+X push (@current_leftovers, $first);
+X }
+X else
+X {
+X warn "${Script_Name}: unknown option: $first\n";
+X ++$errs;
+X };
+X if($rest ne '')
+X {
+X $ARGV[0] = "-$rest";
+X }
+X else
+X {
+X shift(@ARGV);
+X }
+X }
+X }
+X
+X else
+X {
+X push (@leftovers, shift (@ARGV));
+X };
+X
+X # Save any other switches if $Pass_Valid
+X if ((@current_leftovers) && ($rest eq ''))
+X {
+X push (@leftovers, "-" . join ("", @current_leftovers));
+X @current_leftovers = ();
+X };
+X };
+X
+X # Automatically print Usage if a warning was given
+X @ARGV = @leftovers;
+X if ($errs != 0)
+X {
+X warn $Usage;
+X return (0);
+X }
+X else
+X {
+X return (1);
+X }
+X
+}
+X
+1;
+SHAR_EOF
+chmod 0444 libs/newgetopts.pl ||
+echo 'restore of libs/newgetopts.pl failed'
+Wc_c="`wc -c < 'libs/newgetopts.pl'`"
+test 7024 -eq "$Wc_c" ||
+ echo 'libs/newgetopts.pl: original size 7024, current size' "$Wc_c"
+fi
+# ============= libs/strings1.pl ==============
+if test -f 'libs/strings1.pl' -a X"$1" != X"-c"; then
+ echo 'x - skipping libs/strings1.pl (File already exists)'
+else
+echo 'x - extracting libs/strings1.pl (Text)'
+sed 's/^X//' << 'SHAR_EOF' > 'libs/strings1.pl' &&
+;# NAME
+;# strings1.pl - FUN with strings #1
+;#
+;# NOTES
+;# I wrote Format_Text_Block when I just started programming Perl so
+;# it is probably not very Perlish code. Center is more like it :-).
+;#
+;# AUTHOR
+;# Michael S. Muegel (mmuegel@mot.com)
+;#
+;# RCS INFORMATION
+;# mmuegel
+;# /usr/local/ustart/src/mail-tools/dist/foo/libs/strings1.pl,v 1.1 1993/07/28 08:07:19 mmuegel Exp
+X
+package strings1;
+X
+;###############################################################################;# Center
+;#
+;# Center $Text assuming the output should be $Columns wide. $Text can span
+;# multiple lines, of course :-). Lines within $Text that contain only
+;# whitespace are not centered and are instead collapsed. This may save time
+;# when printing them later.
+;#
+;# Arguments:
+;# $Text, $Columns
+;#
+;# Returns:
+;# $Centered_Text
+;###############################################################################
+sub main'Center
+{
+X local ($_, $Columns) = @_;
+X local ($*) = 1;
+X
+X s@^(.*)$@" " x (($Columns - length ($1)) / 2) . $1@eg;
+X s/^[\t ]*$//g;
+X return ($_);
+};
+X
+;###############################################################################
+;# Format_Text_Block
+;#
+;# Formats a text string to be printed to the display or other similar device.
+;# Text in $String will be fomratted such that the following hold:
+;#
+;# + $String contains the (possibly) multi-line text to print. It is
+;# automatically word-wrapped to fit in $Columns.
+;#
+;# + \n'd are maintained and are not folded.
+;#
+;# + $Offset is pre-pended before each separate line of text.
+;#
+;# + If $Offset_Once is $TRUE $Offset will only appear on the first line.
+;# All other lines will be indented to match the amount of whitespace of
+;# $Offset.
+;#
+;# + If $Bullet_Indent is $TRUE $Offset will only be applied to the begining
+;# of lines as they occured in the original $String. Lines that are created
+;# by this routine will always be indented by blank spaces.
+;#
+;# + If $Columns is 0 no word-wrap is done. This might be useful to still
+;# to offset each line in a buffer.
+;#
+;# + If $Split_Expr is supplied the string is split on it. If not supplied
+;# the string is split on " \t\/\-\,\." by default.
+;#
+;# + If $Offset_Blank is $TRUE then empty lines will have $Offset pre-pended
+;# to them. Otherwise, they will still empty.
+;#
+;# This is a realy workhorse routine that I use in many places because of its
+;# veratility.
+;#
+;# Arguments:
+;# $String, $Offset, $Offset_Once, $Bullet_Indent, $Columns, $Split_Expr,
+;# $Offset_Blank
+;#
+;# Returns:
+;# $Buffer
+;###############################################################################
+sub main'Format_Text_Block
+{
+X local ($String, $Real_Offset, $Offset_Once, $Bullet_Indent, $Columns,
+X $Split_Expr, $Offset_Blank) = @_;
+X
+X local ($New_Line, $Line, $Chars_Per_Line, $Space_Offset, $Buffer,
+X $Next_New_Line, $Num_Lines, $Num_Offsets, $Offset);
+X local ($*) = 0;
+X local ($BLANK_TAG) = "__FORMAT_BLANK__";
+X local ($Blank_Offset) = $Real_Offset if ($Offset_Blank);
+X
+X # What should we split on?
+X $Split_Expr = " \\t\\/\\-\\,\\." if (! $Split_Expr);
+X
+X # Pre-process the string - convert blank lines to __FORMAT_BLANK__ sequence
+X $String =~ s/\n\n/\n$BLANK_TAG\n/g;
+X $String =~ s/^\n/$BLANK_TAG\n/g;
+X $String =~ s/\n$/\n$BLANK_TAG/g;
+X
+X # If bad $Columns/$Offset combo or no $Columns make a VERRRYYY wide $Column
+X $Offset = $Real_Offset;
+X $Chars_Per_Line = 16000 if (($Chars_Per_Line = $Columns - length ($Offset)) <= 0);
+X $Space_Offset = " " x length ($Offset);
+X
+X # Get a buffer
+X foreach $Line (split ("\n", $String))
+X {
+X $Offset = $Real_Offset if ($Bullet_Indent);
+X
+X # Find where to split the line
+X if ($Line ne $BLANK_TAG)
+X {
+X $New_Line = "";
+X while ($Line =~ /^([$Split_Expr]*)([^$Split_Expr]+)/)
+X {
+X if (length ("$New_Line$&") >= $Chars_Per_Line)
+X {
+X $Next_New_Line = $+;
+X $New_Line = "$Offset$New_Line$1";
+X $Buffer .= "\n" if ($Num_Lines++);
+X $Buffer .= $New_Line;
+X $Offset = $Space_Offset if (($Offset) && ($Offset_Once));
+X $New_Line = $Next_New_Line;
+X ++$Num_Lines;
+X }
+X else
+X {
+X $New_Line .= $&;
+X };
+X $Line = $';
+X };
+X
+X $Buffer .= "\n" if ($Num_Lines++);
+X $Buffer .= "$Offset$New_Line$Line";
+X $Offset = $Space_Offset if (($Offset) && ($Offset_Once));
+X }
+X
+X else
+X {
+X $Buffer .= "\n$Blank_Offset";
+X };
+X };
+X
+X return ($Buffer);
+X
+};
+X
+1;
+SHAR_EOF
+chmod 0444 libs/strings1.pl ||
+echo 'restore of libs/strings1.pl failed'
+Wc_c="`wc -c < 'libs/strings1.pl'`"
+test 4687 -eq "$Wc_c" ||
+ echo 'libs/strings1.pl: original size 4687, current size' "$Wc_c"
+fi
+# ============= libs/timespec.pl ==============
+if test -f 'libs/timespec.pl' -a X"$1" != X"-c"; then
+ echo 'x - skipping libs/timespec.pl (File already exists)'
+else
+echo 'x - extracting libs/timespec.pl (Text)'
+sed 's/^X//' << 'SHAR_EOF' > 'libs/timespec.pl' &&
+;# NAME
+;# timespec.pl - convert a pre-defined time specifyer to seconds
+;#
+;# AUTHOR
+;# Michael S. Muegel (mmuegel@mot.com)
+;#
+;# RCS INFORMATION
+;# mmuegel
+;# /usr/local/ustart/src/mail-tools/dist/foo/libs/timespec.pl,v 1.1 1993/07/28 08:07:19 mmuegel Exp
+X
+package timespec;
+X
+%TIME_SPEC_TO_SECONDS = ("s", 1,
+X "m", 60,
+X "h", 60 * 60,
+X "d", 60 * 60 * 24
+X );
+X
+$VALID_TIME_SPEC_EXPR = "[" . join ("", keys (%TIME_SPEC_TO_SECONDS)) . "]";
+X
+;###############################################################################
+;# Time_Spec_To_Seconds
+;#
+;# Converts a string of the form:
+;#
+;# (<number>(s|m|h|d))+
+;#
+;# to seconds. The second part of the time spec specifies seconds, minutes,
+;# hours, or days, respectfully. The first part is the number of those untis.
+;# There can be any number of such specifiers. As an example, 1h30m means 1
+;# hour and 30 minutes.
+;#
+;# If the parsing went OK then $Status is 1, $Msg is undefined, and $Seconds
+;# is $Time_Spec converted to seconds. If something went wrong then $Status
+;# is 0 and $Msg explains what went wrong.
+;#
+;# Arguments:
+;# $Time_Spec
+;#
+;# Returns:
+;# $Status, $Msg, $Seconds
+;###############################################################################
+sub main'Time_Spec_To_Seconds
+{
+X $Time_Spec = $_[0];
+X
+X $Seconds = 0;
+X while ($Time_Spec =~ /^(\d+)($VALID_TIME_SPEC_EXPR)/)
+X {
+X $Seconds += $1 * $TIME_SPEC_TO_SECONDS {$2};
+X $Time_Spec = $';
+X };
+X
+X return (0, "error parsing time spec: $Time_Spec") if ($Time_Spec ne "");
+X return (1, "", $Seconds);
+X
+};
+X
+X
+1;
+SHAR_EOF
+chmod 0444 libs/timespec.pl ||
+echo 'restore of libs/timespec.pl failed'
+Wc_c="`wc -c < 'libs/timespec.pl'`"
+test 1609 -eq "$Wc_c" ||
+ echo 'libs/timespec.pl: original size 1609, current size' "$Wc_c"
+fi
+# ============= man/cqueue.1 ==============
+if test ! -d 'man'; then
+ echo 'x - creating directory man'
+ mkdir 'man'
+fi
+if test -f 'man/cqueue.1' -a X"$1" != X"-c"; then
+ echo 'x - skipping man/cqueue.1 (File already exists)'
+else
+echo 'x - extracting man/cqueue.1 (Text)'
+sed 's/^X//' << 'SHAR_EOF' > 'man/cqueue.1' &&
+.TH CQUEUE 1L
+\"
+\" mmuegel
+\" /usr/local/ustart/src/mail-tools/dist/foo/man/cqueue.1,v 1.1 1993/07/28 08:08:25 mmuegel Exp
+\"
+.ds mp \fBcqueue\fR
+.de IB
+.IP \(bu 2
+..
+.SH NAME
+\*(mp - check sendmail queue for problems
+.SH SYNOPSIS
+.IP \*(mp 7
+[ \fB-abdms\fR ] [ \fB-q\fR \fIqueue-dir\fI ] [ \fB-t\fR \fItime\fR ]
+[ \fB-u\fR \fIusers\fR ] [ \fB-w\fR \fIwidth\fR ]
+.SH DESCRIPTION
+Reports on problems in the sendmail queue. With no options this simply
+means listing messages that have been in the queue longer than a default
+period along with a summary of queue mail by host and status message.
+.SH OPTIONS
+.IP \fB-a\fR 14
+Report on all messages in the queue. This is equivalent to saying \fB-t\fR 0s.
+You may like this command so much that you use it as a replacement for
+\fBmqueue\fR. For example:
+.sp 1
+.RS
+.RS
+\fBalias mqueue cqueue -a\fR
+.RE
+.RE
+.IP \fB-b\fR 14
+Also report on bogus queue files. Those are files that
+have data files and no control files or vice versa.
+.IP \fB-d\fR
+Print a detailed report of mail messages that have been queued longer than
+the specified or default time. Information that is presented includes:
+.RS
+.RS
+.IB
+Sendmail queue identifier.
+.IB
+Date the message was first queued.
+.IB
+Sender of the message.
+.IB
+One or more recipients of the message.
+.IB
+An optional status of the message. This usually indicates why the message
+has not been delivered.
+.RE
+.RE
+.IP \fB-m\fR 14
+Mail off the results if any problems were found.
+Normaly results are printed to stdout. If this option
+is specified they are mailed to one or more users. Results
+are not printed to stdout in this case. Results are \fBonly\fR
+mailed if \*(mp found something wrong.
+.IP "\fB-q\fR \fIqueue-dir\fI"
+The sendmail mail queue directory. Default is \fB/usr/spool/mqueue\fR or
+some other site configured value.
+.IP "\fB-t\fR \fItime\fR"
+List messages that have been in the queue longer than
+\fItime\fR. Time should of the form:
+.sp 1
+.RS
+.RS
+(<number>(s|m|h|d))+
+.sp 1
+.RE
+.RE
+.RS 14
+The second portion of the above definition
+specifies seconds, minutes, hours, or
+days, respectfully. The first portion is the number of
+those units. There can be any number of such specifiers.
+As an example, 1h30m means 1 hour and 30 minutes.
+.sp 1
+The default is 2 hours.
+.RE
+.IP \fB-s\fR 14
+Print a summary of messages that have been queued longer than
+the specified or default time. Two separate types of summaries are printed.
+The first summarizes the queue messages by destination host. The host name
+is gleaned from the recipient addresses for each message.
+Thus the actual host names for this summary should be taken with a grain
+of salt since ruleset 0 has not been applied to the address the host was
+taken from nor were MX records consulted. It would be possible to add
+this; however, the execution time of the script would increase
+dramatically. The second summary is by status message.
+.IP "\fB-u\fR \fIusers\fR"
+Specify list of users to send a mail report to other than
+the invoker. This option is only valid when \fB-m\fR has been
+specified. Multiple recipients may be separated by spaces.
+.IP "\fB-w\fR \fIwidth\fR"
+Specify the page width to which the output should tailored. \fIwidth\fR
+should be an integer representing some character position. The default is
+80 or some other site configured value. Output is folded neatly to match
+\fIwidth\fR.
+.SH EXAMPLES
+.nf
+% \fBdate\fR
+Tue Jan 19 12:07:20 CST 1993
+X
+% \fBcqueue -t 21h45m -w 70\fR
+X
+Summary of messages in queue longer than 21:45:00 by destination
+host:
+X
+X Number of
+X Messages Destination Host
+X --------- ----------------
+X 2 cigseg.rtsg.mot.com
+X 1 mnesouth.corp.mot.com
+X ---------
+X 3
+X
+Summary of messages in queue longer than 21:45:00 by status message:
+X
+X Number of
+X Messages Status Message
+X --------- --------------
+X 1 Deferred: Connection refused by mnesouth.corp.mot.com
+X 2 Deferred: Host Name Lookup Failure
+X ---------
+X 3
+X
+Detail of messages in queue longer than 21:45:00 sorted by creation
+date:
+X
+X ID: AA20573
+X Date: 02:09:27 PM 01/18/93
+X Sender: melrose-place-owner@ferkel.ucsb.edu
+X Recipient: pbaker@cigseg.rtsg.mot.com
+X Status: Deferred: Host Name Lookup Failure
+X
+X ID: AA20757
+X Date: 02:11:30 PM 01/18/93
+X Sender: 90210-owner@ferkel.ucsb.edu
+X Recipient: pbaker@cigseg.rtsg.mot.com
+X Status: Deferred: Host Name Lookup Failure
+X
+X ID: AA21110
+X Date: 02:17:01 PM 01/18/93
+X Sender: rd_lap_wg@mdd.comm.mot.com
+X Recipient: jim_mathis@mnesouth.corp.mot.com
+X Status: Deferred: Connection refused by mnesouth.corp.mot.com
+.fi
+.SH AUTHOR
+.nf
+Michael S. Muegel (mmuegel@mot.com)
+UNIX Applications Startup Group
+Corporate Information Office, Schaumburg, IL
+Motorola, Inc.
+.fi
+.SH COPYRIGHT NOTICE
+Copyright 1993, Motorola, Inc.
+.sp 1
+Permission to use, copy, modify and distribute without charge this
+software, documentation, etc. is granted, provided that this
+comment and the author's name is retained. The author nor Motorola assume any
+responsibility for problems resulting from the use of this software.
+.SH SEE ALSO
+.nf
+\fBsendmail(8)\fR
+\fISendmail Installation and Operation Guide\fR.
+.fi
+SHAR_EOF
+chmod 0444 man/cqueue.1 ||
+echo 'restore of man/cqueue.1 failed'
+Wc_c="`wc -c < 'man/cqueue.1'`"
+test 5212 -eq "$Wc_c" ||
+ echo 'man/cqueue.1: original size 5212, current size' "$Wc_c"
+fi
+# ============= man/postclip.1 ==============
+if test -f 'man/postclip.1' -a X"$1" != X"-c"; then
+ echo 'x - skipping man/postclip.1 (File already exists)'
+else
+echo 'x - extracting man/postclip.1 (Text)'
+sed 's/^X//' << 'SHAR_EOF' > 'man/postclip.1' &&
+.TH POSTCLIP 1L
+\"
+\" mmuegel
+\" /usr/local/ustart/src/mail-tools/dist/foo/man/postclip.1,v 1.1 1993/07/28 08:08:25 mmuegel Exp
+\"
+.ds mp \fBpostclip\fR
+.SH NAME
+\*(mp - send only the headers to Postmaster
+.SH SYNOPSIS
+\*(mp [ \fB-v\fR ] [ \fIto\fR ... ]
+.SH DESCRIPTION
+\*(mp will forward non-delivery reports to a postmaster after deleting the body
+of the message. This keeps bounced mail private and helps to avoid disk space problems. \*(mp tries its best to keep as much of the header trail as possible.
+Hopefully only the original body of the message will be filtered. Only messages
+that have a subject that begins with 'Returned mail:' are filtered. This
+ensures that other mail is not accidently mucked with. Finally, note that
+\fBsendmail\fR is used to deliver the message after it has been (possibly)
+filtered. All of the original headers will remain intact.
+.sp 1
+You can use this with any \fBsendmail\fR by modifying the Postmaster alias.
+If you use IDA \fBsendmail\fR you could add the following to <machine>.m4:
+.sp 1
+.RS
+define(POSTMASTERBOUNCE, mailer-errors)
+.RE
+.sp 1
+In the aliases file, add a line similar to the following:
+.sp 1
+.RS
+mailer-errors: "|/usr/local/bin/postclip postmaster"
+.RE
+.SH OPTIONS
+.IP \fB-v\fR
+Be verbose about delivery. Probably only useful when debugging \*(mp.
+.IP \fIto\fR
+A list of one or more e-mail ids to send the modified
+Postmaster messages to. If none are specified postmaster
+is used.
+.SH AUTHOR
+.nf
+Michael S. Muegel (mmuegel@mot.com)
+UNIX Applications Startup Group
+Corporate Information Office, Schaumburg, IL
+Motorola, Inc.
+.fi
+.SH CREDITS
+The original idea to filter Postmaster mail was taken from a script by
+Christopher Davis <ckd@eff.org>.
+.SH COPYRIGHT NOTICE
+Copyright 1992, Motorola, Inc.
+.sp 1
+Permission to use, copy, modify and distribute without charge this
+software, documentation, etc. is granted, provided that this
+comment and the author's name is retained. The author nor Motorola assume any
+responsibility for problems resulting from the use of this software.
+.SH SEE ALSO
+.nf
+\fBsendmail(8)\fR
+.fi
+SHAR_EOF
+chmod 0444 man/postclip.1 ||
+echo 'restore of man/postclip.1 failed'
+Wc_c="`wc -c < 'man/postclip.1'`"
+test 2078 -eq "$Wc_c" ||
+ echo 'man/postclip.1: original size 2078, current size' "$Wc_c"
+fi
+# ============= src/cqueue ==============
+if test ! -d 'src'; then
+ echo 'x - creating directory src'
+ mkdir 'src'
+fi
+if test -f 'src/cqueue' -a X"$1" != X"-c"; then
+ echo 'x - skipping src/cqueue (File already exists)'
+else
+echo 'x - extracting src/cqueue (Text)'
+sed 's/^X//' << 'SHAR_EOF' > 'src/cqueue' &&
+#!/usr/local/ustart/bin/suidperl
+X
+# NAME
+# cqueue - check sendmail queue for problems
+#
+# SYNOPSIS
+# Type cqueue -usage
+#
+# AUTHOR
+# Michael S. Muegel <mmuegel@mot.com>
+#
+# RCS INFORMATION
+# mmuegel
+# /usr/local/ustart/src/mail-tools/dist/foo/src/cqueue,v 1.1 1993/07/28 08:09:02 mmuegel Exp
+X
+# So that date.pl does not yell (Domain/OS version does a ``)
+$ENV{'PATH'} = "";
+X
+# A better getopts routine
+require "newgetopts.pl";
+require "timespec.pl";
+require "mail.pl";
+require "date.pl";
+require "mqueue.pl";
+require "strings1.pl";
+require "elapsed.pl";
+X
+($Script_Name = $0) =~ s/.*\///;
+X
+# Some defaults you may want to change
+$DEF_TIME = "2h";
+$DEF_QUEUE = "/usr/spool/mqueue";
+$DEF_COLUMNS = 80;
+$DATE_FORMAT = "%r %D";
+X
+# Constants that probably should not be changed
+$USAGE = "Usage: $Script_Name [ -abdms ] [ -q queue-dir ] [ -t time ] [ -u user ] [ -w width ]\n";
+$VERSION = "${Script_Name} by mmuegel; 1.1 of 1993/07/28 08:09:02";
+$SWITCHES = "abdmst:u:q:w:";
+$SPLIT_EXPR = '\s,\.@!%:';
+$ADDR_PART_EXPR = '[^!@%]+';
+X
+# Let getopts parse for switches
+$Status = &New_Getopts ($SWITCHES, $USAGE);
+exit (0) if ($Status == -1);
+exit (1) if (! $Status);
+X
+# Check args
+die "${Script_Name}: -u only valid with -m\n" if (($opt_u) && (! $opt_m));
+die "${Script_Name}: -a not valid with -t option\n" if ($opt_a && $opt_t);
+$opt_u = getlogin || (getpwuid ($<))[0] || $ENV{"USER"} || die "${Script_Name}: can not determine who you are!\n" if (! $opt_u);
+X
+# Set defaults
+$opt_t = "0s" if ($opt_a);
+$opt_t = $DEF_TIME if ($opt_t eq "");
+$opt_w = $DEF_COLUMNS if ($opt_w eq "");
+$opt_q = $DEF_QUEUE if ($opt_q eq "");
+$opt_s = $opt_d = 1 if (! ($opt_s || $opt_d));
+X
+# Untaint the users to mail to
+$opt_u =~ /^(.*)$/;
+$Users = $1;
+X
+# Convert time option to seconds and seconds to elapsed form
+die "${Script_Name}: $Msg\n" if (! (($Status, $Msg, $Seconds) = &Time_Spec_To_Seconds ($opt_t))[0]);
+$Elapsed = &Seconds_To_Elapsed ($Seconds, 1);
+$Time_Info = " longer than $Elapsed" if ($Seconds);
+X
+# Get the current time
+$Current_Time = time;
+$Current_Date = &date ($Current_Time, $DATE_FORMAT);
+X
+($Status, $Msg, @Queue_IDs) = &Get_Queue_IDs ($opt_q, 1, @Missing_Control_IDs,
+X @Missing_Data_IDs);
+die "$Script_Name: $Msg\n" if (! $Status);
+X
+# Yell about missing data/control files?
+if ($opt_b)
+{
+X
+X $Report = "\nMessages missing control files:\n\n " .
+X join ("\n ", @Missing_Control_IDs) .
+X "\n"
+X if (@Missing_Control_IDs);
+X
+X $Report .= "\nMessages missing data files:\n\n " .
+X join ("\n ", @Missing_Data_IDs) .
+X "\n"
+X if (@Missing_Data_IDs);
+};
+X
+# See if any mail messages are older than $Seconds
+foreach $Queue_ID (@Queue_IDs)
+{
+X # Get lots of info about this sendmail message via the control file
+X ($Status, $Msg) = &Parse_Control_File ($opt_q, $Queue_ID, *Sender,
+X *Recipients, *Errors_To, *Creation_Time, *Priority, *Status_Message,
+X *Headers);
+X next if ($Status == -1);
+X if (! $Status)
+X {
+X warn "$Script_Name: $Queue_ID: $Msg\n";
+X next;
+X };
+X
+X # Report on message if it is older than $Seconds
+X if ($Current_Time - $Creation_Time >= $Seconds)
+X {
+X # Build summary by host information. Keep track of each host destination
+X # encountered.
+X if ($opt_s)
+X {
+X %Host_Map = ();
+X foreach (@Recipients)
+X {
+X if ((/@($ADDR_PART_EXPR)$/) || (/($ADDR_PART_EXPR)!$ADDR_PART_EXPR$/))
+X {
+X ($Host = $1) =~ tr/A-Z/a-z/;
+X $Host_Map {$Host} = 1;
+X }
+X else
+X {
+X warn "$Script_Name: could not find host part from $_; contact author\n";
+X };
+X };
+X
+X # For each unique target host add to its stats
+X grep ($Host_Queued {$_}++, keys (%Host_Map));
+X
+X # Build summary by message information.
+X $Message_Queued {$Status_Message}++ if ($Status_Message);
+X };
+X
+X # Build long report information for this creation time (there may be
+X # more than one message created at the same time)
+X if ($opt_d)
+X {
+X $Creation_Date = &date ($Creation_Time, $DATE_FORMAT);
+X $Recipient_Info = &Format_Text_Block (join (", ", @Recipients),
+X " Recipient: ", 1, 0, $opt_w, $SPLIT_EXPR);
+X $Time_To_Report {$Creation_Time} .= <<"EOS";
+X
+X ID: $Queue_ID
+X Date: $Creation_Date
+X Sender: $Sender
+$Recipient_Info
+EOS
+X
+X # Add the status message if available to long report
+X if ($Status_Message)
+X {
+X $Time_To_Report {$Creation_Time} .= &Format_Text_Block ($Status_Message,
+X " Status: ", 1, 0, $opt_w, $SPLIT_EXPR) . "\n";
+X };
+X };
+X };
+X
+};
+X
+# Add the summary report by target host?
+if ($opt_s)
+{
+X foreach $Host (sort (keys (%Host_Queued)))
+X {
+X $Host_Report .= &Format_Text_Block ($Host,
+X sprintf (" %-9d ", $Host_Queued{$Host}), 1, 0, $opt_w,
+X $SPLIT_EXPR) . "\n";
+X $Num_Hosts += $Host_Queued{$Host};
+X };
+X if ($Host_Report)
+X {
+X chop ($Host_Report);
+X $Report .= &Format_Text_Block("\nSummary of messages in queue$Time_Info by destination host:\n", "", 0, 0, $opt_w);
+X
+X $Report .= <<"EOS";
+X
+X Number of
+X Messages Destination Host
+X --------- ----------------
+$Host_Report
+X ---------
+X $Num_Hosts
+EOS
+X };
+};
+X
+# Add the summary by message report?
+if ($opt_s)
+{
+X foreach $Message (sort (keys (%Message_Queued)))
+X {
+X $Message_Report .= &Format_Text_Block ($Message,
+X sprintf (" %-9d ", $Message_Queued{$Message}), 1, 0, $opt_w,
+X $SPLIT_EXPR) . "\n";
+X $Num_Messages += $Message_Queued{$Message};
+X };
+X if ($Message_Report)
+X {
+X chop ($Message_Report);
+X $Report .= &Format_Text_Block ("\nSummary of messages in queue$Time_Info by status message:\n", "", 0, 0, $opt_w);
+X
+X $Report .= <<"EOS";
+X
+X Number of
+X Messages Status Message
+X --------- --------------
+$Message_Report
+X ---------
+X $Num_Messages
+EOS
+X };
+};
+X
+# Add the detailed message reports?
+if ($opt_d)
+{
+X foreach $Time (sort { $a <=> $b} (keys (%Time_To_Report)))
+X {
+X $Report .= &Format_Text_Block ("\nDetail of messages in queue$Time_Info sorted by creation date:\n","", 0, 0, $opt_w) if (! $Detailed_Header++);
+X $Report .= $Time_To_Report {$Time};
+X };
+};
+X
+# Now mail or print the report
+if ($Report)
+{
+X $Report .= "\n";
+X if ($opt_m)
+X {
+X ($Status, $Msg) = &Send_Mail ($Users, "sendmail queue report for $Current_Date", $Report, 0);
+X die "${Script_Name}: $Msg" if (! $Status);
+X }
+X
+X else
+X {
+X print $Report;
+X };
+X
+};
+X
+# I am outta here...
+exit (0);
+SHAR_EOF
+chmod 0555 src/cqueue ||
+echo 'restore of src/cqueue failed'
+Wc_c="`wc -c < 'src/cqueue'`"
+test 6647 -eq "$Wc_c" ||
+ echo 'src/cqueue: original size 6647, current size' "$Wc_c"
+fi
+# ============= src/postclip ==============
+if test -f 'src/postclip' -a X"$1" != X"-c"; then
+ echo 'x - skipping src/postclip (File already exists)'
+else
+echo 'x - extracting src/postclip (Text)'
+sed 's/^X//' << 'SHAR_EOF' > 'src/postclip' &&
+#!/usr/local/bin/perl
+X
+# NAME
+# postclip - send only the headers to Postmaster
+#
+# SYNOPSIS
+# postclip [ -v ] [ to ... ]
+#
+# AUTHOR
+# Michael S. Muegel <mmuegel@mot.com>
+#
+# RCS INFORMATION
+# /usr/local/ustart/src/mail-tools/dist/foo/src/postclip,v
+# 1.1 of 1993/07/28 08:09:02
+X
+# We use this to send off the mail
+require "newgetopts.pl";
+require "mail.pl";
+X
+# Get the basename of the script
+($Script_Name = $0) =~ s/.*\///;
+X
+# Some famous constants
+$USAGE = "Usage: $Script_Name [ -v ] [ to ... ]\n";
+$VERSION = "${Script_Name} by mmuegel; 1.1 of 1993/07/28 08:09:02";
+$SWITCHES = "v";
+X
+# Let getopts parse for switches
+$Status = &New_Getopts ($SWITCHES, $USAGE);
+exit (0) if ($Status == -1);
+exit (1) if (! $Status);
+X
+# Who should we send the modified mail to?
+@ARGV = ("postmaster") if (! @ARGV);
+$Users = join (" ", @ARGV);
+@ARGV = ();
+X
+# Suck in the original header and save a few interesting lines
+while (<>)
+{
+X $Buffer .= $_ if (! /^From /);
+X $Subject = $1 if (/^Subject:\s+(.*)$/);
+X $From = $1 if (/^From:\s+(.*)$/);
+X last if (/^$/);
+};
+X
+# Do not filter the message unless it has a subject and the subject indicates
+# it is an NDN
+if ($Subject && ($Subject =~ /^returned mail/i))
+{
+X # Slurp input by paragraph. Keep track of the last time we saw what
+X # appeared to be NDN text. We keep this.
+X $/ = "\n\n";
+X $* = 1;
+X while (<>)
+X {
+X push (@Paragraphs, $_);
+X $Last_Error_Para = $#Paragraphs
+X if (/unsent message follows/i || /was not delivered because/);
+X };
+X
+X # Now save the NDN text into $Buffer
+X $Buffer .= join ("", @Paragraphs [0..$Last_Error_Para]);
+}
+X
+else
+{
+X undef $/;
+X $Buffer .= <>;
+};
+X
+# Send off the (possibly) modified mail
+($Status, $Msg) = &Send_Mail ($Users, "", $Buffer, 0, $opt_v, 1);
+die "$Script_Name: $Msg\n" if (! $Status);
+SHAR_EOF
+chmod 0555 src/postclip ||
+echo 'restore of src/postclip failed'
+Wc_c="`wc -c < 'src/postclip'`"
+test 1836 -eq "$Wc_c" ||
+ echo 'src/postclip: original size 1836, current size' "$Wc_c"
+fi
+exit 0
+
+--
++----------------------------------------------------------------------------+
+| Michael S. Muegel | Internet E-Mail: mmuegel@mot.com |
+| UNIX Applications Startup Group | Moto Dist E-Mail: X10090 |
+| Corporate Information Office | Voice: (708) 576-0507 |
+| Motorola | Fax: (708) 576-4153 |
++----------------------------------------------------------------------------+
+
+ "I'm disturbed, I'm depressed, I'm inadequate -- I've got it all!"
+ -- George from _Seinfeld_
diff --git a/usr.sbin/sendmail/contrib/oldbind.compat.c b/usr.sbin/sendmail/contrib/oldbind.compat.c
new file mode 100644
index 0000000..1621a7b
--- /dev/null
+++ b/usr.sbin/sendmail/contrib/oldbind.compat.c
@@ -0,0 +1,79 @@
+/*
+** OLDBIND.COMPAT.C
+**
+** Very old systems do not have res_query(), res_querydomain() or
+** res_search(), so emulate them here.
+**
+** You really ought to be upgrading to a newer version of BIND
+** (4.8.2 or later) rather than be using this.
+**
+** J.R. Oldroyd <jr@inset.com>
+*/
+
+#include <sys/types.h>
+#include <netinet/in.h>
+#include <arpa/nameser.h>
+#include <resolv.h>
+
+typedef union
+{
+ HEADER qb1;
+ char qb2[PACKETSZ];
+} querybuf;
+
+res_query(dname, class, type, data, datalen)
+ char * dname;
+ int class;
+ int type;
+ char * data;
+ int datalen;
+{
+ int n;
+ querybuf buf;
+
+ n = res_mkquery(QUERY, dname, class, type, (char *) NULL, 0,
+ NULL, (char *) &buf, sizeof buf);
+ n = res_send((char *)&buf, n, data, datalen);
+
+ return n;
+}
+
+res_querydomain(host, dname, class, type, data, datalen)
+ char * host;
+ char * dname;
+ int class;
+ int type;
+ char * data;
+ int datalen;
+{
+ int n;
+ querybuf buf;
+ char dbuf[256];
+
+ strcpy(dbuf, host);
+ if (dbuf[strlen(dbuf)-1] != '.')
+ strcat(dbuf, ".");
+ strcat(dbuf, dname);
+ n = res_mkquery(QUERY, dbuf, class, type, (char *) NULL, 0,
+ NULL, (char *)&buf, sizeof buf);
+ n = res_send((char *) &buf, n, data, datalen);
+
+ return n;
+}
+
+res_search(dname, class, type, data, datalen)
+ char * dname;
+ int class;
+ int type;
+ char * data;
+ int datalen;
+{
+ int n;
+ querybuf buf;
+
+ n = res_mkquery(QUERY, dname, class, type, (char *)NULL, 0,
+ NULL, (char *) &buf, sizeof buf);
+ n = res_send((char *) &buf, n, data, datalen);
+
+ return n;
+}
diff --git a/usr.sbin/sendmail/contrib/xla/README b/usr.sbin/sendmail/contrib/xla/README
new file mode 100644
index 0000000..a72fd03
--- /dev/null
+++ b/usr.sbin/sendmail/contrib/xla/README
@@ -0,0 +1,207 @@
+ XLA - Extended Load Average design for Sendmail R6
+ --------------------------------------------------
+
+ Christophe Wolfhugel - Herve Schauer Consultants
+ wolf@grasp.insa-lyon.fr, wolf@hsc-sec.fr
+
+
+WARNING: this extension is supplied as a contribution to Sendmail.
+Should you have trouble, questions, please contact me directly, and
+*not* the Sendmail development team.
+
+
+ABSTRACT
+
+Sendmail currently furnishes a limitation mecanism which is based on
+the system load average, when available. Experience has prooven that
+this was not sufficiant for some particular situations, for example
+if you have slow and/or overloaded links. This can easily cause both
+system and network congestions with Sendmail having to handle a large
+number of simultaneous sessions on the same overloaded link, causing
+most of the SMTP sessions to timeout after a long time. The system
+load average is also generally too slow to react when your system
+gets a burst of incoming or outgoing SMTP sessions which on some
+stations can easily cause system unavailabilities.
+
+The extended load average module has been designed in order to furnish
+a way of limitation the load generated by Sendmail to both your
+system and your network. This design can be used either alone or as
+complementary to the system load average if your system supports it.
+
+Limitation is based on the number of incoming/outgoing SMTP sessions,
+and remote hosts are classified in classes. The system administrator
+will define a maximum number of incoming SMTP sessions as well as
+a maximum total (incoming + outgoing) sessions for each class of
+hosts. A class can be either an individual machine or a network.
+
+When the limit is reached for a given class, all incoming SMTP
+connections will be politely refused. When the limit is reached for
+all classes, the SMTP connections will be refused by the system
+(which one could consider as less politely :)).
+On outgoing mail, messages will be queued for delayed processing.
+
+The extended load average parameters are given in the Sendmail
+configuration file, and when not present, Sendmail behaves the
+usual way.
+
+
+COMPILATION
+
+Copy the xla.c module in the src sub-directory, edit the Makefile
+in order to define XLA (-DXLA). Also add the xla.[co] module name
+in the list of files so that it gets compiled.
+
+Regenerate sendmail by removing all objects, or at least those
+containing references to XLA (this list may vary, so use grep to
+get the module list). This will generate a new sendmail executable
+containing the xla code.
+
+Debugging level 59 has been assigned to this module and when used
+it provides some output (sendmail -d59.x). Please check the source
+code to see which levels are supported.
+
+
+CONFIGURATION
+
+The extended average uses a new set of configuration lines in the
+sendmail.cf file. All newly introduced line begin with the letter L
+(capital L).
+
+Before detailling the syntax, first an example (this can be placed
+at any section of the sendmail.cf file, note that the order is
+important). Fields are separated by (one or more) tabs/spaces.
+
+# File name used to store the counters
+L/etc/sendmail.la
+# Classes definition
+# Lname #queue #reject
+L*.insa-lyon.fr 8 3
+L*.univ-lyon1.fr 6 4
+L* 15 16
+
+The first line defines the working file which will be used in order
+to have the occurences of Sendmail read and update the counters. The
+format of this file is described in the "Design" section.
+This line is mandatory and the specified file must be absolute (ie
+begin with a slash).
+
+Then you can specify one or more classes. The last class (*) is also
+mandatory and should be in last position as the first match will stop
+the search and if there is no match the behavior of Sendmail is unknown.
+
+Each class has three fields separated by one or more tabs/spaces.
+
+L{mask} {queue_#} {refuse_#}
+
+The {mask} is a simple mask. It can be either an explicit host name
+(like grasp.insa-lyon.fr) or a mask starting with "*." or just "*".
+No other variants are allowed.
+
+Lgrasp.insa-lyon.fr will match exactely any session to/from this host.
+
+L*.insa-lyon.fr will match any session to/from any machine in the
+ insa-lyon.fr domain as well as from the machine
+ named "insa-lyon.fr" if it exists.
+
+L* will match any session, and thus should also be
+ last in the list to act as a catchup line.
+
+The {queue_#} is the maximum number of SMTP sessions in the given class
+for both incoming and outgoing messages. The {refuse_#} indicates when
+to refuse incoming messages for this class. The interaction between
+those counters is somewhat subtle. It seems logical that a standard
+configuration has {queue_#} >= {refuse_#}, and in fact in most
+configurations they can be equal (that's why what I use in my environment).
+Thus, this is not mandatory. If {queue_#} < {refuse_#} outgoing messages
+will be lower priority than incoming messages and once a class gets loaded
+the outgoing messages are blocked first.
+
+I use very low values in some situations, for example I have a customer
+connected to the Internet via a 9600 bps line, they also have internal
+users sending burst of messages (10, 20 small messages coming in just
+one or two seconds). Both situations were unsupportable. The line is
+too slow to handle many simultaneous connections and the mail server
+does not have the ressources to handle such a heavy load (it's a 12 Megs
+Sun 3 also doing Usenet news).
+
+I have defined following section in the configuration file, and experience
+shows the benefits for everyone. Fake domain for the example: customer.fr.
+
+L/etc/sendmail.la
+L*.customer.fr 8 8
+L* 3 3
+
+This means that there might not be more than 8 simultaneous SMTP sessions
+between the mail server and any other internal host. This is to protect
+the station from heavy loads like users (or applications !) sending
+several tenths of messages in just a few seconds).
+No more than 3 SMTP sessions are authorized with any other host, this is
+to save the load of the slow 9600 line to the Internet.
+
+Drawback is that is you have 3 * 2 Megs sessions established from/to the
+outside, all your mail will be held until one slot gets available, on
+a 9600 bps line just make your counts, il blocks your line during over
+one hour.
+
+
+DESIGN
+
+Sendmail will analyze the "L" lines in the configuration file during
+startup (or read the initialized structure from the frozen file).
+When started in daemon mode (and only there), any existing working file
+will be cleared and a new one is created. Each class gets a record in
+the sendmail.la work file. The size of this record is a short integer
+(generally two bytes) and represents the count of active sessions in
+the given class. Read/Write operations in this file are done in
+one operation (as anyway the size is far below one disk sector). The
+file is locked with Sendmail's lockfile() function priori to any
+access.
+
+Handling incoming SMTP sessions.
+
+There is interaction is two points in the Sendmail source code. First
+on the listen system call: if all slots in all classes are in use,
+a listen(0) is done so that the system rejects any incoming SMTP session.
+This avois to fork and then reject the connexion.
+
+If there are some free slots, nothing better than accepting the
+connection, then forking can be done. The child process then checks if
+the adequate class is full or not. If full, it rejects the connection
+with a "421 Too many sessions" diagnostic to the sender (which should
+then appear when the remote users do a mailq). If the treshold {reject_#}
+is not reached, the connection is accepted and the counter is sendmail.la
+is updated.
+
+Handling outgoing SMTP sessions.
+
+As soon as Sendmail needs to connect to a distant host, the adequate class
+is checked against {queue_#} and if no slots are available, the message is
+queued for further processing.
+
+Sendmail's connection caching.
+
+Sendmail-R6 introduces a new design: connection caching, ie several SMTP
+sessions can be opened at the same time. This could cause some problems
+when sending mail, as after having a few connections opened, all slots
+could be in use and generate a partial delivery of the message. In
+order to deal with this, xla.c uses following design "for a given
+sendmail process, only the first connection in a given class is counted".
+This can be done because sendmail does not do parralel message sending
+on the different channels.
+
+End of connection.
+
+As soon as a connection is closed, the counters will be automatically
+updated.
+
+
+
+Please look at the code to understand of all this works. Comments,
+suggestions, questions welcome.
+
+
+
+ Christophe Wolfhugel
+ Herve Schauer Consultants
+ Paris, France
+ May 23, 1993
diff --git a/usr.sbin/sendmail/contrib/xla/xla.c b/usr.sbin/sendmail/contrib/xla/xla.c
new file mode 100644
index 0000000..627d383
--- /dev/null
+++ b/usr.sbin/sendmail/contrib/xla/xla.c
@@ -0,0 +1,532 @@
+/*
+ * (C) Copyright 1993-94, Herve Schauer Consultants
+ *
+ * This module written by Christophe.Wolfhugel@hsc-sec.fr
+ * is to be used under the same conditions and terms (and absence
+ * or warranties) than the other modules of the Sendmail package.
+ *
+ * ABSOLUTELY NO WARRANTY. USE AT YOUR OWN RISKS.
+ *
+ * Version: 940417, applied a patch from Paul Graham <pjg@acsu.buffalo.edu>
+ * (lockfile syntax in xla.c did not reflect anymore the
+ * new one used by sendmail, now fine).
+ *
+ */
+
+
+#ifdef XLA
+
+#ifndef MAXLARULES
+# define MAXLARULES 20
+#endif
+
+# include "sendmail.h"
+
+typedef struct {
+ short queue; /* # of connexions to have queueing */
+ short reject; /* # of conn. to reject */
+ short num; /* # of increments this process */
+ char *mask; /* Mask (domain) */
+ } XLARULE;
+
+char *XlaFname; /* Work file name */
+char XlaHostName[1024]; /* Temporary */
+int XlaNext; /* # of XlaRules */
+pid_t XlaPid; /* Pid updating the tables */
+XLARULE XlaRules[MAXLARULES]; /* The rules themselves */
+short XlaCtr[MAXLARULES]; /* Counter (for work file only) */
+
+extern bool lockfile();
+
+/*
+** XLAMATCH -- Matches a fnmatch like expression.
+**
+** Parameters:
+** mask -- mask to match the string too;
+** name -- string.
+**
+** Mask can either be a plain string or a simplified fnmatch like mask:
+** *.string or string.*
+** No other alternatives are accepted.
+**
+** Returns:
+** none.
+**
+** Side Effects:
+** none.
+*/
+
+bool
+XlaMatch(mask, name)
+ char *mask, *name;
+{
+ int l1, l2;
+
+ l1 = strlen(mask); l2 = strlen(name);
+ if (l1 == 1 && mask[0] == '*') return(TRUE);
+ if (mask[0] == '*' && mask[1] == '.') {
+ if (l2 < (l1 - 2)) return(FALSE);
+ if (strcasecmp(&mask[2], name) == 0) return(TRUE);
+ if (strcasecmp(&mask[1], name + l2 - l1 + 1) == 0) return(TRUE);
+ return(FALSE);
+ }
+ if (l1 < 3) return(FALSE);
+ if (mask[l1 -1] == '*') {
+ if (l2 < l1 - 1) return(FALSE);
+ if (strncasecmp(mask, name, l1 - 1) == 0) return(TRUE);
+ return(FALSE);
+ }
+ if (strcasecmp(mask, name) == 0) return(TRUE);
+ return(FALSE);
+}
+
+/*
+** XLAZERO -- Zeroes the used variables
+**
+** Just initializes some variables, called once at sendmail
+** startup.
+**
+** Parameters:
+** none.
+**
+** Returns:
+** none.
+**
+** Side Effects:
+** none.
+*/
+
+xla_zero()
+{
+ if (tTd(59, 1)) {
+ printf("xla_zero\n");
+ }
+ XlaFname = NULL;
+ XlaNext = 0;
+ XlaPid = 0;
+ memset((char *) &XlaRules[0], 0, sizeof(XLARULE) * MAXLARULES);
+}
+
+
+/*
+** XLAINIT -- initialized extended load average stuff
+**
+** This routine handles the L lines appearing in the configuration
+** file.
+**
+** L/etc/sendmail.la indicates the working file
+** Lmask #1 #2 Xtended LA to apply to mask
+** #1 = Queueing # of connections
+** #2 = Reject connections.
+**
+** Parameters:
+** line -- the cf file line to parse.
+**
+** Returns:
+** none.
+**
+** Side Effects:
+** Builds several internal tables.
+*/
+
+xla_init(line)
+ char *line;
+{
+ char *s;
+
+ if (tTd(59, 1)) {
+ printf("xla_init line: %s\n", line);
+ }
+ if (XlaFname == NULL && *line == '/') { /* Work file name */
+ XlaFname = newstr(line);
+ if (tTd(59, 10))
+ printf("xla_init: fname = %s\n", XlaFname);
+ return;
+ }
+ if (XlaNext == MAXLARULES) {
+ syserr("too many xla rules defined (%d max)", MAXLARULES);
+ return;
+ }
+ s = strtok(line, " \t");
+ if (s == NULL) {
+ syserr("xla: line unparseable");
+ return;
+ }
+ XlaRules[XlaNext].mask = newstr(s);
+ s = strtok(NULL, " \t");
+ if (s == NULL) {
+ syserr("xla: line unparseable");
+ return;
+ }
+ XlaRules[XlaNext].queue = atoi(s);
+ s = strtok(NULL, " \t");
+ if (s == NULL) {
+ syserr("xla: line unparseable");
+ return;
+ }
+ XlaRules[XlaNext].reject = atoi(s);
+ if (tTd(59, 10))
+ printf("xla_init: rule #%d = %s q=%d r=%d\n", XlaNext,
+ XlaRules[XlaNext].mask,
+ XlaRules[XlaNext].queue, XlaRules[XlaNext].reject);
+ XlaNext++;
+}
+
+
+/*
+** XLACREATEFILE -- Create the working file
+**
+** Tries to create the working file, called each time sendmail is
+** invoked with the -bd option.
+**
+** Parameters:
+** none.
+**
+** Returns:
+** none.
+**
+** Side Effects:
+** Creates the working file (sendmail.la) and zeroes it.
+*/
+
+xla_create_file()
+{
+ int fd, i;
+
+ if (tTd(59, 1))
+ printf("xla_create_file:\n");
+ if (XlaFname == NULL) return;
+ fd = open(XlaFname, O_RDWR|O_CREAT, 0644);
+ if (fd == -1) {
+ XlaFname = NULL;
+ syserr("xla_create_file: open failed");
+ return;
+ }
+ if (!lockfile(fd, XlaFname, NULL, LOCK_EX)) {
+ close(fd);
+ XlaFname = NULL;
+ syserr("xla_create_file: can't set lock");
+ return;
+ }
+ if (ftruncate(fd, 0) == -1) {
+ close(fd);
+ XlaFname = NULL;
+ syserr("xla_create_file: can't truncate XlaFname");
+ return;
+ }
+ if (write(fd, XlaCtr, sizeof(XlaCtr)) != sizeof(XlaCtr)) {
+ XlaFname == NULL;
+ syserr("xla_create_file: can't write XlaFname");
+ }
+ close(fd);
+}
+
+
+/*
+** XLASMTPOK -- Checks if all slots are in use
+**
+** Check is there are still some slots available for an SMTP
+** connection.
+**
+** Parameters:
+** none.
+**
+** Returns:
+** TRUE -- slots are available;
+** FALSE -- no more slots.
+**
+** Side Effects:
+** Reads a file, uses a lock and updates sendmail.la if a slot
+** is free for use.
+*/
+
+bool
+xla_smtp_ok()
+{
+ int fd, i;
+
+ if (tTd(59, 1))
+ printf("xla_smtp_ok:\n");
+ if (XlaFname == NULL) return(TRUE);
+ fd = open(XlaFname, O_RDWR, 0644);
+ if (fd == -1) {
+ XlaFname = NULL;
+ syserr("xla_smtp_ok: open failed");
+ return(TRUE);
+ }
+ if (!lockfile(fd, XlaFname, NULL, LOCK_EX)) {
+ close(fd);
+ XlaFname = NULL;
+ syserr("xla_smtp_ok: can't set lock");
+ return(TRUE);
+ }
+ if (read(fd, XlaCtr, sizeof(XlaCtr)) != sizeof(XlaCtr)) {
+ close(fd);
+ XlaFname = NULL;
+ syserr("xla_smtp_ok: can't read XlaFname");
+ return(TRUE);
+ }
+ close(fd);
+ for (i = 0; i < XlaNext; i++) {
+ if (XlaCtr[i] < XlaRules[i].reject)
+ return(TRUE);
+ }
+ return(FALSE);
+}
+
+
+/*
+** XLAHOSTOK -- Can we accept a connection from this host
+**
+** Check the quota for the indicated host
+**
+** Parameters:
+** name -- host name or IP# (string)
+**
+** Returns:
+** TRUE -- we can accept the connection;
+** FALSE -- we must refuse the connection.1
+**
+** Side Effects:
+** Reads and writes a file, uses a lock and still updates
+** sendmail.la is a slot gets assigned.
+*/
+
+bool
+xla_host_ok(name)
+ char *name;
+{
+ int fd, i;
+
+ if (tTd(59, 1))
+ printf("xla_host_ok:\n");
+ if (XlaFname == NULL) return(TRUE);
+ fd = open(XlaFname, O_RDWR, 0644);
+ if (fd == -1) {
+ XlaFname = NULL;
+ syserr("xla_host_ok: open failed");
+ return(TRUE);
+ }
+ XlaPid = getpid();
+ if (!lockfile(fd, XlaFname, NULL, LOCK_EX)) {
+ close(fd);
+ XlaFname = NULL;
+ syserr("xla_host_ok: can't set lock");
+ return(TRUE);
+ }
+ if (read(fd, XlaCtr, sizeof(XlaCtr)) != sizeof(XlaCtr)) {
+ close(fd);
+ XlaFname = NULL;
+ syserr("xla_smtp_ok: can't read XlaFname");
+ return(TRUE);
+ }
+ strncpy(XlaHostName, name, sizeof(XlaHostName) -1);
+ XlaHostName[sizeof(XlaHostName) -1] = 0;
+ i = strlen(name) - 1;
+ if (i >= 0 && XlaHostName[i] == '.') XlaHostName[i] = 0;
+ for (i = 0; i < XlaNext; i++) {
+ if (XlaMatch(XlaRules[i].mask, XlaHostName)) {
+ if (XlaCtr[i] < XlaRules[i].reject) {
+ if (XlaRules[i].num++ == 0) {
+ XlaCtr[i]++;
+ lseek(fd, i*sizeof(XlaCtr[i]), SEEK_SET);
+ if (write(fd, &XlaCtr[i], sizeof(XlaCtr[i])) != sizeof(XlaCtr[i]))
+ XlaFname = NULL;
+ }
+ close(fd);
+ return(TRUE);
+ }
+ close(fd);
+ return(FALSE);
+ }
+ }
+ close(fd);
+ return(TRUE);
+}
+
+/*
+** XLANOQUEUEOK -- Can we sent this message to the remote host
+**
+** Check if we can send to the remote host
+**
+** Parameters:
+** name -- host name or IP# (string)
+**
+** Returns:
+** TRUE -- we can send the message to the remote site;
+** FALSE -- we can't connect the remote host, queue.
+**
+** Side Effects:
+** Reads and writes a file, uses a lock.
+** And still updates the sendmail.la file.
+*/
+
+bool
+xla_noqueue_ok(name)
+ char *name;
+{
+ int fd, i;
+
+ if (tTd(59, 1))
+ printf("xla_noqueue_ok:\n");
+ if (XlaFname == NULL) return(TRUE);
+ fd = open(XlaFname, O_RDWR, 0644);
+ if (fd == -1) {
+ XlaFname = NULL;
+ syserr("xla_noqueue_ok: open failed");
+ return(TRUE);
+ }
+ if (!lockfile(fd, XlaFname, NULL, LOCK_EX)) {
+ close(fd);
+ XlaFname = NULL;
+ syserr("xla_noqueue_ok: can't set lock");
+ return(TRUE);
+ }
+ XlaPid = getpid();
+ if (read(fd, XlaCtr, sizeof(XlaCtr)) != sizeof(XlaCtr)) {
+ close(fd);
+ XlaFname = NULL;
+ syserr("xla_noqueue_ok: can't read XlaFname");
+ return(TRUE);
+ }
+ strncpy(XlaHostName, name, sizeof(XlaHostName) -1);
+ XlaHostName[sizeof(XlaHostName) -1] = 0;
+ i = strlen(name) - 1;
+ if (i >= 0 && XlaHostName[i] == '.') XlaHostName[i] = 0;
+ for (i = 0; i < XlaNext; i++) {
+ if (XlaMatch(XlaRules[i].mask, XlaHostName)) {
+ if (XlaCtr[i] < XlaRules[i].queue) {
+ if (XlaRules[i].num++ == 0) {
+ XlaCtr[i]++;
+ lseek(fd, i*sizeof(XlaCtr[i]), SEEK_SET);
+ if (write(fd, &XlaCtr[i], sizeof(XlaCtr[i])) != sizeof(XlaCtr[i]))
+ XlaFname = NULL;
+ }
+ close(fd);
+ return(TRUE);
+ }
+ close(fd);
+ return(FALSE);
+ }
+ }
+ close(fd);
+ return(TRUE);
+}
+
+
+/*
+** XLAHOSTEND -- Notice that a connection is terminated.
+**
+** Updates the counters to reflect the end of an SMTP session
+** (in or outgoing).
+**
+** Parameters:
+** name -- host name or IP# (string)
+**
+** Returns:
+** none.
+**
+** Side Effects:
+** Reads and writes a file, uses a lock.
+** And still updates sendmail.la.
+*/
+
+xla_host_end(name)
+ char *name;
+{
+ int fd, i;
+
+ if (tTd(59, 1))
+ printf("xla_host_end:\n");
+ if (XlaFname == NULL || XlaPid != getpid()) return;
+ fd = open(XlaFname, O_RDWR, 0644);
+ if (fd == -1) {
+ XlaFname = NULL;
+ syserr("xla_host_end: open failed");
+ return;
+ }
+ if (!lockfile(fd, XlaFname, NULL, LOCK_EX)) {
+ close(fd);
+ XlaFname = NULL;
+ syserr("xla_host_end: can't set lock");
+ return;
+ }
+ if (read(fd, XlaCtr, sizeof(XlaCtr)) != sizeof(XlaCtr)) {
+ close(fd);
+ XlaFname = NULL;
+ syserr("xla_host_end: can't read XlaFname");
+ return(TRUE);
+ }
+ strncpy(XlaHostName, name, sizeof(XlaHostName) -1);
+ XlaHostName[sizeof(XlaHostName) -1] = 0;
+ i = strlen(name) - 1;
+ if (i >= 0 && XlaHostName[i] == '.') XlaHostName[i] = 0;
+ for (i = 0; i < XlaNext; i++) {
+ if (XlaMatch(XlaRules[i].mask, XlaHostName)) {
+ if (XlaRules[i].num > 0 && XlaRules[i].num-- == 1) {
+ if (XlaCtr[i]) XlaCtr[i]--;
+ lseek(fd, i*sizeof(XlaCtr[i]), SEEK_SET);
+ if (write(fd, &XlaCtr[i], sizeof(XlaCtr[i]))
+ != sizeof(XlaCtr[i]))
+ XlaFname = NULL;
+ }
+ close(fd);
+ return;
+ }
+ }
+ close(fd);
+}
+
+/*
+** XLAALLEND -- Mark all connections as closed.
+**
+** Generally due to an emergency exit.
+**
+** Parameters:
+** name -- host name or IP# (string)
+**
+** Returns:
+** none.
+**
+** Side Effects:
+** Reads and writes a file, uses a lock.
+** And guess what: updates sendmail.la.
+*/
+
+xla_all_end()
+{
+ int fd, i;
+
+ if (tTd(59, 1))
+ printf("xla_all_end:\n");
+ if (XlaFname == NULL || XlaPid != getpid()) return;
+ fd = open(XlaFname, O_RDWR, 0644);
+ if (fd == -1) {
+ XlaFname = NULL;
+ syserr("xla_all_end: open failed");
+ return;
+ }
+ if (!lockfile(fd, XlaFname, NULL, LOCK_EX)) {
+ close(fd);
+ XlaFname = NULL;
+ syserr("xla_all_end: can't set lock");
+ return;
+ }
+ if (read(fd, XlaCtr, sizeof(XlaCtr)) != sizeof(XlaCtr)) {
+ close(fd);
+ XlaFname = NULL;
+ syserr("xla_all_end: can't read XlaFname");
+ return(TRUE);
+ }
+ for (i = 0; i < XlaNext; i++) {
+ if (XlaCtr[i] > 0 && XlaRules[i].num > 0) {
+ XlaCtr[i]--; XlaRules[i].num = 0;
+ }
+ }
+ lseek(fd, 0, SEEK_SET);
+ if (write(fd, XlaCtr, sizeof(XlaCtr)) != sizeof(XlaCtr)) {
+ XlaFname = NULL;
+ }
+ close(fd);
+}
+#endif /* XLA */
diff --git a/usr.sbin/sendmail/doc/changes/Makefile b/usr.sbin/sendmail/doc/changes/Makefile
new file mode 100644
index 0000000..46447c2
--- /dev/null
+++ b/usr.sbin/sendmail/doc/changes/Makefile
@@ -0,0 +1,13 @@
+# @(#)Makefile 8.1 (Berkeley) 4/13/94
+
+DIR= smm/09.sendmail
+SRCS= changes.me
+MACROS= -me
+
+all: changes.ps
+
+changes.ps: ${SRCS}
+ rm -f ${.TARGET}
+ ${PIC} ${SRCS} | ${ROFF} > ${.TARGET}
+
+.include <bsd.doc.mk>
diff --git a/usr.sbin/sendmail/doc/changes/changes.me b/usr.sbin/sendmail/doc/changes/changes.me
new file mode 100644
index 0000000..0b91ed0
--- /dev/null
+++ b/usr.sbin/sendmail/doc/changes/changes.me
@@ -0,0 +1,997 @@
+.\" Copyright (c) 1994 Eric P. Allman
+.\" Copyright (c) 1988, 1994
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)changes.me 8.1 (Berkeley) 4/13/94
+.\"
+.\" ditroff -me -Pxx changes.me
+.eh '%''Changes in Sendmail Version 8'
+.oh 'Changes in Sendmail Version 8''%'
+.nr si 3n
+.if n .ls 2
+.+c
+.(l C
+.sz 14
+Changes in Sendmail Version 8*
+.sz
+.sp
+Eric Allman
+.sp 0.5
+.i
+University of California, Berkeley
+Mammoth Project
+.)l
+.(f
+*An earlier version of this paper was printed in the
+Proceedings of the 1994 AUUG Queensland Summer Technical Conference,
+Gateway Hotel, Brisbane, March 1994.
+.)f
+.sp
+.(l F
+.ce
+ABSTRACT
+.sp \n(psu
+Version 8 of
+.i sendmail
+includes a number of major changes from previous versions.
+This paper gives a very short history of
+.i sendmail ,
+a summary of the major differences between version 5
+(the last publically available version)
+and version 8,
+and some discussion of future directions.
+.)l
+.sp 2
+.pp
+In 1987, the author stopped major work on
+.i sendmail
+due to other time committments,
+only to return to active work in 1991.
+This paper explores why work resumed
+and what changes have been made.
+.pp
+Section 1 gives a short history of
+.i sendmail
+through version 5 and the motivation behind working on version 8.
+Section 2 has
+a rather detailed description of what has changed
+between version 5 and version 8.
+The paper finishes off with some thoughts
+about what still needs to be done.
+.sh 1 "HISTORY"
+.pp
+As discussed elsewhere,
+[Allman83a, Allman83b, Allman&Amos85]
+sendmail has existed in various forms since 1980.
+It was released under the name
+.i delivermail
+in 4BSD and 4.1BSD, and as
+.i sendmail
+in 4.2BSD.
+.\"4.0BSD delivermail 1.10
+.\"4.1BSD delivermail 1.10
+.\"4.2BSD sendmail 4.12
+.\"4.3BSD sendmail 5.52
+It quickly became the dominant mail system for networked UNIX systems.
+.pp
+Prior the release of 4.3BSD in November 1986,
+the author had left the University for private industry,
+but continued to do some work on
+.i sendmail
+with activity slowly trailing off
+until effectively stopping after February 1987.
+There was minimal support done by many people for several years,
+until July of 1991 when the original author,
+who had returned the University,
+started active work on it again.
+.pp
+There were several reasons for renewed work on
+.i sendmail .
+There was a desire at Berkeley to convert to a subdomained structure
+so that individuals were identified by their subdomain
+rather than by their individual workstation;
+although possible in the old code, there were some problems,
+and the author was the obvious person to address them.
+The Computer Systems Research Group (CSRG),
+the group that produced the Berkeley Software Distributions,
+was working on 4.4BSD,
+and wanted an update to the mail system.
+Bryan Costales was working on a book on
+.i sendmail
+that was being reviewed by the author,
+which encouraged him to make some revisions.
+And the author wanted to try to unify some of the disparate versions of
+.i sendmail
+that had been permitted to proliferate.
+.pp
+During the 1987\-91 fallow period,
+many vendors and outside volunteers
+had produced variants of
+.i sendmail .
+Perhaps the best known is the IDA version
+[IDA87].
+Originally intended to be a new set of configuration files,
+IDA expanded into a fairly large set of patches for the code.
+Originally produced in Sweden,
+IDA development passed to the University of Illinois,
+and was widely used by the fairly large set of people
+who prefer to get and compile their own source code
+rather than use vendor-supplied binaries.
+.pp
+In about the same time frame,
+attempts were made to clean up and extend the Simple Mail Transport Protocol
+(SMTP)
+[RFC821].
+This involved clarifications of some ambiguities in the protocol,
+and correction of some problem areas
+[RFC1123],
+as well as extensions for additional functionality
+(dubbed Extended Simple Mail Transport Protocol, or ESMTP)
+[RFC1425, RFC1426, RFC1427]
+and a richer set of semantics in the body of messages
+(the Multipurpose Internet Mail Extensions, a.k.a. MIME)
+[RFC1521, RFC1344].
+Neither the IDA group nor most vendors
+were modifying
+.i sendmail
+to conform to these new standards.
+It seemed clear that these were ``good things''
+that should be encouraged.
+However, since no one was working on a publically available version of
+.i sendmail
+with these updates,
+they were unlikely to be widely deployed any time in the near future.
+.pp
+There are, of course, other mail transport agents available,
+such as
+.i MMDF
+.\"[ref],
+.i zmailer
+.\"[ref],
+.i smail
+.\"[ref],
+and
+.i PP
+.\"[ref].
+However, none of these seemed to be gaining the prominence of
+.i sendmail ;
+it appeared that most companies would not convert to another
+mail transport agent any time in the forseeable future.
+However, they might be persuaded to convert to a newer version of
+.i sendmail .
+.pp
+All of these convinced the author
+to work on a updated version of
+.i sendmail
+for public distribution.
+.pp
+The new version of
+.i sendmail
+is referred to as version eight (V8).
+Versions six and seven were skipped
+because of an agreement
+that all files in 4.4BSD would be numbered as
+.q 8.1 .
+Rather than have an external version number
+that differed from the file version numbers,
+.i sendmail
+just jumped directly to V8.
+.sh 1 "CHANGES IN VERSION EIGHT"
+.pp
+The following is a summary of the changes between the last commonly
+available version of sendmail from Berkeley (5.67) and the latest
+version (8.6.6).
+.pp
+Many of these are ideas that had been tried in IDA,
+but many of them were generalized in V8.
+.sh 2 "Performance Enhancements"
+.pp
+Instead of closing SMTP connections immediately, open connections are
+cached for possible future use. There is a limit to the number of
+simultaneous open connections and the idle time of any individual
+connection.
+.pp
+This is of best help during queue processing (since there is the
+potential of many different messages going to one site), although
+it can also help when processing MX records which aren't handled
+by MX Piggybacking.
+.pp
+If two hosts with different names in a single message happen to
+have the same set of MX hosts, they can be sent in the same
+transaction. Version 8 notices this and tries to batch the messages.
+.pp
+For example, if two sites ``foo.com'' and ``bar.com'' are both
+served by UUNET, they will have the same set of MX hosts and will
+be sent in one transaction. UUNET will then split the message
+and send it to the two individual hosts.
+.sh 2 "RFC 1123 Changes"
+.pp
+A number of changes have been made to make sendmail ``conditionally
+compliant'' (that is, it satisfies all of the MUST clauses and most
+but not all of the SHOULD clauses in RFC 1123).
+.pp
+The major areas of change are (numbers are RFC 1123 section numbers):
+.nr ii 0.75i
+.ip \(sc5.2.7
+Response to RCPT command is fast. Previously, sendmail
+expanded all aliases as far as it could \*- this could
+take a very long time, particularly if there were
+name server delays. Version 8 only checks for the
+existence of an alias and does the expansion later.
+It does still do a DNS lookup if there is an explicit host name
+in the RCPT command,
+but this time is bounded.
+.ip \(sc5.2.8
+Numeric IP addresses are logged in Received: lines.
+This helps tracing spoofed messages.
+.ip \(sc5.2.17
+Self domain literal is properly handled. Previously,
+if someone sent to user@[1.2.3.4], where 1.2.3.4 is
+your IP address, the mail would probably be rejected
+with a ``configuration error''.
+Version 8 can handle these addresses.
+.ip \(sc5.3.2
+Better control over individual timeouts. RFC 821 specified
+no timeouts. Older versions of sendmail had a single
+timeout, typically set to two hours. Version 8 allows
+the configuration file to set timeouts for various
+SMTP commands individually.
+.ip \(sc5.3.3
+Error messages are sent as From:<>. This was urged by
+RFC 821 and reiterated by RFC 1123, but older versions
+of sendmail never really did it properly. Version 8
+does. However, some systems cannot handle this
+perfectly legal address; if necessary, you can create
+a special mailer that uses the `g' flag to disable this.
+.ip \(sc5.3.3
+Error messages are never sent to <>. Previously,
+sendmail was happy to send responses-to-responses which
+sometimes resulted in responses-to-responses-to-responses
+which resulted in .... you get the idea.
+.ip \(sc5.3.3
+Route-addrs (the ugly ``<@hosta,@hostb:user@hostc>''
+syntax) are pruned. RFC 821 urged the use of this
+bletcherous syntax. RFC 1123 has seen the light and
+officially deprecates them, further urging that you
+eliminate all but ``user@hostc'' should you receive
+one of these things. Version 8 is slightly more generous
+than the standards suggest; instead of stripping off all
+the route addressees, it only strips hosts off up to
+the one before the last one known to DNS, thus allowing
+you to have pseudo-hosts such as foo.BITNET. The `R'
+option will turn this off.
+.lp
+The areas in which sendmail is not ``unconditionally compliant'' are:
+.ip \(sc5.2.6
+Sendmail does do header munging.
+.ip \(sc5.2.10
+Sendmail doesn't always use the exact SMTP message
+text from RFC 821. This is a rather silly requirement.
+.ip \(sc5.3.1.1
+Sendmail doesn't guarantee only one connect for each
+host on queue runs. Connection caching gives you most
+of this, but it does not provide a guarantee.
+.ip \(sc5.3.1.1
+Sendmail doesn't always provide an adequate limit
+on concurrency. That is, there can be several
+independent sendmails running at once. My feeling
+is that doing an absolute limit would be a mistake
+(it might result in lost mail). However, if you use
+the XLA contributed software, most of this will be
+guaranteed (but I don't guarantee the guarantee).
+.sh 2 "Extended SMTP Support
+.pp
+Version 8 includes both sending and receiving support for Extended
+SMTP support as defined by RFC 1425 (basic) and RFC 1427 (SIZE);
+and limited support for RFC 1426 (BODY).
+The body support is minimal because the
+.q 8BITMIME
+body type is not currently advertised.
+Although such a body type will be accepted,
+it will not be correctly converted to 7 bits
+if speaking to a non-8-bit-MIME aware SMTP server.
+.pp
+.i Sendmail
+tries to speak ESMTP if you have the `a' flag set
+in the flags for the mailer descriptor,
+or if the other end advertises the fact that it speaks ESMTP.
+This is a non-standard advertisement:
+.i sendmail
+announces
+.q "ESMTP spoken here"
+during the initial connection message,
+and client sendmails search for this message.
+This creates some problems for some PC-based mailers,
+which do not understand two-line greeting messages
+as required by RFC 821.
+.sh 2 "Eight-Bit Clean
+.pp
+Previous versions of sendmail used the 0200 bit for quoting. This
+version avoids that use.
+However, you can set option `7' to get seven bit stripping
+for compatibility with RFC 821,
+which is a 7-bit protocol.
+This option says ``strip to 7 bits on input''.
+.pp
+Individual mailers can still produce seven bit out put using the
+`7' mailer flag.
+This flag says ``strip to 7 bits on output''.
+.sh 2 "User Database"
+.pp
+The User Database (UDB) is an as-yet experimental attempt to provide
+unified large-site name support.
+We are installing it at Berkeley;
+future versions may show significant modifications.
+Briefly, UDB contains a database that is intended to contain
+all the per-user information for your workgroup,
+such as people's full names, their .plan information,
+their outgoing mail name, and their mail drop.
+.pp
+The user database allows you to map both incoming and outgoing
+addresses, much like IDA. However, the interface is still
+better with IDA;
+in particular, the alias file with incoming/outgoing marks
+provides better locality of information.
+.sh 2 "Improved BIND Support"
+.pp
+The BIND support, particularly for MX records, had a number of
+annoying ``features'' which have been removed in this release. In
+particular, these more tightly bind (pun intended) the name server
+to sendmail, so that the name server resolution rules are incorporated
+directly into sendmail.
+.pp
+The major change has been that the $[ ... $] operator didn't fully
+qualify names that were in DNS as A or MX records. Version 8 does
+this qualification.
+.pp
+This has proven to be an annoyance in Sun shops,
+who often still run without BIND support.
+However, it is really critical that this be supported,
+since MX records are mandatory.
+In SunOS you can choose either MX support or NIS support,
+but not both.
+This is fixed in Solaris,
+and some
+.i sendmail
+support to allow this in SunOS should be forthcoming in a future release.
+.sh 2 "Keyed Files"
+.pp
+Generalized keyed files is an idea taken directly from IDA sendmail
+(albeit with a completely different implementation).
+They can be useful on large sites.
+.pp
+Version 8 includes the following built-in map classes:
+.ip dbm
+Support for the ndbm(3) library.
+.ip hash
+Support for the ``Hash'' type from the new Berkeley db(3) library.
+this library provides substantially better database support
+than ndbm(3),
+including in-memory caching,
+arbitrarily long keys and values,
+and better disk utilization.
+.ip btree
+Support for the ``B-Tree'' type from the new Berkeley db(3) library.
+B-Trees provide better clustering than Hashed files
+if you are fetching lots of records that have similar keys,
+such as searching a dictionary for words beginning with ``detr''.
+.ip nis
+Support for NIS (a.k.a. YP) maps.
+NIS+ is not supported in this version.
+.ip host
+Support for DNS lookups.
+.ip dequote
+A ``pseudo-map'' (that is, once that does not have any external data)
+that allows a configuration file to break apart a quoted string
+in the address.
+This is necessary primarily for DECnet addresses,
+which often have quoted addresses that need to be unwrapped on gateways.
+.sh 2 "Multi-Word Classes & Macros in Classes"
+.pp
+Classes can now be multiple words. For example,
+.(b
+CShofmann.CS.Berkeley.EDU
+.)b
+allows you to match the entire string ``hofmann.CS.Berkeley.EDU''
+using the single construct ``$=S''.
+.pp
+Class definitions are now allowed to include macros \*- for example:
+.(b
+Cw$k
+.)b
+is legal.
+.sh 2 "IDENT Protocol Support"
+.pp
+The IDENT protocol as defined in RFC 1413 [RFC1413] is supported.
+However, many systems have a TCP/IP bug that renders this useless,
+and the feature must be turned off.
+Roughly, if one of these system receives a
+.q "No route to host"
+message (ICMP message ICMP_UNREACH_HOST) on
+.i any
+connection, all connections to that host are closed.
+Some firewalls return this error if you try to connect
+to the IDENT port,
+so you can't receive email from these hosts on these systems.
+It's possible that if the firewall used a more specific message
+(such as ICMP_UNREACH_PROTOCOL, ICMP_UNREACH_PORT or ICMP_UNREACH_NET_PROHIB)
+it would work, but this hasn't been verified.
+.pp
+IDENT protocol support cannot be used on
+4.3BSD,
+Apollo DomainOS,
+Apple A/UX,
+ConvexOS,
+Data General DG/UX,
+HP-UX,
+Sequent Dynix,
+or
+Ultrix.
+It seems to work on
+4.4BSD,
+IBM AIX 3.x,
+OSF/1,
+SGI IRIX,
+Solaris,
+and
+SunOS.
+.sh 2 "Separate Envelope/Header Processing
+.pp
+Since the From: line is passed in separately from the envelope
+sender, these have both been made visible; the $g macro is set to
+the envelope sender during processing of mailer argument vectors
+and the header sender during processing of headers.
+.pp
+It is also possible to specify separate per-mailer envelope and
+header processing. The SenderRWSet and RecipientRWset arguments
+for mailers can be specified as ``envelope/header'' to give different
+rewritings for envelope versus header addresses.
+.sh 2 "Owner-List Propagates to Envelope
+.pp
+When an alias has an associated owner-list name, that alias is used
+to change the envelope sender address. This will cause downstream
+errors to be returned to that owner.
+.pp
+Some people find this confusing
+because the envelope sender is what appears in the first
+``From_'' line in UNIX messages
+(that is, the line beginning ``From<space>''
+instead of ``From:'';
+the latter is the header from, which
+.i does
+indicate the sender of the message).
+In previous versions,
+.i sendmail
+has tried to avoid changing the envelope sender
+for back compatibility with UNIX convention;
+at this point that back compatibility is creating too many problems,
+and it is necessary to move forward into the 1980s.
+.sh 2 "Command Line Flags"
+.pp
+The
+.b \-B
+flag has been added to pass in body type information.
+.pp
+The
+.b \-p
+flag has been added to pass in protocol information
+that was previously passed in by defining the
+.b $r
+and
+.b $s
+macros.
+.pp
+The
+.b \-X
+flag has been added to allow logging of all protocol in and
+out of sendmail for debugging.
+You can set
+.q "\-X filename"
+and a complete transcript will be logged in that file.
+This gets big fast: the option is only for debugging.
+.pp
+The
+.b \-q
+flag can limit limit a queue run to specific recipients,
+senders, or queue ids using \-qRsubstring, \-qSsubstring, or
+\-qIsubstring respectively.
+.sh 2 "New Configuration Line Types
+.pp
+The `T' (Trusted users) configuration line has been deleted. It
+will still be accepted but will be ignored.
+.pp
+The `K' line has been added to declare database maps.
+.pp
+The `V' line has been added to declare the configuration version
+level.
+.pp
+The `M' (mailer) line takes a D= field to specify execution
+directory.
+.sh 2 "New and Extended Options"
+.pp
+Several new options have been added, many to support new features,
+others to allow tuning that was previously available only by
+recompiling. Briefly:
+.nr ii 0.5i
+.ip A
+The alias file specification can now be a list of alias files.
+Also, the configuration can specify a class of file.
+For example, to search the NIS aliases, use
+.q OAnis:mail.aliases .
+.ip b
+Insist on a minimum number of disk blocks.
+.ip C
+Delivery checkpoint interval. Checkpoint the queue (to avoid
+duplicate deliveries) every C addresses.
+.ip E
+Default error message. This message (or the contents of the
+indicated file) are prepended to error messages.
+.ip G
+Enable GECOS matching. If you can't find a local user name
+and this option is enabled, do a sequential scan of the passwd
+file to match against full names. Previously a compile option.
+.ip h
+Maximum hop count. Previously this was compiled in.
+.ip I
+This option has been extended to allow setting of resolver parameters.
+.ip j
+Send errors in MIME-encapsulated format.
+.ip J
+Forward file path. Where to search for .forward files \*- defaults
+to $HOME/.forward.
+.ip k
+Connection cache size. The total number of connections that will
+be kept open at any time.
+.ip K
+Connection cache lifetime. The amount of time any connection
+will be permitted to sit idle.
+.ip l
+Enable Errors-To: header. These headers violate RFC 1123;
+this option is included to provide back compatibility with
+old versions of sendmail.
+.ip O
+Incoming daemon options (e.g., use alternate SMTP port).
+.ip p
+Privacy options. These can be used to make your SMTP server
+less friendly.
+.ip r
+This option has been extended to allow finer grained control
+over timeouts.
+For example, you can set the timeout for SMTP commands individually.
+.ip R
+Don't prune route-addrs. Normally, if version 8 sees an address
+like "<@hostA,@hostB:user@hostC>, sendmail will try to strip off
+as much as it can (up to user@hostC) as suggested by RFC 1123.
+This option disables that behaviour.
+.ip T
+The
+.q "Return To Sender"
+timeout has been extended
+to allow specification of a warning message interval,
+typically something on the order of four hours.
+If a message cannot be delivered in that interval,
+a warning message is sent back to the sender
+but the message continues to be tried.
+.ip U
+User database spec. This is still experimental.
+.ip V
+Fallback ``MX'' host. This can be thought of as an MX host
+that applies to all addresses that has a very high preference
+value (that is, use it only if everything else fails).
+.ip w
+If set, assume that if you are the best MX host for a host,
+you should send directly to that host. This is intended
+for compatibility with UIUC sendmail, and may have some
+use on firewalls.
+.ip 7
+Do not run eight bit clean. Technically, you have to assert
+this option to be RFC 821 compatible.
+.sh 2 "New Mailer Definitions"
+.ip L=
+Set the allowable line length. In V5, the L mailer flag implied
+a line length limit of 990 characters; this is now settable to
+an arbitrary value.
+.ip F=a
+Try to use ESMTP. It will fall back to SMTP if the initial
+EHLO packet is rejected.
+.ip F=b
+Ensure a blank line at the end of messages. Useful on the
+*file* mailer.
+.ip F=c
+Strip all comments from addresses; this should only be used as
+a last resort when dealing with cranky mailers.
+.ip F=g
+Never use the null sender as the envelope sender, even when
+running SMTP. This violates RFC 1123.
+.ip F=7
+Strip all output to this mailer to 7 bits.
+.ip F=L
+Used to set the line limit to 990 bytes for SMTP compatibility.
+It now does that only if the L= keyletter is not specified.
+This flag is obsolete and should not be used.
+.sh 2 "New or Changed Pre-Defined Macros"
+.ip $k
+UUCP node name from uname(2).
+.ip $m
+Domain part of our full hostname.
+.ip $_
+RFC 1413-provided sender address.
+.ip $w
+Previously was sometimes the full domain name, sometimes
+just the first word. Now guaranteed to be the first word
+of the domain name (i.e., the host name).
+.ip $j
+Previously had to be defined \*- it is now predefined to be
+the full domain name, if that can be determined. That is,
+it is equivalent to $w.$m.
+.sh 2 "New and Changed Classes"
+.ip $=k
+Initialized to contain $k.
+.ip $=w
+Now includes
+.q [1.2.3.4]
+(where 1.2.3.4 is your IP address)
+to allow the configuration file to recognize your own IP address.
+.sh 2 "New Rewriting Tokens"
+.pp
+The
+.b $&
+construct has been adopted from IDA to defer macro evaluation.
+Normally, macros in rulesets are bound when the rule is first parsed
+during startup.
+Some macros change during processing and are uninteresting during startup.
+However, that macro can be referenced using
+.q $&x
+to defer the evaulation of
+$x
+until the rule is processed.
+.pp
+The tokens
+.b $(
+and
+.b $)
+have been added to allow specification of map rewriting.
+.pp
+Version 8 allows
+.b $@
+on the Left Hand Side of an `R' line to match
+zero tokens.
+This is intended to be used to match the null input.
+.sh 2 "Bigger Defaults
+.pp
+Version 8 allows up to 100 rulesets instead of 30. It is recommended
+that rulesets 0\-9 be reserved for sendmail's dedicated use in future
+releases.
+.pp
+The total number of MX records that can be used has been raised to
+20.
+.pp
+The number of queued messages that can be handled at one time has
+been raised from 600 to 1000.
+.sh 2 "Different Default Tuning Parameters
+.pp
+Version 8 has changed the default parameters for tuning queue costs
+to make the number of recipients more important than the size of
+the message (for small messages). This is reasonable if you are
+connected with reasonably fast links.
+.sh 2 "Auto-Quoting in Addresses
+.pp
+Previously, the ``Full Name <email address>'' syntax would generate
+incorrect protocol output if ``Full Name'' had special characters
+such as dot. This version puts quotes around such names.
+.sh 2 "Symbolic Names On Error Mailer
+.pp
+Several names have been built in to the $@ portion of the $#error
+mailer. For example:
+.(b
+$#error $@NOHOST $: Host unknown
+.)b
+Prints the indicated message
+and sets the exit status of
+.i sendmail
+to
+.sm EX_NOHOST .
+.sh 2 "New Built-In Mailers"
+.pp
+Two new mailers, *file* and *include*, are included to define options
+when mailing to a file or a :include: file respectively. Previously
+these were overloaded on the local mailer.
+.sh 2 "SMTP VRFY Doesn't Expand
+.pp
+Previous versions of sendmail treated VRFY and EXPN the same. In
+this version, VRFY doesn't expand aliases or follow .forward files.
+.pp
+As an optimization, if you run with your default delivery mode
+being queue-only, the RCPT command will also not chase aliases and
+\&.forward files.
+It will chase them when it processes the queue.
+This speeds up RCPT processing.
+.sh 2 "[IPC] Mailers Allow Multiple Hosts
+.pp
+When an address resolves to a mailer that has ``[IPC]'' as its
+``Path'', the $@ part (host name) can be a colon-separated list of
+hosts instead of a single hostname. This asks sendmail to search
+the list for the first entry that is available exactly as though
+it were an MX record. The intent is to route internal traffic
+through internal networks without publishing an MX record to the
+net. MX expansion is still done on the individual items.
+.sh 2 "Aliases Extended"
+.pp
+The implementation has been merged with maps. Among other things,
+this supports multiple alias files and NIS-based aliases. For
+example:
+.(b
+OA/etc/aliases,nis:mail.aliases
+.)b
+will search first the local database
+.q /etc/aliases
+followed by the NIS map
+
+.sh 2 "Portability and Security Enhancements
+.pp
+A number of internal changes have been made to enhance portability.
+.pp
+Several fixes have been made to increase the paranoia factor.
+.pp
+In particular, the permissions required for .forward and :include:
+files have been tightened up considerably. V5 would pretty much
+read any file it could get to as root, which exposed some security
+holes. V8 insists that all directories leading up to the .forward
+or :include: file be searchable ("x" permission) by the controlling
+user" (defined below), that the file itself be readable by the
+controlling user, and that .forward files be owned by the user
+who is being forwarded to or root.
+.pp
+The "controlling user" is the user on whose behalf the mail is
+being delivered. For example, if you mail to "user1" then the
+controlling user for ~user1/.forward and any mailers invoked
+by that .forward file, including :include: files.
+.pp
+Previously, anyone who had a home directory could create a .forward
+could forward to a program. Now, sendmail checks to make sure
+that they have an "approved shell", that is, a shell listed in
+the /etc/shells file.
+.sh 2 "Miscellaneous Fixes and Enhancements"
+.pp
+A number of small bugs having to do with things like backslash-escaped
+quotes inside of comments have been fixed.
+.pp
+The fixed size limit on header lines
+(such as
+.q To:
+and
+.q Cc: )
+has been eliminated;
+those buffers are dynamically allocated now.
+.pp
+Sendmail writes a /etc/sendmail.pid file with the current process id
+and the current invocation flags.
+.pp
+Two people using the same program (e.g., submit) are considered
+"different" so that duplicate elimination doesn't delete one of
+them. For example, two people forwarding their email to
+|submit will be treated as two recipients.
+.pp
+The mailstats program prints mailer names and gets the location of
+the sendmail.st file from /etc/sendmail.cf.
+.pp
+Many minor bugs have been fixed, such as handling of backslashes
+inside of quotes.
+.pp
+A hook has been added to allow rewriting of local addresses after
+aliasing.
+.sh 1 "FUTURE WORK"
+.pp
+The previous section describes
+.i sendmail
+as of version 8.6.6.
+There is still much to be done.
+Some high points are described below.
+This list is by no means exhaustive.
+.sh 2 "Full MIME Support"
+.pp
+Currently
+.i sendmail
+only supports seven bit MIME messages.
+Although it can pass eight bit MIME messages,
+it cannot advertise that fact because the standards say
+that the mail agent must be able to do 8- to 7-bit conversion
+to have full 8-bit support.
+This requires far more extensive modification of the message body
+than is currently supported.
+.pp
+The best way to do this would be to support the general concept
+of an external
+``message filter''
+that could do arbitrary modifications of the message.
+This would allow MIME conversion as well as such things as
+automatic encryption of messages sent over external links.
+This is probably an extremely non-trivial change.
+.sh 2 "Service Switch Abstraction"
+.pp
+Most modern systems include some concept of a
+.q "service switch"
+\*- for example, to look up host names you can try
+DNS, NIS, NIS+, text tables, NetInfo,
+or other services in some arbitrary order.
+This is currently very clumsy in
+.i sendmail ,
+with only limited control of the services provided.
+.sh 2 "More Control of Local Addresses"
+.pp
+Currently some addresses are declared as
+.q local
+and are handled specially \*-
+for example, they may have .forward files,
+may be translated into program calls or file deliveries,
+and so forth.
+These should be broken out into separate flags
+to allow the local system administrator
+to have more fine-grained control over operations.
+.sh 2 "More Run-Time Configuration Options"
+.pp
+There are many options that are configured at compile time,
+such as the method of file locking
+and the use of the IDENT protocol
+[RFC1413].
+These should be transfered to run time
+by adding new options.
+.pp
+Similarly, some options are currently overloaded,
+that is, a single option controls more than one thing.
+These should probably be broken out into separate options.
+.pp
+This implies that options will change from single characters
+to words.
+.sh 2 "More Configuration Control Over Errors"
+.pp
+Currently,
+the configuration file can generate an error message during parsing.
+However,
+it cannot tweak other operations,
+such as issuing a warning message to the system postmaster.
+Similarly,
+some errors should not be triggered if they are in aliases
+during an alias file rebuild,
+but should be triggered if that alias is actually used.
+.sh 2 "Long Term Host State"
+.pp
+Currently,
+.i sendmail
+only remembers host status during a single queue run.
+This should be converted to long term status
+stored on disk
+so it can be shared between instantiations of
+.i sendmail .
+Entries will have to be timestamped
+so they can time out.
+This will allow
+.i sendmail
+to implement exponential backoff on queue runs
+on a per-host basis.
+.sh 2 "Connection Control"
+.pp
+Modern networks have different types of connectivity
+than the past.
+In particular, the rising prominence of dialup IP
+has created certain challenges for automated servers.
+It is not uncommon to try to make a connection to a host
+and have it fail, even though if you tried again it would succeed.
+The connection management could be a bit cleverer
+to try to adapt to such situations.
+.sh 2 "Other Caching"
+.pp
+When you do an MX record lookup,
+the name server automatically returns the IP addresses
+of the associated MX servers.
+This information is currently ignored,
+and another query is done to get this information.
+It should be cached to avoid excess name server traffic.
+.sh 1 "REFERENCES"
+.ip [Allman83a]
+.q "Sendmail \*- An Internetwork Mail Router."
+E. Allman.
+In
+.ul
+Unix Programmers's Manual,
+4.2 Berkeley Software Distribution,
+volume 2C.
+August 1983.
+.ip [Allman83b]
+.q "Mail Systems and Addressing in 4.2BSD."
+E. Allman
+In
+.ul
+UNICOM Conference Proceedings.
+San Diego, California.
+January 1983.
+.ip [Allman&Amos85]
+``Sendmail Revisited.''
+E. Allman and M. Amos.
+In
+.ul
+Usenix Summer 1985 Conference Proceedings.
+Portland, Oregon.
+June 1985.
+.ip [IDA87]
+.ul 3
+Electronic Mail Addressing in Theory and Practice
+with the IDA Sendmail Enhancement Kit
+(or The Postmaster's Last Will and Testament).
+Lennart Lo\*:vstrand.
+Department of Computer and Information Science,
+University of Linko\*:ping,
+Sweden,
+Report no. LiTH-IDA-Ex-8715.
+May 1987.
+.ip [RFC821]
+.ul
+Simple Mail Transport Protocol.
+J. Postel.
+August 1982.
+.ip [RFC1123]
+.ul
+Requirements for Internet Hosts \*- Application and Support.
+Internet Engineering Task Force,
+R. Braden, Editor.
+October 1989.
+.ip [RFC1344]
+.ul
+Implications of MIME for Internet Mail Gateways.
+N. Borenstein.
+June 1992.
+.ip [RFC1413]
+.ul
+Identification Protocol.
+M. St. Johns.
+February 1993.
+.ip [RFC1425]
+.ul
+SMTP Service Extensions.
+J. Klensin, N. Freed, M. Rose, E. Stefferud, and D. Crocker.
+February 1993.
+.ip [RFC1426]
+.ul
+SMTP Service Extension for 8bit-MIMEtransport.
+J. Klensin, N. Freed, M. Rose, E. Stefferud, and D. Crocker.
+February 1993.
+.ip [RFC1427]
+.ul
+SMTP Service Extension for Message Size Declaration.
+J. Klensin, N. Freed, and K. Moore.
+February 1993.
+.ip [RFC1521]
+.ul 3
+MIME (Multipurpose Internet Mail Extensions) Part One:
+Mechanisms for Specifying and Describing
+the Format of Internet Message Bodies.
+N. Borenstein and N. Freed.
+September 1993.
diff --git a/usr.sbin/sendmail/doc/changes/changes.ps b/usr.sbin/sendmail/doc/changes/changes.ps
new file mode 100644
index 0000000..755cb57
--- /dev/null
+++ b/usr.sbin/sendmail/doc/changes/changes.ps
@@ -0,0 +1,1088 @@
+%!PS-Adobe-3.0
+%%Creator: groff version 1.08
+%%DocumentNeededResources: font Times-Roman
+%%+ font Times-Italic
+%%+ font Times-Bold
+%%DocumentSuppliedResources: procset grops 1.08 0
+%%Pages: 11
+%%PageOrder: Ascend
+%%Orientation: Portrait
+%%EndComments
+%%BeginProlog
+%%BeginResource: procset grops 1.08 0
+/setpacking where{
+pop
+currentpacking
+true setpacking
+}if
+/grops 120 dict dup begin
+/SC 32 def
+/A/show load def
+/B{0 SC 3 -1 roll widthshow}bind def
+/C{0 exch ashow}bind def
+/D{0 exch 0 SC 5 2 roll awidthshow}bind def
+/E{0 rmoveto show}bind def
+/F{0 rmoveto 0 SC 3 -1 roll widthshow}bind def
+/G{0 rmoveto 0 exch ashow}bind def
+/H{0 rmoveto 0 exch 0 SC 5 2 roll awidthshow}bind def
+/I{0 exch rmoveto show}bind def
+/J{0 exch rmoveto 0 SC 3 -1 roll widthshow}bind def
+/K{0 exch rmoveto 0 exch ashow}bind def
+/L{0 exch rmoveto 0 exch 0 SC 5 2 roll awidthshow}bind def
+/M{rmoveto show}bind def
+/N{rmoveto 0 SC 3 -1 roll widthshow}bind def
+/O{rmoveto 0 exch ashow}bind def
+/P{rmoveto 0 exch 0 SC 5 2 roll awidthshow}bind def
+/Q{moveto show}bind def
+/R{moveto 0 SC 3 -1 roll widthshow}bind def
+/S{moveto 0 exch ashow}bind def
+/T{moveto 0 exch 0 SC 5 2 roll awidthshow}bind def
+/SF{
+findfont exch
+[exch dup 0 exch 0 exch neg 0 0]makefont
+dup setfont
+[exch/setfont cvx]cvx bind def
+}bind def
+/MF{
+findfont
+[5 2 roll
+0 3 1 roll
+neg 0 0]makefont
+dup setfont
+[exch/setfont cvx]cvx bind def
+}bind def
+/level0 0 def
+/RES 0 def
+/PL 0 def
+/LS 0 def
+/PLG{
+gsave newpath clippath pathbbox grestore
+exch pop add exch pop
+}bind def
+/BP{
+/level0 save def
+1 setlinecap
+1 setlinejoin
+72 RES div dup scale
+LS{
+90 rotate
+}{
+0 PL translate
+}ifelse
+1 -1 scale
+}bind def
+/EP{
+level0 restore
+showpage
+}bind def
+/DA{
+newpath arcn stroke
+}bind def
+/SN{
+transform
+.25 sub exch .25 sub exch
+round .25 add exch round .25 add exch
+itransform
+}bind def
+/DL{
+SN
+moveto
+SN
+lineto stroke
+}bind def
+/DC{
+newpath 0 360 arc closepath
+}bind def
+/TM matrix def
+/DE{
+TM currentmatrix pop
+translate scale newpath 0 0 .5 0 360 arc closepath
+TM setmatrix
+}bind def
+/RC/rcurveto load def
+/RL/rlineto load def
+/ST/stroke load def
+/MT/moveto load def
+/CL/closepath load def
+/FL{
+currentgray exch setgray fill setgray
+}bind def
+/BL/fill load def
+/LW/setlinewidth load def
+/RE{
+findfont
+dup maxlength 1 index/FontName known not{1 add}if dict begin
+{
+1 index/FID ne{def}{pop pop}ifelse
+}forall
+/Encoding exch def
+dup/FontName exch def
+currentdict end definefont pop
+}bind def
+/DEFS 0 def
+/EBEGIN{
+moveto
+DEFS begin
+}bind def
+/EEND/end load def
+/CNT 0 def
+/level1 0 def
+/PBEGIN{
+/level1 save def
+translate
+div 3 1 roll div exch scale
+neg exch neg exch translate
+0 setgray
+0 setlinecap
+1 setlinewidth
+0 setlinejoin
+10 setmiterlimit
+[]0 setdash
+/setstrokeadjust where{
+pop
+false setstrokeadjust
+}if
+/setoverprint where{
+pop
+false setoverprint
+}if
+newpath
+/CNT countdictstack def
+userdict begin
+/showpage{}def
+}bind def
+/PEND{
+clear
+countdictstack CNT sub{end}repeat
+level1 restore
+}bind def
+end def
+/setpacking where{
+pop
+setpacking
+}if
+%%EndResource
+%%IncludeResource: font Times-Roman
+%%IncludeResource: font Times-Italic
+%%IncludeResource: font Times-Bold
+grops begin/DEFS 1 dict def DEFS begin/u{.001 mul}bind def end/RES 72 def/PL
+792 def/LS false def/ENC0[/asciicircum/asciitilde/Scaron/Zcaron/scaron/zcaron
+/Ydieresis/trademark/quotesingle/.notdef/.notdef/.notdef/.notdef/.notdef
+/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef
+/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/space
+/exclam/quotedbl/numbersign/dollar/percent/ampersand/quoteright/parenleft
+/parenright/asterisk/plus/comma/hyphen/period/slash/zero/one/two/three/four
+/five/six/seven/eight/nine/colon/semicolon/less/equal/greater/question/at/A/B/C
+/D/E/F/G/H/I/J/K/L/M/N/O/P/Q/R/S/T/U/V/W/X/Y/Z/bracketleft/backslash
+/bracketright/circumflex/underscore/quoteleft/a/b/c/d/e/f/g/h/i/j/k/l/m/n/o/p/q
+/r/s/t/u/v/w/x/y/z/braceleft/bar/braceright/tilde/.notdef/quotesinglbase
+/guillemotleft/guillemotright/bullet/florin/fraction/perthousand/dagger
+/daggerdbl/endash/emdash/ff/fi/fl/ffi/ffl/dotlessi/dotlessj/grave/hungarumlaut
+/dotaccent/breve/caron/ring/ogonek/quotedblleft/quotedblright/oe/lslash
+/quotedblbase/OE/Lslash/.notdef/exclamdown/cent/sterling/currency/yen/brokenbar
+/section/dieresis/copyright/ordfeminine/guilsinglleft/logicalnot/minus
+/registered/macron/degree/plusminus/twosuperior/threesuperior/acute/mu
+/paragraph/periodcentered/cedilla/onesuperior/ordmasculine/guilsinglright
+/onequarter/onehalf/threequarters/questiondown/Agrave/Aacute/Acircumflex/Atilde
+/Adieresis/Aring/AE/Ccedilla/Egrave/Eacute/Ecircumflex/Edieresis/Igrave/Iacute
+/Icircumflex/Idieresis/Eth/Ntilde/Ograve/Oacute/Ocircumflex/Otilde/Odieresis
+/multiply/Oslash/Ugrave/Uacute/Ucircumflex/Udieresis/Yacute/Thorn/germandbls
+/agrave/aacute/acircumflex/atilde/adieresis/aring/ae/ccedilla/egrave/eacute
+/ecircumflex/edieresis/igrave/iacute/icircumflex/idieresis/eth/ntilde/ograve
+/oacute/ocircumflex/otilde/odieresis/divide/oslash/ugrave/uacute/ucircumflex
+/udieresis/yacute/thorn/ydieresis]def/Times-Bold@0 ENC0/Times-Bold RE
+/Times-Italic@0 ENC0/Times-Italic RE/Times-Roman@0 ENC0/Times-Roman RE
+%%EndProlog
+%%Page: 1 1
+%%BeginPageSetup
+BP
+%%EndPageSetup
+/F0 14/Times-Roman@0 SF(Changes in Sendmail V)196.615 141 Q(ersion 8*)-1.554 E
+/F1 10/Times-Roman@0 SF(Eric Allman)263.42 165 Q/F2 10/Times-Italic@0 SF
+(Univer)220.2 183 Q(sity of California, Berk)-.1 E(ele)-.1 E(y)-.3 E
+(Mammoth Pr)251.98 195 Q(oject)-.45 E F1(ABSTRA)262.085 227.4 Q(CT)-.4 E -1.11
+(Ve)112 243.6 S 1.709(rsion 8 of)1.11 F F2(sendmail)4.209 E F1 1.709
+(includes a number of major changes from pre)4.209 F 1.71(vious v)-.25 F
+(ersions.)-.15 E .701(This paper gi)112 255.6 R -.15(ve)-.25 G 3.201(sav).15 G
+.701(ery short history of)194.794 255.6 R F2(sendmail)3.201 E F1 3.201(,as)C .7
+(ummary of the major dif)329.82 255.6 R(ferences)-.25 E .953(between v)112
+267.6 R .954(ersion 5 \(the last publically a)-.15 F -.25(va)-.2 G .954
+(ilable v).25 F .954(ersion\) and v)-.15 F .954(ersion 8, and some dis-)-.15 F
+(cussion of future directions.)112 279.6 Q .48
+(In 1987, the author stopped major w)97 324 R .48(ork on)-.1 F F2(sendmail)2.98
+E F1 .48(due to other time committments, only to return)2.98 F(to acti)72 336 Q
+.3 -.15(ve w)-.25 H(ork in 1991.).05 E(This paper e)5 E(xplores wh)-.15 E 2.5
+(yw)-.05 G(ork resumed and what changes ha)277 336 Q .3 -.15(ve b)-.2 H
+(een made.).15 E .58(Section 1 gi)97 352.2 R -.15(ve)-.25 G 3.08(sas).15 G .58
+(hort history of)173.36 352.2 R F2(sendmail)3.08 E F1 .58(through v)3.08 F .58
+(ersion 5 and the moti)-.15 F -.25(va)-.25 G .58(tion behind w).25 F .58
+(orking on)-.1 F -.15(ve)72 364.2 S .126(rsion 8.).15 F .126
+(Section 2 has a rather detailed description of what has changed between v)
+5.126 F .125(ersion 5 and v)-.15 F .125(ersion 8.)-.15 F
+(The paper \214nishes of)72 376.2 Q 2.5(fw)-.25 G
+(ith some thoughts about what still needs to be done.)168.95 376.2 Q/F3 10
+/Times-Bold@0 SF 2.5(1. HIST)72 400.2 R(OR)-.18 E(Y)-.35 E F1 .151
+(As discussed else)112 416.4 R .151
+(where, [Allman83a, Allman83b, Allman&Amos85] sendmail has e)-.25 F .151
+(xisted in v)-.15 F(ar)-.25 E(-)-.2 E .405(ious forms since 1980.)87 428.4 R
+.405(It w)5.405 F .405(as released under the name)-.1 F F2(delivermail)2.905 E
+F1 .404(in 4BSD and 4.1BSD, and as)2.905 F F2(send-)2.904 E(mail)87 440.4 Q F1
+(in 4.2BSD.)2.5 E(It quickly became the dominant mail system for netw)5 E(ork)
+-.1 E(ed UNIX systems.)-.1 E 1.569(Prior the release of 4.3BSD in No)112 456.6
+R -.15(ve)-.15 G 1.569(mber 1986, the author had left the Uni).15 F -.15(ve)
+-.25 G 1.57(rsity for pri).15 F -.25(va)-.25 G(te).25 E(industry)87 468.6 Q
+3.347(,b)-.65 G .847(ut continued to do some w)129.777 468.6 R .847(ork on)-.1
+F F2(sendmail)3.347 E F1 .847(with acti)3.347 F .846(vity slo)-.25 F .846
+(wly trailing of)-.25 F 3.346(fu)-.25 G .846(ntil ef)445.204 468.6 R(fecti)-.25
+E -.15(ve)-.25 G(ly).15 E .255(stopping after February 1987.)87 480.6 R .255
+(There w)5.255 F .255(as minimal support done by man)-.1 F 2.756(yp)-.15 G .256
+(eople for se)389.796 480.6 R -.15(ve)-.25 G .256(ral years, until).15 F
+(July of 1991 when the original author)87 492.6 Q 2.5(,w)-.4 G
+(ho had returned the Uni)249.36 492.6 Q -.15(ve)-.25 G(rsity).15 E 2.5(,s)-.65
+G(tarted acti)379.4 492.6 Q .3 -.15(ve w)-.25 H(ork on it ag).05 E(ain.)-.05 E
+1.271(There were se)112 508.8 R -.15(ve)-.25 G 1.271(ral reasons for rene).15 F
+1.271(wed w)-.25 F 1.271(ork on)-.1 F F2(sendmail)3.771 E F1 6.271(.T)C 1.271
+(here w)369.549 508.8 R 1.27(as a desire at Berk)-.1 F(ele)-.1 E 3.77(yt)-.15 G
+(o)499 508.8 Q(con)87 520.8 Q -.15(ve)-.4 G .097
+(rt to a subdomained structure so that indi).15 F .098
+(viduals were identi\214ed by their subdomain rather than by)-.25 F 1.758
+(their indi)87 532.8 R 1.758(vidual w)-.25 F 1.758(orkstation; although possib\
+le in the old code, there were some problems, and the)-.1 F .66(author w)87
+544.8 R .66(as the ob)-.1 F .66(vious person to address them.)-.15 F .66
+(The Computer Systems Research Group \(CSRG\), the)5.66 F 1.89
+(group that produced the Berk)87 556.8 R(ele)-.1 E 4.39(yS)-.15 G(oftw)238.12
+556.8 Q 1.89(are Distrib)-.1 F 1.89(utions, w)-.2 F 1.89(as w)-.1 F 1.89
+(orking on 4.4BSD, and w)-.1 F 1.89(anted an)-.1 F .053
+(update to the mail system.)87 568.8 R .053(Bryan Costales w)5.053 F .053(as w)
+-.1 F .053(orking on a book on)-.1 F F2(sendmail)2.553 E F1 .053(that w)2.553 F
+.053(as being re)-.1 F(vie)-.25 E(wed)-.25 E .923(by the author)87 580.8 R
+3.423(,w)-.4 G .923(hich encouraged him to mak)154.359 580.8 R 3.422(es)-.1 G
+.922(ome re)283.572 580.8 R 3.422(visions. And)-.25 F .922(the author w)3.422 F
+.922(anted to try to unify)-.1 F(some of the disparate v)87 592.8 Q(ersions of)
+-.15 E F2(sendmail)2.5 E F1(that had been permitted to proliferate.)2.5 E .023
+(During the 1987\25591 f)112 609 R(allo)-.1 E 2.523(wp)-.25 G .023(eriod, man)
+228.482 609 R 2.523(yv)-.15 G .023(endors and outside v)283.498 609 R .023
+(olunteers had produced v)-.2 F .024(ariants of)-.25 F F2(sendmail)87 621 Q F1
+5.518(.P)C .517(erhaps the best kno)136.688 621 R .517(wn is the ID)-.25 F
+3.017(Av)-.4 G .517(ersion [ID)280.317 621 R 3.017(A87]. Originally)-.4 F .517
+(intended to be a ne)3.017 F 3.017(ws)-.25 G .517(et of)485.433 621 R .268
+(con\214guration \214les, ID)87 633 R 2.768(Ae)-.4 G .269(xpanded into a f)
+189.464 633 R .269(airly lar)-.1 F .269(ge set of patches for the code.)-.18 F
+.269(Originally produced in)5.269 F .471(Sweden, ID)87 645 R 2.971(Ad)-.4 G
+-2.15 -.25(ev e)149.472 645 T .471(lopment passed to the Uni).25 F -.15(ve)-.25
+G .471(rsity of Illinois, and w).15 F .47(as widely used by the f)-.1 F .47
+(airly lar)-.1 F(ge)-.18 E .077
+(set of people who prefer to get and compile their o)87 657 R .077
+(wn source code rather than use v)-.25 F(endor)-.15 E .078(-supplied bina-)-.2
+F(ries.)87 669 Q .32 LW 76 678.6 72 678.6 DL 80 678.6 76 678.6 DL 84 678.6 80
+678.6 DL 88 678.6 84 678.6 DL 92 678.6 88 678.6 DL 96 678.6 92 678.6 DL 100
+678.6 96 678.6 DL 104 678.6 100 678.6 DL 108 678.6 104 678.6 DL 112 678.6 108
+678.6 DL 116 678.6 112 678.6 DL 120 678.6 116 678.6 DL 124 678.6 120 678.6 DL
+128 678.6 124 678.6 DL 132 678.6 128 678.6 DL 136 678.6 132 678.6 DL 140 678.6
+136 678.6 DL 144 678.6 140 678.6 DL 148 678.6 144 678.6 DL 152 678.6 148 678.6
+DL 156 678.6 152 678.6 DL 160 678.6 156 678.6 DL 164 678.6 160 678.6 DL 168
+678.6 164 678.6 DL 172 678.6 168 678.6 DL 176 678.6 172 678.6 DL 180 678.6 176
+678.6 DL 184 678.6 180 678.6 DL 188 678.6 184 678.6 DL 192 678.6 188 678.6 DL
+196 678.6 192 678.6 DL 200 678.6 196 678.6 DL 204 678.6 200 678.6 DL 208 678.6
+204 678.6 DL 212 678.6 208 678.6 DL 216 678.6 212 678.6 DL/F4 8/Times-Roman@0
+SF .045(*An earlier v)93.6 690.6 R .045(ersion of this paper w)-.12 F .044
+(as printed in the Proceedings of the 1994 A)-.08 F .044
+(UUG Queensland Summer T)-.44 F .044(echnical Conference,)-.56 F(Gate)72 700.2
+Q -.08(wa)-.2 G 2(yH).08 G(otel, Brisbane, March 1994.)107.928 700.2 Q F3
+(Changes in Sendmail V)72 756 Q(ersion 8)-1 E(1)499 756 Q EP
+%%Page: 2 2
+%%BeginPageSetup
+BP
+%%EndPageSetup
+/F0 10/Times-Bold@0 SF 294.65(2C)72 60 S(hanges in Sendmail V)378.87 60 Q
+(ersion 8)-1 E/F1 10/Times-Roman@0 SF .151
+(In about the same time frame, attempts were made to clean up and e)112 96 R
+.151(xtend the Simple Mail T)-.15 F(rans-)-.35 E .468
+(port Protocol \(SMTP\) [RFC821].)87 108 R .468(This in)5.468 F -.2(vo)-.4 G
+(lv).2 E .469(ed clari\214cations of some ambiguities in the protocol, and)-.15
+F .085(correction of some problem areas [RFC1123], as well as e)87 120 R .084
+(xtensions for additional functionality \(dubbed)-.15 F 1.052
+(Extended Simple Mail T)87 132 R 1.053
+(ransport Protocol, or ESMTP\) [RFC1425, RFC1426, RFC1427] and a richer)-.35 F
+1.376(set of semantics in the body of messages \(the Multipurpose Internet Mai\
+l Extensions, a.k.a. MIME\))87 144 R .497([RFC1521, RFC1344].)87 156 R .497
+(Neither the ID)5.497 F 2.998(Ag)-.4 G .498(roup nor most v)258.526 156 R .498
+(endors were modifying)-.15 F/F2 10/Times-Italic@0 SF(sendmail)2.998 E F1 .498
+(to conform)2.998 F 1.7(to these ne)87 168 R 4.2(ws)-.25 G 4.2(tandards. It)
+148.23 168 R 1.699(seemed clear that these were `)4.2 F 1.699(`good things')
+-.74 F 4.199('t)-.74 G 1.699(hat should be encouraged.)394.483 168 R(Ho)87 180
+Q(we)-.25 E -.15(ve)-.25 G 1.635 -.4(r, s).15 H .835(ince no one w).4 F .835
+(as w)-.1 F .835(orking on a publically a)-.1 F -.25(va)-.2 G .835(ilable v).25
+F .836(ersion of)-.15 F F2(sendmail)3.336 E F1 .836(with these updates,)3.336 F
+(the)87 192 Q 2.5(yw)-.15 G(ere unlik)113.79 192 Q(ely to be widely deplo)-.1 E
+(yed an)-.1 E 2.5(yt)-.15 G(ime in the near future.)274.25 192 Q .466
+(There are, of course, other mail transport agents a)112 208.2 R -.25(va)-.2 G
+.465(ilable, such as).25 F F2 .465(MMDF zmailer smail)2.965 F F1(and)2.965 E F2
+(PP)2.965 E F1(Ho)87 220.2 Q(we)-.25 E -.15(ve)-.25 G .842 -.4(r, n).15 H .042
+(one of these seemed to be g).4 F .043(aining the prominence of)-.05 F F2
+(sendmail)2.543 E F1 2.543(;i)C 2.543(ta)390.518 220.2 S .043
+(ppeared that most compa-)400.281 220.2 R .238(nies w)87 232.2 R .238
+(ould not con)-.1 F -.15(ve)-.4 G .238(rt to another mail transport agent an)
+.15 F 2.737(yt)-.15 G .237(ime in the forseeable future.)327.438 232.2 R(Ho)
+5.237 E(we)-.25 E -.15(ve)-.25 G 1.037 -.4(r, t).15 H(he).4 E(y)-.15 E
+(might be persuaded to con)87 244.2 Q -.15(ve)-.4 G(rt to a ne).15 E(wer v)-.25
+E(ersion of)-.15 E F2(sendmail)2.5 E F1(.)A .841(All of these con)112 260.4 R
+.841(vinced the author to w)-.4 F .841(ork on a updated v)-.1 F .841(ersion of)
+-.15 F F2(sendmail)3.342 E F1 .842(for public distrib)3.342 F(u-)-.2 E(tion.)87
+272.4 Q 1.024(The ne)112 288.6 R 3.524(wv)-.25 G 1.023(ersion of)155.858 288.6
+R F2(sendmail)3.523 E F1 1.023(is referred to as v)3.523 F 1.023
+(ersion eight \(V8\).)-.15 F -1.11(Ve)6.023 G 1.023(rsions six and se)1.11 F
+-.15(ve)-.25 G 3.523(nw).15 G(ere)491.79 288.6 Q 1.281
+(skipped because of an agreement that all \214les in 4.4BSD w)87 300.6 R 1.281
+(ould be numbered as \2318.1\232.)-.1 F 1.282(Rather than)6.282 F(ha)87 312.6 Q
+2.05 -.15(ve a)-.2 H 4.25(ne).15 G 1.75(xternal v)127.76 312.6 R 1.75
+(ersion number that dif)-.15 F 1.75(fered from the \214le v)-.25 F 1.75
+(ersion numbers,)-.15 F F2(sendmail)4.25 E F1 1.75(just jumped)4.25 F
+(directly to V8.)87 324.6 Q F0 2.5(2. CHANGES)72 348.6 R(IN VERSION EIGHT)2.5 E
+F1 .138(The follo)112 364.8 R .139
+(wing is a summary of the changes between the last commonly a)-.25 F -.25(va)
+-.2 G .139(ilable v).25 F .139(ersion of send-)-.15 F(mail from Berk)87 376.8 Q
+(ele)-.1 E 2.5(y\()-.15 G(5.67\) and the latest v)170.9 376.8 Q
+(ersion \(8.6.6\).)-.15 E(Man)112 393 Q 2.5(yo)-.15 G 2.5(ft)142.68 393 S
+(hese are ideas that had been tried in ID)151.29 393 Q(A, b)-.4 E(ut man)-.2 E
+2.5(yo)-.15 G 2.5(ft)363.27 393 S(hem were generalized in V8.)371.88 393 Q F0
+2.5(2.1. P)87 417 R(erf)-.2 E(ormance Enhancements)-.25 E F1 .549
+(Instead of closing SMTP connections immediately)127 433.2 R 3.049(,o)-.65 G
+.549(pen connections are cached for possible)342.135 433.2 R .029(future use.)
+102 445.2 R .029(There is a limit to the number of simultaneous open connectio\
+ns and the idle time of an)5.029 F(y)-.15 E(indi)102 457.2 Q
+(vidual connection.)-.25 E 1.219(This is of best help during queue processing \
+\(since there is the potential of man)127 473.4 R 3.719(yd)-.15 G(if)474.82
+473.4 Q(ferent)-.25 E 1.113(messages going to one site\), although it can also\
+ help when processing MX records which aren')102 485.4 R(t)-.18 E
+(handled by MX Piggybacking.)102 497.4 Q 1.258(If tw)127 513.6 R 3.757(oh)-.1 G
+1.257(osts with dif)161.075 513.6 R 1.257
+(ferent names in a single message happen to ha)-.25 F 1.557 -.15(ve t)-.2 H
+1.257(he same set of MX).15 F .94(hosts, the)102 525.6 R 3.44(yc)-.15 G .94
+(an be sent in the same transaction.)153.45 525.6 R -1.11(Ve)5.94 G .94
+(rsion 8 notices this and tries to batch the mes-)1.11 F(sages.)102 537.6 Q
+-.15(Fo)127 553.8 S 3.638(re).15 G 1.138(xample, if tw)148.668 553.8 R 3.637
+(os)-.1 G 1.137(ites `)216.42 553.8 R(`foo.com')-.74 E 3.637('a)-.74 G 1.137
+(nd `)286.914 553.8 R(`bar)-.74 E(.com')-.55 E 3.637('a)-.74 G 1.137
+(re both serv)352.408 553.8 R 1.137(ed by UUNET)-.15 F 3.637(,t)-.74 G(he)
+470.513 553.8 Q 3.637(yw)-.15 G(ill)495.66 553.8 Q(ha)102 565.8 Q .557 -.15
+(ve t)-.2 H .257(he same set of MX hosts and will be sent in one transaction.)
+.15 F .258(UUNET will then split the mes-)5.258 F(sage and send it to the tw)
+102 577.8 Q 2.5(oi)-.1 G(ndi)213.28 577.8 Q(vidual hosts.)-.25 E F0 2.5
+(2.2. RFC)87 601.8 R(1123 Changes)2.5 E F1 2.607(An)127 618 S .107
+(umber of changes ha)141.827 618 R .407 -.15(ve b)-.2 H .106(een made to mak)
+.15 F 2.606(es)-.1 G .106(endmail `)321.07 618 R .106
+(`conditionally compliant')-.74 F 2.606('\()-.74 G .106(that is, it)469.058 618
+R(satis\214es all of the MUST clauses and most b)102 630 Q
+(ut not all of the SHOULD clauses in RFC 1123\).)-.2 E
+(The major areas of change are \(numbers are RFC 1123 section numbers\):)127
+646.2 Q 26.5(\2475.2.7 Response)102 662.4 R .565(to RCPT command is f)3.065 F
+3.065(ast. Pre)-.1 F(viously)-.25 E 3.065(,s)-.65 G .565(endmail e)362.295
+662.4 R .565(xpanded all aliases as f)-.15 F(ar)-.1 E .686
+(as it could \212 this could tak)156 674.4 R 3.186(eav)-.1 G .685
+(ery long time, particularly if there were name serv)290.118 674.4 R(er)-.15 E
+3.891(delays. V)156 686.4 R 1.391(ersion 8 only checks for the e)-1.11 F 1.392
+(xistence of an alias and does the e)-.15 F(xpansion)-.15 E(later)156 698.4 Q
+5.176(.I)-.55 G 2.676(td)184.226 698.4 S .176
+(oes still do a DNS lookup if there is an e)194.682 698.4 R .175
+(xplicit host name in the RCPT com-)-.15 F(mand, b)156 710.4 Q
+(ut this time is bounded.)-.2 E EP
+%%Page: 3 3
+%%BeginPageSetup
+BP
+%%EndPageSetup
+/F0 10/Times-Bold@0 SF(Changes in Sendmail V)72 60 Q(ersion 8)-1 E(3)499 60 Q
+/F1 10/Times-Roman@0 SF 26.5(\2475.2.8 Numeric)102 96 R .612
+(IP addresses are logged in Recei)3.112 F -.15(ve)-.25 G .613(d: lines.).15 F
+.613(This helps tracing spoofed mes-)5.613 F(sages.)156 108 Q 21.5
+(\2475.2.17 Self)102 124.2 R .127(domain literal is properly handled.)2.627 F
+(Pre)5.126 E(viously)-.25 E 2.626(,i)-.65 G 2.626(fs)368.196 124.2 S .126
+(omeone sent to user@[1.2.3.4],)378.042 124.2 R .12
+(where 1.2.3.4 is your IP address, the mail w)156 136.2 R .12
+(ould probably be rejected with a `)-.1 F(`con\214gu-)-.74 E(ration error')156
+148.2 Q 2.5('. V)-.74 F(ersion 8 can handle these addresses.)-1.11 E 26.5
+(\2475.3.2 Better)102 164.4 R 1.189(control o)3.69 F -.15(ve)-.15 G 3.689(ri)
+.15 G(ndi)240.088 164.4 Q 1.189(vidual timeouts.)-.25 F 1.189
+(RFC 821 speci\214ed no timeouts.)6.189 F 1.189(Older v)6.189 F(er)-.15 E(-)-.2
+E .002(sions of sendmail had a single timeout, typically set to tw)156 176.4 R
+2.502(oh)-.1 G 2.502(ours. V)398.142 176.4 R .002(ersion 8 allo)-1.11 F .002
+(ws the)-.25 F(con\214guration \214le to set timeouts for v)156 188.4 Q
+(arious SMTP commands indi)-.25 E(vidually)-.25 E(.)-.65 E 26.5
+(\2475.3.3 Error)102 204.6 R 1.06(messages are sent as From:<>.)3.56 F 1.059
+(This w)6.059 F 1.059(as ur)-.1 F 1.059(ged by RFC 821 and reiterated by)-.18 F
+.237(RFC 1123, b)156 216.6 R .237(ut older v)-.2 F .237(ersions of sendmail ne)
+-.15 F -.15(ve)-.25 G 2.737(rr).15 G .237(eally did it properly)355.186 216.6 R
+5.237(.V)-.65 G .238(ersion 8 does.)448.254 216.6 R(Ho)156 228.6 Q(we)-.25 E
+-.15(ve)-.25 G 1.934 -.4(r, s).15 H 1.134
+(ome systems cannot handle this perfectly le).4 F -.05(ga)-.15 G 3.633(la).05 G
+1.133(ddress; if necessary)402.941 228.6 R 3.633(,y)-.65 G(ou)494 228.6 Q
+(can create a special mailer that uses the `g' \215ag to disable this.)156
+240.6 Q 26.5(\2475.3.3 Error)102 256.8 R 3.212(messages are ne)5.712 F -.15(ve)
+-.25 G 5.712(rs).15 G 3.212(ent to <>.)275.628 256.8 R(Pre)8.213 E(viously)-.25
+E 5.713(,s)-.65 G 3.213(endmail w)383.028 256.8 R 3.213(as happ)-.1 F 5.713(yt)
+-.1 G 5.713(os)474.957 256.8 S(end)489.56 256.8 Q 6
+(responses-to-responses which sometimes resulted in responses-to-responses-to-)
+156 268.8 R(responses which resulted in ....)156 280.8 Q(you get the idea.)5 E
+26.5(\2475.3.3 Route-addrs)102 297 R .111(\(the ugly `)2.611 F
+(`<@hosta,@hostb:user@hostc>')-.74 E 2.611('s)-.74 G .111(yntax\) are pruned.)
+389.124 297 R .112(RFC 821)5.112 F(ur)156 309 Q 1.001
+(ged the use of this bletcherous syntax.)-.18 F 1
+(RFC 1123 has seen the light and of)6.001 F(\214cially)-.25 E 1.124
+(deprecates them, further ur)156 321 R 1.125(ging that you eliminate all b)-.18
+F 1.125(ut `)-.2 F(`user@hostc')-.74 E 3.625('s)-.74 G 1.125(hould you)462.595
+321 R(recei)156 333 Q 1.698 -.15(ve o)-.25 H 1.398(ne of these things.).15 F
+-1.11(Ve)6.398 G 1.398(rsion 8 is slightly more generous than the standards)
+1.11 F .753(suggest; instead of stripping of)156 345 R 3.253(fa)-.25 G .753
+(ll the route addressees, it only strips hosts of)293.115 345 R 3.254(fu)-.25 G
+3.254(pt)487.966 345 S(o)499 345 Q 1.29(the one before the last one kno)156 357
+R 1.289(wn to DNS, thus allo)-.25 F 1.289(wing you to ha)-.25 F 1.589 -.15
+(ve p)-.2 H(seudo-hosts).15 E(such as foo.BITNET)156 369 Q 5(.T)-.74 G
+(he `R' option will turn this of)251.91 369 Q(f.)-.25 E
+(The areas in which sendmail is not `)102 385.2 Q(`unconditionally compliant')
+-.74 E 2.5('a)-.74 G(re:)367.43 385.2 Q 26.5(\2475.2.6 Sendmail)102 401.4 R
+(does do header munging.)2.5 E 21.5(\2475.2.10 Sendmail)102 417.6 R(doesn')3.2
+E 3.2(ta)-.18 G -.1(lwa)233.88 417.6 S .7(ys use the e).1 F .701
+(xact SMTP message te)-.15 F .701(xt from RFC 821.)-.15 F .701(This is a)5.701
+F(rather silly requirement.)156 429.6 Q 19(\2475.3.1.1 Sendmail)102 445.8 R
+(doesn')3.512 E 3.512(tg)-.18 G 1.012
+(uarantee only one connect for each host on queue runs.)235.064 445.8 R
+(Connec-)6.011 E(tion caching gi)156 457.8 Q -.15(ve)-.25 G 2.5(sy).15 G
+(ou most of this, b)235.87 457.8 Q(ut it does not pro)-.2 E(vide a guarantee.)
+-.15 E 19(\2475.3.1.1 Sendmail)102 474 R(doesn')2.843 E 2.843(ta)-.18 G -.1
+(lwa)233.166 474 S .343(ys pro).1 F .343(vide an adequate limit on concurrenc)
+-.15 F 4.144 -.65(y. T)-.15 H .344(hat is, there can).65 F .757(be se)156 486 R
+-.15(ve)-.25 G .757(ral independent sendmails running at once.).15 F .757
+(My feeling is that doing an abso-)5.757 F 1.047(lute limit w)156 498 R 1.047
+(ould be a mistak)-.1 F 3.547(e\()-.1 G 1.048(it might result in lost mail\).)
+284.302 498 R(Ho)6.048 E(we)-.25 E -.15(ve)-.25 G 1.848 -.4(r, i).15 H 3.548
+(fy).4 G 1.048(ou use the)461.354 498 R .801(XLA contrib)156 510 R .801
+(uted softw)-.2 F .801(are, most of this will be guaranteed \(b)-.1 F .801
+(ut I don')-.2 F 3.3(tg)-.18 G .8(uarantee the)454.61 510 R(guarantee\).)156
+522 Q F0 2.5(2.3. Extended)87 546 R(SMTP Support)2.5 E F1 -1.11(Ve)127 562.2 S
+.154(rsion 8 includes both sending and recei)1.11 F .155
+(ving support for Extended SMTP support as de\214ned)-.25 F .229(by RFC 1425 \
+\(basic\) and RFC 1427 \(SIZE\); and limited support for RFC 1426 \(BOD)102
+574.2 R 2.729(Y\). The)-.55 F(body)2.729 E .275(support is minimal because the\
+ \2318BITMIME\232 body type is not currently adv)102 586.2 R 2.776
+(ertised. Although)-.15 F(such)2.776 E 3.076(ab)102 598.2 S .576
+(ody type will be accepted, it will not be correctly con)114.516 598.2 R -.15
+(ve)-.4 G .576(rted to 7 bits if speaking to a non-8-bit-).15 F(MIME a)102
+610.2 Q -.1(wa)-.15 G(re SMTP serv).1 E(er)-.15 E(.)-.55 E/F2 10/Times-Italic@0
+SF(Sendmail)127 626.4 Q F1 .287(tries to speak ESMTP if you ha)2.787 F .588
+-.15(ve t)-.2 H .288(he `a' \215ag set in the \215ags for the mailer descrip-)
+.15 F(tor)102 638.4 Q 3.322(,o)-.4 G 3.322(ri)123.532 638.4 S 3.322(ft)132.964
+638.4 S .822(he other end adv)142.396 638.4 R .822(ertises the f)-.15 F .822
+(act that it speaks ESMTP)-.1 F 5.822(.T)-1.11 G .821
+(his is a non-standard adv)376.446 638.4 R(ertise-)-.15 E(ment:)102 650.4 Q F2
+(sendmail)2.98 E F1 .48(announces \231ESMTP spok)2.98 F .48
+(en here\232 during the initial connection message, and client)-.1 F .587
+(sendmails search for this message.)102 662.4 R .586
+(This creates some problems for some PC-based mailers, which)5.586 F
+(do not understand tw)102 674.4 Q
+(o-line greeting messages as required by RFC 821.)-.1 E EP
+%%Page: 4 4
+%%BeginPageSetup
+BP
+%%EndPageSetup
+/F0 10/Times-Bold@0 SF 294.65(4C)72 60 S(hanges in Sendmail V)378.87 60 Q
+(ersion 8)-1 E 2.5(2.4. Eight-Bit)87 96 R(Clean)2.5 E/F1 10/Times-Roman@0 SF
+(Pre)127 112.2 Q 1.263(vious v)-.25 F 1.263
+(ersions of sendmail used the 0200 bit for quoting.)-.15 F 1.264(This v)6.264 F
+1.264(ersion a)-.15 F -.2(vo)-.2 G 1.264(ids that use.).2 F(Ho)102 124.2 Q(we)
+-.25 E -.15(ve)-.25 G 1.119 -.4(r, y).15 H .318
+(ou can set option `7' to get se).4 F -.15(ve)-.25 G 2.818(nb).15 G .318
+(it stripping for compatibility with RFC 821, which is)290.046 124.2 R 2.5(a7)
+102 136.2 S(-bit protocol.)113.94 136.2 Q(This option says `)5 E
+(`strip to 7 bits on input')-.74 E('.)-.74 E(Indi)127 152.4 Q .375
+(vidual mailers can still produce se)-.25 F -.15(ve)-.25 G 2.875(nb).15 G .376
+(it out put using the `7' mailer \215ag.)303.02 152.4 R .376(This \215ag says)
+5.376 F -.74(``)102 164.4 S(strip to 7 bits on output').74 E('.)-.74 E F0 2.5
+(2.5. User)87 188.4 R(Database)2.5 E F1 1.926
+(The User Database \(UDB\) is an as-yet e)127 204.6 R 1.926
+(xperimental attempt to pro)-.15 F 1.925(vide uni\214ed lar)-.15 F(ge-site)-.18
+E .396(name support.)102 216.6 R 1.996 -.8(We a)5.396 H .396
+(re installing it at Berk).8 F(ele)-.1 E .396(y; future v)-.15 F .396
+(ersions may sho)-.15 F 2.897(ws)-.25 G .397(igni\214cant modi\214cations.)
+406.373 216.6 R(Brie\215y)102 228.6 Q 3.583(,U)-.65 G 1.083
+(DB contains a database that is intended to contain all the per)142.433 228.6 R
+1.082(-user information for your)-.2 F -.1(wo)102 240.6 S .172
+(rkgroup, such as people').1 F 2.673(sf)-.55 G .173
+(ull names, their .plan information, their outgoing mail name, and their)222.29
+240.6 R(mail drop.)102 252.6 Q .438(The user database allo)127 268.8 R .438
+(ws you to map both incoming and outgoing addresses, much lik)-.25 F 2.937(eI)
+-.1 G -.4(DA)487.46 268.8 S(.).4 E(Ho)102 280.8 Q(we)-.25 E -.15(ve)-.25 G
+1.799 -.4(r, t).15 H .999(he interf).4 F .999(ace is still better with ID)-.1 F
+.999(A; in particular)-.4 F 3.499(,t)-.4 G 1
+(he alias \214le with incoming/outgoing)355.55 280.8 R(marks pro)102 292.8 Q
+(vides better locality of information.)-.15 E F0 2.5(2.6. Impr)87 316.8 R -.1
+(ove)-.18 G 2.5(dB).1 G(IND Support)158.01 316.8 Q F1 .262
+(The BIND support, particularly for MX records, had a number of anno)127 333 R
+.261(ying `)-.1 F(`features')-.74 E 2.761('w)-.74 G(hich)486.78 333 Q(ha)102
+345 Q 1.212 -.15(ve b)-.2 H .912(een remo).15 F -.15(ve)-.15 G 3.412(di).15 G
+3.412(nt)187.116 345 S .912(his release.)198.308 345 R .912(In particular)5.912
+F 3.412(,t)-.4 G .912(hese more tightly bind \(pun intended\) the name)307.916
+345 R(serv)102 357 Q(er to sendmail, so that the name serv)-.15 E
+(er resolution rules are incorporated directly into sendmail.)-.15 E .688
+(The major change has been that the $[ ... $] operator didn')127 373.2 R 3.188
+(tf)-.18 G .688(ully qualify names that were in)376.41 373.2 R
+(DNS as A or MX records.)102 385.2 Q -1.11(Ve)5 G
+(rsion 8 does this quali\214cation.)1.11 E .429(This has pro)127 401.4 R -.15
+(ve)-.15 G 2.929(nt).15 G 2.929(ob)197.147 401.4 S 2.929(ea)210.076 401.4 S
+2.929(na)221.885 401.4 S(nno)234.254 401.4 Q .43
+(yance in Sun shops, who often still run without BIND support.)-.1 F(Ho)102
+413.4 Q(we)-.25 E -.15(ve)-.25 G 1.001 -.4(r, i).15 H 2.701(ti).4 G 2.701(sr)
+153.842 413.4 S .201
+(eally critical that this be supported, since MX records are mandatory)163.763
+413.4 R 5.2(.I)-.65 G 2.7(nS)450.26 413.4 S .2(unOS you)463.52 413.4 R .101
+(can choose either MX support or NIS support, b)102 425.4 R .101(ut not both.)
+-.2 F .101(This is \214x)5.101 F .101(ed in Solaris, and some)-.15 F/F2 10
+/Times-Italic@0 SF(send-)2.602 E(mail)102 437.4 Q F1(support to allo)2.5 E 2.5
+(wt)-.25 G(his in SunOS should be forthcoming in a future release.)192.31 437.4
+Q F0 2.5(2.7. K)87 461.4 R(ey)-.25 E(ed Files)-.1 E F1 .242(Generalized k)127
+477.6 R -.15(ey)-.1 G .242(ed \214les is an idea tak).15 F .241
+(en directly from ID)-.1 F 2.741(As)-.4 G .241
+(endmail \(albeit with a completely)368.606 477.6 R(dif)102 489.6 Q
+(ferent implementation\).)-.25 E(The)5 E 2.5(yc)-.15 G(an be useful on lar)
+239.63 489.6 Q(ge sites.)-.18 E -1.11(Ve)127 505.8 S
+(rsion 8 includes the follo)1.11 E(wing b)-.25 E(uilt-in map classes:)-.2 E
+33.72(dbm Support)102 522 R(for the ndbm\(3\) library)2.5 E(.)-.65 E 33.17
+(hash Support)102 538.2 R 1.229(for the `)3.729 F(`Hash')-.74 E 3.729('t)-.74 G
+1.229(ype from the ne)261.636 538.2 R 3.729(wB)-.25 G(erk)345.732 538.2 Q(ele)
+-.1 E 3.729(yd)-.15 G 1.229(b\(3\) library)383.641 538.2 R 6.23(.t)-.65 G 1.23
+(his library pro-)441.55 538.2 R 4.094(vides substantially better database sup\
+port than ndbm\(3\), including in-memory)156 550.2 R
+(caching, arbitrarily long k)156 562.2 Q -.15(ey)-.1 G 2.5(sa).15 G(nd v)279.89
+562.2 Q(alues, and better disk utilization.)-.25 E 31.51(btree Support)102
+578.4 R .547(for the `)3.047 F(`B-T)-.74 E(ree')-.35 E 3.047('t)-.74 G .547
+(ype from the ne)266.328 578.4 R 3.048(wB)-.25 G(erk)347.698 578.4 Q(ele)-.1 E
+3.048(yd)-.15 G .548(b\(3\) library)384.926 578.4 R 5.548(.B)-.65 G(-T)445.362
+578.4 Q .548(rees pro)-.35 F(vide)-.15 E .521(better clustering than Hashed \
+\214les if you are fetching lots of records that ha)156 590.4 R .821 -.15(ve s)
+-.2 H(imilar).15 E -.1(ke)156 602.4 S(ys, such as searching a dictionary for w)
+-.05 E(ords be)-.1 E(ginning with `)-.15 E(`detr')-.74 E('.)-.74 E 39.83
+(nis Support)102 618.6 R(for NIS \(a.k.a. YP\) maps.)2.5 E
+(NIS+ is not supported in this v)5 E(ersion.)-.15 E 34.83(host Support)102
+634.8 R(for DNS lookups.)2.5 E 19.84(dequote A)102 651 R -.74(``)2.642 G
+(pseudo-map').74 E 2.642('\()-.74 G .142(that is, once that does not ha)232.554
+651 R .442 -.15(ve a)-.2 H .442 -.15(ny ex).15 H .142(ternal data\) that allo)
+.15 F .142(ws a con-)-.25 F .099
+(\214guration \214le to break apart a quoted string in the address.)156 663 R
+.098(This is necessary primarily)5.098 F .726
+(for DECnet addresses, which often ha)156 675 R 1.026 -.15(ve q)-.2 H .726
+(uoted addresses that need to be unwrapped).15 F(on g)156 687 Q(ate)-.05 E -.1
+(wa)-.25 G(ys.).1 E EP
+%%Page: 5 5
+%%BeginPageSetup
+BP
+%%EndPageSetup
+/F0 10/Times-Bold@0 SF(Changes in Sendmail V)72 60 Q(ersion 8)-1 E(5)499 60 Q
+2.5(2.8. Multi-W)87 96 R(ord Classes & Macr)-.75 E(os in Classes)-.18 E/F1 10
+/Times-Roman@0 SF(Classes can no)127 112.2 Q 2.5(wb)-.25 G 2.5(em)200.35 112.2
+S(ultiple w)215.07 112.2 Q 2.5(ords. F)-.1 F(or e)-.15 E(xample,)-.15 E
+(CShofmann.CS.Berk)142 128.4 Q(ele)-.1 E -.65(y.)-.15 G(EDU).65 E(allo)102
+144.6 Q 2.395(ws you to match the entire string `)-.25 F(`hofmann.CS.Berk)-.74
+E(ele)-.1 E -.65(y.)-.15 G(EDU').65 E 4.894('u)-.74 G 2.394
+(sing the single construct)399.878 144.6 R -.74(``)102 156.6 S($=S').74 E('.)
+-.74 E(Class de\214nitions are no)127 172.8 Q 2.5(wa)-.25 G(llo)234.52 172.8 Q
+(wed to include macros \212 for e)-.25 E(xample:)-.15 E(Cw$k)142 189 Q(is le)
+102 205.2 Q -.05(ga)-.15 G(l.).05 E F0 2.5(2.9. IDENT)87 229.2 R(Pr)2.5 E
+(otocol Support)-.18 E F1 .633
+(The IDENT protocol as de\214ned in RFC 1413 [RFC1413] is supported.)127 245.4
+R(Ho)5.633 E(we)-.25 E -.15(ve)-.25 G 1.433 -.4(r, m).15 H(an).4 E 3.134(ys)
+-.15 G(ys-)491.78 245.4 Q .909(tems ha)102 257.4 R 1.209 -.15(ve a T)-.2 H .909
+(CP/IP b).15 F .908
+(ug that renders this useless, and the feature must be turned of)-.2 F 3.408
+(f. Roughly)-.25 F 3.408(,i)-.65 G(f)500.67 257.4 Q 8.538
+(one of these system recei)102 269.4 R -.15(ve)-.25 G 11.038(sa\231).15 G 8.539
+(No route to host\232 message \(ICMP message)280.568 269.4 R(ICMP_UNREA)102
+281.4 Q .829(CH_HOST\) on)-.4 F/F2 10/Times-Italic@0 SF(any)3.329 E F1 .828
+(connection, all connections to that host are closed.)3.329 F .828
+(Some \214re-)5.828 F -.1(wa)102 293.4 S .087
+(lls return this error if you try to connect to the IDENT port, so you can').1
+F 2.587(tr)-.18 G(ecei)408.889 293.4 Q .387 -.15(ve e)-.25 H .087
+(mail from these).15 F 1.712(hosts on these systems.)102 305.4 R(It')6.712 E
+4.212(sp)-.55 G 1.712(ossible that if the \214re)228.62 305.4 R -.1(wa)-.25 G
+1.712(ll used a more speci\214c message \(such as).1 F(ICMP_UNREA)102 317.4 Q
+(CH_PR)-.4 E -1.88 -.4(OT O)-.4 H 72.325(COL, ICMP_UNREA).4 F(CH_POR)-.4 E
+74.825(To)-.6 G(r)500.67 317.4 Q(ICMP_UNREA)102 329.4 Q(CH_NET_PR)-.4 E
+(OHIB\) it w)-.4 E(ould w)-.1 E(ork, b)-.1 E(ut this hasn')-.2 E 2.5(tb)-.18 G
+(een v)375.62 329.4 Q(eri\214ed.)-.15 E .678(IDENT protocol support cannot be \
+used on 4.3BSD, Apollo DomainOS, Apple A/UX, Con-)127 345.6 R -.15(vex)102
+357.6 S 1.405(OS, Data General DG/UX, HP-UX, Sequent Dynix, or Ultrix.).15 F
+1.405(It seems to w)6.405 F 1.405(ork on 4.4BSD,)-.1 F
+(IBM AIX 3.x, OSF/1, SGI IRIX, Solaris, and SunOS.)102 369.6 Q F0 2.5
+(2.10. Separate)87 393.6 R(En)2.5 E -.1(ve)-.4 G(lope/Header Pr).1 E(ocessing)
+-.18 E F1 .854(Since the From: line is passed in separately from the en)127
+409.8 R -.15(ve)-.4 G .854(lope sender).15 F 3.354(,t)-.4 G .854(hese ha)
+420.978 409.8 R 1.154 -.15(ve b)-.2 H .854(oth been).15 F .427
+(made visible; the $g macro is set to the en)102 421.8 R -.15(ve)-.4 G .428
+(lope sender during processing of mailer ar).15 F .428(gument v)-.18 F(ec-)-.15
+E(tors and the header sender during processing of headers.)102 433.8 Q .085
+(It is also possible to specify separate per)127 450 R .085(-mailer en)-.2 F
+-.15(ve)-.4 G .084(lope and header processing.).15 F .084(The Sender)5.084 F(-)
+-.2 E -.55(RW)102 462 S 1.085(Set and RecipientR).55 F 1.085(Wset ar)-.55 F
+1.085(guments for mailers can be speci\214ed as `)-.18 F(`en)-.74 E -.15(ve)-.4
+G(lope/header').15 E 3.585('t)-.74 G 3.585(og)478.595 462 S -2.15 -.25(iv e)
+492.18 462 T(dif)102 474 Q(ferent re)-.25 E(writings for en)-.25 E -.15(ve)-.4
+G(lope v).15 E(ersus header addresses.)-.15 E F0 2.5(2.11. Owner)87 498 R
+(-List Pr)-.37 E(opagates to En)-.18 E -.1(ve)-.4 G(lope).1 E F1 1.168
+(When an alias has an associated o)127 514.2 R(wner)-.25 E 1.168
+(-list name, that alias is used to change the en)-.2 F -.15(ve)-.4 G(lope).15 E
+(sender address.)102 526.2 Q(This will cause do)5 E
+(wnstream errors to be returned to that o)-.25 E(wner)-.25 E(.)-.55 E 1.813
+(Some people \214nd this confusing because the en)127 542.4 R -.15(ve)-.4 G
+1.813(lope sender is what appears in the \214rst).15 F -.74(``)102 554.4 S
+(From_').74 E 3.127('l)-.74 G .627(ine in UNIX messages \(that is, the line be)
+146.417 554.4 R .627(ginning `)-.15 F(`From<space>')-.74 E 3.127('i)-.74 G .627
+(nstead of `)424.797 554.4 R(`From:')-.74 E(';)-.74 E .502
+(the latter is the header from, which)102 566.4 R F2(does)3.002 E F1 .503
+(indicate the sender of the message\).)3.002 F .503(In pre)5.503 F .503
+(vious v)-.25 F(ersions,)-.15 E F2(sendmail)102 578.4 Q F1 .057(has tried to a)
+2.557 F -.2(vo)-.2 G .057(id changing the en).2 F -.15(ve)-.4 G .056
+(lope sender for back compatibility with UNIX con).15 F -.15(ve)-.4 G(n-).15 E
+.177(tion; at this point that back compatibility is creating too man)102 590.4
+R 2.678(yp)-.15 G .178(roblems, and it is necessary to mo)357.972 590.4 R -.15
+(ve)-.15 G(forw)102 602.4 Q(ard into the 1980s.)-.1 E F0 2.5(2.12. Command)87
+626.4 R(Line Flags)2.5 E F1(The)127 642.6 Q F0<ad42>2.5 E F1
+(\215ag has been added to pass in body type information.)2.5 E(The)127 658.8 Q
+F0<ad70>3.057 E F1 .557
+(\215ag has been added to pass in protocol information that w)3.057 F .557
+(as pre)-.1 F .556(viously passed in by)-.25 F(de\214ning the)102 670.8 Q F0
+($r)2.5 E F1(and)2.5 E F0($s)2.5 E F1(macros.)2.5 E(The)127 687 Q F0<ad58>2.6 E
+F1 .1(\215ag has been added to allo)2.6 F 2.6(wl)-.25 G .1
+(ogging of all protocol in and out of sendmail for deb)279.89 687 R(ug-)-.2 E
+2.732(ging. Y)102 699 R .232(ou can set \231\255X \214lename\232 and a complet\
+e transcript will be logged in that \214le.)-1.1 F .231(This gets big)5.231 F
+-.1(fa)102 711 S(st: the option is only for deb).1 E(ugging.)-.2 E EP
+%%Page: 6 6
+%%BeginPageSetup
+BP
+%%EndPageSetup
+/F0 10/Times-Bold@0 SF 294.65(6C)72 60 S(hanges in Sendmail V)378.87 60 Q
+(ersion 8)-1 E/F1 10/Times-Roman@0 SF(The)127 96 Q F0<ad71>4.006 E F1 1.507(\
+\215ag can limit limit a queue run to speci\214c recipients, senders, or queue\
+ ids using)4.006 F
+(\255qRsubstring, \255qSsubstring, or \255qIsubstring respecti)102 108 Q -.15
+(ve)-.25 G(ly).15 E(.)-.65 E F0 2.5(2.13. New)87 132 R(Con\214guration Line T)
+2.5 E(ypes)-.74 E F1 .674(The `T' \(T)127 148.2 R .674
+(rusted users\) con\214guration line has been deleted.)-.35 F .674
+(It will still be accepted b)5.674 F .674(ut will)-.2 F(be ignored.)102 160.2 Q
+(The `K' line has been added to declare database maps.)127 176.4 Q
+(The `V' line has been added to declare the con\214guration v)127 192.6 Q
+(ersion le)-.15 E -.15(ve)-.25 G(l.).15 E(The `M' \(mailer\) line tak)127 208.8
+Q(es a D= \214eld to specify e)-.1 E -.15(xe)-.15 G(cution directory).15 E(.)
+-.65 E F0 2.5(2.14. New)87 232.8 R(and Extended Options)2.5 E F1(Se)127 249 Q
+-.15(ve)-.25 G .9(ral ne).15 F 3.4(wo)-.25 G .9(ptions ha)184.8 249 R 1.2 -.15
+(ve b)-.2 H .9(een added, man).15 F 3.4(yt)-.15 G 3.4(os)314.89 249 S .9
+(upport ne)327.18 249 R 3.4(wf)-.25 G .9(eatures, others to allo)379.83 249 R
+3.4(wt)-.25 G(uning)481.22 249 Q(that w)102 261 Q(as pre)-.1 E(viously a)-.25 E
+-.25(va)-.2 G(ilable only by recompiling.).25 E(Brie\215y:)5 E 28.78(AT)102
+277.2 S .099(he alias \214le speci\214cation can no)144.11 277.2 R 2.599(wb)
+-.25 G 2.599(eal)286.654 277.2 S .099(ist of alias \214les.)303.512 277.2 R
+.098(Also, the con\214guration can spec-)5.099 F(ify a class of \214le.)138
+289.2 Q -.15(Fo)5 G 2.5(re).15 G(xample, to search the NIS aliases, use \231O)
+232.13 289.2 Q(Anis:mail.aliases\232.)-.35 E 31(bI)102 305.4 S
+(nsist on a minimum number of disk blocks.)141.33 305.4 Q 29.33(CD)102 321.6 S
+(eli)145.22 321.6 Q -.15(ve)-.25 G .24(ry checkpoint interv).15 F 2.74
+(al. Checkpoint)-.25 F .24(the queue \(to a)2.74 F -.2(vo)-.2 G .24
+(id duplicate deli).2 F -.15(ve)-.25 G .24(ries\) e).15 F -.15(ve)-.25 G .24
+(ry C).15 F(addresses.)138 333.6 Q 29.89(ED)102 349.8 S(ef)145.22 349.8 Q .712
+(ault error message.)-.1 F .711
+(This message \(or the contents of the indicated \214le\) are prepended)5.712 F
+(to error messages.)138 361.8 Q 28.78(GE)102 378 S .785(nable GECOS matching.)
+144.11 378 R .785(If you can')5.785 F 3.285<748c>-.18 G .786
+(nd a local user name and this option is enabled,)307.51 378 R .59
+(do a sequential scan of the passwd \214le to match ag)138 390 R .589
+(ainst full names.)-.05 F(Pre)5.589 E .589(viously a compile)-.25 F(option.)138
+402 Q 31(hM)102 418.2 S(aximum hop count.)146.89 418.2 Q(Pre)5 E
+(viously this w)-.25 E(as compiled in.)-.1 E 32.67(IT)102 434.4 S
+(his option has been e)144.11 434.4 Q(xtended to allo)-.15 E 2.5(ws)-.25 G
+(etting of resolv)300.64 434.4 Q(er parameters.)-.15 E 33.22(jS)102 450.6 S
+(end errors in MIME-encapsulated format.)143.56 450.6 Q 32.11(JF)102 466.8 S
+(orw)143.41 466.8 Q(ard \214le path.)-.1 E(Where to search for .forw)5 E
+(ard \214les \212 def)-.1 E(aults to $HOME/.forw)-.1 E(ard.)-.1 E 31(kC)102 483
+S .05(onnection cache size.)144.67 483 R .05
+(The total number of connections that will be k)5.05 F .05(ept open at an)-.1 F
+2.55(yt)-.15 G(ime.)486.5 483 Q 28.78(KC)102 499.2 S 1.395
+(onnection cache lifetime.)144.67 499.2 R 1.395(The amount of time an)6.395 F
+3.895(yc)-.15 G 1.394(onnection will be permitted to sit)364.53 499.2 R(idle.)
+138 511.2 Q 33.22(lE)102 527.4 S .333(nable Errors-T)144.11 527.4 R .333
+(o: header)-.8 F 5.334(.T)-.55 G .334
+(hese headers violate RFC 1123; this option is included to pro-)252.89 527.4 R
+(vide back compatibility with old v)138 539.4 Q(ersions of sendmail.)-.15 E
+28.78(OI)102 555.6 S(ncoming daemon options \(e.g., use alternate SMTP port\).)
+141.33 555.6 Q 31(pP)102 571.8 S(ri)143.56 571.8 Q -.25(va)-.25 G .3 -.15(cy o)
+.25 H 2.5(ptions. These).15 F(can be used to mak)2.5 E 2.5(ey)-.1 G
+(our SMTP serv)322.22 571.8 Q(er less friendly)-.15 E(.)-.65 E 32.67(rT)102 588
+S .67(his option has been e)144.11 588 R .67(xtended to allo)-.15 F 3.17<778c>
+-.25 G .67(ner grained control o)307 588 R -.15(ve)-.15 G 3.17(rt).15 G 3.17
+(imeouts. F)411.02 588 R .67(or e)-.15 F(xample,)-.15 E
+(you can set the timeout for SMTP commands indi)138 600 Q(vidually)-.25 E(.)
+-.65 E 29.33(RD)102 616.2 S(on')145.22 616.2 Q 11.797(tp)-.18 G 9.297
+(rune route-addrs.)177.947 616.2 R(Normally)269.851 616.2 Q 11.797(,i)-.65 G
+11.797(fv)324.608 616.2 S 9.297(ersion 8 sees an address lik)344.585 616.2 R(e)
+-.1 E 1.256("<@hostA,@hostB:user@hostC>, sendmail will try to strip of)138
+628.2 R 3.755(fa)-.25 G 3.755(sm)406.48 628.2 S 1.255(uch as it can \(up to)
+421.905 628.2 R(user@hostC\) as suggested by RFC 1123.)138 640.2 Q
+(This option disables that beha)5 E(viour)-.2 E(.)-.55 E 29.89(TT)102 656.4 S
+1.485(he \231Return T)144.11 656.4 R 3.985(oS)-.8 G 1.485
+(ender\232 timeout has been e)213.035 656.4 R 1.485(xtended to allo)-.15 F
+3.986(ws)-.25 G 1.486(peci\214cation of a w)399.942 656.4 R(arning)-.1 E .789
+(message interv)138 668.4 R .789
+(al, typically something on the order of four hours.)-.25 F .788
+(If a message cannot be)5.788 F(deli)138 680.4 Q -.15(ve)-.25 G 1.245
+(red in that interv).15 F 1.245(al, a w)-.25 F 1.245
+(arning message is sent back to the sender b)-.1 F 1.246(ut the message)-.2 F
+(continues to be tried.)138 692.4 Q 28.78(UU)102 708.6 S(ser database spec.)
+145.22 708.6 Q(This is still e)5 E(xperimental.)-.15 E EP
+%%Page: 7 7
+%%BeginPageSetup
+BP
+%%EndPageSetup
+/F0 10/Times-Bold@0 SF(Changes in Sendmail V)72 60 Q(ersion 8)-1 E(7)499 60 Q
+/F1 10/Times-Roman@0 SF 28.78(VF)102 96 S .758(allback `)143.41 96 R(`MX')-.74
+E 3.258('h)-.74 G 3.258(ost. This)211.756 96 R .757
+(can be thought of as an MX host that applies to all addresses)3.258 F
+(that has a v)138 108 Q(ery high preference v)-.15 E
+(alue \(that is, use it only if e)-.25 E -.15(ve)-.25 G(rything else f).15 E
+(ails\).)-.1 E 28.78(wI)102 124.2 S 3.066(fs)141.33 124.2 S .566(et, assume th\
+at if you are the best MX host for a host, you should send directly to that)
+151.616 124.2 R 3.213(host. This)138 136.2 R .713
+(is intended for compatibility with UIUC sendmail, and may ha)3.213 F 1.013
+-.15(ve s)-.2 H .712(ome use on).15 F(\214re)138 148.2 Q -.1(wa)-.25 G(lls.).1
+E 31(7D)102 164.4 S 2.758(on)145.22 164.4 S .258(ot run eight bit clean.)
+157.978 164.4 R -.7(Te)5.258 G(chnically).7 E 2.758(,y)-.65 G .258(ou ha)
+305.656 164.4 R .558 -.15(ve t)-.2 H 2.758(oa).15 G .259
+(ssert this option to be RFC 821 com-)354.68 164.4 R(patible.)138 176.4 Q F0
+2.5(2.15. New)87 200.4 R(Mailer De\214nitions)2.5 E F1 21.75(L= Set)102 216.6 R
+.93(the allo)3.43 F -.1(wa)-.25 G .93(ble line length.).1 F .93
+(In V5, the L mailer \215ag implied a line length limit of 990)5.93 F
+(characters; this is no)138 228.6 Q 2.5(ws)-.25 G(ettable to an arbitrary v)
+233.29 228.6 Q(alue.)-.25 E 17.86(F=a T)102 244.8 R(ry to use ESMTP)-.35 E 5
+(.I)-1.11 G 2.5(tw)222.65 244.8 S(ill f)235.15 244.8 Q
+(all back to SMTP if the initial EHLO pack)-.1 E(et is rejected.)-.1 E 17.3
+(F=b Ensure)102 261 R 2.5(ab)2.5 G(lank line at the end of messages.)180.21 261
+Q(Useful on the *\214le* mailer)5 E(.)-.55 E 17.86(F=c Strip)102 277.2 R .68(a\
+ll comments from addresses; this should only be used as a last resort when dea\
+ling)3.18 F(with crank)138 289.2 Q 2.5(ym)-.15 G(ailers.)195.62 289.2 Q 17.3
+(F=g Ne)102 305.4 R -.15(ve)-.25 G 2.88(ru).15 G .38
+(se the null sender as the en)169.91 305.4 R -.15(ve)-.4 G .379(lope sender).15
+F 2.879(,e)-.4 G -.15(ve)343.645 305.4 S 2.879(nw).15 G .379(hen running SMTP)
+368.034 305.4 R 5.379(.T)-1.11 G .379(his violates)458.341 305.4 R(RFC 1123.)
+138 317.4 Q 17.3(F=7 Strip)102 333.6 R(all output to this mailer to 7 bits.)2.5
+E 16.19(F=L Used)102 349.8 R .198
+(to set the line limit to 990 bytes for SMTP compatibility)2.697 F 5.198(.I)
+-.65 G 2.698(tn)398.622 349.8 S .698 -.25(ow d)409.1 349.8 T .198
+(oes that only if the).25 F(L= k)138 361.8 Q -.15(ey)-.1 G
+(letter is not speci\214ed.).15 E
+(This \215ag is obsolete and should not be used.)5 E F0 2.5(2.16. New)87 385.8
+R(or Changed Pr)2.5 E(e-De\214ned Macr)-.18 E(os)-.18 E F1 23.5($k UUCP)102 402
+R(node name from uname\(2\).)2.5 E 20.72($m Domain)102 418.2 R
+(part of our full hostname.)2.5 E 23.5($_ RFC)102 434.4 R(1413-pro)2.5 E
+(vided sender address.)-.15 E 21.28($w Pre)102 450.6 R .148(viously w)-.25 F
+.148(as sometimes the full domain name, sometimes just the \214rst w)-.1 F
+2.647(ord. No)-.1 F 2.647(wg)-.25 G(uar)488.1 450.6 Q(-)-.2 E
+(anteed to be the \214rst w)138 462.6 Q
+(ord of the domain name \(i.e., the host name\).)-.1 E 25.72($j Pre)102 478.8 R
+.193(viously had to be de\214ned \212 it is no)-.25 F 2.693(wp)-.25 G .194
+(rede\214ned to be the full domain name, if that can)310.067 478.8 R
+(be determined.)138 490.8 Q(That is, it is equi)5 E -.25(va)-.25 G(lent to $w)
+.25 E(.$m.)-.65 E F0 2.5(2.17. New)87 514.8 R(and Changed Classes)2.5 E F1
+17.86($=k Initialized)102 531 R(to contain $k.)2.5 E 15.64($=w No)102 547.2 R
+3.069(wi)-.25 G .569
+(ncludes \231[1.2.3.4]\232 \(where 1.2.3.4 is your IP address\) to allo)163.039
+547.2 R 3.068(wt)-.25 G .568(he con\214guration \214le)422.314 547.2 R
+(to recognize your o)138 559.2 Q(wn IP address.)-.25 E F0 2.5(2.18. New)87
+583.2 R(Rewriting T)2.5 E(ok)-.92 E(ens)-.1 E F1(The)127 599.4 Q F0($&)3.25 E
+F1 .75(construct has been adopted from ID)3.25 F 3.25(At)-.4 G 3.25(od)322
+599.4 S .75(efer macro e)335.25 599.4 R -.25(va)-.25 G 3.25(luation. Normally)
+.25 F 3.25(,m)-.65 G(acros)482.9 599.4 Q .476
+(in rulesets are bound when the rule is \214rst parsed during startup.)102
+611.4 R .476(Some macros change during pro-)5.476 F .046
+(cessing and are uninteresting during startup.)102 623.4 R(Ho)5.046 E(we)-.25 E
+-.15(ve)-.25 G .846 -.4(r, t).15 H .047
+(hat macro can be referenced using \231$&x\232 to).4 F(defer the e)102 635.4 Q
+-.25(va)-.25 G(ulation of $x until the rule is processed.).25 E(The tok)127
+651.6 Q(ens)-.1 E F0($\()2.5 E F1(and)2.5 E F0($\))2.5 E F1(ha)2.5 E .3 -.15
+(ve b)-.2 H(een added to allo).15 E 2.5(ws)-.25 G(peci\214cation of map re)
+319.59 651.6 Q(writing.)-.25 E -1.11(Ve)127 667.8 S 1.499(rsion 8 allo)1.11 F
+(ws)-.25 E F0($@)3.999 E F1 1.499
+(on the Left Hand Side of an `R' line to match zero tok)3.999 F 3.998
+(ens. This)-.1 F(is)3.998 E(intended to be used to match the null input.)102
+679.8 Q EP
+%%Page: 8 8
+%%BeginPageSetup
+BP
+%%EndPageSetup
+/F0 10/Times-Bold@0 SF 294.65(8C)72 60 S(hanges in Sendmail V)378.87 60 Q
+(ersion 8)-1 E 2.5(2.19. Bigger)87 96 R(Defaults)2.5 E/F1 10/Times-Roman@0 SF
+-1.11(Ve)127 112.2 S 1.283(rsion 8 allo)1.11 F 1.284
+(ws up to 100 rulesets instead of 30.)-.25 F 1.284
+(It is recommended that rulesets 0\2559 be)6.284 F(reserv)102 124.2 Q
+(ed for sendmail')-.15 E 2.5(sd)-.55 G(edicated use in future releases.)202.66
+124.2 Q(The total number of MX records that can be used has been raised to 20.)
+127 140.4 Q .335(The number of queued messages that can be handled at one time\
+ has been raised from 600 to)127 156.6 R(1000.)102 168.6 Q F0 2.5(2.20. Differ)
+87 192.6 R(ent Default T)-.18 E(uning P)-.92 E(arameters)-.1 E F1 -1.11(Ve)127
+208.8 S .8(rsion 8 has changed the def)1.11 F .8
+(ault parameters for tuning queue costs to mak)-.1 F 3.3(et)-.1 G .8
+(he number of)449.08 208.8 R .712(recipients more important than the size of t\
+he message \(for small messages\).)102 220.8 R .712(This is reasonable if)5.712
+F(you are connected with reasonably f)102 232.8 Q(ast links.)-.1 E F0 2.5
+(2.21. A)87 256.8 R(uto-Quoting in Addr)-.5 E(esses)-.18 E F1(Pre)127 273 Q
+(viously)-.25 E 3.2(,t)-.65 G .701(he `)177.36 273 R .701
+(`Full Name <email address>')-.74 F 3.201('s)-.74 G .701(yntax w)322.025 273 R
+.701(ould generate incorrect protocol out-)-.1 F .006(put if `)102 285 R .006
+(`Full Name')-.74 F 2.506('h)-.74 G .006(ad special characters such as dot.)
+187.754 285 R .005(This v)5.006 F .005(ersion puts quotes around such names.)
+-.15 F F0 2.5(2.22. Symbolic)87 309 R(Names On Err)2.5 E(or Mailer)-.18 E F1
+(Se)127 325.2 Q -.15(ve)-.25 G(ral names ha).15 E .3 -.15(ve b)-.2 H(een b).15
+E(uilt in to the $@ portion of the $#error mailer)-.2 E 5(.F)-.55 G(or e)428.96
+325.2 Q(xample:)-.15 E($#error $@NOHOST $: Host unkno)142 341.4 Q(wn)-.25 E
+(Prints the indicated message and sets the e)102 357.6 Q(xit status of)-.15 E
+/F2 10/Times-Italic@0 SF(sendmail)2.5 E F1(to)2.5 E/F3 9/Times-Roman@0 SF
+(EX_NOHOST)2.5 E F1(.)A F0 2.5(2.23. New)87 381.6 R(Built-In Mailers)2.5 E F1
+-1 -.8(Tw o)127 397.8 T(ne)3.901 E 3.101(wm)-.25 G .601(ailers, *\214le* and *\
+include*, are included to de\214ne options when mailing to a \214le)174.822
+397.8 R(or a :include: \214le respecti)102 409.8 Q -.15(ve)-.25 G(ly).15 E 5
+(.P)-.65 G(re)232.88 409.8 Q(viously these were o)-.25 E -.15(ve)-.15 G
+(rloaded on the local mailer).15 E(.)-.55 E F0 2.5(2.24. SMTP)87 433.8 R
+(VRFY Doesn't Expand)2.5 E F1(Pre)127 450 Q 1.438(vious v)-.25 F 1.438
+(ersions of sendmail treated VRFY and EXPN the same.)-.15 F 1.437(In this v)
+6.437 F 1.437(ersion, VRFY)-.15 F(doesn')102 462 Q 2.5(te)-.18 G
+(xpand aliases or follo)138.05 462 Q 2.5(w.)-.25 G(forw)235.84 462 Q
+(ard \214les.)-.1 E .663(As an optimization, if you run with your def)127 478.2
+R .664(ault deli)-.1 F -.15(ve)-.25 G .664(ry mode being queue-only).15 F 3.164
+(,t)-.65 G .664(he RCPT)466.386 478.2 R 1.09
+(command will also not chase aliases and .forw)102 490.2 R 1.09(ard \214les.)
+-.1 F 1.09(It will chase them when it processes the)6.09 F 2.5(queue. This)102
+502.2 R(speeds up RCPT processing.)2.5 E F0 2.5(2.25. [IPC])87 526.2 R
+(Mailers Allo)2.5 E 2.5(wM)-.1 G(ultiple Hosts)210.49 526.2 Q F1 .099
+(When an address resolv)127 542.4 R .099(es to a mailer that has `)-.15 F
+(`[IPC]')-.74 E 2.599('a)-.74 G 2.6(si)353.52 542.4 S .1(ts `)362.79 542.4 R
+(`P)-.74 E(ath')-.15 E .1(', the $@ part \(host name\))-.74 F .138
+(can be a colon-separated list of hosts instead of a single hostname.)102 554.4
+R .137(This asks sendmail to search the)5.137 F .16
+(list for the \214rst entry that is a)102 566.4 R -.25(va)-.2 G .16(ilable e)
+.25 F .161(xactly as though it were an MX record.)-.15 F .161
+(The intent is to route)5.161 F .738(internal traf)102 578.4 R .738
+(\214c through internal netw)-.25 F .738
+(orks without publishing an MX record to the net.)-.1 F .737(MX e)5.737 F
+(xpan-)-.15 E(sion is still done on the indi)102 590.4 Q(vidual items.)-.25 E
+F0 2.5(2.26. Aliases)87 614.4 R(Extended)2.5 E F1 .298
+(The implementation has been mer)127 630.6 R .298(ged with maps.)-.18 F .299
+(Among other things, this supports multiple)5.298 F
+(alias \214les and NIS-based aliases.)102 642.6 Q -.15(Fo)5 G 2.5(re).15 G
+(xample:)258.34 642.6 Q -.35(OA)142 658.8 S(/etc/aliases,nis:mail.aliases).35 E
+(will search \214rst the local database \231/etc/aliases\232 follo)102 675 Q
+(wed by the NIS map)-.25 E EP
+%%Page: 9 9
+%%BeginPageSetup
+BP
+%%EndPageSetup
+/F0 10/Times-Bold@0 SF(Changes in Sendmail V)72 60 Q(ersion 8)-1 E(9)499 60 Q
+2.5(2.27. P)87 96 R(ortability and Security Enhancements)-.2 E/F1 10
+/Times-Roman@0 SF 2.5(An)127 112.2 S(umber of internal changes ha)141.72 112.2
+Q .3 -.15(ve b)-.2 H(een made to enhance portability).15 E(.)-.65 E(Se)127
+128.4 Q -.15(ve)-.25 G(ral \214x).15 E(es ha)-.15 E .3 -.15(ve b)-.2 H
+(een made to increase the paranoia f).15 E(actor)-.1 E(.)-.55 E .46
+(In particular)127 144.6 R 2.96(,t)-.4 G .46(he permissions required for .forw)
+184.45 144.6 R .46(ard and :include: \214les ha)-.1 F .76 -.15(ve b)-.2 H .46
+(een tightened up).15 F(considerably)102 156.6 Q 5.182(.V)-.65 G 2.683(5w)
+167.352 156.6 S .183(ould pretty much read an)182.155 156.6 R 2.683<798c>-.15 G
+.183(le it could get to as root, which e)295.96 156.6 R .183(xposed some secu-)
+-.15 F 1.02(rity holes.)102 168.6 R 1.02
+(V8 insists that all directories leading up to the .forw)6.02 F 1.02
+(ard or :include: \214le be searchable)-.1 F .334
+(\("x" permission\) by the controlling user" \(de\214ned belo)102 180.6 R .335
+(w\), that the \214le itself be readable by the con-)-.25 F(trolling user)102
+192.6 Q 2.5(,a)-.4 G(nd that .forw)159.65 192.6 Q(ard \214les be o)-.1 E
+(wned by the user who is being forw)-.25 E(arded to or root.)-.1 E .565
+(The "controlling user" is the user on whose behalf the mail is being deli)127
+208.8 R -.15(ve)-.25 G 3.065(red. F).15 F .565(or e)-.15 F(xample,)-.15 E .459
+(if you mail to "user1" then the controlling user for ~user1/.forw)102 220.8 R
+.46(ard and an)-.1 F 2.96(ym)-.15 G .46(ailers in)416.94 220.8 R -.2(vo)-.4 G
+-.1(ke).2 G 2.96(db).1 G 2.96(yt)481.04 220.8 S(hat)491.78 220.8 Q(.forw)102
+232.8 Q(ard \214le, including :include: \214les.)-.1 E(Pre)127 249 Q(viously)
+-.25 E 2.816(,a)-.65 G -.15(ny)178.636 249 S .316
+(one who had a home directory could create a .forw).15 F .316(ard could forw)
+-.1 F .316(ard to a pro-)-.1 F 2.965(gram. No)102 261 R 1.765 -.65(w, s)-.25 H
+.466(endmail checks to mak).65 F 2.966(es)-.1 G .466(ure that the)262.934 261 R
+2.966(yh)-.15 G -2.25 -.2(av e)321.672 261 T .466(an "appro)3.166 F -.15(ve)
+-.15 G 2.966(ds).15 G .466(hell", that is, a shell listed)398.42 261 R
+(in the /etc/shells \214le.)102 273 Q F0 2.5(2.28. Miscellaneous)87 297 R
+(Fixes and Enhancements)2.5 E F1 4.03(An)127 313.2 S 1.53(umber of small b)
+143.25 313.2 R 1.53(ugs ha)-.2 F 1.53(ving to do with things lik)-.2 F 4.03(eb)
+-.1 G 1.53(ackslash-escaped quotes inside of)364.72 313.2 R(comments ha)102
+325.2 Q .3 -.15(ve b)-.2 H(een \214x).15 E(ed.)-.15 E 1.552(The \214x)127 341.4
+R 1.552(ed size limit on header lines \(such as \231T)-.15 F 1.553
+(o:\232 and \231Cc:\232\) has been eliminated; those)-.8 F -.2(bu)102 353.4 S
+-.25(ff).2 G(ers are dynamically allocated no).25 E -.65(w.)-.25 G .289(Sendma\
+il writes a /etc/sendmail.pid \214le with the current process id and the curre\
+nt in)127 369.6 R -.2(vo)-.4 G(cation).2 E(\215ags.)102 381.6 Q -1 -.8(Tw o)127
+397.8 T .218
+(people using the same program \(e.g., submit\) are considered "dif)3.518 F
+.219(ferent" so that duplicate)-.25 F .508(elimination doesn')102 409.8 R 3.008
+(td)-.18 G .508(elete one of them.)187.836 409.8 R -.15(Fo)5.508 G 3.008(re).15
+G .508(xample, tw)287.556 409.8 R 3.008(op)-.1 G .508(eople forw)345.412 409.8
+R .508(arding their email to |submit)-.1 F(will be treated as tw)102 421.8 Q
+2.5(or)-.1 G(ecipients.)193.27 421.8 Q .721(The mailstats program prints maile\
+r names and gets the location of the sendmail.st \214le from)127 438 R
+(/etc/sendmail.cf.)102 450 Q(Man)127 466.2 Q 2.5(ym)-.15 G(inor b)160.46 466.2
+Q(ugs ha)-.2 E .3 -.15(ve b)-.2 H(een \214x).15 E
+(ed, such as handling of backslashes inside of quotes.)-.15 E 2.5(Ah)127 482.4
+S(ook has been added to allo)141.72 482.4 Q 2.5(wr)-.25 G -.25(ew)260.89 482.4
+S(riting of local addresses after aliasing.).25 E F0 2.5(3. FUTURE)72 506.4 R
+-.1(WO)2.5 G(RK).1 E F1 1.719(The pre)112 522.6 R 1.719
+(vious section describes)-.25 F/F2 10/Times-Italic@0 SF(sendmail)4.219 E F1
+1.719(as of v)4.219 F 1.719(ersion 8.6.6.)-.15 F 1.718
+(There is still much to be done.)6.719 F(Some high points are described belo)87
+534.6 Q 3.8 -.65(w. T)-.25 H(his list is by no means e).65 E(xhausti)-.15 E
+-.15(ve)-.25 G(.).15 E F0 2.5(3.1. Full)87 558.6 R(MIME Support)2.5 E F1
+(Currently)127 574.8 Q F2(sendmail)3.305 E F1 .805(only supports se)3.305 F
+-.15(ve)-.25 G 3.305(nb).15 G .805(it MIME messages.)297.005 574.8 R .806
+(Although it can pass eight bit)5.805 F .371(MIME messages, it cannot adv)102
+586.8 R .371(ertise that f)-.15 F .37
+(act because the standards say that the mail agent must be)-.1 F .26
+(able to do 8- to 7-bit con)102 598.8 R -.15(ve)-.4 G .26(rsion to ha).15 F
+.561 -.15(ve f)-.2 H .261(ull 8-bit support.).15 F .261(This requires f)5.261 F
+.261(ar more e)-.1 F(xtensi)-.15 E .561 -.15(ve m)-.25 H(odi\214-).15 E
+(cation of the message body than is currently supported.)102 610.8 Q .464
+(The best w)127 627 R .464(ay to do this w)-.1 F .463
+(ould be to support the general concept of an e)-.1 F .463(xternal `)-.15 F
+.463(`message \214l-)-.74 F(ter')102 639 Q 3.319('t)-.74 G .819
+(hat could do arbitrary modi\214cations of the message.)124.569 639 R .819
+(This w)5.819 F .82(ould allo)-.1 F 3.32(wM)-.25 G .82(IME con)427.37 639 R
+-.15(ve)-.4 G .82(rsion as).15 F .63
+(well as such things as automatic encryption of messages sent o)102 651 R -.15
+(ve)-.15 G 3.129(re).15 G .629(xternal links.)379.264 651 R .629
+(This is probably)5.629 F(an e)102 663 Q(xtremely non-tri)-.15 E(vial change.)
+-.25 E F0 2.5(3.2. Ser)87 687 R(vice Switch Abstraction)-.1 E F1 .369(Most mod\
+ern systems include some concept of a \231service switch\232 \212 for e)127
+703.2 R .37(xample, to look up)-.15 F .984
+(host names you can try DNS, NIS, NIS+, te)102 715.2 R .984
+(xt tables, NetInfo, or other services in some arbitrary)-.15 F EP
+%%Page: 10 10
+%%BeginPageSetup
+BP
+%%EndPageSetup
+/F0 10/Times-Bold@0 SF 287.15(10 Changes)72 60 R(in Sendmail V)2.5 E(ersion 8)
+-1 E/F1 10/Times-Roman@0 SF(order)102 96 Q 5.174(.T)-.55 G .174
+(his is currently v)136.334 96 R .174(ery clumsy in)-.15 F/F2 10/Times-Italic@0
+SF(sendmail)2.674 E F1 2.674(,w)C .174
+(ith only limited control of the services pro)309.612 96 R(vided.)-.15 E F0 2.5
+(3.3. Mor)87 120 R 2.5(eC)-.18 G(ontr)139.86 120 Q(ol of Local Addr)-.18 E
+(esses)-.18 E F1 .943(Currently some addresses are declared as \231local\232 a\
+nd are handled specially \212 for e)127 136.2 R(xample,)-.15 E(the)102 148.2 Q
+3.455(ym)-.15 G .955(ay ha)130.305 148.2 R 1.255 -.15(ve .)-.2 H(forw).15 E
+.956(ard \214les, may be translated into program calls or \214le deli)-.1 F
+-.15(ve)-.25 G .956(ries, and so forth.).15 F .311(These should be brok)102
+160.2 R .311(en out into separate \215ags to allo)-.1 F 2.811(wt)-.25 G .31
+(he local system administrator to ha)330.29 160.2 R .61 -.15(ve m)-.2 H(ore).15
+E(\214ne-grained control o)102 172.2 Q -.15(ve)-.15 G 2.5(ro).15 G(perations.)
+208.62 172.2 Q F0 2.5(3.4. Mor)87 196.2 R 2.5(eR)-.18 G(un-T)139.86 196.2 Q
+(ime Con\214guration Options)-.18 E F1 .016(There are man)127 212.4 R 2.516(yo)
+-.15 G .016(ptions that are con\214gured at compile time, such as the method o\
+f \214le locking)197.148 212.4 R .719
+(and the use of the IDENT protocol [RFC1413].)102 224.4 R .719
+(These should be transfered to run time by adding)5.719 F(ne)102 236.4 Q 2.5
+(wo)-.25 G(ptions.)125.91 236.4 Q(Similarly)127 252.6 Q 3.413(,s)-.65 G .913
+(ome options are currently o)173.383 252.6 R -.15(ve)-.15 G .913
+(rloaded, that is, a single option controls more than).15 F(one thing.)102
+264.6 Q(These should probably be brok)5 E(en out into separate options.)-.1 E
+(This implies that options will change from single characters to w)127 280.8 Q
+(ords.)-.1 E F0 2.5(3.5. Mor)87 304.8 R 2.5(eC)-.18 G(on\214guration Contr)
+139.86 304.8 Q(ol Ov)-.18 E(er Err)-.1 E(ors)-.18 E F1(Currently)127 321 Q
+3.649(,t)-.65 G 1.148
+(he con\214guration \214le can generate an error message during parsing.)
+173.609 321 R(Ho)6.148 E(we)-.25 E -.15(ve)-.25 G 1.948 -.4(r, i).15 H(t).4 E
+.569(cannot tweak other operations, such as issuing a w)102 333 R .57
+(arning message to the system postmaster)-.1 F 5.57(.S)-.55 G(imi-)487.33 333 Q
+(larly)102 345 Q 2.558(,s)-.65 G .057
+(ome errors should not be triggered if the)128.628 345 R 2.557(ya)-.15 G .057
+(re in aliases during an alias \214le reb)302.237 345 R .057(uild, b)-.2 F .057
+(ut should)-.2 F(be triggered if that alias is actually used.)102 357 Q F0 2.5
+(3.6. Long)87 381 R -.92(Te)2.5 G(rm Host State).92 E F1(Currently)127 397.2 Q
+(,)-.65 E F2(sendmail)3.731 E F1 1.231
+(only remembers host status during a single queue run.)3.731 F 1.232
+(This should be)6.232 F(con)102 409.2 Q -.15(ve)-.4 G .492(rted to long term s\
+tatus stored on disk so it can be shared between instantiations of).15 F F2
+(sendmail)2.991 E F1(.)A .866(Entries will ha)102 421.2 R 1.167 -.15(ve t)-.2 H
+3.367(ob).15 G 3.367(et)190.666 421.2 S .867(imestamped so the)201.253 421.2 R
+3.367(yc)-.15 G .867(an time out.)290.084 421.2 R .867(This will allo)5.867 F
+(w)-.25 E F2(sendmail)3.367 E F1 .867(to implement)3.367 F -.15(ex)102 433.2 S
+(ponential back).15 E(of)-.1 E 2.5(fo)-.25 G 2.5(nq)188.7 433.2 S
+(ueue runs on a per)201.2 433.2 Q(-host basis.)-.2 E F0 2.5(3.7. Connection)87
+457.2 R(Contr)2.5 E(ol)-.18 E F1 .819(Modern netw)127 473.4 R .819(orks ha)-.1
+F 1.119 -.15(ve d)-.2 H(if).15 E .819(ferent types of connecti)-.25 F .818
+(vity than the past.)-.25 F .818(In particular)5.818 F 3.318(,t)-.4 G .818
+(he rising)468.462 473.4 R .636
+(prominence of dialup IP has created certain challenges for automated serv)102
+485.4 R 3.136(ers. It)-.15 F .636(is not uncommon)3.136 F .732(to try to mak)
+102 497.4 R 3.232(eac)-.1 G .732(onnection to a host and ha)175.27 497.4 R
+1.032 -.15(ve i)-.2 H 3.232(tf).15 G .732(ail, e)307.984 497.4 R -.15(ve)-.25 G
+3.232(nt).15 G .732(hough if you tried ag)348.208 497.4 R .732(ain it w)-.05 F
+.731(ould suc-)-.1 F 2.5(ceed. The)102 509.4 R
+(connection management could be a bit cle)2.5 E -.15(ve)-.25 G
+(rer to try to adapt to such situations.).15 E F0 2.5(3.8. Other)87 533.4 R
+(Caching)2.5 E F1 .074(When you do an MX record lookup, the name serv)127 549.6
+R .075(er automatically returns the IP addresses of)-.15 F .518
+(the associated MX serv)102 561.6 R 3.018(ers. This)-.15 F .518
+(information is currently ignored, and another query is done to get)3.018 F
+(this information.)102 573.6 Q(It should be cached to a)5 E -.2(vo)-.2 G(id e)
+.2 E(xcess name serv)-.15 E(er traf)-.15 E(\214c.)-.25 E F0 2.5(4. REFERENCES)
+72 597.6 R F1([Allman83a])87 613.8 Q .137(\231Sendmail \212 An Internetw)123
+625.8 R .137(ork Mail Router)-.1 F 4.037 -.7(.\232 E)-.55 H 2.638(.A).7 G 2.638
+(llman. In)327.58 625.8 R F2 .138(Unix Pr)2.638 F -.1(og)-.45 G -.15(ra).1 G
+(mmer).15 E(s')-.1 E 2.638(sM)-.4 G(anual,)463.582 625.8 Q F1(4.2)2.638 E(Berk)
+123 637.8 Q(ele)-.1 E 2.5(yS)-.15 G(oftw)166.91 637.8 Q(are Distrib)-.1 E
+(ution, v)-.2 E(olume 2C.)-.2 E(August 1983.)5 E([Allman83b])87 654 Q .384
+(\231Mail Systems and Addressing in 4.2BSD.)123 666 R 5.384<9a45>-.7 G 2.884
+(.A)311.544 666 S .383(llman In)324.148 666 R F2 .383(UNICOM Confer)2.883 F
+.383(ence Pr)-.37 F(oceedings.)-.45 E F1(San Die)123 678 Q(go, California.)-.15
+E(January 1983.)5 E([Allman&Amos85])87 694.2 Q -.74(``)123 706.2 S 1.145
+(Sendmail Re).74 F(visited.)-.25 E 5.125 -.74('' E)-.7 H 3.645(.A).74 G 1.145
+(llman and M. Amos.)241.215 706.2 R(In)6.145 E F2 1.145
+(Usenix Summer 1985 Confer)3.645 F 1.145(ence Pr)-.37 F(o-)-.45 E(ceedings.)123
+718.2 Q F1(Portland, Ore)5 E 2.5(gon. June)-.15 F(1985.)2.5 E EP
+%%Page: 11 11
+%%BeginPageSetup
+BP
+%%EndPageSetup
+/F0 10/Times-Bold@0 SF(Changes in Sendmail V)72 60 Q(ersion 8)-1 E(11)494 60 Q
+/F1 10/Times-Roman@0 SF([ID)87 96 Q(A87])-.4 E/F2 10/Times-Italic@0 SF(Electr)
+1.97 E .983(onic Mail Addr)-.45 F .983(essing in Theory and Pr)-.37 F .982
+(actice with the ID)-.15 F 3.482(AS)-.35 G .982(endmail Enhancement Kit)398.156
+96 R .563(\(or The P)123 108 R(ostmaster')-.8 E 3.063(sL)-.4 G .563(ast W)
+215.989 108 R .564(ill and T)-.55 F(estament\).)-.92 E F1 .564(Lennart Lo)5.564
+F -.5(..)359.828 102 S 3.064(vstrand. Department)364.828 108 R .564
+(of Computer)3.064 F 1.267(and Information Science, Uni)123 120 R -.15(ve)-.25
+G 1.267(rsity of Link).15 F(o)-.1 E -.5(..)306.585 114 S 1.266
+(ping, Sweden, Report no. LiTH-ID)311.585 120 R(A-Ex-8715.)-.4 E(May 1987.)123
+132 Q([RFC821])87 148.2 Q F2(Simple Mail T)123 160.2 Q -.15(ra)-.55 G
+(nsport Pr).15 E(otocol.)-.45 E F1(J. Postel.)5 E(August 1982.)5 E([RFC1123])87
+176.4 Q F2(Requir)123 188.4 Q .163
+(ements for Internet Hosts \212 Application and Support.)-.37 F F1 .164
+(Internet Engineering T)5.164 F .164(ask F)-.8 F(orce,)-.15 E
+(R. Braden, Editor)123 200.4 Q 5(.O)-.55 G(ctober 1989.)207.72 200.4 Q
+([RFC1344])87 216.6 Q F2(Implications of MIME for Internet Mail Gate)123 228.6
+Q(ways.)-.15 E F1(N. Borenstein.)5 E(June 1992.)5 E([RFC1413])87 244.8 Q F2
+(Identi\214cation Pr)123 256.8 Q(otocol.)-.45 E F1(M. St. Johns.)5 E
+(February 1993.)5 E([RFC1425])87 273 Q F2 2.352(SMTP Service Extensions.)123
+285 R F1 2.352(J. Klensin, N. Freed, M. Rose, E. Stef)7.352 F 2.351
+(ferud, and D. Crock)-.25 F(er)-.1 E(.)-.55 E(February 1993.)123 297 Q
+([RFC1426])87 313.2 Q F2 .12(SMTP Service Extension for 8bit-MIMEtr)123 325.2 R
+(ansport.)-.15 E F1 .12(J. Klensin, N. Freed, M. Rose, E. Stef)5.12 F(ferud,)
+-.25 E(and D. Crock)123 337.2 Q(er)-.1 E 5(.F)-.55 G(ebruary 1993.)196.78 337.2
+Q([RFC1427])87 353.4 Q F2 .813(SMTP Service Extension for Messa)123 365.4 R
+1.013 -.1(ge S)-.1 H .813(ize Declar).1 F(ation.)-.15 E F1 .813
+(J. Klensin, N. Freed, and K. Moore.)5.813 F(February 1993.)123 377.4 Q
+([RFC1521])87 393.6 Q F2 2.033
+(MIME \(Multipurpose Internet Mail Extensions\) P)123 405.6 R 2.033
+(art One: Mec)-.8 F 2.033(hanisms for Specifying and)-.15 F .933
+(Describing the F)123 417.6 R .933(ormat of Internet Messa)-1.05 F 1.133 -.1
+(ge B)-.1 H(odies.).1 E F1 .932(N. Borenstein and N. Freed.)5.932 F(September)
+5.932 E(1993.)123 429.6 Q EP
+%%Trailer
+end
+%%EOF
diff --git a/usr.sbin/sendmail/doc/intro/Makefile b/usr.sbin/sendmail/doc/intro/Makefile
new file mode 100644
index 0000000..939cd6c
--- /dev/null
+++ b/usr.sbin/sendmail/doc/intro/Makefile
@@ -0,0 +1,13 @@
+# @(#)Makefile 8.2 (Berkeley) 2/28/94
+
+DIR= smm/09.sendmail
+SRCS= intro.me
+MACROS= -me
+
+all: intro.ps
+
+intro.ps: ${SRCS}
+ rm -f ${.TARGET}
+ ${PIC} ${SRCS} | ${ROFF} > ${.TARGET}
+
+.include <bsd.doc.mk>
diff --git a/usr.sbin/sendmail/doc/intro/intro.me b/usr.sbin/sendmail/doc/intro/intro.me
new file mode 100644
index 0000000..0406bb1
--- /dev/null
+++ b/usr.sbin/sendmail/doc/intro/intro.me
@@ -0,0 +1,1478 @@
+.\" Copyright (c) 1983 Eric P. Allman
+.\" Copyright (c) 1988, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)intro.me 8.2 (Berkeley) 11/27/93
+.\"
+.\" pic -Pxx intro.me | ditroff -me -Pxx
+.eh 'SMM:9-%''SENDMAIL \*- An Internetwork Mail Router'
+.oh 'SENDMAIL \*- An Internetwork Mail Router''SMM:9-%'
+.nr si 3n
+.if n .ls 2
+.+c
+.(l C
+.sz 14
+SENDMAIL \*- An Internetwork Mail Router
+.sz
+.sp
+Eric Allman*
+.sp 0.5
+.i
+University of California, Berkeley
+Mammoth Project
+.)l
+.sp
+.(l F
+.ce
+ABSTRACT
+.sp \n(psu
+Routing mail through a heterogenous internet presents many new
+problems. Among the worst of these is that of address mapping.
+Historically, this has been handled on an
+.i "ad hoc"
+basis. However,
+this approach has become unmanageable as internets grow.
+.sp \n(psu
+Sendmail acts a unified "post office" to which all mail can be
+submitted. Address interpretation is controlled by a production
+system, which can parse both domain-based addressing and old-style
+.i "ad hoc"
+addresses.
+The production system is powerful
+enough to rewrite addresses in the message header to conform to the
+standards of a number of common target networks, including old
+(NCP/RFC733) Arpanet, new (TCP/RFC822) Arpanet, UUCP, and Phonenet.
+Sendmail also implements an SMTP server, message
+queueing, and aliasing.
+.)l
+.sp 2
+.(f
+*A considerable part of this work
+was done while under the employ
+of the INGRES Project
+at the University of California at Berkeley
+and at Britton Lee.
+.)f
+.pp
+.i Sendmail
+implements a general internetwork mail routing facility,
+featuring aliasing and forwarding,
+automatic routing to network gateways,
+and flexible configuration.
+.pp
+In a simple network,
+each node has an address,
+and resources can be identified
+with a host-resource pair;
+in particular,
+the mail system can refer to users
+using a host-username pair.
+Host names and numbers have to be administered by a central authority,
+but usernames can be assigned locally to each host.
+.pp
+In an internet,
+multiple networks with different characterstics
+and managements
+must communicate.
+In particular,
+the syntax and semantics of resource identification change.
+Certain special cases can be handled trivially
+by
+.i "ad hoc"
+techniques,
+such as
+providing network names that appear local to hosts
+on other networks,
+as with the Ethernet at Xerox PARC.
+However, the general case is extremely complex.
+For example,
+some networks require point-to-point routing,
+which simplifies the database update problem
+since only adjacent hosts must be entered
+into the system tables,
+while others use end-to-end addressing.
+Some networks use a left-associative syntax
+and others use a right-associative syntax,
+causing ambiguity in mixed addresses.
+.pp
+Internet standards seek to eliminate these problems.
+Initially, these proposed expanding the address pairs
+to address triples,
+consisting of
+{network, host, resource}
+triples.
+Network numbers must be universally agreed upon,
+and hosts can be assigned locally
+on each network.
+The user-level presentation was quickly expanded
+to address domains,
+comprised of a local resource identification
+and a hierarchical domain specification
+with a common static root.
+The domain technique
+separates the issue of physical versus logical addressing.
+For example,
+an address of the form
+.q "eric@a.cc.berkeley.arpa"
+describes only the logical
+organization of the address space.
+.pp
+.i Sendmail
+is intended to help bridge the gap
+between the totally
+.i "ad hoc"
+world
+of networks that know nothing of each other
+and the clean, tightly-coupled world
+of unique network numbers.
+It can accept old arbitrary address syntaxes,
+resolving ambiguities using heuristics
+specified by the system administrator,
+as well as domain-based addressing.
+It helps guide the conversion of message formats
+between disparate networks.
+In short,
+.i sendmail
+is designed to assist a graceful transition
+to consistent internetwork addressing schemes.
+.sp
+.pp
+Section 1 discusses the design goals for
+.i sendmail .
+Section 2 gives an overview of the basic functions of the system.
+In section 3,
+details of usage are discussed.
+Section 4 compares
+.i sendmail
+to other internet mail routers,
+and an evaluation of
+.i sendmail
+is given in section 5,
+including future plans.
+.sh 1 "DESIGN GOALS"
+.pp
+Design goals for
+.i sendmail
+include:
+.np
+Compatibility with the existing mail programs,
+including Bell version 6 mail,
+Bell version 7 mail
+[UNIX83],
+Berkeley
+.i Mail
+[Shoens79],
+BerkNet mail
+[Schmidt79],
+and hopefully UUCP mail
+[Nowitz78a, Nowitz78b].
+ARPANET mail
+[Crocker77a, Postel77]
+was also required.
+.np
+Reliability, in the sense of guaranteeing
+that every message is correctly delivered
+or at least brought to the attention of a human
+for correct disposal;
+no message should ever be completely lost.
+This goal was considered essential
+because of the emphasis on mail in our environment.
+It has turned out to be one of the hardest goals to satisfy,
+especially in the face of the many anomalous message formats
+produced by various ARPANET sites.
+For example,
+certain sites generate improperly formated addresses,
+occasionally
+causing error-message loops.
+Some hosts use blanks in names,
+causing problems with
+UNIX mail programs that assume that an address
+is one word.
+The semantics of some fields
+are interpreted slightly differently
+by different sites.
+In summary,
+the obscure features of the ARPANET mail protocol
+really
+.i are
+used and
+are difficult to support,
+but must be supported.
+.np
+Existing software to do actual delivery
+should be used whenever possible.
+This goal derives as much from political and practical considerations
+as technical.
+.np
+Easy expansion to
+fairly complex environments,
+including multiple
+connections to a single network type
+(such as with multiple UUCP or Ether nets
+[Metcalfe76]).
+This goal requires consideration of the contents of an address
+as well as its syntax
+in order to determine which gateway to use.
+For example,
+the ARPANET is bringing up the
+TCP protocol to replace the old NCP protocol.
+No host at Berkeley runs both TCP and NCP,
+so it is necessary to look at the ARPANET host name
+to determine whether to route mail to an NCP gateway
+or a TCP gateway.
+.np
+Configuration should not be compiled into the code.
+A single compiled program should be able to run as is at any site
+(barring such basic changes as the CPU type or the operating system).
+We have found this seemingly unimportant goal
+to be critical in real life.
+Besides the simple problems that occur when any program gets recompiled
+in a different environment,
+many sites like to
+.q fiddle
+with anything that they will be recompiling anyway.
+.np
+.i Sendmail
+must be able to let various groups maintain their own mailing lists,
+and let individuals specify their own forwarding,
+without modifying the system alias file.
+.np
+Each user should be able to specify which mailer to execute
+to process mail being delivered for him.
+This feature allows users who are using specialized mailers
+that use a different format to build their environment
+without changing the system,
+and facilitates specialized functions
+(such as returning an
+.q "I am on vacation"
+message).
+.np
+Network traffic should be minimized
+by batching addresses to a single host where possible,
+without assistance from the user.
+.pp
+These goals motivated the architecture illustrated in figure 1.
+.(z
+.hl
+.ie t \
+\{\
+.ie !"\*(.T"" \
+\{\
+.PS
+boxht = 0.5i
+boxwid = 1.0i
+
+ down
+S: [
+ right
+ S1: box "sender1"
+ move
+ box "sender2"
+ move
+ S3: box "sender3"
+ ]
+ arrow
+SM: box "sendmail" wid 2i ht boxht
+ arrow
+M: [
+ right
+ M1: box "mailer1"
+ move
+ box "mailer2"
+ move
+ M3: box "mailer3"
+ ]
+
+ arrow from S.S1.s to 1/2 between SM.nw and SM.n
+ arrow from S.S3.s to 1/2 between SM.n and SM.ne
+
+ arrow from 1/2 between SM.sw and SM.s to M.M1.n
+ arrow from 1/2 between SM.s and SM.se to M.M3.n
+.PE
+.\}
+.el \
+. sp 18
+.\}
+.el \{\
+.(c
++---------+ +---------+ +---------+
+| sender1 | | sender2 | | sender3 |
++---------+ +---------+ +---------+
+ | | |
+ +----------+ + +----------+
+ | | |
+ v v v
+ +-------------+
+ | sendmail |
+ +-------------+
+ | | |
+ +----------+ + +----------+
+ | | |
+ v v v
++---------+ +---------+ +---------+
+| mailer1 | | mailer2 | | mailer3 |
++---------+ +---------+ +---------+
+.)c
+.\}
+
+.ce
+Figure 1 \*- Sendmail System Structure.
+.hl
+.)z
+The user interacts with a mail generating and sending program.
+When the mail is created,
+the generator calls
+.i sendmail ,
+which routes the message to the correct mailer(s).
+Since some of the senders may be network servers
+and some of the mailers may be network clients,
+.i sendmail
+may be used as an internet mail gateway.
+.sh 1 "OVERVIEW"
+.sh 2 "System Organization"
+.pp
+.i Sendmail
+neither interfaces with the user
+nor does actual mail delivery.
+Rather,
+it collects a message
+generated by a user interface program (UIP)
+such as Berkeley
+.i Mail ,
+MS
+[Crocker77b],
+or MH
+[Borden79],
+edits the message as required by the destination network,
+and calls appropriate mailers
+to do mail delivery or queueing for network transmission\**.
+.(f
+\**except when mailing to a file,
+when
+.i sendmail
+does the delivery directly.
+.)f
+This discipline allows the insertion of new mailers
+at minimum cost.
+In this sense
+.i sendmail
+resembles the Message Processing Module (MPM)
+of [Postel79b].
+.sh 2 "Interfaces to the Outside World"
+.pp
+There are three ways
+.i sendmail
+can communicate with the outside world,
+both in receiving and in sending mail.
+These are using the conventional UNIX
+argument vector/return status,
+speaking SMTP over a pair of UNIX pipes,
+and speaking SMTP over an interprocess(or) channel.
+.sh 3 "Argument vector/exit status"
+.pp
+This technique is the standard UNIX method
+for communicating with the process.
+A list of recipients is sent in the argument vector,
+and the message body is sent on the standard input.
+Anything that the mailer prints
+is simply collected and sent back to the sender
+if there were any problems.
+The exit status from the mailer is collected
+after the message is sent,
+and a diagnostic is printed if appropriate.
+.sh 3 "SMTP over pipes"
+.pp
+The SMTP protocol
+[Postel82]
+can be used to run an interactive lock-step interface
+with the mailer.
+A subprocess is still created,
+but no recipient addresses are passed to the mailer
+via the argument list.
+Instead, they are passed one at a time
+in commands sent to the processes standard input.
+Anything appearing on the standard output
+must be a reply code
+in a special format.
+.sh 3 "SMTP over an IPC connection"
+.pp
+This technique is similar to the previous technique,
+except that it uses a 4.2bsd IPC channel
+[UNIX83].
+This method is exceptionally flexible
+in that the mailer need not reside
+on the same machine.
+It is normally used to connect to a sendmail process
+on another machine.
+.sh 2 "Operational Description"
+.pp
+When a sender wants to send a message,
+it issues a request to
+.i sendmail
+using one of the three methods described above.
+.i Sendmail
+operates in two distinct phases.
+In the first phase,
+it collects and stores the message.
+In the second phase,
+message delivery occurs.
+If there were errors during processing
+during the second phase,
+.i sendmail
+creates and returns a new message describing the error
+and/or returns an status code
+telling what went wrong.
+.sh 3 "Argument processing and address parsing"
+.pp
+If
+.i sendmail
+is called using one of the two subprocess techniques,
+the arguments
+are first scanned
+and option specifications are processed.
+Recipient addresses are then collected,
+either from the command line
+or from the SMTP
+RCPT command,
+and a list of recipients is created.
+Aliases are expanded at this step,
+including mailing lists.
+As much validation as possible of the addresses
+is done at this step:
+syntax is checked, and local addresses are verified,
+but detailed checking of host names and addresses
+is deferred until delivery.
+Forwarding is also performed
+as the local addresses are verified.
+.pp
+.i Sendmail
+appends each address
+to the recipient list after parsing.
+When a name is aliased or forwarded,
+the old name is retained in the list,
+and a flag is set that tells the delivery phase
+to ignore this recipient.
+This list is kept free from duplicates,
+preventing alias loops
+and duplicate messages deliverd to the same recipient,
+as might occur if a person is in two groups.
+.sh 3 "Message collection"
+.pp
+.i Sendmail
+then collects the message.
+The message should have a header at the beginning.
+No formatting requirements are imposed on the message
+except that they must be lines of text
+(i.e., binary data is not allowed).
+The header is parsed and stored in memory,
+and the body of the message is saved
+in a temporary file.
+.pp
+To simplify the program interface,
+the message is collected even if no addresses were valid.
+The message will be returned with an error.
+.sh 3 "Message delivery"
+.pp
+For each unique mailer and host in the recipient list,
+.i sendmail
+calls the appropriate mailer.
+Each mailer invocation sends to all users receiving the message on one host.
+Mailers that only accept one recipient at a time
+are handled properly.
+.pp
+The message is sent to the mailer
+using one of the same three interfaces
+used to submit a message to sendmail.
+Each copy of the message is
+prepended by a customized header.
+The mailer status code is caught and checked,
+and a suitable error message given as appropriate.
+The exit code must conform to a system standard
+or a generic message
+(\c
+.q "Service unavailable" )
+is given.
+.sh 3 "Queueing for retransmission"
+.pp
+If the mailer returned an status that
+indicated that it might be able to handle the mail later,
+.i sendmail
+will queue the mail and try again later.
+.sh 3 "Return to sender"
+.pp
+If errors occur during processing,
+.i sendmail
+returns the message to the sender for retransmission.
+The letter can be mailed back
+or written in the file
+.q dead.letter
+in the sender's home directory\**.
+.(f
+\**Obviously, if the site giving the error is not the originating
+site, the only reasonable option is to mail back to the sender.
+Also, there are many more error disposition options,
+but they only effect the error message \*- the
+.q "return to sender"
+function is always handled in one of these two ways.
+.)f
+.sh 2 "Message Header Editing"
+.pp
+Certain editing of the message header
+occurs automatically.
+Header lines can be inserted
+under control of the configuration file.
+Some lines can be merged;
+for example,
+a
+.q From:
+line and a
+.q Full-name:
+line can be merged under certain circumstances.
+.sh 2 "Configuration File"
+.pp
+Almost all configuration information is read at runtime
+from an ASCII file,
+encoding
+macro definitions
+(defining the value of macros used internally),
+header declarations
+(telling sendmail the format of header lines that it will process specially,
+i.e., lines that it will add or reformat),
+mailer definitions
+(giving information such as the location and characteristics
+of each mailer),
+and address rewriting rules
+(a limited production system to rewrite addresses
+which is used to parse and rewrite the addresses).
+.pp
+To improve performance when reading the configuration file,
+a memory image can be provided.
+This provides a
+.q compiled
+form of the configuration file.
+.sh 1 "USAGE AND IMPLEMENTATION"
+.sh 2 "Arguments"
+.pp
+Arguments may be flags and addresses.
+Flags set various processing options.
+Following flag arguments,
+address arguments may be given,
+unless we are running in SMTP mode.
+Addresses follow the syntax in RFC822
+[Crocker82]
+for ARPANET
+address formats.
+In brief, the format is:
+.np
+Anything in parentheses is thrown away
+(as a comment).
+.np
+Anything in angle brackets (\c
+.q "<\|>" )
+is preferred
+over anything else.
+This rule implements the ARPANET standard that addresses of the form
+.(b
+user name <machine-address>
+.)b
+will send to the electronic
+.q machine-address
+rather than the human
+.q "user name."
+.np
+Double quotes
+(\ "\ )
+quote phrases;
+backslashes quote characters.
+Backslashes are more powerful
+in that they will cause otherwise equivalent phrases
+to compare differently \*- for example,
+.i user
+and
+.i
+"user"
+.r
+are equivalent,
+but
+.i \euser
+is different from either of them.
+.pp
+Parentheses, angle brackets, and double quotes
+must be properly balanced and nested.
+The rewriting rules control remaining parsing\**.
+.(f
+\**Disclaimer: Some special processing is done
+after rewriting local names; see below.
+.)f
+.sh 2 "Mail to Files and Programs"
+.pp
+Files and programs are legitimate message recipients.
+Files provide archival storage of messages,
+useful for project administration and history.
+Programs are useful as recipients in a variety of situations,
+for example,
+to maintain a public repository of systems messages
+(such as the Berkeley
+.i msgs
+program,
+or the MARS system
+[Sattley78]).
+.pp
+Any address passing through the initial parsing algorithm
+as a local address
+(i.e, not appearing to be a valid address for another mailer)
+is scanned for two special cases.
+If prefixed by a vertical bar (\c
+.q \^|\^ )
+the rest of the address is processed as a shell command.
+If the user name begins with a slash mark (\c
+.q /\^ )
+the name is used as a file name,
+instead of a login name.
+.pp
+Files that have setuid or setgid bits set
+but no execute bits set
+have those bits honored if
+.i sendmail
+is running as root.
+.sh 2 "Aliasing, Forwarding, Inclusion"
+.pp
+.i Sendmail
+reroutes mail three ways.
+Aliasing applies system wide.
+Forwarding allows each user to reroute incoming mail
+destined for that account.
+Inclusion directs
+.i sendmail
+to read a file for a list of addresses,
+and is normally used
+in conjunction with aliasing.
+.sh 3 "Aliasing"
+.pp
+Aliasing maps names to address lists using a system-wide file.
+This file is indexed to speed access.
+Only names that parse as local
+are allowed as aliases;
+this guarantees a unique key
+(since there are no nicknames for the local host).
+.sh 3 "Forwarding"
+.pp
+After aliasing,
+recipients that are local and valid
+are checked for the existence of a
+.q .forward
+file in their home directory.
+If it exists,
+the message is
+.i not
+sent to that user,
+but rather to the list of users in that file.
+Often
+this list will contain only one address,
+and the feature will be used for network mail forwarding.
+.pp
+Forwarding also permits a user to specify a private incoming mailer.
+For example,
+forwarding to:
+.(b
+"\^|\|/usr/local/newmail myname"
+.)b
+will use a different incoming mailer.
+.sh 3 "Inclusion"
+.pp
+Inclusion is specified in RFC 733 [Crocker77a] syntax:
+.(b
+:Include: pathname
+.)b
+An address of this form reads the file specified by
+.i pathname
+and sends to all users listed in that file.
+.pp
+The intent is
+.i not
+to support direct use of this feature,
+but rather to use this as a subset of aliasing.
+For example,
+an alias of the form:
+.(b
+project: :include:/usr/project/userlist
+.)b
+is a method of letting a project maintain a mailing list
+without interaction with the system administration,
+even if the alias file is protected.
+.pp
+It is not necessary to rebuild the index on the alias database
+when a :include: list is changed.
+.sh 2 "Message Collection"
+.pp
+Once all recipient addresses are parsed and verified,
+the message is collected.
+The message comes in two parts:
+a message header and a message body,
+separated by a blank line.
+.pp
+The header is formatted as a series of lines
+of the form
+.(b
+ field-name: field-value
+.)b
+Field-value can be split across lines by starting the following
+lines with a space or a tab.
+Some header fields have special internal meaning,
+and have appropriate special processing.
+Other headers are simply passed through.
+Some header fields may be added automatically,
+such as time stamps.
+.pp
+The body is a series of text lines.
+It is completely uninterpreted and untouched,
+except that lines beginning with a dot
+have the dot doubled
+when transmitted over an SMTP channel.
+This extra dot is stripped by the receiver.
+.sh 2 "Message Delivery"
+.pp
+The send queue is ordered by receiving host
+before transmission
+to implement message batching.
+Each address is marked as it is sent
+so rescanning the list is safe.
+An argument list is built as the scan proceeds.
+Mail to files is detected during the scan of the send list.
+The interface to the mailer
+is performed using one of the techniques
+described in section 2.2.
+.pp
+After a connection is established,
+.i sendmail
+makes the per-mailer changes to the header
+and sends the result to the mailer.
+If any mail is rejected by the mailer,
+a flag is set to invoke the return-to-sender function
+after all delivery completes.
+.sh 2 "Queued Messages"
+.pp
+If the mailer returns a
+.q "temporary failure"
+exit status,
+the message is queued.
+A control file is used to describe the recipients to be sent to
+and various other parameters.
+This control file is formatted as a series of lines,
+each describing a sender,
+a recipient,
+the time of submission,
+or some other salient parameter of the message.
+The header of the message is stored
+in the control file,
+so that the associated data file in the queue
+is just the temporary file that was originally collected.
+.sh 2 "Configuration"
+.pp
+Configuration is controlled primarily by a configuration file
+read at startup.
+.i Sendmail
+should not need to be recomplied except
+.np
+To change operating systems
+(V6, V7/32V, 4BSD).
+.np
+To remove or insert the DBM
+(UNIX database)
+library.
+.np
+To change ARPANET reply codes.
+.np
+To add headers fields requiring special processing.
+.lp
+Adding mailers or changing parsing
+(i.e., rewriting)
+or routing information
+does not require recompilation.
+.pp
+If the mail is being sent by a local user,
+and the file
+.q .mailcf
+exists in the sender's home directory,
+that file is read as a configuration file
+after the system configuration file.
+The primary use of this feature is to add header lines.
+.pp
+The configuration file encodes macro definitions,
+header definitions,
+mailer definitions,
+rewriting rules,
+and options.
+.sh 3 Macros
+.pp
+Macros can be used in three ways.
+Certain macros transmit
+unstructured textual information
+into the mail system,
+such as the name
+.i sendmail
+will use to identify itself in error messages.
+Other macros transmit information from
+.i sendmail
+to the configuration file
+for use in creating other fields
+(such as argument vectors to mailers);
+e.g., the name of the sender,
+and the host and user
+of the recipient.
+Other macros are unused internally,
+and can be used as shorthand in the configuration file.
+.sh 3 "Header declarations"
+.pp
+Header declarations inform
+.i sendmail
+of the format of known header lines.
+Knowledge of a few header lines
+is built into
+.i sendmail ,
+such as the
+.q From:
+and
+.q Date:
+lines.
+.pp
+Most configured headers
+will be automatically inserted
+in the outgoing message
+if they don't exist in the incoming message.
+Certain headers are suppressed by some mailers.
+.sh 3 "Mailer declarations"
+.pp
+Mailer declarations tell
+.i sendmail
+of the various mailers available to it.
+The definition specifies the internal name of the mailer,
+the pathname of the program to call,
+some flags associated with the mailer,
+and an argument vector to be used on the call;
+this vector is macro-expanded before use.
+.sh 3 "Address rewriting rules"
+.pp
+The heart of address parsing in
+.i sendmail
+is a set of rewriting rules.
+These are an ordered list of pattern-replacement rules,
+(somewhat like a production system,
+except that order is critical),
+which are applied to each address.
+The address is rewritten textually until it is either rewritten
+into a special canonical form
+(i.e.,
+a (mailer, host, user)
+3-tuple,
+such as {arpanet, usc-isif, postel}
+representing the address
+.q "postel@usc-isif" ),
+or it falls off the end.
+When a pattern matches,
+the rule is reapplied until it fails.
+.pp
+The configuration file also supports the editing of addresses
+into different formats.
+For example,
+an address of the form:
+.(b
+ucsfcgl!tef
+.)b
+might be mapped into:
+.(b
+tef@ucsfcgl.UUCP
+.)b
+to conform to the domain syntax.
+Translations can also be done in the other direction.
+.sh 3 "Option setting"
+.pp
+There are several options that can be set
+from the configuration file.
+These include the pathnames of various support files,
+timeouts,
+default modes,
+etc.
+.sh 1 "COMPARISON WITH OTHER MAILERS"
+.sh 2 "Delivermail"
+.pp
+.i Sendmail
+is an outgrowth of
+.i delivermail .
+The primary differences are:
+.np
+Configuration information is not compiled in.
+This change simplifies many of the problems
+of moving to other machines.
+It also allows easy debugging of new mailers.
+.np
+Address parsing is more flexible.
+For example,
+.i delivermail
+only supported one gateway to any network,
+whereas
+.i sendmail
+can be sensitive to host names
+and reroute to different gateways.
+.np
+Forwarding and
+:include:
+features eliminate the requirement that the system alias file
+be writable by any user
+(or that an update program be written,
+or that the system administration make all changes).
+.np
+.i Sendmail
+supports message batching across networks
+when a message is being sent to multiple recipients.
+.np
+A mail queue is provided in
+.i sendmail.
+Mail that cannot be delivered immediately
+but can potentially be delivered later
+is stored in this queue for a later retry.
+The queue also provides a buffer against system crashes;
+after the message has been collected
+it may be reliably redelivered
+even if the system crashes during the initial delivery.
+.np
+.i Sendmail
+uses the networking support provided by 4.2BSD
+to provide a direct interface networks such as the ARPANET
+and/or Ethernet
+using SMTP (the Simple Mail Transfer Protocol)
+over a TCP/IP connection.
+.sh 2 "MMDF"
+.pp
+MMDF
+[Crocker79]
+spans a wider problem set than
+.i sendmail .
+For example,
+the domain of
+MMDF includes a
+.q "phone network"
+mailer, whereas
+.i sendmail
+calls on preexisting mailers in most cases.
+.pp
+MMDF and
+.i sendmail
+both support aliasing,
+customized mailers,
+message batching,
+automatic forwarding to gateways,
+queueing,
+and retransmission.
+MMDF supports two-stage timeout,
+which
+.i sendmail
+does not support.
+.pp
+The configuration for MMDF
+is compiled into the code\**.
+.(f
+\**Dynamic configuration tables are currently being considered
+for MMDF;
+allowing the installer to select either compiled
+or dynamic tables.
+.)f
+.pp
+Since MMDF does not consider backwards compatibility
+as a design goal,
+the address parsing is simpler but much less flexible.
+.pp
+It is somewhat harder to integrate a new channel\**
+.(f
+\**The MMDF equivalent of a
+.i sendmail
+.q mailer.
+.)f
+into MMDF.
+In particular,
+MMDF must know the location and format
+of host tables for all channels,
+and the channel must speak a special protocol.
+This allows MMDF to do additional verification
+(such as verifying host names)
+at submission time.
+.pp
+MMDF strictly separates the submission and delivery phases.
+Although
+.i sendmail
+has the concept of each of these stages,
+they are integrated into one program,
+whereas in MMDF they are split into two programs.
+.sh 2 "Message Processing Module"
+.pp
+The Message Processing Module (MPM)
+discussed by Postel [Postel79b]
+matches
+.i sendmail
+closely in terms of its basic architecture.
+However,
+like MMDF,
+the MPM includes the network interface software
+as part of its domain.
+.pp
+MPM also postulates a duplex channel to the receiver,
+as does MMDF,
+thus allowing simpler handling of errors
+by the mailer
+than is possible in
+.i sendmail .
+When a message queued by
+.i sendmail
+is sent,
+any errors must be returned to the sender
+by the mailer itself.
+Both MPM and MMDF mailers
+can return an immediate error response,
+and a single error processor can create an appropriate response.
+.pp
+MPM prefers passing the message as a structured object,
+with type-length-value tuples\**.
+.(f
+\**This is similar to the NBS standard.
+.)f
+Such a convention requires a much higher degree of cooperation
+between mailers than is required by
+.i sendmail .
+MPM also assumes a universally agreed upon internet name space
+(with each address in the form of a net-host-user tuple),
+which
+.i sendmail
+does not.
+.sh 1 "EVALUATIONS AND FUTURE PLANS"
+.pp
+.i Sendmail
+is designed to work in a nonhomogeneous environment.
+Every attempt is made to avoid imposing unnecessary constraints
+on the underlying mailers.
+This goal has driven much of the design.
+One of the major problems
+has been the lack of a uniform address space,
+as postulated in [Postel79a]
+and [Postel79b].
+.pp
+A nonuniform address space implies that a path will be specified
+in all addresses,
+either explicitly (as part of the address)
+or implicitly
+(as with implied forwarding to gateways).
+This restriction has the unpleasant effect of making replying to messages
+exceedingly difficult,
+since there is no one
+.q address
+for any person,
+but only a way to get there from wherever you are.
+.pp
+Interfacing to mail programs
+that were not initially intended to be applied
+in an internet environment
+has been amazingly successful,
+and has reduced the job to a manageable task.
+.pp
+.i Sendmail
+has knowledge of a few difficult environments
+built in.
+It generates ARPANET FTP/SMTP compatible error messages
+(prepended with three-digit numbers
+[Neigus73, Postel74, Postel82])
+as necessary,
+optionally generates UNIX-style
+.q From
+lines on the front of messages for some mailers,
+and knows how to parse the same lines on input.
+Also,
+error handling has an option customized for BerkNet.
+.pp
+The decision to avoid doing any type of delivery where possible
+(even, or perhaps especially, local delivery)
+has turned out to be a good idea.
+Even with local delivery,
+there are issues of the location of the mailbox,
+the format of the mailbox,
+the locking protocol used,
+etc.,
+that are best decided by other programs.
+One surprisingly major annoyance in many internet mailers
+is that the location and format of local mail is built in.
+The feeling seems to be that local mail is so common
+that it should be efficient.
+This feeling is not born out by
+our experience;
+on the contrary,
+the location and format of mailboxes seems to vary widely
+from system to system.
+.pp
+The ability to automatically generate a response to incoming mail
+(by forwarding mail to a program)
+seems useful
+(\c
+.q "I am on vacation until late August...." )
+but can create problems
+such as forwarding loops
+(two people on vacation whose programs send notes back and forth,
+for instance)
+if these programs are not well written.
+A program could be written to do standard tasks correctly,
+but this would solve the general case.
+.pp
+It might be desirable to implement some form of load limiting.
+I am unaware of any mail system that addresses this problem,
+nor am I aware of any reasonable solution at this time.
+.pp
+The configuration file is currently practically inscrutable;
+considerable convenience could be realized
+with a higher-level format.
+.pp
+It seems clear that common protocols will be changing soon
+to accommodate changing requirements and environments.
+These changes will include modifications to the message header
+(e.g., [NBS80])
+or to the body of the message itself
+(such as for multimedia messages
+[Postel80]).
+Experience indicates that
+these changes should be relatively trivial to integrate
+into the existing system.
+.pp
+In tightly coupled environments,
+it would be nice to have a name server
+such as Grapvine
+[Birrell82]
+integrated into the mail system.
+This would allow a site such as
+.q Berkeley
+to appear as a single host,
+rather than as a collection of hosts,
+and would allow people to move transparently among machines
+without having to change their addresses.
+Such a facility
+would require an automatically updated database
+and some method of resolving conflicts.
+Ideally this would be effective even without
+all hosts being under
+a single management.
+However,
+it is not clear whether this feature
+should be integrated into the
+aliasing facility
+or should be considered a
+.q "value added"
+feature outside
+.i sendmail
+itself.
+.pp
+As a more interesting case,
+the CSNET name server
+[Solomon81]
+provides an facility that goes beyond a single
+tightly-coupled environment.
+Such a facility would normally exist outside of
+.i sendmail
+however.
+.sh 0 "ACKNOWLEDGEMENTS"
+.pp
+Thanks are due to Kurt Shoens for his continual cheerful
+assistance and good advice,
+Bill Joy for pointing me in the correct direction
+(over and over),
+and Mark Horton for more advice,
+prodding,
+and many of the good ideas.
+Kurt and Eric Schmidt are to be credited
+for using
+.i delivermail
+as a server for their programs
+(\c
+.i Mail
+and BerkNet respectively)
+before any sane person should have,
+and making the necessary modifications
+promptly and happily.
+Eric gave me considerable advice about the perils
+of network software which saved me an unknown
+amount of work and grief.
+Mark did the original implementation of the DBM version
+of aliasing, installed the VFORK code,
+wrote the current version of
+.i rmail ,
+and was the person who really convinced me
+to put the work into
+.i delivermail
+to turn it into
+.i sendmail .
+Kurt deserves accolades for using
+.i sendmail
+when I was myself afraid to take the risk;
+how a person can continue to be so enthusiastic
+in the face of so much bitter reality is beyond me.
+.pp
+Kurt,
+Mark,
+Kirk McKusick,
+Marvin Solomon,
+and many others have reviewed this paper,
+giving considerable useful advice.
+.pp
+Special thanks are reserved for Mike Stonebraker at Berkeley
+and Bob Epstein at Britton-Lee,
+who both knowingly allowed me to put so much work into this
+project
+when there were so many other things I really should
+have been working on.
+.+c
+.ce
+REFERENCES
+.nr ii 1.5i
+.ip [Birrell82]
+Birrell, A. D.,
+Levin, R.,
+Needham, R. M.,
+and
+Schroeder, M. D.,
+.q "Grapevine: An Exercise in Distributed Computing."
+In
+.ul
+Comm. A.C.M. 25,
+4,
+April 82.
+.ip [Borden79]
+Borden, S.,
+Gaines, R. S.,
+and
+Shapiro, N. Z.,
+.ul
+The MH Message Handling System: Users' Manual.
+R-2367-PAF.
+Rand Corporation.
+October 1979.
+.ip [Crocker77a]
+Crocker, D. H.,
+Vittal, J. J.,
+Pogran, K. T.,
+and
+Henderson, D. A. Jr.,
+.ul
+Standard for the Format of ARPA Network Text Messages.
+RFC 733,
+NIC 41952.
+In [Feinler78].
+November 1977.
+.ip [Crocker77b]
+Crocker, D. H.,
+.ul
+Framework and Functions of the MS Personal Message System.
+R-2134-ARPA,
+Rand Corporation,
+Santa Monica, California.
+1977.
+.ip [Crocker79]
+Crocker, D. H.,
+Szurkowski, E. S.,
+and
+Farber, D. J.,
+.ul
+An Internetwork Memo Distribution Facility \*- MMDF.
+6th Data Communication Symposium,
+Asilomar.
+November 1979.
+.ip [Crocker82]
+Crocker, D. H.,
+.ul
+Standard for the Format of Arpa Internet Text Messages.
+RFC 822.
+Network Information Center,
+SRI International,
+Menlo Park, California.
+August 1982.
+.ip [Metcalfe76]
+Metcalfe, R.,
+and
+Boggs, D.,
+.q "Ethernet: Distributed Packet Switching for Local Computer Networks" ,
+.ul
+Communications of the ACM 19,
+7.
+July 1976.
+.ip [Feinler78]
+Feinler, E.,
+and
+Postel, J.
+(eds.),
+.ul
+ARPANET Protocol Handbook.
+NIC 7104,
+Network Information Center,
+SRI International,
+Menlo Park, California.
+1978.
+.ip [NBS80]
+National Bureau of Standards,
+.ul
+Specification of a Draft Message Format Standard.
+Report No. ICST/CBOS 80-2.
+October 1980.
+.ip [Neigus73]
+Neigus, N.,
+.ul
+File Transfer Protocol for the ARPA Network.
+RFC 542, NIC 17759.
+In [Feinler78].
+August, 1973.
+.ip [Nowitz78a]
+Nowitz, D. A.,
+and
+Lesk, M. E.,
+.ul
+A Dial-Up Network of UNIX Systems.
+Bell Laboratories.
+In
+UNIX Programmer's Manual, Seventh Edition,
+Volume 2.
+August, 1978.
+.ip [Nowitz78b]
+Nowitz, D. A.,
+.ul
+Uucp Implementation Description.
+Bell Laboratories.
+In
+UNIX Programmer's Manual, Seventh Edition,
+Volume 2.
+October, 1978.
+.ip [Postel74]
+Postel, J.,
+and
+Neigus, N.,
+Revised FTP Reply Codes.
+RFC 640, NIC 30843.
+In [Feinler78].
+June, 1974.
+.ip [Postel77]
+Postel, J.,
+.ul
+Mail Protocol.
+NIC 29588.
+In [Feinler78].
+November 1977.
+.ip [Postel79a]
+Postel, J.,
+.ul
+Internet Message Protocol.
+RFC 753,
+IEN 85.
+Network Information Center,
+SRI International,
+Menlo Park, California.
+March 1979.
+.ip [Postel79b]
+Postel, J. B.,
+.ul
+An Internetwork Message Structure.
+In
+.ul
+Proceedings of the Sixth Data Communications Symposium,
+IEEE.
+New York.
+November 1979.
+.ip [Postel80]
+Postel, J. B.,
+.ul
+A Structured Format for Transmission of Multi-Media Documents.
+RFC 767.
+Network Information Center,
+SRI International,
+Menlo Park, California.
+August 1980.
+.ip [Postel82]
+Postel, J. B.,
+.ul
+Simple Mail Transfer Protocol.
+RFC821
+(obsoleting RFC788).
+Network Information Center,
+SRI International,
+Menlo Park, California.
+August 1982.
+.ip [Schmidt79]
+Schmidt, E.,
+.ul
+An Introduction to the Berkeley Network.
+University of California, Berkeley California.
+1979.
+.ip [Shoens79]
+Shoens, K.,
+.ul
+Mail Reference Manual.
+University of California, Berkeley.
+In UNIX Programmer's Manual,
+Seventh Edition,
+Volume 2C.
+December 1979.
+.ip [Sluizer81]
+Sluizer, S.,
+and
+Postel, J. B.,
+.ul
+Mail Transfer Protocol.
+RFC 780.
+Network Information Center,
+SRI International,
+Menlo Park, California.
+May 1981.
+.ip [Solomon81]
+Solomon, M., Landweber, L., and Neuhengen, D.,
+.q "The Design of the CSNET Name Server."
+CS-DN-2,
+University of Wisconsin, Madison.
+November 1981.
+.ip [Su82]
+Su, Zaw-Sing,
+and
+Postel, Jon,
+.ul
+The Domain Naming Convention for Internet User Applications.
+RFC819.
+Network Information Center,
+SRI International,
+Menlo Park, California.
+August 1982.
+.ip [UNIX83]
+.ul
+The UNIX Programmer's Manual, Seventh Edition,
+Virtual VAX-11 Version,
+Volume 1.
+Bell Laboratories,
+modified by the University of California,
+Berkeley, California.
+March, 1983.
diff --git a/usr.sbin/sendmail/doc/intro/intro.ps b/usr.sbin/sendmail/doc/intro/intro.ps
new file mode 100644
index 0000000..57c4216
--- /dev/null
+++ b/usr.sbin/sendmail/doc/intro/intro.ps
@@ -0,0 +1,1295 @@
+%!PS-Adobe-3.0
+%%Creator: groff version 1.08
+%%DocumentNeededResources: font Times-Roman
+%%+ font Times-Italic
+%%+ font Times-Bold
+%%DocumentSuppliedResources: procset grops 1.08 0
+%%Pages: 13
+%%PageOrder: Ascend
+%%Orientation: Portrait
+%%EndComments
+%%BeginProlog
+%%BeginResource: procset grops 1.08 0
+/setpacking where{
+pop
+currentpacking
+true setpacking
+}if
+/grops 120 dict dup begin
+/SC 32 def
+/A/show load def
+/B{0 SC 3 -1 roll widthshow}bind def
+/C{0 exch ashow}bind def
+/D{0 exch 0 SC 5 2 roll awidthshow}bind def
+/E{0 rmoveto show}bind def
+/F{0 rmoveto 0 SC 3 -1 roll widthshow}bind def
+/G{0 rmoveto 0 exch ashow}bind def
+/H{0 rmoveto 0 exch 0 SC 5 2 roll awidthshow}bind def
+/I{0 exch rmoveto show}bind def
+/J{0 exch rmoveto 0 SC 3 -1 roll widthshow}bind def
+/K{0 exch rmoveto 0 exch ashow}bind def
+/L{0 exch rmoveto 0 exch 0 SC 5 2 roll awidthshow}bind def
+/M{rmoveto show}bind def
+/N{rmoveto 0 SC 3 -1 roll widthshow}bind def
+/O{rmoveto 0 exch ashow}bind def
+/P{rmoveto 0 exch 0 SC 5 2 roll awidthshow}bind def
+/Q{moveto show}bind def
+/R{moveto 0 SC 3 -1 roll widthshow}bind def
+/S{moveto 0 exch ashow}bind def
+/T{moveto 0 exch 0 SC 5 2 roll awidthshow}bind def
+/SF{
+findfont exch
+[exch dup 0 exch 0 exch neg 0 0]makefont
+dup setfont
+[exch/setfont cvx]cvx bind def
+}bind def
+/MF{
+findfont
+[5 2 roll
+0 3 1 roll
+neg 0 0]makefont
+dup setfont
+[exch/setfont cvx]cvx bind def
+}bind def
+/level0 0 def
+/RES 0 def
+/PL 0 def
+/LS 0 def
+/PLG{
+gsave newpath clippath pathbbox grestore
+exch pop add exch pop
+}bind def
+/BP{
+/level0 save def
+1 setlinecap
+1 setlinejoin
+72 RES div dup scale
+LS{
+90 rotate
+}{
+0 PL translate
+}ifelse
+1 -1 scale
+}bind def
+/EP{
+level0 restore
+showpage
+}bind def
+/DA{
+newpath arcn stroke
+}bind def
+/SN{
+transform
+.25 sub exch .25 sub exch
+round .25 add exch round .25 add exch
+itransform
+}bind def
+/DL{
+SN
+moveto
+SN
+lineto stroke
+}bind def
+/DC{
+newpath 0 360 arc closepath
+}bind def
+/TM matrix def
+/DE{
+TM currentmatrix pop
+translate scale newpath 0 0 .5 0 360 arc closepath
+TM setmatrix
+}bind def
+/RC/rcurveto load def
+/RL/rlineto load def
+/ST/stroke load def
+/MT/moveto load def
+/CL/closepath load def
+/FL{
+currentgray exch setgray fill setgray
+}bind def
+/BL/fill load def
+/LW/setlinewidth load def
+/RE{
+findfont
+dup maxlength 1 index/FontName known not{1 add}if dict begin
+{
+1 index/FID ne{def}{pop pop}ifelse
+}forall
+/Encoding exch def
+dup/FontName exch def
+currentdict end definefont pop
+}bind def
+/DEFS 0 def
+/EBEGIN{
+moveto
+DEFS begin
+}bind def
+/EEND/end load def
+/CNT 0 def
+/level1 0 def
+/PBEGIN{
+/level1 save def
+translate
+div 3 1 roll div exch scale
+neg exch neg exch translate
+0 setgray
+0 setlinecap
+1 setlinewidth
+0 setlinejoin
+10 setmiterlimit
+[]0 setdash
+/setstrokeadjust where{
+pop
+false setstrokeadjust
+}if
+/setoverprint where{
+pop
+false setoverprint
+}if
+newpath
+/CNT countdictstack def
+userdict begin
+/showpage{}def
+}bind def
+/PEND{
+clear
+countdictstack CNT sub{end}repeat
+level1 restore
+}bind def
+end def
+/setpacking where{
+pop
+setpacking
+}if
+%%EndResource
+%%IncludeResource: font Times-Roman
+%%IncludeResource: font Times-Italic
+%%IncludeResource: font Times-Bold
+grops begin/DEFS 1 dict def DEFS begin/u{.001 mul}bind def end/RES 72 def/PL
+792 def/LS false def/ENC0[/asciicircum/asciitilde/Scaron/Zcaron/scaron/zcaron
+/Ydieresis/trademark/quotesingle/.notdef/.notdef/.notdef/.notdef/.notdef
+/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef
+/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/space
+/exclam/quotedbl/numbersign/dollar/percent/ampersand/quoteright/parenleft
+/parenright/asterisk/plus/comma/hyphen/period/slash/zero/one/two/three/four
+/five/six/seven/eight/nine/colon/semicolon/less/equal/greater/question/at/A/B/C
+/D/E/F/G/H/I/J/K/L/M/N/O/P/Q/R/S/T/U/V/W/X/Y/Z/bracketleft/backslash
+/bracketright/circumflex/underscore/quoteleft/a/b/c/d/e/f/g/h/i/j/k/l/m/n/o/p/q
+/r/s/t/u/v/w/x/y/z/braceleft/bar/braceright/tilde/.notdef/quotesinglbase
+/guillemotleft/guillemotright/bullet/florin/fraction/perthousand/dagger
+/daggerdbl/endash/emdash/ff/fi/fl/ffi/ffl/dotlessi/dotlessj/grave/hungarumlaut
+/dotaccent/breve/caron/ring/ogonek/quotedblleft/quotedblright/oe/lslash
+/quotedblbase/OE/Lslash/.notdef/exclamdown/cent/sterling/currency/yen/brokenbar
+/section/dieresis/copyright/ordfeminine/guilsinglleft/logicalnot/minus
+/registered/macron/degree/plusminus/twosuperior/threesuperior/acute/mu
+/paragraph/periodcentered/cedilla/onesuperior/ordmasculine/guilsinglright
+/onequarter/onehalf/threequarters/questiondown/Agrave/Aacute/Acircumflex/Atilde
+/Adieresis/Aring/AE/Ccedilla/Egrave/Eacute/Ecircumflex/Edieresis/Igrave/Iacute
+/Icircumflex/Idieresis/Eth/Ntilde/Ograve/Oacute/Ocircumflex/Otilde/Odieresis
+/multiply/Oslash/Ugrave/Uacute/Ucircumflex/Udieresis/Yacute/Thorn/germandbls
+/agrave/aacute/acircumflex/atilde/adieresis/aring/ae/ccedilla/egrave/eacute
+/ecircumflex/edieresis/igrave/iacute/icircumflex/idieresis/eth/ntilde/ograve
+/oacute/ocircumflex/otilde/odieresis/divide/oslash/ugrave/uacute/ucircumflex
+/udieresis/yacute/thorn/ydieresis]def/Times-Bold@0 ENC0/Times-Bold RE
+/Times-Italic@0 ENC0/Times-Italic RE/Times-Roman@0 ENC0/Times-Roman RE
+%%EndProlog
+%%Page: 1 1
+%%BeginPageSetup
+BP
+%%EndPageSetup
+/F0 14/Times-Roman@0 SF(SENDMAIL \212 An Internetw)159.172 141 Q
+(ork Mail Router)-.14 E/F1 10/Times-Roman@0 SF(Eric Allman*)260.92 165 Q/F2 10
+/Times-Italic@0 SF(Univer)220.2 183 Q(sity of California, Berk)-.1 E(ele)-.1 E
+(y)-.3 E(Mammoth Pr)251.98 195 Q(oject)-.45 E F1(ABSTRA)262.085 227.4 Q(CT)-.4
+E 1.41(Routing mail through a heterogenous internet presents man)112 243.6 R
+3.91(yn)-.15 G 1.91 -.25(ew p)372.55 243.6 T 3.91(roblems. Among).25 F .297
+(the w)112 255.6 R .297(orst of these is that of address mapping.)-.1 F
+(Historically)5.297 E 2.797(,t)-.65 G .298(his has been handled on an)355.03
+255.6 R F2(ad hoc)112 267.6 Q F1 2.5(basis. Ho)2.5 F(we)-.25 E -.15(ve)-.25 G
+.8 -.4(r, t).15 H(his approach has become unmanageable as internets gro).4 E
+-.65(w.)-.25 G .15(Sendmail acts a uni\214ed "post of)112 283.8 R .15
+(\214ce" to which all mail can be submitted.)-.25 F .15(Address inter)5.15 F(-)
+-.2 E .426(pretation is controlled by a production system, which can parse bot\
+h domain-based ad-)112 295.8 R .423(dressing and old-style)112 307.8 R F2 .423
+(ad hoc)2.923 F F1 2.923(addresses. The)2.923 F .422(production system is po)
+2.922 F .422(werful enough to)-.25 F(re)112 319.8 Q 1.357(write addresses in t\
+he message header to conform to the standards of a number of)-.25 F 1.15
+(common tar)112 331.8 R 1.15(get netw)-.18 F 1.15
+(orks, including old \(NCP/RFC733\) Arpanet, ne)-.1 F 3.65(w\()-.25 G
+(TCP/RFC822\))405.65 331.8 Q 1.119(Arpanet, UUCP)112 343.8 R 3.619(,a)-1.11 G
+1.119(nd Phonenet.)186.448 343.8 R 1.119(Sendmail also implements an SMTP serv)
+6.119 F(er)-.15 E 3.619(,m)-.4 G(essage)437.9 343.8 Q(queueing, and aliasing.)
+112 355.8 Q F2(Sendmail)97 400.2 Q F1 .501(implements a general internetw)3 F
+.501(ork mail routing f)-.1 F(acility)-.1 E 3.001(,f)-.65 G .501
+(eaturing aliasing and forw)369.847 400.2 R(arding,)-.1 E
+(automatic routing to netw)72 412.2 Q(ork g)-.1 E(ate)-.05 E -.1(wa)-.25 G
+(ys, and \215e).1 E(xible con\214guration.)-.15 E .624(In a simple netw)97
+428.4 R .624(ork, each node has an address, and resources can be identi\214ed \
+with a host-resource)-.1 F .374(pair; in particular)72 440.4 R 2.874(,t)-.4 G
+.374(he mail system can refer to users using a host-username pair)149.932 440.4
+R 5.374(.H)-.55 G .375(ost names and numbers)409.276 440.4 R(ha)72 452.4 Q .3
+-.15(ve t)-.2 H 2.5(ob).15 G 2.5(ea)108.31 452.4 S
+(dministered by a central authority)119.69 452.4 Q 2.5(,b)-.65 G
+(ut usernames can be assigned locally to each host.)263.82 452.4 Q .649
+(In an internet, multiple netw)97 468.6 R .649(orks with dif)-.1 F .649
+(ferent characterstics and managements must communicate.)-.25 F .389
+(In particular)72 480.6 R 2.889(,t)-.4 G .389
+(he syntax and semantics of resource identi\214cation change.)129.308 480.6 R
+.39(Certain special cases can be han-)5.389 F 1.033(dled tri)72 492.6 R 1.033
+(vially by)-.25 F F2 1.033(ad hoc)3.533 F F1 1.032(techniques, such as pro)
+3.533 F 1.032(viding netw)-.15 F 1.032
+(ork names that appear local to hosts on other)-.1 F(netw)72 504.6 Q 1.454
+(orks, as with the Ethernet at Xerox P)-.1 F 3.955(ARC. Ho)-.92 F(we)-.25 E
+-.15(ve)-.25 G 4.755 -.4(r, t).15 H 1.455(he general case is e).4 F 1.455
+(xtremely comple)-.15 F 3.955(x. F)-.15 F(or)-.15 E -.15(ex)72 516.6 S .192
+(ample, some netw).15 F .192(orks require point-to-point routing, which simpli\
+\214es the database update problem since)-.1 F .618(only adjacent hosts must b\
+e entered into the system tables, while others use end-to-end addressing.)72
+528.6 R(Some)5.618 E(netw)72 540.6 Q .123(orks use a left-associati)-.1 F .423
+-.15(ve s)-.25 H .123(yntax and others use a right-associati).15 F .423 -.15
+(ve s)-.25 H .123(yntax, causing ambiguity in mix).15 F(ed)-.15 E(addresses.)72
+552.6 Q .678(Internet standards seek to eliminate these problems.)97 568.8 R
+(Initially)5.678 E 3.178(,t)-.65 G .679(hese proposed e)353.134 568.8 R .679
+(xpanding the address)-.15 F .65(pairs to address triples, consisting of {netw)
+72 580.8 R .649(ork, host, resource} triples.)-.1 F(Netw)5.649 E .649
+(ork numbers must be uni)-.1 F -.15(ve)-.25 G -.2(r-).15 G 1.452
+(sally agreed upon, and hosts can be assigned locally on each netw)72 592.8 R
+3.952(ork. The)-.1 F(user)3.952 E(-le)-.2 E -.15(ve)-.25 G 3.952(lp).15 G 1.452
+(resentation w)440.718 592.8 R(as)-.1 E 2.352(quickly e)72 604.8 R 2.352(xpand\
+ed to address domains, comprised of a local resource identi\214cation and a hi\
+erarchical)-.15 F .256(domain speci\214cation with a common static root.)72
+616.8 R .257(The domain technique separates the issue of ph)5.257 F .257
+(ysical v)-.05 F(er)-.15 E(-)-.2 E .807(sus logical addressing.)72 628.8 R -.15
+(Fo)5.807 G 3.307(re).15 G .807
+(xample, an address of the form \231eric@a.cc.berk)191.028 628.8 R(ele)-.1 E
+-.65(y.)-.15 G .807(arpa\232 describes only the).65 F(logical or)72 640.8 Q
+-.05(ga)-.18 G(nization of the address space.).05 E F2(Sendmail)97 657 Q F1
+.493(is intended to help bridge the g)2.992 F .493(ap between the totally)-.05
+F F2 .493(ad hoc)2.993 F F1 -.1(wo)2.993 G .493(rld of netw).1 F .493
+(orks that kno)-.1 F(w)-.25 E .855
+(nothing of each other and the clean, tightly-coupled w)72 669 R .854
+(orld of unique netw)-.1 F .854(ork numbers.)-.1 F .854(It can accept old)5.854
+F .32 LW 76 678.6 72 678.6 DL 80 678.6 76 678.6 DL 84 678.6 80 678.6 DL 88
+678.6 84 678.6 DL 92 678.6 88 678.6 DL 96 678.6 92 678.6 DL 100 678.6 96 678.6
+DL 104 678.6 100 678.6 DL 108 678.6 104 678.6 DL 112 678.6 108 678.6 DL 116
+678.6 112 678.6 DL 120 678.6 116 678.6 DL 124 678.6 120 678.6 DL 128 678.6 124
+678.6 DL 132 678.6 128 678.6 DL 136 678.6 132 678.6 DL 140 678.6 136 678.6 DL
+144 678.6 140 678.6 DL 148 678.6 144 678.6 DL 152 678.6 148 678.6 DL 156 678.6
+152 678.6 DL 160 678.6 156 678.6 DL 164 678.6 160 678.6 DL 168 678.6 164 678.6
+DL 172 678.6 168 678.6 DL 176 678.6 172 678.6 DL 180 678.6 176 678.6 DL 184
+678.6 180 678.6 DL 188 678.6 184 678.6 DL 192 678.6 188 678.6 DL 196 678.6 192
+678.6 DL 200 678.6 196 678.6 DL 204 678.6 200 678.6 DL 208 678.6 204 678.6 DL
+212 678.6 208 678.6 DL 216 678.6 212 678.6 DL/F3 8/Times-Roman@0 SF .557
+(*A considerable part of this w)93.6 690.6 R .557(ork w)-.08 F .557
+(as done while under the emplo)-.08 F 2.557(yo)-.08 G 2.556(ft)323.116 690.6 S
+.556(he INGRES Project at the Uni)330.56 690.6 R -.12(ve)-.2 G .556
+(rsity of California at).12 F(Berk)72 700.2 Q(ele)-.08 E 2(ya)-.12 G
+(nd at Britton Lee.)106.232 700.2 Q/F4 10/Times-Bold@0 SF
+(SENDMAIL \212 An Inter)72 756 Q(netw)-.15 E(ork Mail Router)-.1 E(SMM:9-1)
+462.9 756 Q EP
+%%Page: 2 2
+%%BeginPageSetup
+BP
+%%EndPageSetup
+/F0 10/Times-Bold@0 SF 192.28(SMM:9-2 SENDMAIL)72 60 R 2.5<8a41>2.5 G 2.5(nI)
+383.99 60 S(nter)395.94 60 Q(netw)-.15 E(ork Mail Router)-.1 E/F1 10
+/Times-Roman@0 SF .632(arbitrary address syntax)72 96 R .633(es, resolving amb\
+iguities using heuristics speci\214ed by the system administrator)-.15 F 3.133
+(,a)-.4 G(s)500.11 96 Q .348(well as domain-based addressing.)72 108 R .347
+(It helps guide the con)5.347 F -.15(ve)-.4 G .347
+(rsion of message formats between disparate net-).15 F -.1(wo)72 120 S 3.394
+(rks. In).1 F(short,)3.394 E/F2 10/Times-Italic@0 SF(sendmail)3.394 E F1 .894
+(is designed to assist a graceful transition to consistent internetw)3.394 F
+.895(ork addressing)-.1 F(schemes.)72 132 Q .153
+(Section 1 discusses the design goals for)97 160.2 R F2(sendmail)2.653 E F1
+5.153(.S)C .152(ection 2 gi)308.214 160.2 R -.15(ve)-.25 G 2.652(sa).15 G 2.652
+(no)370.76 160.2 S -.15(ve)383.262 160.2 S(rvie).15 E 2.652(wo)-.25 G 2.652(ft)
+422.724 160.2 S .152(he basic functions)431.486 160.2 R .644(of the system.)72
+172.2 R .644(In section 3, details of usage are discussed.)5.644 F .644
+(Section 4 compares)5.644 F F2(sendmail)3.144 E F1 .645(to other internet)3.144
+F(mail routers, and an e)72 184.2 Q -.25(va)-.25 G(luation of).25 E F2
+(sendmail)2.5 E F1(is gi)2.5 E -.15(ve)-.25 G 2.5(ni).15 G 2.5(ns)283.3 184.2 S
+(ection 5, including future plans.)294.69 184.2 Q F0 2.5(1. DESIGN)72 208.2 R
+(GO)2.5 E(ALS)-.4 E F1(Design goals for)112 224.4 Q F2(sendmail)2.5 E F1
+(include:)2.5 E 12.5(\(1\) Compatibility)92 240.6 R 1.363(with the e)3.864 F
+1.363(xisting mail programs, including Bell v)-.15 F 1.363
+(ersion 6 mail, Bell v)-.15 F 1.363(ersion 7)-.15 F 1.202(mail [UNIX83], Berk)
+118.66 252.6 R(ele)-.1 E(y)-.15 E F2(Mail)3.702 E F1 1.202
+([Shoens79], BerkNet mail [Schmidt79], and hopefully UUCP)3.702 F(mail [No)
+118.66 264.6 Q(witz78a, No)-.25 E 2.5(witz78b]. ARP)-.25 F(ANET mail [Crock)
+-.92 E(er77a, Postel77] w)-.1 E(as also required.)-.1 E 12.5(\(2\) Reliability)
+92 280.8 R 4.003(,i)-.65 G 4.003(nt)169.523 280.8 S 1.502
+(he sense of guaranteeing that e)181.306 280.8 R -.15(ve)-.25 G 1.502
+(ry message is correctly deli).15 F -.15(ve)-.25 G 1.502(red or at least).15 F
+.368
+(brought to the attention of a human for correct disposal; no message should e)
+118.66 292.8 R -.15(ve)-.25 G 2.868(rb).15 G 2.868(ec)452.252 292.8 S
+(ompletely)464 292.8 Q 2.541(lost. This)118.66 304.8 R .041(goal w)2.541 F .041
+(as considered essential because of the emphasis on mail in our en)-.1 F 2.54
+(vironment. It)-.4 F 1.754
+(has turned out to be one of the hardest goals to satisfy)118.66 316.8 R 4.255
+(,e)-.65 G 1.755(specially in the f)363.75 316.8 R 1.755(ace of the man)-.1 F
+(y)-.15 E .978(anomalous message formats produced by v)118.66 328.8 R .977
+(arious ARP)-.25 F .977(ANET sites.)-.92 F -.15(Fo)5.977 G 3.477(re).15 G .977
+(xample, certain sites)420.116 328.8 R .069
+(generate improperly formated addresses, occasionally causing error)118.66
+340.8 R .069(-message loops.)-.2 F .069(Some hosts)5.069 F .063(use blanks in \
+names, causing problems with UNIX mail programs that assume that an address is)
+118.66 352.8 R .111(one w)118.66 364.8 R 2.611(ord. The)-.1 F .111
+(semantics of some \214elds are interpreted slightly dif)2.611 F .112
+(ferently by dif)-.25 F .112(ferent sites.)-.25 F(In)5.112 E(summary)118.66
+376.8 Q 3.023(,t)-.65 G .523(he obscure features of the ARP)163.533 376.8 R
+.523(ANET mail protocol really)-.92 F F2(ar)3.023 E(e)-.37 E F1 .522
+(used and are dif)3.023 F(\214cult)-.25 E(to support, b)118.66 388.8 Q
+(ut must be supported.)-.2 E 12.5(\(3\) Existing)92 405 R(softw)2.938 E .438
+(are to do actual deli)-.1 F -.15(ve)-.25 G .439(ry should be used whene).15 F
+-.15(ve)-.25 G 2.939(rp).15 G 2.939(ossible. This)387.654 405 R .439(goal deri)
+2.939 F -.15(ve)-.25 G 2.939(sa).15 G(s)500.11 405 Q
+(much from political and practical considerations as technical.)118.66 417 Q
+12.5(\(4\) Easy)92 433.2 R -.15(ex)2.899 G .399(pansion to f).15 F .399
+(airly comple)-.1 F 2.898(xe)-.15 G -.4(nv)261.064 433.2 S .398
+(ironments, including multiple connections to a single net-).4 F -.1(wo)118.66
+445.2 S .115
+(rk type \(such as with multiple UUCP or Ether nets [Metcalfe76]\).).1 F .115
+(This goal requires consid-)5.115 F .587(eration of the contents of an address\
+ as well as its syntax in order to determine which g)118.66 457.2 R(ate)-.05 E
+-.1(wa)-.25 G(y).1 E 1.018(to use.)118.66 469.2 R -.15(Fo)6.018 G 3.518(re).15
+G 1.018(xample, the ARP)173.354 469.2 R 1.019
+(ANET is bringing up the TCP protocol to replace the old NCP)-.92 F 4.791
+(protocol. No)118.66 481.2 R 2.291(host at Berk)4.791 F(ele)-.1 E 4.791(yr)-.15
+G 2.291(uns both TCP and NCP)256.235 481.2 R 4.791(,s)-1.11 G 4.79(oi)369.37
+481.2 S 4.79(ti)381.94 481.2 S 4.79(sn)392.29 481.2 S 2.29
+(ecessary to look at the)405.97 481.2 R(ARP)118.66 493.2 Q .016
+(ANET host name to determine whether to route mail to an NCP g)-.92 F(ate)-.05
+E -.1(wa)-.25 G 2.517(yo).1 G 2.517(raT)435.569 493.2 S .017(CP g)454.483 493.2
+R(ate)-.05 E -.1(wa)-.25 G -.65(y.).1 G 12.5(\(5\) Con\214guration)92 509.4 R
+.145(should not be compiled into the code.)2.645 F 2.645(As)5.145 G .145
+(ingle compiled program should be able)346.905 509.4 R .91(to run as is at an)
+118.66 521.4 R 3.41(ys)-.15 G .91
+(ite \(barring such basic changes as the CPU type or the operating system\).)
+200.63 521.4 R 2.61 -.8(We h)118.66 533.4 T -2.25 -.2(av e).8 H 1.009
+(found this seemingly unimportant goal to be critical in real life.)3.71 F
+1.009(Besides the simple)6.009 F .66(problems that occur when an)118.66 545.4 R
+3.16(yp)-.15 G .66(rogram gets recompiled in a dif)249.84 545.4 R .66
+(ferent en)-.25 F .66(vironment, man)-.4 F 3.16(ys)-.15 G(ites)490.11 545.4 Q
+(lik)118.66 557.4 Q 2.5(et)-.1 G 2.5<6f99>138.84 557.4 S(\214ddle\232 with an)
+150.78 557.4 Q(ything that the)-.15 E 2.5(yw)-.15 G(ill be recompiling an)
+282.42 557.4 Q(yw)-.15 E(ay)-.1 E(.)-.65 E(\(6\))92 573.6 Q F2(Sendmail)118.66
+573.6 Q F1 .184(must be able to let v)2.684 F .184
+(arious groups maintain their o)-.25 F .184(wn mailing lists, and let indi)-.25
+F(viduals)-.25 E(specify their o)118.66 585.6 Q(wn forw)-.25 E
+(arding, without modifying the system alias \214le.)-.1 E 12.5(\(7\) Each)92
+601.8 R .313(user should be able to specify which mailer to e)2.813 F -.15(xe)
+-.15 G .313(cute to process mail being deli).15 F -.15(ve)-.25 G .314(red for)
+.15 F 3.098(him. This)118.66 613.8 R .598(feature allo)3.098 F .598
+(ws users who are using specialized mailers that use a dif)-.25 F .598
+(ferent format to)-.25 F -.2(bu)118.66 625.8 S .25(ild their en).2 F .25
+(vironment without changing the system, and f)-.4 F .25
+(acilitates specialized functions \(such)-.1 F(as returning an \231I am on v)
+118.66 637.8 Q(acation\232 message\).)-.25 E 12.5(\(8\) Netw)92 654 R 1.553
+(ork traf)-.1 F 1.552(\214c should be minimized by batching addresses to a sin\
+gle host where possible,)-.25 F(without assistance from the user)118.66 666 Q
+(.)-.55 E .374(These goals moti)112 682.2 R -.25(va)-.25 G .374
+(ted the architecture illustrated in \214gure 1.).25 F .375
+(The user interacts with a mail gen-)5.375 F .491(erating and sending program.)
+87 694.2 R .491(When the mail is created, the generator calls)5.491 F F2
+(sendmail)2.99 E F1 2.99(,w)C .49(hich routes the)444.14 694.2 R .84
+(message to the correct mailer\(s\).)87 706.2 R .841
+(Since some of the senders may be netw)5.84 F .841(ork serv)-.1 F .841
+(ers and some of the)-.15 F(mailers may be netw)87 718.2 Q(ork clients,)-.1 E
+F2(sendmail)2.5 E F1(may be used as an internet mail g)2.5 E(ate)-.05 E -.1(wa)
+-.25 G -.65(y.).1 G EP
+%%Page: 3 3
+%%BeginPageSetup
+BP
+%%EndPageSetup
+/F0 10/Times-Bold@0 SF(SENDMAIL \212 An Inter)72 60 Q(netw)-.15 E
+(ork Mail Router)-.1 E(SMM:9-3)462.9 60 Q .4 LW 77 108 72 108 DL 79 108 74 108
+DL 84 108 79 108 DL 89 108 84 108 DL 94 108 89 108 DL 99 108 94 108 DL 104 108
+99 108 DL 109 108 104 108 DL 114 108 109 108 DL 119 108 114 108 DL 124 108 119
+108 DL 129 108 124 108 DL 134 108 129 108 DL 139 108 134 108 DL 144 108 139 108
+DL 149 108 144 108 DL 154 108 149 108 DL 159 108 154 108 DL 164 108 159 108 DL
+169 108 164 108 DL 174 108 169 108 DL 179 108 174 108 DL 184 108 179 108 DL 189
+108 184 108 DL 194 108 189 108 DL 199 108 194 108 DL 204 108 199 108 DL 209 108
+204 108 DL 214 108 209 108 DL 219 108 214 108 DL 224 108 219 108 DL 229 108 224
+108 DL 234 108 229 108 DL 239 108 234 108 DL 244 108 239 108 DL 249 108 244 108
+DL 254 108 249 108 DL 259 108 254 108 DL 264 108 259 108 DL 269 108 264 108 DL
+274 108 269 108 DL 279 108 274 108 DL 284 108 279 108 DL 289 108 284 108 DL 294
+108 289 108 DL 299 108 294 108 DL 304 108 299 108 DL 309 108 304 108 DL 314 108
+309 108 DL 319 108 314 108 DL 324 108 319 108 DL 329 108 324 108 DL 334 108 329
+108 DL 339 108 334 108 DL 344 108 339 108 DL 349 108 344 108 DL 354 108 349 108
+DL 359 108 354 108 DL 364 108 359 108 DL 369 108 364 108 DL 374 108 369 108 DL
+379 108 374 108 DL 384 108 379 108 DL 389 108 384 108 DL 394 108 389 108 DL 399
+108 394 108 DL 404 108 399 108 DL 409 108 404 108 DL 414 108 409 108 DL 419 108
+414 108 DL 424 108 419 108 DL 429 108 424 108 DL 434 108 429 108 DL 439 108 434
+108 DL 444 108 439 108 DL 449 108 444 108 DL 454 108 449 108 DL 459 108 454 108
+DL 464 108 459 108 DL 469 108 464 108 DL 474 108 469 108 DL 479 108 474 108 DL
+484 108 479 108 DL 489 108 484 108 DL 494 108 489 108 DL 499 108 494 108 DL 504
+108 499 108 DL/F1 10/Times-Roman@0 SF(sender1)164.45 155.6 Q 144 135.6 144
+171.6 DL 216 135.6 144 135.6 DL 216 171.6 216 135.6 DL 144 171.6 216 171.6 DL
+(sender2)272.45 155.6 Q 252 135.6 252 171.6 DL 324 135.6 252 135.6 DL 324 171.6
+324 135.6 DL 252 171.6 324 171.6 DL(sender3)380.45 155.6 Q 360 135.6 360 171.6
+DL 432 135.6 360 135.6 DL 432 171.6 432 135.6 DL 360 171.6 432 171.6 DL 288
+207.6 288 171.6 DL 288 207.6 286.2 200.4 DL 288 207.6 289.8 200.4 DL(sendmail)
+269.945 227.6 Q 216 207.6 216 243.6 DL 360 207.6 216 207.6 DL 360 243.6 360
+207.6 DL 216 243.6 360 243.6 DL 288 279.6 288 243.6 DL 288 279.6 286.2 272.4 DL
+288 279.6 289.8 272.4 DL(mailer1)164.725 299.6 Q 144 279.6 144 315.6 DL 216
+279.6 144 279.6 DL 216 315.6 216 279.6 DL 144 315.6 216 315.6 DL(mailer2)
+272.725 299.6 Q 252 279.6 252 315.6 DL 324 279.6 252 279.6 DL 324 315.6 324
+279.6 DL 252 315.6 324 315.6 DL(mailer3)380.725 299.6 Q 360 279.6 360 315.6 DL
+432 279.6 360 279.6 DL 432 315.6 432 279.6 DL 360 315.6 432 315.6 DL 252 207.6
+180 171.6 DL 252 207.6 244.728 206.016 DL 252 207.6 246.384 202.776 DL 324
+207.6 396 171.6 DL 324 207.6 329.616 202.776 DL 324 207.6 331.272 206.016 DL
+180 279.6 252 243.6 DL 180 279.6 185.616 274.776 DL 180 279.6 187.272 278.016
+DL 396 279.6 324 243.6 DL 396 279.6 388.728 278.016 DL 396 279.6 390.384
+274.776 DL(Figure 1 \212 Sendmail System Structure.)208 346.8 Q 77 358.8 72
+358.8 DL 79 358.8 74 358.8 DL 84 358.8 79 358.8 DL 89 358.8 84 358.8 DL 94
+358.8 89 358.8 DL 99 358.8 94 358.8 DL 104 358.8 99 358.8 DL 109 358.8 104
+358.8 DL 114 358.8 109 358.8 DL 119 358.8 114 358.8 DL 124 358.8 119 358.8 DL
+129 358.8 124 358.8 DL 134 358.8 129 358.8 DL 139 358.8 134 358.8 DL 144 358.8
+139 358.8 DL 149 358.8 144 358.8 DL 154 358.8 149 358.8 DL 159 358.8 154 358.8
+DL 164 358.8 159 358.8 DL 169 358.8 164 358.8 DL 174 358.8 169 358.8 DL 179
+358.8 174 358.8 DL 184 358.8 179 358.8 DL 189 358.8 184 358.8 DL 194 358.8 189
+358.8 DL 199 358.8 194 358.8 DL 204 358.8 199 358.8 DL 209 358.8 204 358.8 DL
+214 358.8 209 358.8 DL 219 358.8 214 358.8 DL 224 358.8 219 358.8 DL 229 358.8
+224 358.8 DL 234 358.8 229 358.8 DL 239 358.8 234 358.8 DL 244 358.8 239 358.8
+DL 249 358.8 244 358.8 DL 254 358.8 249 358.8 DL 259 358.8 254 358.8 DL 264
+358.8 259 358.8 DL 269 358.8 264 358.8 DL 274 358.8 269 358.8 DL 279 358.8 274
+358.8 DL 284 358.8 279 358.8 DL 289 358.8 284 358.8 DL 294 358.8 289 358.8 DL
+299 358.8 294 358.8 DL 304 358.8 299 358.8 DL 309 358.8 304 358.8 DL 314 358.8
+309 358.8 DL 319 358.8 314 358.8 DL 324 358.8 319 358.8 DL 329 358.8 324 358.8
+DL 334 358.8 329 358.8 DL 339 358.8 334 358.8 DL 344 358.8 339 358.8 DL 349
+358.8 344 358.8 DL 354 358.8 349 358.8 DL 359 358.8 354 358.8 DL 364 358.8 359
+358.8 DL 369 358.8 364 358.8 DL 374 358.8 369 358.8 DL 379 358.8 374 358.8 DL
+384 358.8 379 358.8 DL 389 358.8 384 358.8 DL 394 358.8 389 358.8 DL 399 358.8
+394 358.8 DL 404 358.8 399 358.8 DL 409 358.8 404 358.8 DL 414 358.8 409 358.8
+DL 419 358.8 414 358.8 DL 424 358.8 419 358.8 DL 429 358.8 424 358.8 DL 434
+358.8 429 358.8 DL 439 358.8 434 358.8 DL 444 358.8 439 358.8 DL 449 358.8 444
+358.8 DL 454 358.8 449 358.8 DL 459 358.8 454 358.8 DL 464 358.8 459 358.8 DL
+469 358.8 464 358.8 DL 474 358.8 469 358.8 DL 479 358.8 474 358.8 DL 484 358.8
+479 358.8 DL 489 358.8 484 358.8 DL 494 358.8 489 358.8 DL 499 358.8 494 358.8
+DL 504 358.8 499 358.8 DL F0 2.5(2. O)72 394.8 R(VER)-.5 E(VIEW)-.55 E 2.5
+(2.1. System)87 418.8 R(Or)2.5 E(ganization)-.1 E/F2 10/Times-Italic@0 SF
+(Sendmail)127 435 Q F1 .874(neither interf)3.374 F .874
+(aces with the user nor does actual mail deli)-.1 F -.15(ve)-.25 G(ry).15 E
+5.873(.R)-.65 G(ather)431.241 435 Q 3.373(,i)-.4 G 3.373(tc)459.484 435 S .873
+(ollects a)470.077 435 R .619(message generated by a user interf)102 447 R .619
+(ace program \(UIP\) such as Berk)-.1 F(ele)-.1 E(y)-.15 E F2(Mail)3.12 E F1
+3.12(,M)C 3.12(S[)427.6 447 S(Crock)439.61 447 Q .62(er77b], or)-.1 F 1.428
+(MH [Borden79], edits the message as required by the destination netw)102 459 R
+1.427(ork, and calls appropriate)-.1 F .28(mailers to do mail deli)102 473 R
+-.15(ve)-.25 G .281(ry or queueing for netw).15 F .281(ork transmission)-.1 F
+/F3 7/Times-Roman@0 SF(1)364.275 469 Q F1 5.281(.T)367.775 473 S .281
+(his discipline allo)381.666 473 R .281(ws the inser)-.25 F(-)-.2 E 1.354
+(tion of ne)102 485 R 3.854(wm)-.25 G 1.354(ailers at minimum cost.)161.642 485
+R 1.354(In this sense)6.354 F F2(sendmail)3.853 E F1 1.353
+(resembles the Message Processing)3.853 F(Module \(MPM\) of [Postel79b].)102
+497 Q F0 2.5(2.2. Interfaces)87 521 R(to the Outside W)2.5 E(orld)-.75 E F1
+.041(There are three w)127 537.2 R(ays)-.1 E F2(sendmail)2.541 E F1 .041
+(can communicate with the outside w)2.541 F .042(orld, both in recei)-.1 F .042
+(ving and)-.25 F 1.195(in sending mail.)102 549.2 R 1.194
+(These are using the con)6.194 F -.15(ve)-.4 G 1.194(ntional UNIX ar).15 F
+1.194(gument v)-.18 F 1.194(ector/return status, speaking)-.15 F(SMTP o)102
+561.2 Q -.15(ve)-.15 G 2.5(rap).15 G(air of UNIX pipes, and speaking SMTP o)
+162.53 561.2 Q -.15(ve)-.15 G 2.5(ra).15 G 2.5(ni)348.03 561.2 S
+(nterprocess\(or\) channel.)358.31 561.2 Q F0 2.5(2.2.1. Ar)102 585.2 R
+(gument v)-.1 E(ector/exit status)-.1 E F1 .52(This technique is the standard \
+UNIX method for communicating with the process.)142 601.4 R 3.02(Al)5.52 G(ist)
+494.55 601.4 Q .442(of recipients is sent in the ar)117 613.4 R .441(gument v)
+-.18 F(ector)-.15 E 2.941(,a)-.4 G .441
+(nd the message body is sent on the standard input.)299.491 613.4 R(An)117
+625.4 Q .351(ything that the mailer prints is simply collected and sent back t\
+o the sender if there were an)-.15 F(y)-.15 E 2.621(problems. The)117 637.4 R
+-.15(ex)2.621 G .121(it status from the mailer is collected after the message \
+is sent, and a diagnostic).15 F(is printed if appropriate.)117 649.4 Q .32 LW
+76 678.8 72 678.8 DL 80 678.8 76 678.8 DL 84 678.8 80 678.8 DL 88 678.8 84
+678.8 DL 92 678.8 88 678.8 DL 96 678.8 92 678.8 DL 100 678.8 96 678.8 DL 104
+678.8 100 678.8 DL 108 678.8 104 678.8 DL 112 678.8 108 678.8 DL 116 678.8 112
+678.8 DL 120 678.8 116 678.8 DL 124 678.8 120 678.8 DL 128 678.8 124 678.8 DL
+132 678.8 128 678.8 DL 136 678.8 132 678.8 DL 140 678.8 136 678.8 DL 144 678.8
+140 678.8 DL 148 678.8 144 678.8 DL 152 678.8 148 678.8 DL 156 678.8 152 678.8
+DL 160 678.8 156 678.8 DL 164 678.8 160 678.8 DL 168 678.8 164 678.8 DL 172
+678.8 168 678.8 DL 176 678.8 172 678.8 DL 180 678.8 176 678.8 DL 184 678.8 180
+678.8 DL 188 678.8 184 678.8 DL 192 678.8 188 678.8 DL 196 678.8 192 678.8 DL
+200 678.8 196 678.8 DL 204 678.8 200 678.8 DL 208 678.8 204 678.8 DL 212 678.8
+208 678.8 DL 216 678.8 212 678.8 DL/F4 5/Times-Roman@0 SF(1)93.6 689.2 Q/F5 8
+/Times-Roman@0 SF -.12(ex)3.2 K(cept when mailing to a \214le, when).12 E/F6 8
+/Times-Italic@0 SF(sendmail)2 E F5(does the deli)2 E -.12(ve)-.2 G(ry directly)
+.12 E(.)-.52 E EP
+%%Page: 4 4
+%%BeginPageSetup
+BP
+%%EndPageSetup
+/F0 10/Times-Bold@0 SF 192.28(SMM:9-4 SENDMAIL)72 60 R 2.5<8a41>2.5 G 2.5(nI)
+383.99 60 S(nter)395.94 60 Q(netw)-.15 E(ork Mail Router)-.1 E 2.5(2.2.2. SMTP)
+102 96 R -.1(ove)2.5 G 2.5(rp).1 G(ipes)186.52 96 Q/F1 10/Times-Roman@0 SF .774
+(The SMTP protocol [Postel82] can be used to run an interacti)142 112.2 R 1.074
+-.15(ve l)-.25 H .774(ock-step interf).15 F .774(ace with)-.1 F .507
+(the mailer)117 124.2 R 5.507(.A)-.55 G .506(subprocess is still created, b)
+175.461 124.2 R .506(ut no recipient addresses are passed to the mailer via)-.2
+F .075(the ar)117 136.2 R .075(gument list.)-.18 F .075(Instead, the)5.075 F
+2.575(ya)-.15 G .075
+(re passed one at a time in commands sent to the processes stan-)249.805 136.2
+R .19(dard input.)117 148.2 R(An)5.19 E .19(ything appearing on the standard o\
+utput must be a reply code in a special format.)-.15 F F0 2.5(2.2.3. SMTP)102
+172.2 R -.1(ove)2.5 G 2.5(ra).1 G 2.5(nI)185.96 172.2 S(PC connection)197.91
+172.2 Q F1 .366(This technique is similar to the pre)142 188.4 R .366
+(vious technique, e)-.25 F .366(xcept that it uses a 4.2bsd IPC chan-)-.15 F
+.953(nel [UNIX83].)117 200.4 R .953(This method is e)5.953 F .953
+(xceptionally \215e)-.15 F .952
+(xible in that the mailer need not reside on the)-.15 F(same machine.)117 212.4
+Q(It is normally used to connect to a sendmail process on another machine.)5 E
+F0 2.5(2.3. Operational)87 236.4 R(Description)2.5 E F1 .228(When a sender w)
+127 252.6 R .228(ants to send a message, it issues a request to)-.1 F/F2 10
+/Times-Italic@0 SF(sendmail)2.729 E F1 .229(using one of the three)2.729 F
+1.028(methods described abo)102 264.6 R -.15(ve)-.15 G(.).15 E F2(Sendmail)
+6.028 E F1 1.028(operates in tw)3.528 F 3.528(od)-.1 G 1.028(istinct phases.)
+325.706 264.6 R 1.028(In the \214rst phase, it collects)6.028 F .612
+(and stores the message.)102 276.6 R .612(In the second phase, message deli)
+5.612 F -.15(ve)-.25 G .612(ry occurs.).15 F .612(If there were errors during)
+5.612 F 1.59(processing during the second phase,)102 288.6 R F2(sendmail)4.09 E
+F1 1.59(creates and returns a ne)4.09 F 4.09(wm)-.25 G 1.59
+(essage describing the)415.84 288.6 R
+(error and/or returns an status code telling what went wrong.)102 300.6 Q F0
+2.5(2.3.1. Ar)102 324.6 R(gument pr)-.1 E(ocessing and addr)-.18 E(ess parsing)
+-.18 E F1(If)142 340.8 Q F2(sendmail)3.321 E F1 .821
+(is called using one of the tw)3.321 F 3.322(os)-.1 G .822
+(ubprocess techniques, the ar)320.66 340.8 R .822(guments are \214rst)-.18 F
+.797(scanned and option speci\214cations are processed.)117 352.8 R .796
+(Recipient addresses are then collected, either)5.796 F .717(from the command \
+line or from the SMTP RCPT command, and a list of recipients is created.)117
+364.8 R .347(Aliases are e)117 376.8 R .347
+(xpanded at this step, including mailing lists.)-.15 F .347(As much v)5.347 F
+.346(alidation as possible of the)-.25 F 1.001
+(addresses is done at this step: syntax is check)117 388.8 R 1.002
+(ed, and local addresses are v)-.1 F 1.002(eri\214ed, b)-.15 F 1.002
+(ut detailed)-.2 F .709
+(checking of host names and addresses is deferred until deli)117 400.8 R -.15
+(ve)-.25 G(ry).15 E 5.708(.F)-.65 G(orw)388.946 400.8 Q .708
+(arding is also performed)-.1 F(as the local addresses are v)117 412.8 Q
+(eri\214ed.)-.15 E F2(Sendmail)142 429 Q F1 .307
+(appends each address to the recipient list after parsing.)2.807 F .307
+(When a name is aliased)5.307 F .322(or forw)117 441 R .322(arded, the old nam\
+e is retained in the list, and a \215ag is set that tells the deli)-.1 F -.15
+(ve)-.25 G .322(ry phase to).15 F .479(ignore this recipient.)117 453 R .479
+(This list is k)5.479 F .479(ept free from duplicates, pre)-.1 F -.15(ve)-.25 G
+.48(nting alias loops and duplicate).15 F(messages deli)117 465 Q -.15(ve)-.25
+G(rd to the same recipient, as might occur if a person is in tw).15 E 2.5(og)
+-.1 G(roups.)428.12 465 Q F0 2.5(2.3.2. Message)102 489 R(collection)2.5 E F2
+(Sendmail)142 505.2 Q F1 .454(then collects the message.)2.954 F .454
+(The message should ha)5.454 F .754 -.15(ve a h)-.2 H .453(eader at the be).15
+F(ginning.)-.15 E .778(No formatting requirements are imposed on the message e)
+117 517.2 R .778(xcept that the)-.15 F 3.278(ym)-.15 G .778(ust be lines of te)
+427.708 517.2 R(xt)-.15 E .78(\(i.e., binary data is not allo)117 529.2 R 3.28
+(wed\). The)-.25 F .779(header is parsed and stored in memory)3.28 F 3.279(,a)
+-.65 G .779(nd the body of)443.613 529.2 R(the message is sa)117 541.2 Q -.15
+(ve)-.2 G 2.5(di).15 G 2.5(nat)204.97 541.2 S(emporary \214le.)222.19 541.2 Q
+3.227 -.8(To s)142 557.4 T 1.627(implify the program interf).8 F 1.628
+(ace, the message is collected e)-.1 F -.15(ve)-.25 G 4.128(ni).15 G 4.128(fn)
+420.536 557.4 S 4.128(oa)432.994 557.4 S 1.628(ddresses were)446.562 557.4 R
+-.25(va)117 569.4 S 2.5(lid. The).25 F(message will be returned with an error)
+2.5 E(.)-.55 E F0 2.5(2.3.3. Message)102 593.4 R(deli)2.5 E -.1(ve)-.1 G(ry).1
+E F1 -.15(Fo)142 609.6 S 2.618(re).15 G .117
+(ach unique mailer and host in the recipient list,)162.798 609.6 R F2(sendmail)
+2.617 E F1 .117(calls the appropriate mailer)2.617 F(.)-.55 E .619
+(Each mailer in)117 621.6 R -.2(vo)-.4 G .619(cation sends to all users recei)
+.2 F .619(ving the message on one host.)-.25 F .62(Mailers that only)5.62 F
+(accept one recipient at a time are handled properly)117 633.6 Q(.)-.65 E .47
+(The message is sent to the mailer using one of the same three interf)142 649.8
+R .47(aces used to submit a)-.1 F 1.465(message to sendmail.)117 661.8 R 1.465
+(Each cop)6.465 F 3.965(yo)-.1 G 3.965(ft)263.925 661.8 S 1.465
+(he message is prepended by a customized header)274 661.8 R 6.465(.T)-.55 G(he)
+494.56 661.8 Q 1.455(mailer status code is caught and check)117 673.8 R 1.455
+(ed, and a suitable error message gi)-.1 F -.15(ve)-.25 G 3.955(na).15 G 3.955
+(sa)448.115 673.8 S(ppropriate.)460.4 673.8 Q .589(The e)117 685.8 R .589(xit \
+code must conform to a system standard or a generic message \(\231Service una)
+-.15 F -.25(va)-.2 G(ilable\232\)).25 E(is gi)117 697.8 Q -.15(ve)-.25 G(n.).15
+E EP
+%%Page: 5 5
+%%BeginPageSetup
+BP
+%%EndPageSetup
+/F0 10/Times-Bold@0 SF(SENDMAIL \212 An Inter)72 60 Q(netw)-.15 E
+(ork Mail Router)-.1 E(SMM:9-5)462.9 60 Q 2.5(2.3.4. Queueing)102 96 R -.25(fo)
+2.5 G 2.5(rr).25 G(etransmission)192.4 96 Q/F1 10/Times-Roman@0 SF .209(If the\
+ mailer returned an status that indicated that it might be able to handle the \
+mail later)142 112.2 R(,)-.4 E/F2 10/Times-Italic@0 SF(sendmail)117 124.2 Q F1
+(will queue the mail and try ag)2.5 E(ain later)-.05 E(.)-.55 E F0 2.5
+(2.3.5. Retur)102 148.2 R 2.5(nt)-.15 G 2.5(os)165.73 148.2 S(ender)177.12
+148.2 Q F1 .588(If errors occur during processing,)142 164.4 R F2(sendmail)
+3.088 E F1 .589(returns the message to the sender for retrans-)3.088 F 3.133
+(mission. The)117 176.4 R .632(letter can be mailed back or written in the \
+\214le \231dead.letter\232 in the sender')3.133 F 3.132(sh)-.55 G(ome)486.78
+176.4 Q(directory)117 190.4 Q/F3 7/Times-Roman@0 SF(2)153.1 186.4 Q F1(.)156.6
+190.4 Q F0 2.5(2.4. Message)87 214.4 R(Header Editing)2.5 E F1 1.756
+(Certain editing of the message header occurs automatically)127 230.6 R 6.756
+(.H)-.65 G 1.756(eader lines can be inserted)391.456 230.6 R .41
+(under control of the con\214guration \214le.)102 242.6 R .41
+(Some lines can be mer)5.41 F .41(ged; for e)-.18 F .41
+(xample, a \231From:\232 line and)-.15 F 2.5<6199>102 254.6 S
+(Full-name:\232 line can be mer)113.38 254.6 Q
+(ged under certain circumstances.)-.18 E F0 2.5(2.5. Con\214guration)87 278.6 R
+(File)2.5 E F1 .798(Almost all con\214guration information is read at runtime \
+from an ASCII \214le, encoding macro)127 294.8 R .679
+(de\214nitions \(de\214ning the v)102 306.8 R .678
+(alue of macros used internally\), header declarations \(telling sendmail the)
+-.25 F 1.009(format of header lines that it will process specially)102 318.8 R
+3.509(,i)-.65 G 1.009(.e., lines that it will add or reformat\), mailer)320.398
+318.8 R .478(de\214nitions \(gi)102 330.8 R .478(ving information such as the \
+location and characteristics of each mailer\), and address)-.25 F(re)102 342.8
+Q .428(writing rules \(a limited production system to re)-.25 F .429
+(write addresses which is used to parse and re)-.25 F(write)-.25 E
+(the addresses\).)102 354.8 Q 2.828 -.8(To i)127 371 T(mpro).8 E 1.528 -.15
+(ve p)-.15 H 1.228(erformance when reading the con\214guration \214le, a memor\
+y image can be pro-).15 F 2.5(vided. This)102 383 R(pro)2.5 E
+(vides a \231compiled\232 form of the con\214guration \214le.)-.15 E F0 2.5
+(3. USA)72 407 R(GE AND IMPLEMENT)-.55 E -.95(AT)-.9 G(ION).95 E 2.5(3.1. Ar)87
+431 R(guments)-.1 E F1(Ar)127 447.2 Q .376
+(guments may be \215ags and addresses.)-.18 F .377(Flags set v)5.377 F .377
+(arious processing options.)-.25 F -.15(Fo)5.377 G(llo).15 E .377(wing \215ag)
+-.25 F(ar)102 459.2 Q .281(guments, address ar)-.18 F .281(guments may be gi)
+-.18 F -.15(ve)-.25 G .281(n, unless we are running in SMTP mode.).15 F .28
+(Addresses fol-)5.28 F(lo)102 471.2 Q 2.5(wt)-.25 G(he syntax in RFC822 [Crock)
+122.03 471.2 Q(er82] for ARP)-.1 E(ANET address formats.)-.92 E
+(In brief, the format is:)5 E 12.5(\(1\) An)107 487.4 R
+(ything in parentheses is thro)-.15 E(wn a)-.25 E -.1(wa)-.15 G 2.5(y\().1 G
+(as a comment\).)299.65 487.4 Q 12.5(\(2\) An)107 503.6 R .051
+(ything in angle brack)-.15 F .051(ets \(\231<)-.1 F .051
+(>\232\) is preferred o)1.666 F -.15(ve)-.15 G 2.551(ra).15 G -.15(ny)348.064
+503.6 S .051(thing else.).15 F .051(This rule implements the)5.051 F(ARP)133.66
+515.6 Q(ANET standard that addresses of the form)-.92 E
+(user name <machine-address>)173.66 531.8 Q(will send to the electronic \231ma\
+chine-address\232 rather than the human \231user name.)133.66 548 Q<9a>-.7 E
+12.5(\(3\) Double)107 564.2 R 2.246(quotes \()4.746 F -2.754 2.5("\) q)2.5 H
+2.246(uote phrases; backslashes quote characters.)224.188 564.2 R 2.246
+(Backslashes are more)7.246 F(po)133.66 576.2 Q .654(werful in that the)-.25 F
+3.154(yw)-.15 G .655(ill cause otherwise equi)229.196 576.2 R -.25(va)-.25 G
+.655(lent phrases to compare dif).25 F .655(ferently \212 for)-.25 F -.15(ex)
+133.66 588.2 S(ample,).15 E F2(user)2.5 E F1(and)2.5 E F2("user")2.5 E F1
+(are equi)2.5 E -.25(va)-.25 G(lent, b).25 E(ut)-.2 E F2(\\user)2.5 E F1
+(is dif)2.5 E(ferent from either of them.)-.25 E -.15(Pa)127 604.4 S 1.12
+(rentheses, angle brack).15 F 1.12
+(ets, and double quotes must be properly balanced and nested.)-.1 F(The)6.12 E
+(re)102 618.4 Q(writing rules control remaining parsing)-.25 E F3(3)266.17
+614.4 Q F1(.)269.67 618.4 Q .32 LW 76 646 72 646 DL 80 646 76 646 DL 84 646 80
+646 DL 88 646 84 646 DL 92 646 88 646 DL 96 646 92 646 DL 100 646 96 646 DL 104
+646 100 646 DL 108 646 104 646 DL 112 646 108 646 DL 116 646 112 646 DL 120 646
+116 646 DL 124 646 120 646 DL 128 646 124 646 DL 132 646 128 646 DL 136 646 132
+646 DL 140 646 136 646 DL 144 646 140 646 DL 148 646 144 646 DL 152 646 148 646
+DL 156 646 152 646 DL 160 646 156 646 DL 164 646 160 646 DL 168 646 164 646 DL
+172 646 168 646 DL 176 646 172 646 DL 180 646 176 646 DL 184 646 180 646 DL 188
+646 184 646 DL 192 646 188 646 DL 196 646 192 646 DL 200 646 196 646 DL 204 646
+200 646 DL 208 646 204 646 DL 212 646 208 646 DL 216 646 212 646 DL/F4 5
+/Times-Roman@0 SF(2)93.6 656.4 Q/F5 8/Times-Roman@0 SF(Ob)3.2 I(viously)-.12 E
+2.226(,i)-.52 G 2.226(ft)135.246 659.6 S .226(he site gi)142.36 659.6 R .226(v\
+ing the error is not the originating site, the only reasonable option is to ma\
+il back to the sender)-.2 F 4.227(.A)-.44 G(lso,)492.664 659.6 Q .191
+(there are man)72 669.2 R 2.191(ym)-.12 G .19(ore error disposition options, b)
+128.213 669.2 R .19(ut the)-.16 F 2.19(yo)-.12 G .19(nly ef)255.514 669.2 R .19
+(fect the error message \212 the \231return to sender\232 function is al)-.2 F
+-.08(wa)-.08 G .19(ys han-).08 F(dled in one of these tw)72 678.8 Q 2(ow)-.08 G
+(ays.)156.272 678.8 Q F4(3)93.6 689.2 Q F5
+(Disclaimer: Some special processing is done after re)3.2 I
+(writing local names; see belo)-.2 E -.52(w.)-.2 G EP
+%%Page: 6 6
+%%BeginPageSetup
+BP
+%%EndPageSetup
+/F0 10/Times-Bold@0 SF 192.28(SMM:9-6 SENDMAIL)72 60 R 2.5<8a41>2.5 G 2.5(nI)
+383.99 60 S(nter)395.94 60 Q(netw)-.15 E(ork Mail Router)-.1 E 2.5(3.2. Mail)87
+96 R(to Files and Pr)2.5 E(ograms)-.18 E/F1 10/Times-Roman@0 SF .609
+(Files and programs are le)127 112.2 R .609(gitimate message recipients.)-.15 F
+.609(Files pro)5.609 F .609(vide archi)-.15 F -.25(va)-.25 G 3.109(ls).25 G .61
+(torage of mes-)445.02 112.2 R .124
+(sages, useful for project administration and history)102 124.2 R 5.124(.P)-.65
+G .124(rograms are useful as recipients in a v)318.308 124.2 R .124(ariety of)
+-.25 F .69(situations, for e)102 136.2 R .691(xample, to maintain a public rep\
+ository of systems messages \(such as the Berk)-.15 F(ele)-.1 E(y)-.15 E/F2 10
+/Times-Italic@0 SF(msgs)102 148.2 Q F1(program, or the MARS system [Sattle)2.5
+E(y78]\).)-.15 E(An)127 164.4 Q 3.188(ya)-.15 G .688(ddress passing through th\
+e initial parsing algorithm as a local address \(i.e, not appear)151.698 164.4
+R(-)-.2 E .276(ing to be a v)102 176.4 R .276
+(alid address for another mailer\) is scanned for tw)-.25 F 2.776(os)-.1 G .277
+(pecial cases.)362.128 176.4 R .277(If pre\214x)5.277 F .277(ed by a v)-.15 F
+(erti-)-.15 E .18(cal bar \(\231)102 188.4 R .833<7c9a>.833 G 2.68(\)t)-.833 G
+.179(he rest of the address is processed as a shell command.)156.456 188.4 R
+.179(If the user name be)5.179 F .179(gins with a)-.15 F(slash mark \(\231/)102
+200.4 Q(\232\) the name is used as a \214le name, instead of a login name.).833
+E .241(Files that ha)127 216.6 R .541 -.15(ve s)-.2 H .241
+(etuid or setgid bits set b).15 F .241(ut no e)-.2 F -.15(xe)-.15 G .241
+(cute bits set ha).15 F .541 -.15(ve t)-.2 H .241(hose bits honored if).15 F F2
+(send-)2.742 E(mail)102 228.6 Q F1(is running as root.)2.5 E F0 2.5
+(3.3. Aliasing,)87 252.6 R -.25(Fo)2.5 G(rwarding, Inclusion).25 E F2(Sendmail)
+127 268.8 Q F1 1.075(reroutes mail three w)3.575 F 3.575(ays. Aliasing)-.1 F
+1.074(applies system wide.)3.575 F -.15(Fo)6.074 G(rw).15 E 1.074(arding allo)
+-.1 F 1.074(ws each)-.25 F .233
+(user to reroute incoming mail destined for that account.)102 280.8 R .233
+(Inclusion directs)5.233 F F2(sendmail)2.733 E F1 .233(to read a \214le for)
+2.733 F 2.5(al)102 292.8 S
+(ist of addresses, and is normally used in conjunction with aliasing.)111.72
+292.8 Q F0 2.5(3.3.1. Aliasing)102 316.8 R F1 1.554
+(Aliasing maps names to address lists using a system-wide \214le.)142 333 R
+1.553(This \214le is inde)6.553 F -.15(xe)-.15 G 4.053(dt).15 G(o)499 333 Q 1.1
+(speed access.)117 345 R 1.101(Only names that parse as local are allo)6.1 F
+1.101(wed as aliases; this guarantees a unique)-.25 F -.1(ke)117 357 S 2.5(y\()
+-.05 G(since there are no nicknames for the local host\).)137.02 357 Q F0 2.5
+(3.3.2. F)102 381 R(orwarding)-.25 E F1 .651
+(After aliasing, recipients that are local and v)142 397.2 R .651
+(alid are check)-.25 F .65(ed for the e)-.1 F .65(xistence of a \231.for)-.15 F
+(-)-.2 E -.1(wa)117 409.2 S .493(rd\232 \214le in their home directory).1 F
+5.493(.I)-.65 G 2.994(fi)264.178 409.2 S 2.994(te)273.282 409.2 S .494
+(xists, the message is)283.346 409.2 R F2(not)2.994 E F1 .494
+(sent to that user)2.994 F 2.994(,b)-.4 G .494(ut rather to)459.132 409.2 R .37
+(the list of users in that \214le.)117 421.2 R .37
+(Often this list will contain only one address, and the feature will be)5.37 F
+(used for netw)117 433.2 Q(ork mail forw)-.1 E(arding.)-.1 E -.15(Fo)142 449.4
+S(rw).15 E 1.151(arding also permits a user to specify a pri)-.1 F -.25(va)-.25
+G 1.152(te incoming mailer).25 F 6.152(.F)-.55 G 1.152(or e)437.346 449.4 R
+1.152(xample, for)-.15 F(-)-.2 E -.1(wa)117 461.4 S(rding to:).1 E -2.5 .833
+("| /)157 477.6 T(usr/local/ne)-.833 E(wmail myname")-.25 E(will use a dif)117
+493.8 Q(ferent incoming mailer)-.25 E(.)-.55 E F0 2.5(3.3.3. Inclusion)102
+517.8 R F1(Inclusion is speci\214ed in RFC 733 [Crock)142 534 Q(er77a] syntax:)
+-.1 E(:Include: pathname)157 550.2 Q .391
+(An address of this form reads the \214le speci\214ed by)117 566.4 R F2
+(pathname)2.891 E F1 .391(and sends to all users listed in that)2.891 F
+(\214le.)117 578.4 Q .644(The intent is)142 594.6 R F2(not)3.144 E F1 .644
+(to support direct use of this feature, b)3.144 F .644
+(ut rather to use this as a subset of)-.2 F 2.5(aliasing. F)117 606.6 R(or e)
+-.15 E(xample, an alias of the form:)-.15 E
+(project: :include:/usr/project/userlist)157 622.8 Q 1.93(is a method of letti\
+ng a project maintain a mailing list without interaction with the system)117
+639 R(administration, e)117 651 Q -.15(ve)-.25 G 2.5(ni).15 G 2.5(ft)203.54 651
+S(he alias \214le is protected.)212.15 651 Q 2.024(It is not necessary to reb)
+142 667.2 R 2.024(uild the inde)-.2 F 4.524(xo)-.15 G 4.524(nt)317.822 667.2 S
+2.025(he alias database when a :include: list is)330.126 667.2 R(changed.)117
+679.2 Q EP
+%%Page: 7 7
+%%BeginPageSetup
+BP
+%%EndPageSetup
+/F0 10/Times-Bold@0 SF(SENDMAIL \212 An Inter)72 60 Q(netw)-.15 E
+(ork Mail Router)-.1 E(SMM:9-7)462.9 60 Q 2.5(3.4. Message)87 96 R(Collection)
+2.5 E/F1 10/Times-Roman@0 SF .857
+(Once all recipient addresses are parsed and v)127 112.2 R .857
+(eri\214ed, the message is collected.)-.15 F .856(The message)5.857 F
+(comes in tw)102 124.2 Q 2.5(op)-.1 G
+(arts: a message header and a message body)162.73 124.2 Q 2.5(,s)-.65 G
+(eparated by a blank line.)343.42 124.2 Q
+(The header is formatted as a series of lines of the form)127 140.4 Q
+(\214eld-name: \214eld-v)178 156.6 Q(alue)-.25 E(Field-v)102 172.8 Q 1.366
+(alue can be split across lines by starting the follo)-.25 F 1.366
+(wing lines with a space or a tab)-.25 F 6.366(.S)-.4 G(ome)486.78 172.8 Q .211
+(header \214elds ha)102 184.8 R .511 -.15(ve s)-.2 H .211
+(pecial internal meaning, and ha).15 F .511 -.15(ve a)-.2 H .211
+(ppropriate special processing.).15 F .21(Other headers)5.21 F
+(are simply passed through.)102 196.8 Q
+(Some header \214elds may be added automatically)5 E 2.5(,s)-.65 G
+(uch as time stamps.)413.53 196.8 Q .86(The body is a series of te)127 213 R
+.861(xt lines.)-.15 F .861(It is completely uninterpreted and untouched, e)
+5.861 F .861(xcept that)-.15 F 1.43(lines be)102 225 R 1.43
+(ginning with a dot ha)-.15 F 1.729 -.15(ve t)-.2 H 1.429
+(he dot doubled when transmitted o).15 F -.15(ve)-.15 G 3.929(ra).15 G 3.929
+(nS)407.213 225 S 1.429(MTP channel.)421.702 225 R(This)6.429 E -.15(ex)102 237
+S(tra dot is stripped by the recei).15 E -.15(ve)-.25 G -.55(r.).15 G F0 2.5
+(3.5. Message)87 261 R(Deli)2.5 E -.1(ve)-.1 G(ry).1 E F1 .028
+(The send queue is ordered by recei)127 277.2 R .029
+(ving host before transmission to implement message batch-)-.25 F 3.07
+(ing. Each)102 289.2 R .57(address is mark)3.07 F .57
+(ed as it is sent so rescanning the list is safe.)-.1 F .57(An ar)5.57 F .57
+(gument list is b)-.18 F .57(uilt as)-.2 F 1.138(the scan proceeds.)102 301.2 R
+1.139(Mail to \214les is detected during the scan of the send list.)6.139 F
+1.139(The interf)6.139 F 1.139(ace to the)-.1 F
+(mailer is performed using one of the techniques described in section 2.2.)102
+313.2 Q .996(After a connection is established,)127 329.4 R/F2 10
+/Times-Italic@0 SF(sendmail)3.496 E F1(mak)3.495 E .995(es the per)-.1 F .995
+(-mailer changes to the header and)-.2 F .236(sends the result to the mailer)
+102 341.4 R 5.236(.I)-.55 G 2.736(fa)228.406 341.4 S .537 -.15(ny m)238.912
+341.4 T .237(ail is rejected by the mailer).15 F 2.737(,a\215)-.4 G .237
+(ag is set to in)386.628 341.4 R -.2(vo)-.4 G .437 -.1(ke t).2 H .237
+(he return-).1 F(to-sender function after all deli)102 353.4 Q -.15(ve)-.25 G
+(ry completes.).15 E F0 2.5(3.6. Queued)87 377.4 R(Messages)2.5 E F1 .163
+(If the mailer returns a \231temporary f)127 393.6 R .163(ailure\232 e)-.1 F
+.162(xit status, the message is queued.)-.15 F 2.662(Ac)5.162 G .162
+(ontrol \214le is)455.336 393.6 R .85
+(used to describe the recipients to be sent to and v)102 405.6 R .851
+(arious other parameters.)-.25 F .851(This control \214le is for)5.851 F(-)-.2
+E 1.011(matted as a series of lines, each describing a sender)102 417.6 R 3.511
+(,ar)-.4 G 1.011(ecipient, the time of submission, or some)333.494 417.6 R .776
+(other salient parameter of the message.)102 429.6 R .776
+(The header of the message is stored in the control \214le, so)5.776 F(that th\
+e associated data \214le in the queue is just the temporary \214le that w)102
+441.6 Q(as originally collected.)-.1 E F0 2.5(3.7. Con\214guration)87 465.6 R
+F1 .493(Con\214guration is controlled primarily by a con\214guration \214le re\
+ad at startup.)127 481.8 R F2(Sendmail)5.492 E F1(should)2.992 E
+(not need to be recomplied e)102 493.8 Q(xcept)-.15 E 12.5(\(1\) T)107 510 R
+2.5(oc)-.8 G(hange operating systems \(V6, V7/32V)150.91 510 Q 2.5(,4)-1.29 G
+(BSD\).)313.21 510 Q 12.5(\(2\) T)107 526.2 R 2.5(or)-.8 G(emo)149.8 526.2 Q .3
+-.15(ve o)-.15 H 2.5(ri).15 G(nsert the DBM \(UNIX database\) library)192.27
+526.2 Q(.)-.65 E 12.5(\(3\) T)107 542.4 R 2.5(oc)-.8 G(hange ARP)150.91 542.4 Q
+(ANET reply codes.)-.92 E 12.5(\(4\) T)107 558.6 R 2.5(oa)-.8 G
+(dd headers \214elds requiring special processing.)150.91 558.6 Q .434
+(Adding mailers or changing parsing \(i.e., re)102 574.8 R .435
+(writing\) or routing information does not require recom-)-.25 F(pilation.)102
+586.8 Q 1.317(If the mail is being sent by a local user)127 603 R 3.817(,a)-.4
+G 1.317(nd the \214le \231.mailcf\232 e)303.914 603 R 1.317
+(xists in the sender')-.15 F 3.817(sh)-.55 G(ome)486.78 603 Q(directory)102 615
+Q 2.721(,t)-.65 G .221(hat \214le is read as a con\214guration \214le after th\
+e system con\214guration \214le.)145.451 615 R .222(The primary use)5.222 F
+(of this feature is to add header lines.)102 627 Q 3.25(The con\214guration \
+\214le encodes macro de\214nitions, header de\214nitions, mailer de\214nitions\
+,)127 643.2 R(re)102 655.2 Q(writing rules, and options.)-.25 E F0 2.5
+(3.7.1. Macr)102 679.2 R(os)-.18 E F1 .332(Macros can be used in three w)142
+695.4 R 2.833(ays. Certain)-.1 F .333(macros transmit unstructured te)2.833 F
+.333(xtual informa-)-.15 F .07(tion into the mail system, such as the name)117
+707.4 R F2(sendmail)2.57 E F1 .07
+(will use to identify itself in error messages.)2.57 F 1.247
+(Other macros transmit information from)117 719.4 R F2(sendmail)3.747 E F1
+1.247(to the con\214guration \214le for use in creating)3.747 F EP
+%%Page: 8 8
+%%BeginPageSetup
+BP
+%%EndPageSetup
+/F0 10/Times-Bold@0 SF 192.28(SMM:9-8 SENDMAIL)72 60 R 2.5<8a41>2.5 G 2.5(nI)
+383.99 60 S(nter)395.94 60 Q(netw)-.15 E(ork Mail Router)-.1 E/F1 10
+/Times-Roman@0 SF .312(other \214elds \(such as ar)117 96 R .312(gument v)-.18
+F .312(ectors to mailers\); e.g., the name of the sender)-.15 F 2.811(,a)-.4 G
+.311(nd the host and)442.237 96 R .848(user of the recipient.)117 108 R .848
+(Other macros are unused internally)5.848 F 3.348(,a)-.65 G .848
+(nd can be used as shorthand in the)361.142 108 R(con\214guration \214le.)117
+120 Q F0 2.5(3.7.2. Header)102 144 R(declarations)2.5 E F1 .355
+(Header declarations inform)142 160.2 R/F2 10/Times-Italic@0 SF(sendmail)2.854
+E F1 .354(of the format of kno)2.854 F .354(wn header lines.)-.25 F(Kno)5.354 E
+.354(wledge of)-.25 F 2.5(af)117 172.2 S .5 -.25(ew h)127.27 172.2 T
+(eader lines is b).25 E(uilt into)-.2 E F2(sendmail)2.5 E F1 2.5(,s)C
+(uch as the \231From:\232 and \231Date:\232 lines.)284.59 172.2 Q 1.201(Most c\
+on\214gured headers will be automatically inserted in the outgoing message if \
+the)142 188.4 R(y)-.15 E(don')117 200.4 Q 2.5(te)-.18 G
+(xist in the incoming message.)144.72 200.4 Q
+(Certain headers are suppressed by some mailers.)5 E F0 2.5(3.7.3. Mailer)102
+224.4 R(declarations)2.5 E F1 1.756(Mailer declarations tell)142 240.6 R F2
+(sendmail)4.256 E F1 1.756(of the v)4.256 F 1.756(arious mailers a)-.25 F -.25
+(va)-.2 G 1.756(ilable to it.).25 F 1.755(The de\214nition)6.755 F .119
+(speci\214es the internal name of the mailer)117 252.6 R 2.619(,t)-.4 G .12
+(he pathname of the program to call, some \215ags associ-)285.183 252.6 R 2.036
+(ated with the mailer)117 264.6 R 4.536(,a)-.4 G 2.036(nd an ar)213.894 264.6 R
+2.036(gument v)-.18 F 2.036(ector to be used on the call; this v)-.15 F 2.035
+(ector is macro-)-.15 F -.15(ex)117 276.6 S(panded before use.).15 E F0 2.5
+(3.7.4. Addr)102 300.6 R(ess r)-.18 E(ewriting rules)-.18 E F1 .458
+(The heart of address parsing in)142 316.8 R F2(sendmail)2.959 E F1 .459
+(is a set of re)2.959 F .459(writing rules.)-.25 F .459(These are an ordered)
+5.459 F .561(list of pattern-replacement rules, \(some)117 328.8 R .561
+(what lik)-.25 F 3.061(eap)-.1 G .561(roduction system, e)328.867 328.8 R .56
+(xcept that order is criti-)-.15 F 1.905
+(cal\), which are applied to each address.)117 340.8 R 1.905(The address is re)
+6.905 F 1.906(written te)-.25 F 1.906(xtually until it is either)-.15 F(re)117
+352.8 Q .308(written into a special canonical form \(i.e., a \(mailer)-.25 F
+2.807(,h)-.4 G .307(ost, user\) 3-tuple, such as {arpanet, usc-)342.118 352.8 R
+.64(isif, postel} representing the address \231postel@usc-isif\232\), or it f)
+117 364.8 R .641(alls of)-.1 F 3.141(ft)-.25 G .641(he end.)406.466 364.8 R
+.641(When a pattern)5.641 F(matches, the rule is reapplied until it f)117 376.8
+Q(ails.)-.1 E 1.222
+(The con\214guration \214le also supports the editing of addresses into dif)142
+393 R 1.221(ferent formats.)-.25 F -.15(Fo)6.221 G(r).15 E -.15(ex)117 405 S
+(ample, an address of the form:).15 E(ucsfcgl!tef)157 421.2 Q
+(might be mapped into:)117 437.4 Q(tef@ucsfcgl.UUCP)157 453.6 Q
+(to conform to the domain syntax.)117 469.8 Q -.35(Tr)5 G
+(anslations can also be done in the other direction.).35 E F0 2.5
+(3.7.5. Option)102 493.8 R(setting)2.5 E F1 1.168(There are se)142 510 R -.15
+(ve)-.25 G 1.169(ral options that can be set from the con\214guration \214le.)
+.15 F 1.169(These include the)6.169 F(pathnames of v)117 522 Q
+(arious support \214les, timeouts, def)-.25 E(ault modes, etc.)-.1 E F0 2.5
+(4. COMP)72 546 R(ARISON WITH O)-.74 E(THER MAILERS)-.4 E 2.5(4.1. Deli)87 570
+R -.1(ve)-.1 G(rmail).1 E F2(Sendmail)127 586.2 Q F1(is an outgro)2.5 E(wth of)
+-.25 E F2(delivermail)2.5 E F1 5(.T)C(he primary dif)301.18 586.2 Q
+(ferences are:)-.25 E 12.5(\(1\) Con\214guration)107 602.4 R .273
+(information is not compiled in.)2.773 F .272(This change simpli\214es man)
+5.273 F 2.772(yo)-.15 G 2.772(ft)445.686 602.4 S .272(he problems)454.568 602.4
+R(of mo)133.66 614.4 Q(ving to other machines.)-.15 E(It also allo)5 E
+(ws easy deb)-.25 E(ugging of ne)-.2 E 2.5(wm)-.25 G(ailers.)413.89 614.4 Q
+12.5(\(2\) Address)107 630.6 R .681(parsing is more \215e)3.181 F 3.182
+(xible. F)-.15 F .682(or e)-.15 F(xample,)-.15 E F2(delivermail)3.182 E F1 .682
+(only supported one g)3.182 F(ate)-.05 E -.1(wa)-.25 G 3.182(yt).1 G(o)499
+630.6 Q(an)133.66 642.6 Q 2.817(yn)-.15 G(etw)155.767 642.6 Q .317
+(ork, whereas)-.1 F F2(sendmail)2.817 E F1 .317(can be sensiti)2.817 F .616
+-.15(ve t)-.25 H 2.816(oh).15 G .316(ost names and reroute to dif)345.224 642.6
+R .316(ferent g)-.25 F(ate-)-.05 E -.1(wa)133.66 654.6 S(ys.).1 E 12.5(\(3\) F)
+107 670.8 R(orw)-.15 E 1.627(arding and :include: features eliminate the requi\
+rement that the system alias \214le be)-.1 F .074(writable by an)133.66 682.8 R
+2.574(yu)-.15 G .073
+(ser \(or that an update program be written, or that the system administration)
+203.442 682.8 R(mak)133.66 694.8 Q 2.5(ea)-.1 G(ll changes\).)162.16 694.8 Q
+(\(4\))107 711 Q F2(Sendmail)133.66 711 Q F1 .4
+(supports message batching across netw)2.9 F .401
+(orks when a message is being sent to mul-)-.1 F(tiple recipients.)133.66 723 Q
+EP
+%%Page: 9 9
+%%BeginPageSetup
+BP
+%%EndPageSetup
+/F0 10/Times-Bold@0 SF(SENDMAIL \212 An Inter)72 60 Q(netw)-.15 E
+(ork Mail Router)-.1 E(SMM:9-9)462.9 60 Q/F1 10/Times-Roman@0 SF 12.5(\(5\) A)
+107 96 R .875(mail queue is pro)3.375 F .874(vided in)-.15 F/F2 10
+/Times-Italic@0 SF(sendmail.)3.374 E F1 .874(Mail that cannot be deli)5.874 F
+-.15(ve)-.25 G .874(red immediately b).15 F .874(ut can)-.2 F 1.063
+(potentially be deli)133.66 108 R -.15(ve)-.25 G 1.064
+(red later is stored in this queue for a later retry).15 F 6.064(.T)-.65 G
+1.064(he queue also pro-)427.218 108 R .896(vides a b)133.66 120 R(uf)-.2 E
+.896(fer ag)-.25 F .895
+(ainst system crashes; after the message has been collected it may be reli-)
+-.05 F(ably redeli)133.66 132 Q -.15(ve)-.25 G(red e).15 E -.15(ve)-.25 G 2.5
+(ni).15 G 2.5(ft)224.22 132 S(he system crashes during the initial deli)232.83
+132 Q -.15(ve)-.25 G(ry).15 E(.)-.65 E(\(6\))107 148.2 Q F2(Sendmail)133.66
+148.2 Q F1 .197(uses the netw)2.696 F .197(orking support pro)-.1 F .197
+(vided by 4.2BSD to pro)-.15 F .197(vide a direct interf)-.15 F .197(ace net-)
+-.1 F -.1(wo)133.66 160.2 S .07(rks such as the ARP).1 F .07
+(ANET and/or Ethernet using SMTP \(the Simple Mail T)-.92 F .07(ransfer Proto-)
+-.35 F(col\) o)133.66 172.2 Q -.15(ve)-.15 G 2.5(raT).15 G(CP/IP connection.)
+184.73 172.2 Q F0 2.5(4.2. MMDF)87 196.2 R F1 .957(MMDF [Crock)127 212.4 R .957
+(er79] spans a wider problem set than)-.1 F F2(sendmail)3.458 E F1 5.958(.F)C
+.958(or e)395.058 212.4 R .958(xample, the domain of)-.15 F .721
+(MMDF includes a \231phone netw)102 224.4 R .721(ork\232 mailer)-.1 F 3.221(,w)
+-.4 G(hereas)290.516 224.4 Q F2(sendmail)3.221 E F1 .721(calls on pree)3.221 F
+.72(xisting mailers in most)-.15 F(cases.)102 236.4 Q .175(MMDF and)127 252.6 R
+F2(sendmail)2.675 E F1 .175
+(both support aliasing, customized mailers, message batching, automatic)2.675 F
+(forw)102 264.6 Q .792(arding to g)-.1 F(ate)-.05 E -.1(wa)-.25 G .792
+(ys, queueing, and retransmission.).1 F .792(MMDF supports tw)5.792 F .792
+(o-stage timeout, which)-.1 F F2(sendmail)102 276.6 Q F1(does not support.)2.5
+E(The con\214guration for MMDF is compiled into the code)127 294.8 Q/F3 7
+/Times-Roman@0 SF(4)348.65 290.8 Q F1(.)352.15 294.8 Q .037
+(Since MMDF does not consider backw)127 311 R .037
+(ards compatibility as a design goal, the address parsing)-.1 F(is simpler b)
+102 323 Q(ut much less \215e)-.2 E(xible.)-.15 E 1.159(It is some)127 341.2 R
+1.159(what harder to inte)-.25 F 1.159(grate a ne)-.15 F 3.659(wc)-.25 G
+(hannel)302.802 341.2 Q F3(5)329.462 337.2 Q F1 1.159(into MMDF)336.621 341.2 R
+6.16(.I)-.8 G 3.66(np)397.59 341.2 S(articular)411.25 341.2 Q 3.66(,M)-.4 G
+1.16(MDF must)459.22 341.2 R(kno)102 353.2 Q 3.225(wt)-.25 G .725(he location \
+and format of host tables for all channels, and the channel must speak a speci\
+al)129.975 353.2 R 2.525(protocol. This)102 365.2 R(allo)2.525 E .025
+(ws MMDF to do additional v)-.25 F .025(eri\214cation \(such as v)-.15 F .025
+(erifying host names\) at submis-)-.15 F(sion time.)102 377.2 Q 1.761
+(MMDF strictly separates the submission and deli)127 393.4 R -.15(ve)-.25 G
+1.761(ry phases.).15 F(Although)6.761 E F2(sendmail)4.261 E F1 1.76(has the)
+4.261 F .784(concept of each of these stages, the)102 405.4 R 3.284(ya)-.15 G
+.784(re inte)260.068 405.4 R .785(grated into one program, whereas in MMDF the)
+-.15 F 3.285(ya)-.15 G(re)496.23 405.4 Q(split into tw)102 417.4 Q 2.5(op)-.1 G
+(rograms.)162.19 417.4 Q F0 2.5(4.3. Message)87 441.4 R(Pr)2.5 E
+(ocessing Module)-.18 E F1 .925
+(The Message Processing Module \(MPM\) discussed by Postel [Postel79b] matches)
+127 457.6 R F2(sendmail)3.425 E F1 1.364
+(closely in terms of its basic architecture.)102 469.6 R(Ho)6.364 E(we)-.25 E
+-.15(ve)-.25 G 2.164 -.4(r, l).15 H(ik).4 E 3.864(eM)-.1 G(MDF)347.526 469.6 Q
+3.864(,t)-.8 G 1.365(he MPM includes the netw)377.54 469.6 R(ork)-.1 E(interf)
+102 481.6 Q(ace softw)-.1 E(are as part of its domain.)-.1 E .408
+(MPM also postulates a duple)127 497.8 R 2.907(xc)-.15 G .407
+(hannel to the recei)256.937 497.8 R -.15(ve)-.25 G 1.207 -.4(r, a).15 H 2.907
+(sd).4 G .407(oes MMDF)365.362 497.8 R 2.907(,t)-.8 G .407(hus allo)419.546
+497.8 R .407(wing simpler)-.25 F .302
+(handling of errors by the mailer than is possible in)102 509.8 R F2(sendmail)
+2.802 E F1 5.302(.W)C .302(hen a message queued by)362.24 509.8 R F2(sendmail)
+2.802 E F1 .23(is sent, an)102 521.8 R 2.73(ye)-.15 G .23
+(rrors must be returned to the sender by the mailer itself.)154.2 521.8 R .229
+(Both MPM and MMDF mail-)5.229 F .883(ers can return an immediate error respon\
+se, and a single error processor can create an appropriate)102 533.8 R
+(response.)102 545.8 Q 2.24
+(MPM prefers passing the message as a structured object, with type-length-v)127
+564 R 2.24(alue tuples)-.25 F F3(6)498 560 Q F1(.)501.5 564 Q .874(Such a con)
+102 576 R -.15(ve)-.4 G .874(ntion requires a much higher de).15 F .875
+(gree of cooperation between mailers than is required)-.15 F(by)102 588 Q F2
+(sendmail)2.796 E F1 5.296(.M)C .296(PM also assumes a uni)167.592 588 R -.15
+(ve)-.25 G .296(rsally agreed upon internet name space \(with each address).15
+F(in the form of a net-host-user tuple\), which)102 600 Q F2(sendmail)2.5 E F1
+(does not.)2.5 E .32 LW 76 642 72 642 DL 80 642 76 642 DL 84 642 80 642 DL 88
+642 84 642 DL 92 642 88 642 DL 96 642 92 642 DL 100 642 96 642 DL 104 642 100
+642 DL 108 642 104 642 DL 112 642 108 642 DL 116 642 112 642 DL 120 642 116 642
+DL 124 642 120 642 DL 128 642 124 642 DL 132 642 128 642 DL 136 642 132 642 DL
+140 642 136 642 DL 144 642 140 642 DL 148 642 144 642 DL 152 642 148 642 DL 156
+642 152 642 DL 160 642 156 642 DL 164 642 160 642 DL 168 642 164 642 DL 172 642
+168 642 DL 176 642 172 642 DL 180 642 176 642 DL 184 642 180 642 DL 188 642 184
+642 DL 192 642 188 642 DL 196 642 192 642 DL 200 642 196 642 DL 204 642 200 642
+DL 208 642 204 642 DL 212 642 208 642 DL 216 642 212 642 DL/F4 5/Times-Roman@0
+SF(4)93.6 652.4 Q/F5 8/Times-Roman@0 SF .179
+(Dynamic con\214guration tables are currently being considered for MMDF; allo)
+3.2 J .18(wing the installer to select either compiled or dy-)-.2 F
+(namic tables.)72 665.2 Q F4(5)93.6 675.6 Q F5(The MMDF equi)3.2 I -.2(va)-.2 G
+(lent of a).2 E/F6 8/Times-Italic@0 SF(sendmail)2 E F5(\231mailer)2 E -.56
+<2e9a>-.44 G F4(6)93.6 689.2 Q F5(This is similar to the NBS standard.)3.2 I EP
+%%Page: 10 10
+%%BeginPageSetup
+BP
+%%EndPageSetup
+/F0 10/Times-Bold@0 SF 187.28(SMM:9-10 SENDMAIL)72 60 R 2.5<8a41>2.5 G 2.5(nI)
+383.99 60 S(nter)395.94 60 Q(netw)-.15 E(ork Mail Router)-.1 E 2.5(5. EV)72 96
+R(ALU)-1.35 E -.95(AT)-.6 G(IONS AND FUTURE PLANS).95 E/F1 10/Times-Italic@0 SF
+(Sendmail)112 112.2 Q/F2 10/Times-Roman@0 SF 1.851(is designed to w)4.351 F
+1.851(ork in a nonhomogeneous en)-.1 F 4.352(vironment. Ev)-.4 F 1.852
+(ery attempt is made to)-.15 F -.2(avo)87 124.2 S 1.037
+(id imposing unnecessary constraints on the underlying mailers.).2 F 1.036
+(This goal has dri)6.036 F -.15(ve)-.25 G 3.536(nm).15 G 1.036(uch of the)
+461.938 124.2 R 2.723(design. One)87 136.2 R .223(of the major problems has be\
+en the lack of a uniform address space, as postulated in [Pos-)2.723 F
+(tel79a] and [Postel79b].)87 148.2 Q 2.647(An)112 164.4 S .147(onuniform addre\
+ss space implies that a path will be speci\214ed in all addresses, either e)
+126.867 164.4 R(xplicitly)-.15 E .472
+(\(as part of the address\) or implicitly \(as with implied forw)87 176.4 R
+.473(arding to g)-.1 F(ate)-.05 E -.1(wa)-.25 G 2.973(ys\). This).1 F .473
+(restriction has the)2.973 F .493(unpleasant ef)87 188.4 R .493
+(fect of making replying to messages e)-.25 F .493(xceedingly dif)-.15 F .493
+(\214cult, since there is no one \231address\232)-.25 F(for an)87 200.4 Q 2.5
+(yp)-.15 G(erson, b)122.95 200.4 Q(ut only a w)-.2 E
+(ay to get there from where)-.1 E -.15(ve)-.25 G 2.5(ry).15 G(ou are.)324.7
+200.4 Q(Interf)112 216.6 Q .448(acing to mail programs that were not initially\
+ intended to be applied in an internet en)-.1 F(viron-)-.4 E(ment has been ama\
+zingly successful, and has reduced the job to a manageable task.)87 228.6 Q F1
+(Sendmail)112 244.8 Q F2 2.906(has kno)5.406 F 2.906(wledge of a fe)-.25 F
+5.406(wd)-.25 G(if)271.126 244.8 Q 2.906(\214cult en)-.25 F 2.906(vironments b)
+-.4 F 2.906(uilt in.)-.2 F 2.905(It generates ARP)7.906 F(ANET)-.92 E .648(FTP\
+/SMTP compatible error messages \(prepended with three-digit numbers [Neigus73\
+, Postel74, Pos-)87 256.8 R .771(tel82]\) as necessary)87 268.8 R 3.271(,o)-.65
+G .771(ptionally generates UNIX-style \231From\232 lines on the front of messa\
+ges for some)177.523 268.8 R 1.669(mailers, and kno)87 280.8 R 1.669(ws ho)-.25
+F 4.169(wt)-.25 G 4.169(op)195.666 280.8 S 1.669(arse the same lines on input.)
+209.835 280.8 R 1.67(Also, error handling has an option cus-)6.67 F
+(tomized for BerkNet.)87 292.8 Q 1.482(The decision to a)112 309 R -.2(vo)-.2 G
+1.482(id doing an).2 F 3.982(yt)-.15 G 1.481(ype of deli)254.222 309 R -.15(ve)
+-.25 G 1.481(ry where possible \(e).15 F -.15(ve)-.25 G 1.481
+(n, or perhaps especially).15 F(,)-.65 E .574(local deli)87 321 R -.15(ve)-.25
+G .574(ry\) has turned out to be a good idea.).15 F(Ev)5.574 E .574
+(en with local deli)-.15 F -.15(ve)-.25 G(ry).15 E 3.074(,t)-.65 G .575
+(here are issues of the loca-)394.776 321 R .469(tion of the mailbox, the form\
+at of the mailbox, the locking protocol used, etc., that are best decided by)87
+333 R .038(other programs.)87 345 R .038(One surprisingly major anno)5.038 F
+.038(yance in man)-.1 F 2.538(yi)-.15 G .038
+(nternet mailers is that the location and for)333.684 345 R(-)-.2 E .138
+(mat of local mail is b)87 357 R .138(uilt in.)-.2 F .137
+(The feeling seems to be that local mail is so common that it should be ef)
+5.137 F<8c2d>-.25 E 3.045(cient. This)87 369 R .545
+(feeling is not born out by our e)3.045 F .545(xperience; on the contrary)-.15
+F 3.045(,t)-.65 G .545(he location and format of mail-)376.575 369 R(box)87 381
+Q(es seems to v)-.15 E(ary widely from system to system.)-.25 E .681
+(The ability to automatically generate a response to incoming mail \(by forw)
+112 397.2 R .68(arding mail to a pro-)-.1 F .435
+(gram\) seems useful \(\231I am on v)87 409.2 R .435
+(acation until late August....)-.25 F 2.935(\232\) b)-.7 F .435
+(ut can create problems such as forw)-.2 F(ard-)-.1 E .143(ing loops \(tw)87
+421.2 R 2.643(op)-.1 G .143(eople on v)152.609 421.2 R .143(acation whose prog\
+rams send notes back and forth, for instance\) if these pro-)-.25 F .732
+(grams are not well written.)87 433.2 R 3.232(Ap)5.732 G .732
+(rogram could be written to do standard tasks correctly)218.592 433.2 R 3.233
+(,b)-.65 G .733(ut this w)450.404 433.2 R(ould)-.1 E(solv)87 445.2 Q 2.5(et)
+-.15 G(he general case.)113.24 445.2 Q .225
+(It might be desirable to implement some form of load limiting.)112 461.4 R
+2.725(Ia)5.225 G 2.724(mu)380.8 461.4 S(na)396.304 461.4 Q -.1(wa)-.15 G .224
+(re of an).1 F 2.724(ym)-.15 G .224(ail system)463.496 461.4 R
+(that addresses this problem, nor am I a)87 473.4 Q -.1(wa)-.15 G(re of an).1 E
+2.5(yr)-.15 G(easonable solution at this time.)294.05 473.4 Q .113(The con\214\
+guration \214le is currently practically inscrutable; considerable con)112
+489.6 R -.15(ve)-.4 G .114(nience could be real-).15 F(ized with a higher)87
+501.6 Q(-le)-.2 E -.15(ve)-.25 G 2.5(lf).15 G(ormat.)186.93 501.6 Q .778(It se\
+ems clear that common protocols will be changing soon to accommodate changing \
+require-)112 517.8 R 2.774(ments and en)87 529.8 R 5.274(vironments. These)-.4
+F 2.774(changes will include modi\214cations to the message header \(e.g.,)
+5.274 F .859([NBS80]\) or to the body of the message itself \(such as for mult\
+imedia messages [Postel80]\).)87 541.8 R(Experi-)5.859 E
+(ence indicates that these changes should be relati)87 553.8 Q -.15(ve)-.25 G
+(ly tri).15 E(vial to inte)-.25 E(grate into the e)-.15 E(xisting system.)-.15
+E .811(In tightly coupled en)112 570 R .812(vironments, it w)-.4 F .812
+(ould be nice to ha)-.1 F 1.112 -.15(ve a n)-.2 H .812(ame serv).15 F .812
+(er such as Grapvine [Bir)-.15 F(-)-.2 E .095(rell82] inte)87 582 R .095
+(grated into the mail system.)-.15 F .095(This w)5.095 F .095(ould allo)-.1 F
+2.594(was)-.25 G .094(ite such as \231Berk)330.768 582 R(ele)-.1 E .094
+(y\232 to appear as a single)-.15 F 2.606
+(host, rather than as a collection of hosts, and w)87 594 R 2.606(ould allo)-.1
+F 5.106(wp)-.25 G 2.606(eople to mo)352.786 594 R 2.906 -.15(ve t)-.15 H 2.606
+(ransparently among).15 F 1.664(machines without ha)87 606 R 1.664
+(ving to change their addresses.)-.2 F 1.664(Such a f)6.664 F 1.664(acility w)
+-.1 F 1.663(ould require an automatically)-.1 F .428
+(updated database and some method of resolving con\215icts.)87 618 R .428
+(Ideally this w)5.428 F .428(ould be ef)-.1 F(fecti)-.25 E .728 -.15(ve e)-.25
+H -.15(ve)-.1 G 2.928(nw).15 G(ithout)480.66 618 Q .184
+(all hosts being under a single management.)87 630 R(Ho)5.184 E(we)-.25 E -.15
+(ve)-.25 G .984 -.4(r, i).15 H 2.684(ti).4 G 2.683(sn)317.576 630 S .183
+(ot clear whether this feature should be inte-)329.149 630 R
+(grated into the aliasing f)87 642 Q(acility or should be considered a \231v)
+-.1 E(alue added\232 feature outside)-.25 E F1(sendmail)2.5 E F2(itself.)2.5 E
+.79(As a more interesting case, the CSNET name serv)112 658.2 R .791
+(er [Solomon81] pro)-.15 F .791(vides an f)-.15 F .791(acility that goes)-.1 F
+(be)87 670.2 Q .375(yond a single tightly-coupled en)-.15 F 2.875
+(vironment. Such)-.4 F 2.875(af)2.875 G .375(acility w)308.675 670.2 R .374
+(ould normally e)-.1 F .374(xist outside of)-.15 F F1(sendmail)2.874 E F2(ho)87
+682.2 Q(we)-.25 E -.15(ve)-.25 G -.55(r.).15 G EP
+%%Page: 11 11
+%%BeginPageSetup
+BP
+%%EndPageSetup
+/F0 10/Times-Bold@0 SF(SENDMAIL \212 An Inter)72 60 Q(netw)-.15 E
+(ork Mail Router)-.1 E(SMM:9-11)457.9 60 Q -.55(AC)72 96 S(KNO).55 E
+(WLEDGEMENTS)-.5 E/F1 10/Times-Roman@0 SF 1.203(Thanks are due to K)97 112.2 R
+1.204
+(urt Shoens for his continual cheerful assistance and good advice, Bill Jo)-.15
+F 3.704(yf)-.1 G(or)495.67 112.2 Q .102
+(pointing me in the correct direction \(o)72 124.2 R -.15(ve)-.15 G 2.602(ra)
+.15 G .102(nd o)244.324 124.2 R -.15(ve)-.15 G .102
+(r\), and Mark Horton for more advice, prodding, and man).15 F(y)-.15 E .453
+(of the good ideas.)72 136.2 R -.15(Ku)5.453 G .453
+(rt and Eric Schmidt are to be credited for using).15 F/F2 10/Times-Italic@0 SF
+(delivermail)2.953 E F1 .453(as a serv)2.953 F .453(er for their pro-)-.15 F
+1.663(grams \()72 148.2 R F2(Mail)A F1 1.663(and BerkNet respecti)4.163 F -.15
+(ve)-.25 G 1.663(ly\) before an).15 F 4.163(ys)-.15 G 1.663
+(ane person should ha)291.091 148.2 R -.15(ve)-.2 G 4.163(,a).15 G 1.662
+(nd making the necessary)400.423 148.2 R .078
+(modi\214cations promptly and happily)72 160.2 R 5.078(.E)-.65 G .078(ric g)
+228.332 160.2 R -2.25 -.2(av e)-.05 H .079
+(me considerable advice about the perils of netw)2.778 F .079(ork softw)-.1 F
+(are)-.1 E .179(which sa)72 172.2 R -.15(ve)-.2 G 2.679(dm).15 G 2.679(ea)
+131.998 172.2 S 2.679(nu)143.557 172.2 S(nkno)156.236 172.2 Q .178
+(wn amount of w)-.25 F .178(ork and grief.)-.1 F .178
+(Mark did the original implementation of the DBM)5.178 F -.15(ve)72 184.2 S
+.341(rsion of aliasing, installed the VFORK code, wrote the current v).15 F
+.341(ersion of)-.15 F F2(rmail)2.841 E F1 2.841(,a)C .341(nd w)411.083 184.2 R
+.342(as the person who)-.1 F .61(really con)72 196.2 R .61
+(vinced me to put the w)-.4 F .61(ork into)-.1 F F2(delivermail)3.109 E F1 .609
+(to turn it into)3.109 F F2(sendmail)3.109 E F1 5.609(.K)C .609(urt deserv)
+398.753 196.2 R .609(es accolades for)-.15 F(using)72 208.2 Q F2(sendmail)2.57
+E F1 .07(when I w)2.57 F .07(as myself afraid to tak)-.1 F 2.57(et)-.1 G .07
+(he risk; ho)271.01 208.2 R 2.57(wap)-.25 G .07
+(erson can continue to be so enthusiastic in)334.92 208.2 R(the f)72 220.2 Q
+(ace of so much bitter reality is be)-.1 E(yond me.)-.15 E -.15(Ku)97 236.4 S
+1.505(rt, Mark, Kirk McK).15 F 1.505(usick, Marvin Solomon, and man)-.15 F
+4.005(yo)-.15 G 1.504(thers ha)345.79 236.4 R 1.804 -.15(ve r)-.2 H -.25(ev).15
+G(ie).25 E 1.504(wed this paper)-.25 F 4.004(,g)-.4 G -.25(iv)483.69 236.4 S
+(ing).25 E(considerable useful advice.)72 248.4 Q .846
+(Special thanks are reserv)97 264.6 R .846(ed for Mik)-.15 F 3.346(eS)-.1 G
+(tonebrak)256.786 264.6 Q .846(er at Berk)-.1 F(ele)-.1 E 3.347(ya)-.15 G .847
+(nd Bob Epstein at Britton-Lee, who)356.995 264.6 R .542(both kno)72 276.6 R
+.542(wingly allo)-.25 F .542(wed me to put so much w)-.25 F .541
+(ork into this project when there were so man)-.1 F 3.041(yo)-.15 G .541
+(ther things I)454.588 276.6 R(really should ha)72 288.6 Q .3 -.15(ve b)-.2 H
+(een w).15 E(orking on.)-.1 E EP
+%%Page: 12 12
+%%BeginPageSetup
+BP
+%%EndPageSetup
+/F0 10/Times-Roman@0 SF(REFERENCES)256.605 132 Q 62.73([Birrell82] Birrell,)72
+148.2 R 1.084(A. D., Le)3.584 F 1.084(vin, R., Needham, R. M., and Schroeder)
+-.25 F 3.584(,M)-.4 G 3.585(.D)433.49 148.2 S 1.085(., \231Grape)446.795 148.2
+R(vine:)-.25 E(An Ex)180 160.2 Q(ercise in Distrib)-.15 E(uted Computing.)-.2 E
+5<9a49>-.7 G(n)348.66 160.2 Q/F1 10/Times-Italic@0 SF(Comm. A.C.M. 25,)2.5 E F0
+(4, April 82.)2.5 E 59.4([Borden79] Borden,)72 176.4 R .796
+(S., Gaines, R. S., and Shapiro, N. Z.,)3.296 F F1 .795(The MH Messa)3.295 F
+.995 -.1(ge H)-.1 H .795(andling Sys-).1 F(tem: User)180 188.4 Q(s' Manual.)-.1
+E F0(R-2367-P)5 E(AF)-.92 E 5(.R)-.8 G(and Corporation.)332.06 188.4 Q
+(October 1979.)5 E([Crock)72 204.6 Q 52.29(er77a] Crock)-.1 F(er)-.1 E 2.508
+(,D)-.4 G 2.508(.H)223.938 204.6 S .008(., V)236.166 204.6 R .009
+(ittal, J. J., Pogran, K. T)-.6 F .009(., and Henderson, D. A. Jr)-.74 F(.,)
+-.55 E F1(Standar)2.509 E 2.509(df)-.37 G(or)495.11 204.6 Q .955(the F)180
+216.6 R .955(ormat of ARP)-1.05 F 3.454(AN)-.9 G .954(etwork T)272.978 216.6 R
+-.2(ex)-.92 G 3.454(tM).2 G(essa)331.536 216.6 Q -.1(ge)-.1 G(s.).1 E F0 .954
+(RFC 733, NIC 41952.)5.954 F .954(In [Fein-)5.954 F 2.5(ler78]. No)180 228.6 R
+-.15(ve)-.15 G(mber 1977.).15 E([Crock)72 244.8 Q 51.73(er77b] Crock)-.1 F(er)
+-.1 E 3.04(,D)-.4 G 3.04(.H)224.47 244.8 S(.,)237.23 244.8 Q F1 -1.55 -.55
+(Fr a)3.04 H(me).55 E .54(work and Functions of the MS P)-.15 F(er)-.8 E .54
+(sonal Messa)-.1 F .74 -.1(ge S)-.1 H(ystem.).1 E F0(R-2134-ARP)180 256.8 Q
+(A, Rand Corporation, Santa Monica, California.)-.92 E(1977.)5 E([Crock)72 273
+Q 56.73(er79] Crock)-.1 F(er)-.1 E 2.557(,D)-.4 G 2.557(.H)223.987 273 S .056
+(., Szurk)236.264 273 R -.25(ow)-.1 G .056(ski, E. S., and F).25 F(arber)-.15 E
+2.556(,D)-.4 G 2.556(.J)374.85 273 S(.,)383.796 273 Q F1 .056
+(An Internetwork Memo Dis-)2.556 F(trib)180 285 Q 1.341(ution F)-.2 F 1.341
+(acility \212 MMDF)-.75 F(.)-1.35 E F0 1.341
+(6th Data Communication Symposium, Asilomar)6.341 F(.)-.55 E(No)180 297 Q -.15
+(ve)-.15 G(mber 1979.).15 E([Crock)72 313.2 Q 56.73(er82] Crock)-.1 F(er)-.1 E
+3.383(,D)-.4 G 3.383(.H)224.813 313.2 S(.,)237.916 313.2 Q F1(Standar)3.383 E
+3.383(df)-.37 G .883(or the F)288.762 313.2 R .882(ormat of Arpa Internet T)
+-1.05 F -.2(ex)-.92 G 3.382(tM).2 G(essa)446.368 313.2 Q -.1(ge)-.1 G(s.).1 E
+F0(RFC)5.882 E 4.197(822. Netw)180 325.2 R 1.697(ork Information Center)-.1 F
+4.197(,S)-.4 G 1.698(RI International, Menlo P)333.768 325.2 R 1.698
+(ark, California.)-.15 F(August 1982.)180 337.2 Q 53.3([Metcalfe76] Metcalfe,)
+72 353.4 R .727(R., and Boggs, D., \231Ethernet: Distrib)3.227 F .727(uted P)
+-.2 F(ack)-.15 E .727(et Switching for Local)-.1 F(Computer Netw)180 365.4 Q
+(orks\232,)-.1 E F1(Communications of the A)2.5 E(CM 19,)-.3 E F0 2.5(7. July)
+2.5 F(1976.)2.5 E 60.51([Feinler78] Feinler)72 381.6 R 4.438(,E)-.4 G 1.938
+(., and Postel, J.)220.978 381.6 R(\(eds.\),)6.938 E F1(ARP)4.438 E 1.938
+(ANET Pr)-.9 F 1.938(otocol Handbook.)-.45 F F0 1.938(NIC 7104,)6.938 F(Netw)
+180 393.6 Q(ork Information Center)-.1 E 2.5(,S)-.4 G
+(RI International, Menlo P)304.48 393.6 Q(ark, California.)-.15 E(1978.)5 E
+69.39([NBS80] National)72 409.8 R 1.46(Bureau of Standards,)3.96 F F1 1.46
+(Speci\214cation of a Dr)3.96 F 1.46(aft Messa)-.15 F 1.66 -.1(ge F)-.1 H 1.46
+(ormat Stan-)-.95 F(dar)180 421.8 Q(d.)-.37 E F0(Report No. ICST/CBOS 80-2.)5 E
+(October 1980.)5 E 60.51([Neigus73] Neigus,)72 438 R(N.,)5.186 E F1 -.45(Fi)
+5.186 G 2.686(le T).45 F -.15(ra)-.55 G 2.686(nsfer Pr).15 F 2.686
+(otocol for the ARP)-.45 F 5.187(AN)-.9 G(etwork.)402.599 438 Q F0 2.687
+(RFC 542, NIC)7.687 F 2.5(17759. In)180 450 R 2.5([Feinler78]. August,)2.5 F
+(1973.)2.5 E([No)72 466.2 Q 55.21(witz78a] No)-.25 F 1.633
+(witz, D. A., and Lesk, M. E.,)-.25 F F1 4.132(AD)4.132 G 1.632
+(ial-Up Network of UNIX Systems.)338.9 466.2 R F0(Bell)6.632 E 5.403
+(Laboratories. In)180 478.2 R 2.904(UNIX Programmer')5.403 F 5.404(sM)-.55 G
+2.904(anual, Se)356.024 478.2 R -.15(ve)-.25 G 2.904(nth Edition, V).15 F 2.904
+(olume 2.)-1.29 F(August, 1978.)180 490.2 Q([No)72 506.4 Q 54.65(witz78b] No)
+-.25 F .633(witz, D. A.,)-.25 F F1 .632(Uucp Implementation Description.)3.132
+F F0 .632(Bell Laboratories.)5.632 F .632(In UNIX)5.632 F(Programmer')180 518.4
+Q 2.5(sM)-.55 G(anual, Se)248.05 518.4 Q -.15(ve)-.25 G(nth Edition, V).15 E
+(olume 2.)-1.29 E(October)5 E 2.5(,1)-.4 G(978.)431.22 518.4 Q 64.39
+([Postel74] Postel,)72 534.6 R .24(J., and Neigus, N., Re)2.74 F .241
+(vised FTP Reply Codes.)-.25 F .241(RFC 640, NIC 30843.)5.241 F(In)5.241 E 2.5
+([Feinler78]. June,)180 546.6 R(1974.)2.5 E 64.39([Postel77] Postel,)72 562.8 R
+(J.,)2.5 E F1(Mail Pr)2.5 E(otocol.)-.45 E F0(NIC 29588.)5 E(In [Feinler78].)5
+E(No)5 E -.15(ve)-.15 G(mber 1977.).15 E 59.95([Postel79a] Postel,)72 579 R
+(J.,)3.144 E F1 .644(Internet Messa)3.144 F .844 -.1(ge P)-.1 H -.45(ro).1 G
+(tocol.).45 E F0 .644(RFC 753, IEN 85.)5.644 F(Netw)5.644 E .644
+(ork Information)-.1 F(Center)180 591 Q 2.5(,S)-.4 G(RI International, Menlo P)
+216.82 591 Q(ark, California.)-.15 E(March 1979.)5 E 59.39([Postel79b] Postel,)
+72 607.2 R 1.305(J. B.,)3.805 F F1 1.305(An Internetwork Messa)3.805 F 1.505
+-.1(ge S)-.1 H(tructur).1 E -.15(e.)-.37 G F0(In)6.456 E F1(Pr)3.806 E 1.306
+(oceedings of the Sixth)-.45 F(Data Communications Symposium,)180 619.2 Q F0
+2.5(IEEE. Ne)2.5 F 2.5(wY)-.25 G 2.5(ork. No)379.74 619.2 R -.15(ve)-.15 G
+(mber 1979.).15 E 64.39([Postel80] Postel,)72 635.4 R .639(J. B.,)3.139 F F1
+3.139(AS)3.139 G(tructur)248.676 635.4 Q .639(ed F)-.37 F .639(ormat for T)
+-1.05 F -.15(ra)-.55 G .639(nsmission of Multi-Media Documents.).15 F F0 .418
+(RFC 767.)180 647.4 R(Netw)5.419 E .419(ork Information Center)-.1 F 2.919(,S)
+-.4 G .419(RI International, Menlo P)350.474 647.4 R .419(ark, Califor)-.15 F
+(-)-.2 E 2.5(nia. August)180 659.4 R(1980.)2.5 E 64.39([Postel82] Postel,)72
+675.6 R 2.05(J. B.,)4.55 F F1 2.05(Simple Mail T)4.55 F -.15(ra)-.55 G 2.05
+(nsfer Pr).15 F(otocol.)-.45 E F0 2.05(RFC821 \(obsoleting RFC788\).)7.05 F
+(Netw)180 687.6 Q .273(ork Information Center)-.1 F 2.774(,S)-.4 G .274
+(RI International, Menlo P)305.3 687.6 R .274(ark, California.)-.15 F(August)
+5.274 E(1982.)180 699.6 Q/F2 10/Times-Bold@0 SF 187.28(SMM:9-12 SENDMAIL)72 756
+R 2.5<8a41>2.5 G 2.5(nI)383.99 756 S(nter)395.94 756 Q(netw)-.15 E
+(ork Mail Router)-.1 E EP
+%%Page: 13 13
+%%BeginPageSetup
+BP
+%%EndPageSetup
+/F0 10/Times-Bold@0 SF(SENDMAIL \212 An Inter)72 60 Q(netw)-.15 E
+(ork Mail Router)-.1 E(SMM:9-13)457.9 60 Q/F1 10/Times-Roman@0 SF 55.5
+([Schmidt79] Schmidt,)72 96 R(E.,)2.972 E/F2 10/Times-Italic@0 SF .472(An Intr)
+2.972 F .472(oduction to the Berk)-.45 F(ele)-.1 E 2.972(yN)-.3 G(etwork.)
+369.664 96 Q F1(Uni)5.472 E -.15(ve)-.25 G .472(rsity of California,).15 F
+(Berk)180 108 Q(ele)-.1 E 2.5(yC)-.15 G 2.5(alifornia. 1979.)225.02 108 R 59.95
+([Shoens79] Shoens,)72 124.2 R(K.,)4.894 E F2 2.394(Mail Refer)4.894 F 2.394
+(ence Manual.)-.37 F F1(Uni)7.394 E -.15(ve)-.25 G 2.395
+(rsity of California, Berk).15 F(ele)-.1 E 6.195 -.65(y. I)-.15 H(n).65 E
+(UNIX Programmer')180 136.2 Q 2.5(sM)-.55 G(anual, Se)275.54 136.2 Q -.15(ve)
+-.25 G(nth Edition, V).15 E(olume 2C.)-1.29 E(December 1979.)5 E 60.51
+([Sluizer81] Sluizer)72 152.4 R 2.872(,S)-.4 G .372(., and Postel, J. B.,)
+218.862 152.4 R F2 .372(Mail T)2.872 F -.15(ra)-.55 G .372(nsfer Pr).15 F
+(otocol.)-.45 E F1 .371(RFC 780.)5.371 F(Netw)5.371 E .371(ork Infor)-.1 F(-)
+-.2 E(mation Center)180 164.4 Q 2.5(,S)-.4 G(RI International, Menlo P)247.1
+164.4 Q(ark, California.)-.15 E(May 1981.)5 E 52.72([Solomon81] Solomon,)72
+180.6 R .96(M., Landweber)3.46 F 3.46(,L)-.4 G .96
+(., and Neuhengen, D., \231The Design of the CSNET)296.08 180.6 R(Name Serv)180
+192.6 Q(er)-.15 E 3.9 -.7(.\232 C)-.55 H(S-DN-2, Uni).7 E -.15(ve)-.25 G
+(rsity of W).15 E(isconsin, Madison.)-.4 E(No)5 E -.15(ve)-.15 G(mber 1981.).15
+E 78.28([Su82] Su,)72 208.8 R(Za)4.344 E 1.844(w-Sing, and Postel, Jon,)-.15 F
+F2 1.844(The Domain Naming Con)4.344 F 1.844(vention for Internet)-.4 F 1.717
+(User Applications.)180 220.8 R F1 4.217(RFC819. Netw)6.717 F 1.717
+(ork Information Center)-.1 F 4.217(,S)-.4 G 1.718(RI International,)436.182
+220.8 R(Menlo P)180 232.8 Q(ark, California.)-.15 E(August 1982.)5 E([UNIX83])
+72 249 Q F2 2.12(The UNIX Pr)180 249 R -.1(og)-.45 G -.15(ra).1 G(mmer').15 E
+4.62(sM)-.4 G 2.12(anual, Se)298.3 249 R 2.12(venth Edition,)-.15 F F1 -.6(Vi)
+4.62 G 2.12(rtual V).6 F 2.12(AX-11 V)-1.35 F(ersion,)-1.11 E -1.29(Vo)180 261
+S 1.027(lume 1.)1.29 F 1.027(Bell Laboratories, modi\214ed by the Uni)6.027 F
+-.15(ve)-.25 G 1.027(rsity of California, Berk).15 F(e-)-.1 E(le)180 273 Q 1.3
+-.65(y, C)-.15 H 2.5(alifornia. March,).65 F(1983.)2.5 E EP
+%%Trailer
+end
+%%EOF
diff --git a/usr.sbin/sendmail/doc/op/Makefile b/usr.sbin/sendmail/doc/op/Makefile
new file mode 100644
index 0000000..e8f791a
--- /dev/null
+++ b/usr.sbin/sendmail/doc/op/Makefile
@@ -0,0 +1,13 @@
+# @(#)Makefile 8.2 (Berkeley) 2/28/94
+
+DIR= smm/08.sendmailop
+SRCS= op.me
+MACROS= -me
+
+all: op.ps
+
+op.ps: ${SRCS}
+ rm -f ${.TARGET}
+ ${PIC} ${SRCS} | ${EQN} | ${ROFF} > ${.TARGET}
+
+.include <bsd.doc.mk>
diff --git a/usr.sbin/sendmail/doc/op/op.me b/usr.sbin/sendmail/doc/op/op.me
new file mode 100644
index 0000000..9678d14
--- /dev/null
+++ b/usr.sbin/sendmail/doc/op/op.me
@@ -0,0 +1,6921 @@
+.\" Copyright (c) 1983 Eric P. Allman
+.\" Copyright (c) 1983, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)op.me 8.36 (Berkeley) 4/14/94
+.\"
+.\" eqn op.me | pic | troff -me
+.eh 'SMM:08-%''Sendmail Installation and Operation Guide'
+.oh 'Sendmail Installation and Operation Guide''SMM:08-%'
+.\" SD is lib if sendmail is installed in /usr/lib, sbin if in /usr/sbin
+.ds SD sbin
+.\" SB is bin if newaliases/mailq are installed in /usr/bin, ucb if in /usr/ucb
+.ds SB bin
+.nr si 3n
+.de $0
+.(x
+.in \\$3u*3n
+.ti -3n
+\\$2. \\$1
+.)x
+..
+.de $C
+.(x
+.in 0
+\\$1 \\$2. \\$3
+.)x
+..
+.sc
+.+c
+.(l C
+.sz 16
+.b SENDMAIL
+.sz 12
+.sp
+.b "INSTALLATION AND OPERATION GUIDE"
+.sz 10
+.sp
+.r
+Eric Allman
+University of California, Berkeley
+Mammoth Project
+eric@CS.Berkeley.EDU
+.sp
+Version 8.36
+.sp
+For Sendmail Version 8.6
+.)l
+.sp 2
+.pp
+.i Sendmail
+implements a general purpose internetwork mail routing facility
+under the UNIX*
+.(f
+*UNIX is a trademark of Unix Systems Laboratories.
+.)f
+operating system.
+It is not tied to any one transport protocol \*-
+its function may be likened to a crossbar switch,
+relaying messages from one domain into another.
+In the process,
+it can do a limited amount of message header editing
+to put the message into a format that is appropriate
+for the receiving domain.
+All of this is done under the control of a configuration file.
+.pp
+Due to the requirements of flexibility
+for
+.i sendmail ,
+the configuration file can seem somewhat unapproachable.
+However, there are only a few basic configurations
+for most sites,
+for which standard configuration files have been supplied.
+Most other configurations
+can be built by adjusting an existing configuration files
+incrementally.
+.pp
+.i Sendmail
+is based on
+RFC822 (Internet Mail Format Protocol),
+RFC821 (Simple Mail Transport Protocol),
+RFC1123 (Internet Host Requirements),
+and
+RFC1425 (SMTP Service Extensions).
+However, since
+.i sendmail
+is designed to work in a wider world,
+in many cases it can be configured to exceed these protocols.
+These cases are described herein.
+.pp
+Although
+.i sendmail
+is intended to run
+without the need for monitoring,
+it has a number of features
+that may be used to monitor or adjust the operation
+under unusual circumstances.
+These features are described.
+.pp
+Section one describes how to do a basic
+.i sendmail
+installation.
+Section two
+explains the day-to-day information you should know
+to maintain your mail system.
+If you have a relatively normal site,
+these two sections should contain sufficient information
+for you to install
+.i sendmail
+and keep it happy.
+Section three
+describes some parameters that may be safely tweaked.
+Section four
+has information regarding the command line arguments.
+Section five
+contains the nitty-gritty information about the configuration
+file.
+This section is for masochists
+and people who must write their own configuration file.
+Section six
+describes configuration that can be done at compile time.
+Section seven
+gives a brief description of differences
+in this version of
+.i sendmail .
+The appendixes give a brief
+but detailed explanation of a number of features
+not described in the rest of the paper.
+.bp 7
+.sh 1 "BASIC INSTALLATION"
+.pp
+There are two basic steps to installing
+.i sendmail .
+The hard part is to build the configuration table.
+This is a file that
+.i sendmail
+reads when it starts up
+that describes the mailers it knows about,
+how to parse addresses,
+how to rewrite the message header,
+and the settings of various options.
+Although the configuration table is quite complex,
+a configuration can usually be built
+by adjusting an existing off-the-shelf configuration.
+The second part is actually doing the installation,
+i.e., creating the necessary files, etc.
+.pp
+The remainder of this section will describe the installation of
+.i sendmail
+assuming you can use one of the existing configurations
+and that the standard installation parameters are acceptable.
+All pathnames and examples
+are given from the root of the
+.i sendmail
+subtree,
+normally
+.i /usr/src/usr.\*(SD/sendmail
+on 4.4BSD.
+.pp
+If you are loading this off the tape,
+continue with the next section.
+If you have a running binary already on your system,
+you should probably skip to section 1.2.
+.sh 2 "Compiling Sendmail"
+.pp
+All
+.i sendmail
+source is in the
+.i src
+subdirectory.
+If you are running on a 4.4BSD system,
+compile by typing
+.q make .
+On other systems, you may have to make some other adjustments.
+.sh 3 "Old versions of make"
+.pp
+If you are not running the new version of
+.b make
+you will probably have to use
+.(b
+make \-f Makefile.dist
+.)b
+This file does not assume several new syntaxes,
+including the
+.q +=
+syntax in macro definition
+and the
+.q ".include"
+syntax.
+.sh 3 "Compilation flags"
+.pp
+.i Sendmail
+supports two different formats
+for the
+.i aliases
+database.
+These formats are:
+.nr ii 1i
+.ip NDBM
+The ``new DBM'' format,
+available on nearly all systems around today.
+This was the preferred format prior to 4.4BSD.
+It allows such complex things as multiple databases
+and closing a currently open database.
+.ip NEWDB
+The new database package from Berkeley.
+If you have this, use it.
+It allows
+long records,
+multiple open databases,
+real in-memory caching,
+and so forth.
+You can define this in conjunction with one of the other two;
+if you do,
+old databases are read,
+but when a new database is created it will be in NEWDB format.
+As a nasty hack,
+if you have NEWDB, NDBM, and NIS defined,
+and if the file
+.i /var/yp/Makefile
+exists and is readable,
+.i sendmail
+will create both new and old versions of the alias file
+during a
+.i newalias
+command.
+This is required because the Sun NIS/YP system
+reads the DBM version of the alias file.
+It's ugly as sin,
+but it works.
+.lp
+If neither of these are defined,
+.i sendmail
+reads the alias file into memory on every invocation.
+This can be slow and should be avoided.
+.pp
+System V based systems can define
+SYSTEM5
+to make several small adjustments.
+This changes the handling of timezones
+and uses the much less efficient
+.i lockf
+call in preference to
+.i flock .
+These can be specified separately using the compilation flags
+SYS5TZ
+and
+LOCKF
+respectively.
+.pp
+If you don't have the
+.i unsetenv
+routine in your system library, define the UNSETENV compilation flag.
+.pp
+You may also have to define the compilation variable LA_TYPE
+to describe how your load average is computed.
+This and other flags are detailed in section 6.1.
+.sh 3 "Compilation and installation"
+.pp
+After making the local system configuration described above,
+You should be able to compile and install the system.
+Compilation can be performed using
+.q make\**
+.(f
+\**where you may have to replace
+.q make
+with
+.q "make \-f Makefile.dist"
+as appropriate.
+.)f
+in the
+.b sendmail/src
+directory.
+You may be able to install using
+.(b
+make install
+.)b
+This should install the binary in
+/usr/\*(SD
+and create links from
+/usr/\*(SB/newaliases
+and
+/usr/\*(SB/mailq
+to
+/usr/\*(SD/sendmail.
+On 4.4BSD systems it will also format and install man pages.
+.sh 2 "Configuration Files"
+.pp
+.i Sendmail
+cannot operate without a configuration file.
+The configuration defines the mail systems understood at this site,
+how to access them,
+how to forward email to remote mail systems,
+and a number of tuning parameters.
+This configuration file is detailed
+in the later portion of this document.
+.pp
+The
+.i sendmail
+configuration can be daunting at first.
+The world is complex,
+and the mail configuration reflects that.
+The distribution includes an m4-based configuration package
+that hides a lot of the complexity.
+.pp
+These configuration files are simpler than old versions
+largely because the world has become simpler;
+in particular,
+text-based host files are officially eliminated,
+obviating the need to
+.q hide
+hosts behind a registered internet gateway.
+.pp
+These files also assume that most of your neighbors
+use domain-based UUCP addressing;
+that is,
+instead of naming hosts as
+.q host!user
+they will use
+.q host.domain!user .
+The configuration files can be customized to work around this,
+but it is more complex.
+.pp
+I haven't tested these yet on an isolated LAN environment
+with a single UUCP connection to the outside world.
+If you are in such an environment,
+please send comments to
+sendmail@CS.Berkeley.EDU.
+.pp
+Our configuration files are processed by
+.i m4
+to facilitate local customization;
+the directory
+.i cf
+of the
+.i sendmail
+distribution directory
+contains the source files.
+This directory contains several subdirectories:
+.nr ii 1i
+.ip cf
+Both site-dependent and site-independent descriptions of hosts.
+These can be literal host names
+(e.g.,
+.q ucbvax.mc )
+when the hosts are gateways
+or more general descriptions
+(such as
+.q "tcpproto.mc"
+as a general description of an SMTP-connected host
+or
+.q "uucpproto.mc"
+as a general description of a UUCP-connected host).
+Files ending
+.b \&.mc
+(``Master Configuration'')
+are the input descriptions;
+the output is in the corresponding
+.b \&.cf
+file.
+The general structure of these files is described below.
+.ip domain
+Site-dependent subdomain descriptions.
+These are tied to the way your organization wants to do addressing.
+For example,
+.b domain/cs.exposed.m4
+is our description for hosts in the CS.Berkeley.EDU subdomain
+that want their individual hostname to be externally visible;
+.b domain/cs.hidden.m4
+is the same except that the hostname is hidden
+(everything looks like it comes from CS.Berkeley.EDU).
+These are referenced using the
+.sm DOMAIN
+.b m4
+macro in the
+.b \&.mc
+file.
+.ip feature
+Definitions of specific features that some particular host in your site
+might want.
+These are referenced using the
+.sm FEATURE
+.b m4
+macro.
+An example feature is
+use_cw_file
+(which tells
+.i sendmail
+to read an /etc/sendmail.cw file on startup
+to find the set of local names).
+.ip hack
+Local hacks, referenced using the
+.sm HACK
+.b m4
+macro.
+Try to avoid these.
+The point of having them here is to make it clear that they smell.
+.ip m4
+Site-independent
+.i m4 (1)
+include files that have information common to all configuration files.
+This can be thought of as a
+.q #include
+directory.
+.ip mailer
+Definitions of mailers,
+referenced using the
+.sm MAILER
+.b m4
+macro.
+Defined mailer types in this distribution are
+fax,
+local,
+smtp,
+uucp,
+and usenet.
+.ip ostype
+Definitions describing various operating system environments
+(such as the location of support files).
+These are referenced using the
+.sm OSTYPE
+.b m4
+macro.
+.ip sh
+Shell files used by the
+.b m4
+build process.
+You shouldn't have to mess with these.
+.ip siteconfig
+Local site configuration information,
+such as UUCP connectivity.
+They normally contain lists of site information, for example:
+.(b
+SITE(contessa)
+SITE(hoptoad)
+SITE(nkainc)
+SITE(well)
+.)b
+They are referenced using the SITECONFIG macro:
+.(b
+SITECONFIG(site.config.file, name_of_site, X)
+.)b
+where
+.i X
+is the macro/class name to use.
+It can be U
+(indicating locally connected hosts)
+or one of W, X, or Y
+for up to three remote UUCP hubs.
+.pp
+If you are in a new domain
+(e.g., a company),
+you will probably want to create a
+cf/domain
+file for your domain.
+This consists primarily of relay definitions:
+for example, Berkeley's domain definition
+defines relays for
+BitNET,
+CSNET,
+and UUCP.
+Of these,
+only the UUCP relay is particularly specific
+to Berkeley.
+All of these are internet-style domain names.
+Please check to make certain they are reasonable for your domain.
+.pp
+Subdomains at Berkeley are also represented in the
+cf/domain
+directory.
+For example,
+the domain
+cs-exposed
+is the Computer Science subdomain with the local hostname shown
+to other users;
+cs-hidden
+makes users appear to be from the CS.Berkeley.EDU subdomain
+(with no local host information included).
+You will probably have to update this directory
+to be appropriate for your domain.
+.pp
+You will have to use or create
+.b \&.mc
+files in the
+.i cf/cf
+subdirectory for your hosts.
+This is detailed in the
+cf/README
+file.
+.sh 2 "Details of Installation Files"
+.pp
+This subsection describes the files that
+comprise the
+.i sendmail
+installation.
+.sh 3 "/usr/\*(SD/sendmail"
+.pp
+The binary for
+.i sendmail
+is located in /usr/\*(SD\**.
+.(f
+\**This is usually
+/usr/sbin
+on 4.4BSD and newer systems;
+many systems install it in
+/usr/lib.
+I understand it is in /usr/ucblib
+on System V Release 4.
+.)f
+It should be setuid root.
+For security reasons,
+/, /usr, and /usr/\*(SD
+should be owned by root, mode 755\**.
+.(f
+\**Some vendors ship them owned by bin;
+this creates a security hole that is not actually related to
+.i sendmail .
+Other important directories that should have restrictive ownerships
+and permissions are
+/bin, /usr/bin, /etc, /usr/etc, /lib, and /usr/lib.
+.)f
+.sh 3 "/etc/sendmail.cf"
+.pp
+This is the configuration file for
+.i sendmail .
+This is the only non-library file name compiled into
+.i sendmail \**.
+.(f
+\**The system libraries can reference other files;
+in particular, system library subroutines that
+.i sendmail
+calls probably reference
+.i /etc/passwd
+and
+.i /etc/resolv.conf .
+.)f
+Some older systems install it in
+.b /usr/lib/sendmail.cf .
+.pp
+If you want to move this file,
+change
+.i src/pathnames.h .
+.pp
+The configuration file is normally created
+using the distribution files described above.
+If you have a particularly unusual system configuration
+you may need to create a special version.
+The format of this file is detailed in later sections
+of this document.
+.sh 3 "/usr/\*(SB/newaliases"
+.pp
+The
+.i newaliases
+command should just be a link to
+.i sendmail :
+.(b
+rm \-f /usr/\*(SB/newaliases
+ln \-s /usr/\*(SD/sendmail /usr/\*(SB/newaliases
+.)b
+This can be installed in whatever search path you prefer
+for your system.
+.sh 3 "/var/spool/mqueue"
+.pp
+The directory
+.i /var/spool/mqueue
+should be created to hold the mail queue.
+This directory should be mode 700
+and owned by root.
+.pp
+The actual path of this directory
+is defined in the
+.b Q
+option of the
+.i sendmail.cf
+file.
+.sh 3 "/etc/aliases*"
+.pp
+The system aliases are held in
+.q /etc/aliases .
+A sample is given in
+.q lib/aliases
+which includes some aliases which
+.i must
+be defined:
+.(b
+cp lib/aliases /etc/aliases
+.i "edit /etc/aliases"
+.)b
+You should extend this file with any aliases that are apropos to your system.
+.pp
+Normally
+.i sendmail
+looks at a version of these files maintained by the
+.i dbm \|(3)
+or
+.i db \|(3)
+routines.
+These are stored either in
+.q /etc/aliases.dir
+and
+.q /etc/aliases.pag
+or
+.q /etc/aliases.db
+depending on which database package you are using.
+These can initially be created as empty files,
+but they will have to be initialized promptly.
+These should be mode 644:
+.(b
+cp /dev/null /etc/aliases.dir
+cp /dev/null /etc/aliases.pag
+chmod 644 /etc/aliases.*
+newaliases
+.)b
+The
+.i db
+routines preset the mode reasonably,
+so this step can be skipped.
+The actual path of this file
+is defined in the
+.b A
+option of the
+.i sendmail.cf
+file.
+.sh 3 "/etc/rc"
+.pp
+It will be necessary to start up the
+.i sendmail
+daemon when your system reboots.
+This daemon performs two functions:
+it listens on the SMTP socket for connections
+(to receive mail from a remote system)
+and it processes the queue periodically
+to insure that mail gets delivered when hosts come up.
+.pp
+Add the following lines to
+.q /etc/rc
+(or
+.q /etc/rc.local
+as appropriate)
+in the area where it is starting up the daemons:
+.(b
+if [ \-f /usr/\*(SD/sendmail \-a \-f /etc/sendmail.cf ]; then
+ (cd /var/spool/mqueue; rm \-f [lnx]f*)
+ /usr/\*(SD/sendmail \-bd \-q30m &
+ echo \-n ' sendmail' >/dev/console
+fi
+.)b
+The
+.q cd
+and
+.q rm
+commands insure that all lock files have been removed;
+extraneous lock files may be left around
+if the system goes down in the middle of processing a message.
+The line that actually invokes
+.i sendmail
+has two flags:
+.q \-bd
+causes it to listen on the SMTP port,
+and
+.q \-q30m
+causes it to run the queue every half hour.
+.pp
+Some people use a more complex startup script,
+removing zero length qf files and df files for which there is no qf file.
+For example:
+.(b
+# remove zero length qf files
+for qffile in qf*
+do
+ if [ \-r $qffile ]
+ then
+ if [ ! \-s $qffile ]
+ then
+ echo \-n " <zero: $qffile>" > /dev/console
+ rm \-f $qffile
+ fi
+ fi
+done
+# rename tf files to be qf if the qf does not exist
+for tffile in tf*
+do
+ qffile=`echo $tffile | sed 's/t/q/'`
+ if [ \-r $tffile \-a ! \-f $qffile ]
+ then
+ echo \-n " <recovering: $tffile>" > /dev/console
+ mv $tffile $qffile
+ else
+ echo \-n " <extra: $tffile>" > /dev/console
+ rm \-f $tffile
+ fi
+done
+# remove df files with no corresponding qf files
+for dffile in df*
+do
+ qffile=`echo $dffile | sed 's/d/q/'`
+ if [ \-r $dffile \-a ! \-f $qffile ]
+ then
+ echo \-n " <incomplete: $dffile>" > /dev/console
+ mv $dffile `echo $dffile | sed 's/d/D/'`
+ fi
+done
+# announce files that have been saved during disaster recovery
+for xffile in [A-Z]f*
+do
+ echo \-n " <panic: $xffile>" > /dev/console
+done
+.)b
+.pp
+If you are not running a version of UNIX
+that supports Berkeley TCP/IP,
+do not include the
+.b \-bd
+flag.
+.sh 3 "/usr/lib/sendmail.hf"
+.pp
+This is the help file used by the SMTP
+.b HELP
+command.
+It should be copied from
+.q lib/sendmail.hf :
+.(b
+cp lib/sendmail.hf /usr/lib
+.)b
+The actual path of this file
+is defined in the
+.b H
+option of the
+.i sendmail.cf
+file.
+.sh 3 "/etc/sendmail.st"
+.pp
+If you wish to collect statistics
+about your mail traffic,
+you should create the file
+.q /etc/sendmail.st :
+.(b
+cp /dev/null /etc/sendmail.st
+chmod 666 /etc/sendmail.st
+.)b
+This file does not grow.
+It is printed with the program
+.q mailstats/mailstats.c.
+The actual path of this file
+is defined in the
+.b S
+option of the
+.i sendmail.cf
+file.
+.sh 3 "/usr/\*(SB/newaliases"
+.pp
+If
+.i sendmail
+is invoked as
+.q newaliases,
+it will simulate the
+.b \-bi
+flag
+(i.e., will rebuild the alias database;
+see below).
+This should be a link to /usr/\*(SD/sendmail.
+.sh 3 "/usr/\*(SB/mailq"
+.pp
+If
+.i sendmail
+is invoked as
+.q mailq,
+it will simulate the
+.b \-bp
+flag
+(i.e.,
+.i sendmail
+will print the contents of the mail queue;
+see below).
+This should be a link to /usr/\*(SD/sendmail.
+.sh 1 "NORMAL OPERATIONS"
+.sh 2 "The System Log"
+.pp
+The system log is supported by the
+.i syslogd \|(8)
+program.
+All messages from
+.i sendmail
+are logged under the
+.sm LOG_MAIL
+facility.
+.sh 3 "Format"
+.pp
+Each line in the system log
+consists of a timestamp,
+the name of the machine that generated it
+(for logging from several machines
+over the local area network),
+the word
+.q sendmail: ,
+and a message.
+.sh 3 "Levels"
+.pp
+If you have
+.i syslogd \|(8)
+or an equivalent installed,
+you will be able to do logging.
+There is a large amount of information that can be logged.
+The log is arranged as a succession of levels.
+At the lowest level
+only extremely strange situations are logged.
+At the highest level,
+even the most mundane and uninteresting events
+are recorded for posterity.
+As a convention,
+log levels under ten
+are considered generally
+.q useful;
+log levels above 64
+are reserved for debugging purposes.
+Levels from 11\-64 are reserved for verbose information
+that some sites might want.
+.pp
+A complete description of the log levels
+is given in section 4.6.
+.sh 2 "The Mail Queue"
+.pp
+The mail queue should be processed transparently.
+However, you may find that manual intervention is sometimes necessary.
+For example,
+if a major host is down for a period of time
+the queue may become clogged.
+Although
+.i sendmail
+ought to recover gracefully when the host comes up,
+you may find performance unacceptably bad in the meantime.
+.sh 3 "Printing the queue"
+.pp
+The contents of the queue can be printed
+using the
+.i mailq
+command
+(or by specifying the
+.b \-bp
+flag to
+.i sendmail ):
+.(b
+mailq
+.)b
+This will produce a listing of the queue id's,
+the size of the message,
+the date the message entered the queue,
+and the sender and recipients.
+.sh 3 "Forcing the queue"
+.pp
+.i Sendmail
+should run the queue automatically
+at intervals.
+The algorithm is to read and sort the queue,
+and then to attempt to process all jobs in order.
+When it attempts to run the job,
+.i sendmail
+first checks to see if the job is locked.
+If so, it ignores the job.
+.pp
+There is no attempt to insure that only one queue processor
+exists at any time,
+since there is no guarantee that a job cannot take forever
+to process
+(however,
+.i sendmail
+does include heuristics to try to abort jobs
+that are taking absurd amounts of time;
+technically, this violates RFC 821, but is blessed by RFC 1123).
+Due to the locking algorithm,
+it is impossible for one job to freeze the entire queue.
+However,
+an uncooperative recipient host
+or a program recipient
+that never returns
+can accumulate many processes in your system.
+Unfortunately,
+there is no completely general way to solve this.
+.pp
+In some cases,
+you may find that a major host going down
+for a couple of days
+may create a prohibitively large queue.
+This will result in
+.i sendmail
+spending an inordinate amount of time
+sorting the queue.
+This situation can be fixed by moving the queue to a temporary place
+and creating a new queue.
+The old queue can be run later when the offending host returns to service.
+.pp
+To do this,
+it is acceptable to move the entire queue directory:
+.(b
+cd /var/spool
+mv mqueue omqueue; mkdir mqueue; chmod 700 mqueue
+.)b
+You should then kill the existing daemon
+(since it will still be processing in the old queue directory)
+and create a new daemon.
+.pp
+To run the old mail queue,
+run the following command:
+.(b
+/usr/\*(SD/sendmail \-oQ/var/spool/omqueue \-q
+.)b
+The
+.b \-oQ
+flag specifies an alternate queue directory
+and the
+.b \-q
+flag says to just run every job in the queue.
+If you have a tendency toward voyeurism,
+you can use the
+.b \-v
+flag to watch what is going on.
+.pp
+When the queue is finally emptied,
+you can remove the directory:
+.(b
+rmdir /var/spool/omqueue
+.)b
+.sh 2 "The Alias Database"
+.pp
+The alias database exists in two forms.
+One is a text form,
+maintained in the file
+.i /etc/aliases.
+The aliases are of the form
+.(b
+name: name1, name2, ...
+.)b
+Only local names may be aliased;
+e.g.,
+.(b
+eric@prep.ai.MIT.EDU: eric@CS.Berkeley.EDU
+.)b
+will not have the desired effect.
+Aliases may be continued by starting any continuation lines
+with a space or a tab.
+Blank lines and lines beginning with a sharp sign
+(\c
+.q # )
+are comments.
+.pp
+The second form is processed by the
+.i dbm \|(3)
+(or
+.i db \|(3))
+library.
+This form is in the files
+.i /etc/aliases.dir
+and
+.i /etc/aliases.pag.
+This is the form that
+.i sendmail
+actually uses to resolve aliases.
+This technique is used to improve performance.
+.pp
+You can also use
+.sm NIS -based
+alias files.
+For example, the specification:
+.(b
+OA/etc/aliases
+OAnis:mail.aliases@my.nis.domain
+.)b
+will first search the /etc/aliases file
+and then the map named
+.q mail.aliases
+in
+.q my.nis.domain .
+Warning: if you build your own
+.sm NIS -based
+alias files,
+be sure to provide the
+.b \-l
+flag to
+.i makedbm (8)
+to map upper case letters in the keys to lower case;
+otherwise, aliases with upper case letters in their names
+won't match incoming addresses.
+.pp
+Additional flags can be added after the colon
+exactly like a
+.b K
+line \(em for example:
+.(b
+OAnis:-N mail.aliases@my.nis.domain
+.)b
+will search the appropriate NIS map and always include null bytes in the key.
+.sh 3 "Rebuilding the alias database"
+.pp
+The DB or DBM version of the database
+may be rebuilt explicitly by executing the command
+.(b
+newaliases
+.)b
+This is equivalent to giving
+.i sendmail
+the
+.b \-bi
+flag:
+.(b
+/usr/\*(SD/sendmail \-bi
+.)b
+.pp
+If the
+.q D
+option is specified in the configuration,
+.i sendmail
+will rebuild the alias database automatically
+if possible
+when it is out of date.
+Auto-rebuild can be dangerous
+on heavily loaded machines
+with large alias files;
+if it might take more than five minutes
+to rebuild the database,
+there is a chance that several processes will start the rebuild process
+simultaneously.
+.pp
+If you have multiple aliases databases specified,
+the
+.b \-bi
+flag rebuilds all the database types it understands
+(for example, it can rebuild dbm databases but not nis databases).
+.sh 3 "Potential problems"
+.pp
+There are a number of problems that can occur
+with the alias database.
+They all result from a
+.i sendmail
+process accessing the DBM version
+while it is only partially built.
+This can happen under two circumstances:
+One process accesses the database
+while another process is rebuilding it,
+or the process rebuilding the database dies
+(due to being killed or a system crash)
+before completing the rebuild.
+.pp
+Sendmail has two techniques to try to relieve these problems.
+First, it ignores interrupts while rebuilding the database;
+this avoids the problem of someone aborting the process
+leaving a partially rebuilt database.
+Second,
+at the end of the rebuild
+it adds an alias of the form
+.(b
+@: @
+.)b
+(which is not normally legal).
+Before
+.i sendmail
+will access the database,
+it checks to insure that this entry exists\**.
+.(f
+\**The
+.q a
+option is required in the configuration
+for this action to occur.
+This should normally be specified.
+.)f
+.sh 3 "List owners"
+.pp
+If an error occurs on sending to a certain address,
+say
+.q \fIx\fP ,
+.i sendmail
+will look for an alias
+of the form
+.q owner-\fIx\fP
+to receive the errors.
+This is typically useful
+for a mailing list
+where the submitter of the list
+has no control over the maintenance of the list itself;
+in this case the list maintainer would be the owner of the list.
+For example:
+.(b
+unix-wizards: eric@ucbarpa, wnj@monet, nosuchuser,
+ sam@matisse
+owner-unix-wizards: eric@ucbarpa
+.)b
+would cause
+.q eric@ucbarpa
+to get the error that will occur
+when someone sends to
+unix-wizards
+due to the inclusion of
+.q nosuchuser
+on the list.
+.pp
+List owners also cause the envelope sender address to be modified.
+The contents of the owner alias are used if they point to a single user,
+otherwise the name of the alias itself is used.
+For this reason, and to obey Internet conventions,
+a typical scheme would be:
+.(b
+list: some, set, of, addresses
+list-request: list-admin-1, list-admin-2, ...
+owner-list: list-request
+.)b
+.sh 2 "User Information Database"
+.pp
+If you have a version of
+.i sendmail
+with the user information database
+compiled in,
+and you have specified one or more databases using the
+.b U
+option,
+the databases will be searched for a
+.i user :maildrop
+entry.
+If found, the mail will be sent to the specified address.
+.pp
+If the first token passed to user part of the
+.q local
+mailer is an at sign,
+the at sign will be stripped off
+and this step will be skipped.
+.sh 2 "Per-User Forwarding (.forward Files)"
+.pp
+As an alternative to the alias database,
+any user may put a file with the name
+.q .forward
+in his or her home directory.
+If this file exists,
+.i sendmail
+redirects mail for that user
+to the list of addresses listed in the .forward file.
+For example, if the home directory for user
+.q mckusick
+has a .forward file with contents:
+.(b
+mckusick@ernie
+kirk@calder
+.)b
+then any mail arriving for
+.q mckusick
+will be redirected to the specified accounts.
+.pp
+Actually, the configuration file defines a sequence of filenames to check.
+By default, this is the user's .forward file,
+but can be defined to be more generally using the
+.b J
+option.
+If you change this,
+you will have to inform your user base of the change;
+\&.forward is pretty well incorporated into the collective subconscious.
+.sh 2 "Special Header Lines"
+.pp
+Several header lines have special interpretations
+defined by the configuration file.
+Others have interpretations built into
+.i sendmail
+that cannot be changed without changing the code.
+These builtins are described here.
+.sh 3 "Return-Receipt-To:"
+.pp
+If this header is sent,
+a message will be sent to any specified addresses
+when the final delivery is complete,
+that is,
+when successfully delivered to a mailer with the
+.b l
+flag (local delivery) set in the mailer descriptor\**.
+.(f
+\**Some sites disable this header,
+and other (non-\c
+.i sendmail )
+systems do not implement it.
+Do not assume that a failure to get a return receipt
+means that the mail did not arrive.
+Also, do not assume that getting a return receipt
+means that the mail has been read;
+it just means that the message has been delivered
+to the recipient's mailbox.
+.)f
+This header can be disabled with the
+.q noreceipts
+privacy flag.
+.sh 3 "Errors-To:"
+.pp
+If errors occur anywhere during processing,
+this header will cause error messages to go to
+the listed addresses.
+This is intended for mailing lists.
+.pp
+The Errors-To: header was created in the bad old days
+when UUCP didn't understand the distinction between an envelope and a header;
+this was a hack to provide what should now be passed
+as the envelope sender address.
+It should go away.
+It is only used if the
+.b l
+option is set.
+.sh 3 "Apparently-To:"
+.pp
+If a message comes in with no recipients listed in the message
+(in a To:, Cc:, or Bcc: line)
+then
+.i sendmail
+will add an
+.q "Apparently-To:"
+header line for any recipients it is aware of.
+This is not put in as a standard recipient line
+to warn any recipients that the list is not complete.
+.pp
+At least one recipient line is required under RFC 822.
+.sh 2 "IDENT Protocol Support"
+.pp
+.i Sendmail
+supports the IDENT protocol as defined in RFC 1413.
+Although this enhances identification
+of the author of an email message
+by doing a ``call back'' to the originating system to include
+the owner of a particular TCP connection
+in the audit trail
+it is in no sense perfect;
+a determined forger can easily spoof the IDENT protocol.
+The following description is excerpted from RFC 1413:
+.ba +5
+.lp
+6. Security Considerations
+.lp
+The information returned by this protocol is at most as trustworthy
+as the host providing it OR the organization operating the host. For
+example, a PC in an open lab has few if any controls on it to prevent
+a user from having this protocol return any identifier the user
+wants. Likewise, if the host has been compromised the information
+returned may be completely erroneous and misleading.
+.lp
+The Identification Protocol is not intended as an authorization or
+access control protocol. At best, it provides some additional
+auditing information with respect to TCP connections. At worst, it
+can provide misleading, incorrect, or maliciously incorrect
+information.
+.lp
+The use of the information returned by this protocol for other than
+auditing is strongly discouraged. Specifically, using Identification
+Protocol information to make access control decisions - either as the
+primary method (i.e., no other checks) or as an adjunct to other
+methods may result in a weakening of normal host security.
+.lp
+An Identification server may reveal information about users,
+entities, objects or processes which might normally be considered
+private. An Identification server provides service which is a rough
+analog of the CallerID services provided by some phone companies and
+many of the same privacy considerations and arguments that apply to
+the CallerID service apply to Identification. If you wouldn't run a
+"finger" server due to privacy considerations you may not want to run
+this protocol.
+.ba
+.sh 1 "ARGUMENTS"
+.pp
+The complete list of arguments to
+.i sendmail
+is described in detail in Appendix A.
+Some important arguments are described here.
+.sh 2 "Queue Interval"
+.pp
+The amount of time between forking a process
+to run through the queue
+is defined by the
+.b \-q
+flag.
+If you run in mode
+.b f
+or
+.b a
+this can be relatively large,
+since it will only be relevant
+when a host that was down comes back up.
+If you run in
+.b q
+mode
+it should be relatively short,
+since it defines the maximum amount of time that a message
+may sit in the queue.
+.pp
+RFC 1123 section 5.3.1.1 says that this value should be at least 30 minutes
+(although that probably doesn't make sense if you use ``queue-only'' mode).
+.sh 2 "Daemon Mode"
+.pp
+If you allow incoming mail over an IPC connection,
+you should have a daemon running.
+This should be set by your
+.i /etc/rc
+file using the
+.b \-bd
+flag.
+The
+.b \-bd
+flag and the
+.b \-q
+flag may be combined in one call:
+.(b
+/usr/\*(SD/sendmail \-bd \-q30m
+.)b
+.sh 2 "Forcing the Queue"
+.pp
+In some cases you may find that the queue has gotten clogged for some reason.
+You can force a queue run
+using the
+.b \-q
+flag (with no value).
+It is entertaining to use the
+.b \-v
+flag (verbose)
+when this is done to watch what happens:
+.(b
+/usr/\*(SD/sendmail \-q \-v
+.)b
+.pp
+You can also limit the jobs to those with a particular queue identifier,
+sender, or recipient
+using one of the queue modifiers.
+For example,
+.q \-qRberkeley
+restricts the queue run to jobs that have the string
+.q berkeley
+somewhere in one of the recipient addresses.
+Similarly,
+.q \-qSstring
+limits the run to particular senders and
+.q \-qIstring
+limits it to particular identifiers.
+.sh 2 "Debugging"
+.pp
+There are a fairly large number of debug flags
+built into
+.i sendmail .
+Each debug flag has a number and a level,
+where higher levels means to print out more information.
+The convention is that levels greater than nine are
+.q absurd,
+i.e.,
+they print out so much information that you wouldn't normally
+want to see them except for debugging that particular piece of code.
+Debug flags are set using the
+.b \-d
+option;
+the syntax is:
+.(b
+.ta \w'debug-option 'u
+debug-flag: \fB\-d\fP debug-list
+debug-list: debug-option [ , debug-option ]
+debug-option: debug-range [ . debug-level ]
+debug-range: integer | integer \- integer
+debug-level: integer
+.)b
+where spaces are for reading ease only.
+For example,
+.(b
+\-d12 Set flag 12 to level 1
+\-d12.3 Set flag 12 to level 3
+\-d3-17 Set flags 3 through 17 to level 1
+\-d3-17.4 Set flags 3 through 17 to level 4
+.)b
+For a complete list of the available debug flags
+you will have to look at the code
+(they are too dynamic to keep this documentation up to date).
+.sh 2 "Trying a Different Configuration File"
+.pp
+An alternative configuration file
+can be specified using the
+.b \-C
+flag; for example,
+.(b
+/usr/\*(SD/sendmail \-Ctest.cf
+.)b
+uses the configuration file
+.i test.cf
+instead of the default
+.i /etc/sendmail.cf.
+If the
+.b \-C
+flag has no value
+it defaults to
+.i sendmail.cf
+in the current directory.
+.sh 2 "Changing the Values of Options"
+.pp
+Options can be overridden using the
+.b \-o
+flag.
+For example,
+.(b
+/usr/\*(SD/sendmail \-oT2m
+.)b
+sets the
+.b T
+(timeout) option to two minutes
+for this run only.
+.pp
+Some options have security implications.
+Sendmail allows you to set these,
+but refuses to run as root thereafter.
+.sh 2 "Logging Traffic"
+.pp
+Many SMTP implementations do not fully implement the protocol.
+For example, some personal computer based SMTPs
+do not understand continuation lines in reply codes.
+These can be very hard to trace.
+If you suspect such a problem, you can set traffic logging using the
+.b \-X
+flag.
+For example,
+.(b
+/usr/\*(SD/sendmail \-X /tmp/traffic -bd
+.)b
+will log all traffic in the file
+.i /tmp/traffic .
+.pp
+This logs a lot of data very quickly and should never be used
+during normal operations.
+After starting up such a daemon,
+force the errant implementation to send a message to your host.
+All message traffic in and out of
+.i sendmail ,
+including the incoming SMTP traffic,
+will be logged in this file.
+.sh 2 "Dumping State"
+.pp
+You can ask
+.i sendmail
+to log a dump of the open files
+and the connection cache
+by sending it a
+.sm SIGUSR1
+signal.
+The results are logged at
+.sm LOG_DEBUG
+priority.
+.sh 1 "TUNING"
+.pp
+There are a number of configuration parameters
+you may want to change,
+depending on the requirements of your site.
+Most of these are set
+using an option in the configuration file.
+For example,
+the line
+.q OT5d
+sets option
+.q T
+to the value
+.q 5d
+(five days).
+.pp
+Most of these options have appropriate defaults for most sites.
+However,
+sites having very high mail loads may find they need to tune them
+as appropriate for their mail load.
+In particular,
+sites experiencing a large number of small messages,
+many of which are delivered to many recipients,
+may find that they need to adjust the parameters
+dealing with queue priorities.
+.sh 2 "Timeouts"
+.pp
+All time intervals are set
+using a scaled syntax.
+For example,
+.q 10m
+represents ten minutes, whereas
+.q 2h30m
+represents two and a half hours.
+The full set of scales is:
+.(b
+.ta 4n
+s seconds
+m minutes
+h hours
+d days
+w weeks
+.)b
+.sh 3 "Queue interval"
+.pp
+The argument to the
+.b \-q
+flag
+specifies how often a sub-daemon will run the queue.
+This is typically set to between fifteen minutes
+and one hour.
+RFC 1123 section 5.3.1.1 recommends that this be at least 30 minutes.
+.sh 3 "Read timeouts"
+.pp
+It is possible to time out when reading the standard input
+or when reading from a remote SMTP server.
+These timeouts are set using the
+.b r
+option in the configuration file.
+The argument is a list of
+.i keyword=value
+pairs.
+The recognized keywords, their default values, and the minimum values
+allowed by RFC 1123 section 5.3.2 are:
+.nr ii 1i
+.ip initial
+The wait for the initial 220 greeting message
+[5m, 5m].
+.ip helo
+The wait for a reply from a HELO or EHLO command
+[5m, unspecified].
+This may require a host name lookup, so
+five minutes is probably a reasonable minimum.
+.ip mail\(dg
+The wait for a reply from a MAIL command
+[10m, 5m].
+.ip rcpt\(dg
+The wait for a reply from a RCPT command
+[1h, 5m].
+This should be long
+because it could be pointing at a list
+that takes a long time to expand.
+.ip datainit\(dg
+The wait for a reply from a DATA command
+[5m, 2m].
+.ip datablock\(dg
+The wait for reading a data block
+(that is, the body of the message).
+[1h, 3m].
+This should be long because it also applies to programs
+piping input to
+.i sendmail
+which have no guarantee of promptness.
+.ip datafinal\(dg
+The wait for a reply from the dot terminating a message.
+[1h, 10m].
+If this is shorter than the time actually needed
+for the receiver to deliver the message,
+duplicates will be generated.
+This is discussed in RFC 1047.
+.ip rset
+The wait for a reply from a RSET command
+[5m, unspecified].
+.ip quit
+The wait for a reply from a QUIT command
+[2m, unspecified].
+.ip misc
+The wait for a reply from miscellaneous (but short) commands
+such as NOOP (no-operation) and VERB (go into verbose mode).
+[2m, unspecified].
+.ip command\(dg
+In server SMTP,
+the time to wait for another command.
+[1h, 5m].
+.ip ident
+The timeout waiting for a reply to an IDENT query
+[30s, unspecified].
+.lp
+For compatibility with old configuration files,
+if no ``keyword='' is specified,
+all the timeouts marked with \(dg are set to the indicated value.
+.pp
+Many of the RFC 1123 minimum values
+may well be too short.
+.i Sendmail
+was designed to the RFC 822 protocols,
+which did not specify read timeouts;
+hence,
+.i sendmail
+does not guarantee to reply to messages promptly.
+In particular, a
+.q RCPT
+command specifying a mailing list
+will expand and verify the entire list;
+a large list on a slow system
+may take more than five minutes\**.
+.(f
+\**This verification includes looking up every address
+with the name server;
+this involves network delays,
+and can in some cases can be considerable.
+.)f
+I recommend a one hour timeout \*-
+since this failure is rare,
+a long timeout is not onerous
+and may ultimately help reduce network load.
+.pp
+For example, the line:
+.(b
+Orcommand=25m,datablock=3h
+.)b
+sets the server SMTP command timeout to 25 minutes
+and the input data block timeout to three hours.
+.sh 3 "Message timeouts"
+.pp
+After sitting in the queue for a few days,
+a message will time out.
+This is to insure that at least the sender is aware
+of the inability to send a message.
+The timeout is typically set to three days.
+This timeout is set using the
+.b T
+option in the configuration file.
+.pp
+The time of submission is set in the queue,
+rather than the amount of time left until timeout.
+As a result, you can flush messages that have been hanging
+for a short period
+by running the queue
+with a short message timeout.
+For example,
+.(b
+/usr/\*(SD/sendmail \-oT1d \-q
+.)b
+will run the queue
+and flush anything that is one day old.
+.pp
+Since this option is global,
+and since you can not
+.i "a priori"
+know how long another host outside your domain will be down,
+a five day timeout is recommended.
+This allows a recipient to fix the problem even if it occurs
+at the beginning of a long weekend.
+RFC 1123 section 5.3.1.1 says that this parameter
+should be ``at least 4\-5 days''.
+.pp
+The
+.b T
+option can also take a second timeout indicating a time after which
+a warning message should be sent;
+the two timeouts are separated by a slash.
+For example, the value
+.(b
+5d/4h
+.)b
+causes email to fail after five days,
+but a warning message will be sent after four hours.
+This should be large enough that the message will have been tried
+several times.
+.sh 2 "Forking During Queue Runs"
+.pp
+By setting the
+.b Y
+option,
+.i sendmail
+will fork before each individual message
+while running the queue.
+This will prevent
+.i sendmail
+from consuming large amounts of memory,
+so it may be useful in memory-poor environments.
+However, if the
+.b Y
+option is not set,
+.i sendmail
+will keep track of hosts that are down during a queue run,
+which can improve performance dramatically.
+.pp
+If the
+.b Y
+option is set,
+.i sendmail
+can not use connection caching.
+.sh 2 "Queue Priorities"
+.pp
+Every message is assigned a priority when it is first instantiated,
+consisting of the message size (in bytes)
+offset by the message class times the
+.q "work class factor"
+and the number of recipients times the
+.q "work recipient factor."
+The priority is used to order the queue.
+Higher numbers for the priority mean that the message will be processed later
+when running the queue.
+.pp
+The message size is included so that large messages are penalized
+relative to small messages.
+The message class allows users to send
+.q "high priority"
+messages by including a
+.q Precedence:
+field in their message;
+the value of this field is looked up in the
+.b P
+lines of the configuration file.
+Since the number of recipients affects the amount of load a message presents
+to the system,
+this is also included into the priority.
+.pp
+The recipient and class factors
+can be set in the configuration file using the
+.b y
+and
+.b z
+options respectively.
+They default to 30000 (for the recipient factor)
+and 1800
+(for the class factor).
+The initial priority is:
+.EQ
+pri = msgsize - (class times bold z) + (nrcpt times bold y)
+.EN
+(Remember, higher values for this parameter actually mean
+that the job will be treated with lower priority.)
+.pp
+The priority of a job can also be adjusted each time it is processed
+(that is, each time an attempt is made to deliver it)
+using the
+.q "work time factor,"
+set by the
+.b Z
+option.
+This is added to the priority,
+so it normally decreases the precedence of the job,
+on the grounds that jobs that have failed many times
+will tend to fail again in the future.
+The
+.b Z
+option defaults to 90000.
+.sh 2 "Load Limiting"
+.pp
+.i Sendmail
+can be asked to queue (but not deliver)
+mail if the system load average gets too high
+using the
+.b x
+option.
+When the load average exceeds the value of the
+.b x
+option,
+the delivery mode is set to
+.b q
+(queue only)
+if the
+.i "Queue Factor"
+(\c
+.b q
+option)
+divided by the difference in the current load average and the
+.b x
+option
+plus one
+exceeds the priority of the message \(em
+that is, the message is queued iff:
+.EQ
+pri > { bold q } over { LA - { bold x } + 1 }
+.EN
+The
+.b q
+option defaults to 600000,
+so each point of load average is worth 600000
+priority points
+(as described above).
+.pp
+For drastic cases,
+the
+.b X
+option defines a load average at which
+.i sendmail
+will refuse
+to accept network connections.
+Locally generated mail
+(including incoming UUCP mail)
+is still accepted.
+.sh 2 "Delivery Mode"
+.pp
+There are a number of delivery modes that
+.i sendmail
+can operate in,
+set by the
+.q d
+configuration option.
+These modes
+specify how quickly mail will be delivered.
+Legal modes are:
+.(b
+.ta 4n
+i deliver interactively (synchronously)
+b deliver in background (asynchronously)
+q queue only (don't deliver)
+.)b
+There are tradeoffs.
+Mode
+.q i
+passes the maximum amount of information to the sender,
+but is hardly ever necessary.
+Mode
+.q q
+puts the minimum load on your machine,
+but means that delivery may be delayed for up to the queue interval.
+Mode
+.q b
+is probably a good compromise.
+However, this mode can cause large numbers of processes
+if you have a mailer that takes a long time to deliver a message.
+.pp
+If you run in mode
+.q q
+(queue only)
+or
+.q b
+(deliver in background)
+.i sendmail
+will not expand aliases and follow .forward files
+upon initial receipt of the mail.
+This speeds up the response to RCPT commands.
+.sh 2 "Log Level"
+.pp
+The level of logging can be set for
+.i sendmail .
+The default using a standard configuration table is level 9.
+The levels are as follows:
+.nr ii 0.5i
+.ip 0
+No logging.
+.ip 1
+Serious system failures and potential security problems.
+.ip 2
+Lost communications (network problems) and protocol failures.
+.ip 3
+Other serious failures.
+.ip 4
+Minor failures.
+.ip 5
+Message collection statistics.
+.ip 6
+Creation of error messages,
+VRFY and EXPN commands.
+.ip 7
+Delivery failures (host or user unknown, etc.).
+.ip 8
+Successful deliveries.
+.ip 9
+Messages being deferred
+(due to a host being down, etc.).
+.ip 10
+Database expansion (alias, forward, and userdb lookups).
+.ip 15
+Automatic alias database rebuilds.
+.ip 20
+Logs attempts to run locked queue files.
+These are not errors,
+but can be useful to note if your queue appears to be clogged.
+.ip 30
+Lost locks (only if using lockf instead of flock).
+.lp
+Additionally,
+values above 64 are reserved for extremely verbose debuggging output.
+No normal site would ever set these.
+.sh 2 "File Modes"
+.pp
+There are a number of files
+that may have a number of modes.
+The modes depend on what functionality you want
+and the level of security you require.
+.sh 3 "To suid or not to suid?"
+.pp
+.i Sendmail
+can safely be made
+setuid to root.
+At the point where it is about to
+.i exec \|(2)
+a mailer,
+it checks to see if the userid is zero;
+if so,
+it resets the userid and groupid to a default
+(set by the
+.b u
+and
+.b g
+options).
+(This can be overridden
+by setting the
+.b S
+flag to the mailer
+for mailers that are trusted
+and must be called as root.)
+However,
+this will cause mail processing
+to be accounted
+(using
+.i sa \|(8))
+to root
+rather than to the user sending the mail.
+.sh 3 "Should my alias database be writable?"
+.pp
+At Berkeley
+we have the alias database
+(/etc/aliases*)
+mode 644.
+While this is not as flexible as if the database
+were more 666, it avoids potential security problems
+with a globally writable database.
+.pp
+The database that
+.i sendmail
+actually used
+is represented by the two files
+.i aliases.dir
+and
+.i aliases.pag
+(both in /etc)
+(or
+.i aliases.db
+if you are running with the new Berkeley database primitives).
+The mode on these files should match the mode
+on /etc/aliases.
+If
+.i aliases
+is writable
+and the
+DBM
+files
+(\c
+.i aliases.dir
+and
+.i aliases.pag )
+are not,
+users will be unable to reflect their desired changes
+through to the actual database.
+However,
+if
+.i aliases
+is read-only
+and the DBM files are writable,
+a slightly sophisticated user
+can arrange to steal mail anyway.
+.pp
+If your DBM files are not writable by the world
+or you do not have auto-rebuild enabled
+(with the
+.q D
+option),
+then you must be careful to reconstruct the alias database
+each time you change the text version:
+.(b
+newaliases
+.)b
+If this step is ignored or forgotten
+any intended changes will also be ignored or forgotten.
+.sh 2 "Connection Caching"
+.pp
+When processing the queue,
+.i sendmail
+will try to keep the last few open connections open
+to avoid startup and shutdown costs.
+This only applies to IPC connections.
+.pp
+When trying to open a connection
+the cache is first searched.
+If an open connection is found, it is probed to see if it is still active
+by sending a
+.sm NOOP
+command.
+It is not an error if this fails;
+instead, the connection is closed and reopened.
+.pp
+Two parameters control the connection cache.
+The
+.b k
+option defines the number of simultaneous open connections
+that will be permitted.
+If it is set to zero,
+connections will be closed as quickly as possible.
+The default is one.
+This should be set as appropriate for your system size;
+it will limit the amount of system resources that
+.i sendmail
+will use during queue runs.
+.pp
+The
+.b K
+option specifies the maximum time that any cached connection
+will be permitted to idle.
+When the idle time exceeds this value
+the connection is closed.
+This number should be small
+(under ten minutes)
+to prevent you from grabbing too many resources
+from other hosts.
+The default is five minutes.
+.sh 2 "Name Server Access"
+.pp
+If your system supports the name server,
+then the probability is that
+.i sendmail
+will be using it regardless of how you configure
+.i sendmail .
+In particular, the system routine
+.i gethostbyname (3)
+is used to look up host names,
+and most vendor versions try some combination of DNS, NIS,
+and file lookup in /etc/hosts.
+.pp
+However, if you do not have a nameserver configured at all,
+such as at a UUCP-only site,
+.i sendmail
+will get a
+.q "connection refused"
+message when it tries to connect to the name server
+(either indirectly by calling
+.i gethostbyname
+or directly by looking up MX records).
+If the
+.b I
+option is set,
+.i sendmail
+will interpret this to mean a temporary failure
+and will queue the mail for later processing;
+otherwise, it ignores the name server data.
+If your name server is running properly,
+the setting of this option is not relevant;
+however, it is important that it be set properly
+to make error handling work properly.
+.pp
+This option also allows you to tweak name server options.
+The command line takes a series of flags as documented in
+.i resolver (3)
+(with the leading
+.q RES_
+deleted).
+Each can be preceded by an optional `+' or `\(mi'.
+For example, the line
+.(b
+OITrue +AAONLY \(miDNSRCH
+.)b
+turns on the AAONLY (accept authoritative answers only)
+and turns off the DNSRCH (search the domain path) options.
+Most resolver libraries default DNSRCH, DEFNAMES, and RECURSE
+flags on and all others off.
+Note the use of the initial ``True'' \*-
+this is for compatibility with previous versions of
+.i sendmail ,
+but is not otherwise necessary.
+.pp
+Version level 1 configurations
+turn DNSRCH and DEFNAMES off when doing delivery lookups,
+but leave them on everywhere else.
+Version 8 of
+.i sendmail
+ignores them when doing canonification lookups
+(that is, when using $[ ... $]),
+and always does the search.
+If you don't want to do automatic name extension,
+don't call $[ ... $].
+.pp
+The search rules for $[ ... $] are somewhat different than usual.
+If the name (that is, the ``...'')
+has at least one dot, it always tries the unmodified name first.
+If that fails, it tries the reduced search path,
+and lastly tries the unmodified name
+(but only for names without a dot,
+since names with a dot have already been tried).
+This allows names such as
+``utc.CS''
+to match the site in Czechoslovakia
+rather than the site in your local Computer Science department.
+It also prefers A and CNAME records over MX records \*-
+that is, if it finds an MX record it makes note of it,
+but keeps looking.
+This way, if you have a wildcard MX record matching your domain,
+it will not assume that all names match.
+.sh 2 "Moving the Per-User Forward Files"
+.pp
+Some sites mount each user's home directory
+from a local disk on their workstation,
+so that local access is fast.
+However, the result is that .forward file lookups are slow.
+In some cases,
+mail can even be delivered on machines inappropriately
+because of a file server being down.
+The performance can be especially bad if you run the automounter.
+.pp
+The
+.b J
+option allows you to set a path of forward files.
+For example, the config file line
+.(b
+OJ/var/forward/$u:$z/.forward
+.)b
+would first look for a file with the same name as the user's login
+in /var/forward;
+if that is not found (or is inaccessible)
+the file
+.q \&.forward
+in the user's home directory is searched.
+A truly perverse site could also search by sender
+by using $r, $s, or $f.
+.pp
+If you create a directory such as /var/forward,
+it should be mode 1777
+(that is, the sticky bit should be set).
+Users should create the files mode 644.
+.sh 2 "Free Space"
+.pp
+On systems that have the
+.i statfs (2)
+system call,
+you can specify a minimum number of free blocks on the queue filesystem
+using the
+.b b
+option.
+If there are fewer than the indicated number of blocks free
+on the filesystem on which the queue is mounted
+the SMTP server will reject mail
+with the
+452 error code.
+This invites the SMTP client to try again later.
+.pp
+Beware of setting this option too high;
+it can cause rejection of email
+when that mail would be processed without difficulty.
+.pp
+This option can also specify an advertised
+.q "maximum message size"
+for hosts that speak ESMTP.
+.sh 2 "Privacy Flags"
+.pp
+The
+.b p
+option allows you to set certain
+``privacy''
+flags.
+Actually, many of them don't give you any extra privacy,
+rather just insisting that client SMTP servers
+use the HELO command
+before using certain commands.
+.pp
+The option takes a series of flag names;
+the final privacy is the inclusive or of those flags.
+For example:
+.(b
+Op needmailhelo, noexpn
+.)b
+insists that the HELO or EHLO command be used before a MAIL command is accepted
+and disables the EXPN command.
+.pp
+The
+.q restrictmailq
+option restricts printing the queue to the group that owns the queue directory.
+It is absurd to set this if you don't also protect the logs.
+.pp
+The
+.q restrictqrun
+option restricts people running the queue
+(that is, using the
+.b \-q
+command line flag)
+to root and the owner of the queue directory.
+.sh 2 "Send to Me Too"
+.pp
+Normally,
+.i sendmail
+deletes the (envelope) sender from any list expansions.
+For example, if
+.q matt
+sends to a list that contains
+.q matt
+as one of the members he won't get a copy of the message.
+If the
+.b \-m
+(me too)
+command line flag, or if the
+.b m
+option is set in the configuration file,
+this behaviour is supressed.
+Some sites like to run the
+.sm SMTP
+daemon with
+.b \-m .
+.sh 1 "THE WHOLE SCOOP ON THE CONFIGURATION FILE"
+.pp
+This section describes the configuration file
+in detail,
+including hints on how to write one of your own
+if you have to.
+.pp
+There is one point that should be made clear immediately:
+the syntax of the configuration file
+is designed to be reasonably easy to parse,
+since this is done every time
+.i sendmail
+starts up,
+rather than easy for a human to read or write.
+On the
+.q "future project"
+list is a
+configuration-file compiler.
+.pp
+An overview of the configuration file
+is given first,
+followed by details of the semantics.
+.sh 2 "Configuration File Lines"
+.pp
+The configuration file is organized as a series of lines,
+each of which begins with a single character
+defining the semantics for the rest of the line.
+Lines beginning with a space or a tab
+are continuation lines
+(although the semantics are not well defined in many places).
+Blank lines and lines beginning with a sharp symbol
+(`#')
+are comments.
+.sh 3 "R and S \*- rewriting rules"
+.pp
+The core of address parsing
+are the rewriting rules.
+These are an ordered production system.
+.i Sendmail
+scans through the set of rewriting rules
+looking for a match on the left hand side
+(LHS)
+of the rule.
+When a rule matches,
+the address is replaced by the right hand side
+(RHS)
+of the rule.
+.pp
+There are several sets of rewriting rules.
+Some of the rewriting sets are used internally
+and must have specific semantics.
+Other rewriting sets
+do not have specifically assigned semantics,
+and may be referenced by the mailer definitions
+or by other rewriting sets.
+.pp
+The syntax of these two commands are:
+.(b F
+.b S \c
+.i n
+.)b
+Sets the current ruleset being collected to
+.i n .
+If you begin a ruleset more than once
+it deletes the old definition.
+.(b F
+.b R \c
+.i lhs
+.i rhs
+.i comments
+.)b
+The
+fields must be separated
+by at least one tab character;
+there may be embedded spaces
+in the fields.
+The
+.i lhs
+is a pattern that is applied to the input.
+If it matches,
+the input is rewritten to the
+.i rhs .
+The
+.i comments
+are ignored.
+.pp
+Macro expansions of the form
+.b $ \c
+.i x
+are performed when the configuration file is read.
+Expansions of the form
+.b $& \c
+.i x
+are performed at run time using a somewhat less general algorithm.
+This for is intended only for referencing internally defined macros
+such as
+.b $h
+that are changed at runtime.
+.sh 4 "The left hand side"
+.pp
+The left hand side of rewriting rules contains a pattern.
+Normal words are simply matched directly.
+Metasyntax is introduced using a dollar sign.
+The metasymbols are:
+.(b
+.ta \w'\fB$=\fP\fIx\fP 'u
+\fB$*\fP Match zero or more tokens
+\fB$+\fP Match one or more tokens
+\fB$\-\fP Match exactly one token
+\fB$=\fP\fIx\fP Match any phrase in class \fIx\fP
+\fB$~\fP\fIx\fP Match any word not in class \fIx\fP
+.)b
+If any of these match,
+they are assigned to the symbol
+.b $ \c
+.i n
+for replacement on the right hand side,
+where
+.i n
+is the index in the LHS.
+For example,
+if the LHS:
+.(b
+$\-:$+
+.)b
+is applied to the input:
+.(b
+UCBARPA:eric
+.)b
+the rule will match, and the values passed to the RHS will be:
+.(b
+.ta 4n
+$1 UCBARPA
+$2 eric
+.)b
+.pp
+Additionally, the LHS can include
+.b $@
+to match zero tokens.
+This is
+.i not
+bound to a
+.b $ \c
+.i N
+on the RHS, and is normally only used when it stands alone
+in order to match the null input.
+.sh 4 "The right hand side"
+.pp
+When the left hand side of a rewriting rule matches,
+the input is deleted and replaced by the right hand side.
+Tokens are copied directly from the RHS
+unless they begin with a dollar sign.
+Metasymbols are:
+.(b
+.ta \w'$#mailer\0\0\0'u
+\fB$\fP\fIn\fP Substitute indefinite token \fIn\fP from LHS
+\fB$[\fP\fIname\fP\fB$]\fP Canonicalize \fIname\fP
+\fB$(\fP\fImap key\fP \fB$@\fP\fIarguments\fP \fB$:\fP\fIdefault\fP \fB$)\fP
+ Generalized keyed mapping function
+\fB$>\fP\fIn\fP \*(lqCall\*(rq ruleset \fIn\fP
+\fB$#\fP\fImailer\fP Resolve to \fImailer\fP
+\fB$@\fP\fIhost\fP Specify \fIhost\fP
+\fB$:\fP\fIuser\fP Specify \fIuser\fP
+.)b
+.pp
+The
+.b $ \c
+.i n
+syntax substitutes the corresponding value from a
+.b $+ ,
+.b $\- ,
+.b $* ,
+.b $= ,
+or
+.b $~
+match on the LHS.
+It may be used anywhere.
+.pp
+A host name enclosed between
+.b $[
+and
+.b $]
+is looked up using the
+.i gethostent \|(3)
+routines and replaced by the canonical name\**.
+.(f
+\**This is actually
+completely equivalent
+to $(host \fIhostname\fP$).
+In particular, a
+.b $:
+default can be used.
+.)f
+For example,
+.q $[csam$]
+might become
+.q lbl-csam.arpa
+and
+.q $[[128.32.130.2]$]
+would become
+.q vangogh.CS.Berkeley.EDU.
+.i Sendmail
+recognizes it's numeric IP address
+without calling the name server
+and replaces it with it's canonical name.
+.pp
+The
+.b $(
+\&...
+.b $)
+syntax is a more general form of lookup;
+it uses a named map instead of an implicit map.
+If no lookup is found, the indicated
+.i default
+is inserted;
+if no default is specified and no lookup matches,
+the value is left unchanged.
+.pp
+The
+.b $> \c
+.i n
+syntax
+causes the remainder of the line to be substituted as usual
+and then passed as the argument to ruleset
+.i n .
+The final value of ruleset
+.i n
+then becomes
+the substitution for this rule.
+.pp
+The
+.b $#
+syntax should
+.i only
+be used in ruleset zero
+or a subroutine of ruleset zero.
+It causes evaluation of the ruleset to terminate immediately,
+and signals to
+.i sendmail
+that the address has completely resolved.
+The complete syntax is:
+.(b
+\fB$#\fP\fImailer\fP \fB$@\fP\fIhost\fP \fB$:\fP\fIuser\fP
+.)b
+This specifies the
+{mailer, host, user}
+3-tuple necessary to direct the mailer.
+If the mailer is local
+the host part may be omitted\**.
+.(f
+\**You may want to use it for special
+.q "per user"
+extensions.
+For example, at CMU you can send email to
+.q jgm+foo ;
+the part after the plus sign
+is not part of the user name,
+and is passed to the local mailer for local use.
+.)f
+The
+.i mailer
+must be a single word,
+but the
+.i host
+and
+.i user
+may be multi-part.
+If the
+.i mailer
+is the builtin IPC mailer,
+the
+.i host
+may be a colon-separated list of hosts
+that are searched in order for the first working address
+(exactly like MX records).
+The
+.i user
+is later rewritten by the mailer-specific envelope rewriting set
+and assigned to the
+.b $u
+macro.
+As a special case, if the value to
+.b $#
+is
+.q local
+and the first character of the
+.b $:
+value is
+.q @ ,
+the
+.q @
+is stripped off, and a flag is set in the address descriptor
+that causes sendmail to not do ruleset 5 processing.
+.pp
+Normally, a rule that matches is retried,
+that is,
+the rule loops until it fails.
+A RHS may also be preceded by a
+.b $@
+or a
+.b $:
+to change this behavior.
+A
+.b $@
+prefix causes the ruleset to return with the remainder of the RHS
+as the value.
+A
+.b $:
+prefix causes the rule to terminate immediately,
+but the ruleset to continue;
+this can be used to avoid continued application of a rule.
+The prefix is stripped before continuing.
+.pp
+The
+.b $@
+and
+.b $:
+prefixes may precede a
+.b $>
+spec;
+for example:
+.(b
+.ta 8n
+R$+ $: $>7 $1
+.)b
+matches anything,
+passes that to ruleset seven,
+and continues;
+the
+.b $:
+is necessary to avoid an infinite loop.
+.pp
+Substitution occurs in the order described,
+that is,
+parameters from the LHS are substituted,
+hostnames are canonicalized,
+.q subroutines
+are called,
+and finally
+.b $# ,
+.b $@ ,
+and
+.b $:
+are processed.
+.sh 4 "Semantics of rewriting rule sets"
+.pp
+There are five rewriting sets
+that have specific semantics.
+These are related as depicted by figure 2.
+.(z
+.hl
+.ie n \{\
+.(c
+ +---+
+ -->| 0 |-->resolved address
+ / +---+
+ / +---+ +---+
+ / ---->| 1 |-->| S |--
+ +---+ / +---+ / +---+ +---+ \e +---+
+addr-->| 3 |-->| D |-- --->| 4 |-->msg
+ +---+ +---+ \e +---+ +---+ / +---+
+ --->| 2 |-->| R |--
+ +---+ +---+
+.)c
+
+.\}
+.el .ie !"\*(.T"" \
+\{\
+.PS
+boxwid = 0.3i
+boxht = 0.3i
+movewid = 0.3i
+moveht = 0.3i
+linewid = 0.3i
+lineht = 0.3i
+
+ box invis "addr"; arrow
+Box3: box "3"
+A1: arrow
+BoxD: box "D"; line; L1: Here
+C: [
+ C1: arrow; box "1"; arrow; box "S"; line; E1: Here
+ move to C1 down 0.5; right
+ C2: arrow; box "2"; arrow; box "R"; line; E2: Here
+ ] with .w at L1 + (0.5, 0)
+ move to C.e right 0.5
+L4: arrow; box "4"; arrow; box invis "msg"
+ line from L1 to C.C1
+ line from L1 to C.C2
+ line from C.E1 to L4
+ line from C.E2 to L4
+ move to BoxD.n up 0.6; right
+Box0: arrow; box "0"
+ arrow; box invis "resolved address" width 1.3
+ line from 1/3 of the way between A1 and BoxD.w to Box0
+.PE
+.\}
+.el .sp 2i
+.ce
+Figure 2 \*- Rewriting set semantics
+.(c
+D \*- sender domain addition
+S \*- mailer-specific sender rewriting
+R \*- mailer-specific recipient rewriting
+.)c
+.hl
+.)z
+.pp
+Ruleset three
+should turn the address into
+.q "canonical form."
+This form should have the basic syntax:
+.(b
+local-part@host-domain-spec
+.)b
+If no
+.q @
+sign is specified,
+then the
+host-domain-spec
+.i may
+be appended from the
+sender address
+(if the
+.b C
+flag is set in the mailer definition
+corresponding to the
+.i sending
+mailer).
+Ruleset three
+is applied by
+.i sendmail
+before doing anything with any address.
+.pp
+Ruleset zero
+is applied after ruleset three
+to addresses that are going to actually specify recipients.
+It must resolve to a
+.i "{mailer, host, user}"
+triple.
+The
+.i mailer
+must be defined in the mailer definitions
+from the configuration file.
+The
+.i host
+is defined into the
+.b $h
+macro
+for use in the argv expansion of the specified mailer.
+.pp
+Rulesets one and two
+are applied to all sender and recipient addresses respectively.
+They are applied before any specification
+in the mailer definition.
+They must never resolve.
+.pp
+Ruleset four is applied to all addresses
+in the message.
+It is typically used
+to translate internal to external form.
+.sh 4 "IPC mailers"
+.pp
+Some special processing occurs
+if the ruleset zero resolves to an IPC mailer
+(that is, a mailer that has
+.q [IPC]
+listed as the Path in the
+.b M
+configuration line.
+The host name passed after
+.q $@
+has MX expansion performed;
+this looks the name up in DNS to find alternate delivery sites.
+.pp
+The host name can also be provided as a dotted quad in square brackets;
+for example:
+.(b
+[128.32.149.78]
+.)b
+This causes direct conversion of the numeric value
+to a TCP/IP host address.
+.pp
+The host name passed in after the
+.q $@
+may also be a colon-separated list of hosts.
+Each is separately MX expanded and the results are concatenated
+to make (essentially) one long MX list.
+The intent here is to create
+.q fake
+MX records that are not published in DNS
+for private internal networks.
+.pp
+As a final special case, the host name can be passed in
+as a text string
+in square brackets:
+.(b
+[ucbvax.berkeley.edu]
+.)b
+This form avoids the MX mapping.
+.b N.B.:
+This is intended only for situations where you have a network firewall,
+so that your MX record points to a gateway machine;
+this machine could then do direct delivery to machines
+within your local domain.
+Use of this feature directly violates RFC 1123 section 5.3.5:
+it should not be used lightly.
+.sh 3 "D \*- define macro"
+.pp
+Macros are named with a single character.
+These may be selected from the entire ASCII set,
+but user-defined macros
+should be selected from the set of upper case letters only.
+Lower case letters
+and special symbols
+are used internally.
+.pp
+The syntax for macro definitions is:
+.(b F
+.b D \c
+.i x\|val
+.)b
+where
+.i x
+is the name of the macro
+and
+.i val
+is the value it should have.
+.pp
+Macros are interpolated
+using the construct
+.b $ \c
+.i x ,
+where
+.i x
+is the name of the macro to be interpolated.
+This interpolation is done when the configuration file is read,
+except in
+.b M
+lines.
+The special construct
+.b $& \c
+.i x
+can be used in
+.b R
+lines to get deferred interpolation.
+.pp
+Conditionals can be specified using the syntax:
+.(b
+$?x text1 $| text2 $.
+.)b
+This interpolates
+.i text1
+if the macro
+.b $x
+is set,
+and
+.i text2
+otherwise.
+The
+.q else
+(\c
+.b $| )
+clause may be omitted.
+.pp
+Lower case macro names are reserved to have
+special semantics,
+used to pass information in or out of
+.i sendmail ,
+and special characters are reserved to
+provide conditionals, etc.
+Upper case names
+(that is,
+.b $A
+through
+.b $Z )
+are specifically reserved for configuration file authors.
+.pp
+The following macros are defined and/or used internally by
+.i sendmail
+for interpolation into argv's for mailers
+or for other contexts.
+The ones marked \(dg are information passed into sendmail\**,
+.(f
+\**As of version 8.6,
+all of these macros have reasonable defaults.
+Previous versions required that they be defined.
+.)f
+the ones marked \(dd are information passed both in and out of sendmail,
+and the unmarked macros are passed out of sendmail
+but are not otherwise used internally.
+These macros are:
+.nr ii 5n
+.ip $a
+.b "The origination date in RFC 822 format."
+.ip $b
+.b "The current date in RFC 822 format."
+.ip $c
+.b "The hop count."
+.ip $d
+.b "The current date in UNIX (ctime) format."
+.ip $e\(dg
+.b "The SMTP entry message."
+This is printed out when SMTP starts up.
+The first word must be the
+.b $j
+macro as specified by RFC821.
+Defaults to
+.q "$j Sendmail $v ready at $b" .
+Commonly redefined to include the configuration version number, e.g.,
+.q "$j Sendmail $v/$Z ready at $b"
+.ip $f
+.b "The sender (from) address."
+.ip $g
+.b "The sender address relative to the recipient."
+.ip $h
+.b "The recipient host."
+.ip $i
+.b "The queue id."
+.ip $j\(dd
+.b "The \*(lqofficial\*(rq domain name for this site."
+This is fully qualified if the full qualification can be found.
+It
+.i must
+be redefined to be the fully qualified domain name
+if your system is not configured so that information can find
+it automatically.
+.ip $k
+.b "The UUCP node name (from the uname system call)."
+.ip $l\(dg
+.b "The format of the UNIX from line."
+Unless you have changed the UNIX mailbox format,
+you should not change the default,
+which is
+.q "From $g $d" .
+.ip $m
+.b "The domain part of the \fIgethostname\fP return value."
+Under normal circumstances,
+.b $j
+is equivalent to
+.b $w.$m .
+.ip $n\(dg
+.b "The name of the daemon (for error messages)."
+Defaults to
+.q MAILER-DAEMON .
+.ip $o\(dg
+.b "The set of \*(lqoperators\*(rq in addresses."
+A list of characters
+which will be considered tokens
+and which will separate tokens
+when doing parsing.
+For example, if
+.q @
+were in the
+.b $o
+macro, then the input
+.q a@b
+would be scanned as three tokens:
+.q a,
+.q @,
+and
+.q b.
+Defaults to
+.q ".:@[]" ,
+which is the minimum set necessary to do RFC 822 parsing;
+a richer set of operators is
+.q ".:%@!/[]" ,
+which adds support for UUCP, the %-hack, and X.400 addresses.
+.ip $p
+.b "Sendmail's process id."
+.ip $q\(dg
+.b "Default format of sender address."
+The
+.b $q
+macro specifies how an address should appear in a message
+when it is defaulted.
+Defaults to
+.q "<$g>" .
+It is commonly redefined to be
+.q "$?x$x <$g>$|$g$."
+or
+.q "$g$?x ($x)$." ,
+corresponding to the following two formats:
+.(b
+Eric Allman <eric@CS.Berkeley.EDU>
+eric@CS.Berkeley.EDU (Eric Allman)
+.)b
+.i Sendmail
+properly quotes names that have special characters
+if the first form is used.
+.ip $r
+.b "Protocol used to receive the message."
+.ip $s
+.b "Sender's host name."
+.ip $t
+.b "A numeric representation of the current time."
+.ip $u
+.b "The recipient user."
+.ip $v
+.b "The version number of \fIsendmail\fP."
+.ip $w\(dd
+.b "The hostname of this site."
+.pp
+The
+.b $w
+macro is set to the root name of this host (but see below for caveats).
+.ip $x
+.b "The full name of the sender."
+.ip $z
+.b "The home directory of the recipient."
+.ip $_
+.b "The validated sender address."
+.pp
+There are three types of dates that can be used.
+The
+.b $a
+and
+.b $b
+macros are in RFC 822 format;
+.b $a
+is the time as extracted from the
+.q Date:
+line of the message
+(if there was one),
+and
+.b $b
+is the current date and time
+(used for postmarks).
+If no
+.q Date:
+line is found in the incoming message,
+.b $a
+is set to the current time also.
+The
+.b $d
+macro is equivalent to the
+.b $b
+macro in UNIX
+(ctime)
+format.
+.pp
+The macros
+.b $w ,
+.b $j ,
+and
+.b $m
+are set to the identity of this host.
+.i Sendmail
+tries to find the fully qualified name of the host
+if at all possible;
+it does this by calling
+.i gethostname (2)
+to get the current hostname
+and then passing that to
+.i gethostbyname (3)
+which is supposed to return the canonical version of that host name.\**
+.(f
+\**For example, on some systems
+.i gethostname
+might return
+.q foo
+which would be mapped to
+.q foo.bar.com
+by
+.i gethostbyname .
+.)f
+Assuming this is successful,
+.b $j
+is set to the fully qualified name
+and
+.b $m
+is set to the domain part of the name
+(everything after the first dot).
+The
+.b $w
+macro is set to the first word
+(everything before the first dot)
+if you have a level 5 or higher configuration file;
+otherwise, it is set to the same value as
+.b $j .
+If the canonification is not successful,
+it is imperative that the config file set
+.b $j
+to the fully qualified domain name\**.
+.(f
+\**Older versions of sendmail didn't pre-define
+.b $j
+at all, so up until 8.6,
+config files
+.i always
+had to define
+.b $j .
+.)f
+.pp
+The
+.b $f
+macro is the id of the sender
+as originally determined;
+when mailing to a specific host
+the
+.b $g
+macro is set to the address of the sender
+.ul
+relative to the recipient.
+For example,
+if I send to
+.q bollard@matisse.CS.Berkeley.EDU
+from the machine
+.q vangogh.CS.Berkeley.EDU
+the
+.b $f
+macro will be
+.q eric
+and the
+.b $g
+macro will be
+.q eric@vangogh.CS.Berkeley.EDU.
+.pp
+The
+.b $x
+macro is set to the full name of the sender.
+This can be determined in several ways.
+It can be passed as flag to
+.i sendmail .
+The second choice is the value of the
+.q Full-name:
+line in the header if it exists,
+and the third choice is the comment field
+of a
+.q From:
+line.
+If all of these fail,
+and if the message is being originated locally,
+the full name is looked up in the
+.i /etc/passwd
+file.
+.pp
+When sending,
+the
+.b $h ,
+.b $u ,
+and
+.b $z
+macros get set to the host, user, and home directory
+(if local)
+of the recipient.
+The first two are set from the
+.b $@
+and
+.b $:
+part of the rewriting rules, respectively.
+.pp
+The
+.b $p
+and
+.b $t
+macros are used to create unique strings
+(e.g., for the
+.q Message-Id:
+field).
+The
+.b $i
+macro is set to the queue id on this host;
+if put into the timestamp line
+it can be extremely useful for tracking messages.
+The
+.b $v
+macro is set to be the version number of
+.i sendmail ;
+this is normally put in timestamps
+and has been proven extremely useful for debugging.
+.pp
+The
+.b $c
+field is set to the
+.q "hop count,"
+i.e., the number of times this message has been processed.
+This can be determined
+by the
+.b \-h
+flag on the command line
+or by counting the timestamps in the message.
+.pp
+The
+.b $r
+and
+.b $s
+fields are set to the protocol used to communicate with
+.i sendmail
+and the sending hostname.
+.pp
+The
+.b $_
+is set to a validated sender host name.
+If the sender is running an RFC 1413 compliant IDENT server,
+it will include the user name on that host.
+.sh 3 "C and F \*- define classes"
+.pp
+Classes of phrases may be defined
+to match on the left hand side of rewriting rules,
+where a
+.q phrase
+is a sequence of characters that do not contain space characters.
+For example
+a class of all local names for this site
+might be created
+so that attempts to send to oneself
+can be eliminated.
+These can either be defined directly in the configuration file
+or read in from another file.
+Classes may be given names
+from the set of upper case letters.
+Lower case letters and special characters
+are reserved for system use.
+.pp
+The syntax is:
+.(b F
+.b C \c
+.i c\|phrase1
+.i phrase2...
+.br
+.b F \c
+.i c\|file
+.)b
+The first form defines the class
+.i c
+to match any of the named words.
+It is permissible to split them among multiple lines;
+for example, the two forms:
+.(b
+CHmonet ucbmonet
+.)b
+and
+.(b
+CHmonet
+CHucbmonet
+.)b
+are equivalent.
+The second form
+reads the elements of the class
+.i c
+from the named
+.i file .
+.pp
+The
+.b $~
+(match entries not in class)
+only matches a single word;
+multi-word entries in the class are ignored in this context.
+.pp
+The class
+.b $=w
+is set to be the set of all names
+this host is known by.
+This can be used to match local hostnames.
+.pp
+The class
+.b $=k
+is set to be the same as
+.b $k ,
+that is, the UUCP node name.
+.pp
+The class
+.b $=m
+is set to the set of domains by which this host is known,
+initially just
+.b $m .
+.pp
+.i Sendmail
+can be compiled to allow a
+.i scanf (3)
+string on the
+.b F
+line.
+This lets you do simplistic parsing of text files.
+For example, to read all the user names in your system
+.i /etc/passwd
+file into a class, use
+.(b
+FL/etc/passwd %[^:]
+.)b
+which reads every line up to the first colon.
+.sh 3 "M \*- define mailer"
+.pp
+Programs and interfaces to mailers
+are defined in this line.
+The format is:
+.(b F
+.b M \c
+.i name ,
+{\c
+.i field =\c
+.i value \|}*
+.)b
+where
+.i name
+is the name of the mailer
+(used internally only)
+and the
+.q field=name
+pairs define attributes of the mailer.
+Fields are:
+.(b
+.ta 1i
+Path The pathname of the mailer
+Flags Special flags for this mailer
+Sender A rewriting set for sender addresses
+Recipient A rewriting set for recipient addresses
+Argv An argument vector to pass to this mailer
+Eol The end-of-line string for this mailer
+Maxsize The maximum message length to this mailer
+Linelimit The maximum line length in the message body
+Directory The working directory for the mailer
+.)b
+Only the first character of the field name is checked.
+.pp
+The following flags may be set in the mailer description.
+Any other flags may be used freely
+to conditionally assign headers to messages
+destined for particular mailers.
+.nr ii 4n
+.ip a
+Run Extended SMTP (ESMTP) protocol (defined in RFCs 1425, 1426, and 1427).
+.ip b
+Force a blank line on the end of a message.
+This is intended to work around some stupid versions of
+/bin/mail
+that require a blank line, but do not provide it themselves.
+It would not normally be used on network mail.
+.ip c
+Do not include comments in addresses.
+This should only be used if you have to work around
+a remote mailer that gets confused by comments.
+.ip C
+If mail is
+.i received
+from a mailer with this flag set,
+any addresses in the header that do not have an at sign
+(\c
+.q @ )
+after being rewritten by ruleset three
+will have the
+.q @domain
+clause from the sender
+tacked on.
+This allows mail with headers of the form:
+.(b
+From: usera@hosta
+To: userb@hostb, userc
+.)b
+to be rewritten as:
+.(b
+From: usera@hosta
+To: userb@hostb, userc@hosta
+.)b
+automatically.
+.ip D
+This mailer wants a
+.q Date:
+header line.
+.ip e
+This mailer is expensive to connect to,
+so try to avoid connecting normally;
+any necessary connection will occur during a queue run.
+.ip E
+Escape lines beginning with
+.q From
+in the message with a `>' sign.
+.ip f
+The mailer wants a
+.b \-f
+.i from
+flag,
+but only if this is a network forward operation
+(i.e.,
+the mailer will give an error
+if the executing user
+does not have special permissions).
+.ip F
+This mailer wants a
+.q From:
+header line.
+.ip g
+Normally,
+.i sendmail
+sends internally generated email (e.g., error messages)
+using the null return address\**
+.(f
+\**Actually, this only applies to SMTP,
+which uses the ``MAIL FROM:<>'' command.
+.)f
+as required by RFC 1123.
+However, some mailers don't accept a null return address.
+If necessary,
+you can set the
+.b g
+flag to prevent
+.i sendmail
+from obeying the standards;
+error messages will be sent as from the MAILER-DAEMON
+(actually, the value of the
+.b $n
+macro).
+.ip h
+Upper case should be preserved in host names
+for this mailer.
+.ip I
+This mailer will be speaking SMTP
+to another
+.i sendmail
+\*-
+as such it can use special protocol features.
+This option is not required
+(i.e.,
+if this option is omitted the transmission will still operate successfully,
+although perhaps not as efficiently as possible).
+.ip l
+This mailer is local
+(i.e.,
+final delivery will be performed).
+.ip L
+Limit the line lengths as specified in RFC821.
+This deprecated option should be replaced by the
+.b L=
+mail declaration.
+For historic reasons, the
+.b L
+flag also sets the
+.b 7
+flag.
+.ip m
+This mailer can send to multiple users
+on the same host
+in one transaction.
+When a
+.b $u
+macro occurs in the
+.i argv
+part of the mailer definition,
+that field will be repeated as necessary
+for all qualifying users.
+.ip M
+This mailer wants a
+.q Message-Id:
+header line.
+.ip n
+Do not insert a UNIX-style
+.q From
+line on the front of the message.
+.ip p
+Use the route-addr style reverse-path in the SMTP
+.q "MAIL FROM:"
+command
+rather than just the return address;
+although this is required in RFC821 section 3.1,
+many hosts do not process reverse-paths properly.
+Reverse-paths are officially discouraged by RFC 1123.
+.ip P
+This mailer wants a
+.q Return-Path:
+line.
+.ip r
+Same as
+.b f ,
+but sends a
+.b \-r
+flag.
+.ip s
+Strip quote characters off of the address
+before calling the mailer.
+.ip S
+Don't reset the userid
+before calling the mailer.
+This would be used in a secure environment
+where
+.i sendmail
+ran as root.
+This could be used to avoid forged addresses.
+This flag is suppressed if given from an
+.q unsafe
+environment
+(e.g, a user's mail.cf file).
+.ip u
+Upper case should be preserved in user names
+for this mailer.
+.ip U
+This mailer wants Unix-style
+.q From
+lines with the ugly UUCP-style
+.q "remote from <host>"
+on the end.
+.ip x
+This mailer wants a
+.q Full-Name:
+header line.
+.ip X
+This mailer want to use the hidden dot algorithm
+as specified in RFC821;
+basically,
+any line beginning with a dot
+will have an extra dot prepended
+(to be stripped at the other end).
+This insures that lines in the message containing a dot
+will not terminate the message prematurely.
+.ip 7
+Strip all output to seven bits.
+This is the default if the
+.b L
+flag is set.
+Note that clearing this option is not
+sufficient to get full eight bit data passed through
+.i sendmail .
+If the
+.b 7
+option is set, this is essentially always set,
+since the eighth bit was stripped on input.
+.pp
+The mailer with the special name
+.q error
+can be used to generate a user error.
+The (optional) host field is an exit status to be returned,
+and the user field is a message to be printed.
+The exit status may be numeric or one of the values
+USAGE, NOUSER, NOHOST, UNAVAILABLE, SOFTWARE, TEMPFAIL, PROTOCOL, or CONFIG
+to return the corresponding EX_ exit code.
+For example, the entry:
+.(b
+$#error $@ NOHOST $: Host unknown in this domain
+.)b
+on the RHS of a rule
+will cause the specified error to be generated
+and the
+.q "Host unknown"
+exit status to be returned
+if the LHS matches.
+This mailer is only functional in ruleset zero.
+.pp
+The mailer named
+.q local
+.i must
+be defined in every configuration file.
+This is used to deliver local mail,
+and is treated specially in several ways.
+Additionally, three other mailers named
+.q prog ,
+.q *file* ,
+and
+.q *include*
+may be defined to tune the delivery of messages to programs,
+files,
+and :include: lists respectively.
+They default to:
+.(b
+Mprog, P=/bin/sh, F=lsD, A=sh \-c $u
+M*file*, P=/dev/null, F=lsDFMPEu, A=FILE
+M*include*, P=/dev/null, F=su, A=INCLUDE
+.)b
+.pp
+The Sender and Recipient rewriting sets
+may either be a simple integer
+or may be two integers separated by a slash;
+if so, the first rewriting set is applied to envelope
+addresses
+and the second is applied to headers.
+.pp
+The Directory
+is actually a colon-separated path of directories to try.
+For example, the definition
+.q D=$z:/
+first tries to execute in the recipient's home directory;
+if that is not available,
+it tries to execute in the root of the filesystem.
+This is intended to be used only on the
+.q prog
+mailer,
+since some shells (such as
+.i csh )
+refuse to execute if they cannot read the home directory.
+Since the queue directory is not normally readable by normal users
+.i csh
+scripts as recipients can fail.
+.sh 3 "H \*- define header"
+.pp
+The format of the header lines that
+.i sendmail
+inserts into the message
+are defined by the
+.b H
+line.
+The syntax of this line is:
+.(b F
+.b H [\c
+.b ? \c
+.i mflags \c
+.b ? ]\c
+.i hname \c
+.b :
+.i htemplate
+.)b
+Continuation lines in this spec
+are reflected directly into the outgoing message.
+The
+.i htemplate
+is macro expanded before insertion into the message.
+If the
+.i mflags
+(surrounded by question marks)
+are specified,
+at least one of the specified flags
+must be stated in the mailer definition
+for this header to be automatically output.
+If one of these headers is in the input
+it is reflected to the output
+regardless of these flags.
+.pp
+Some headers have special semantics
+that will be described below.
+.sh 3 "O \*- set option"
+.pp
+There are a number of
+.q random
+options that
+can be set from a configuration file.
+Options are represented by single characters.
+The syntax of this line is:
+.(b F
+.b O \c
+.i o\|value
+.)b
+This sets option
+.i o
+to be
+.i value .
+Depending on the option,
+.i value
+may be a string, an integer,
+a boolean
+(with legal values
+.q t ,
+.q T ,
+.q f ,
+or
+.q F ;
+the default is TRUE),
+or
+a time interval.
+.pp
+The options supported are:
+.nr ii 1i
+.ip a\fIN\fP
+If set,
+wait up to
+.i N
+minutes for an
+.q @:@
+entry to exist in the alias database
+before starting up.
+If it does not appear in
+.i N
+minutes,
+rebuild the database
+(if the
+.b D
+option is also set)
+or issue a warning.
+.ip "A\fIspec, spec, ...\fP"
+Specify possible alias file(s).
+Each
+.i spec
+should be in the format
+``\c
+.i class \c
+.b :
+.i file ''
+where
+.i class \c
+.b :
+is optional and defaults to ``implicit''.
+Depending on how
+.i sendmail
+is compiled, valid classes are
+.q implicit
+(search through a compiled-in list of alias file types,
+for back compatibility),
+.q hash
+(if
+.sm NEWDB
+is specified),
+.q dbm
+(if
+.sm NDBM
+is specified),
+.q stab
+(internal symbol table \*- not normally used
+unless you have no other database lookup),
+or
+.q nis
+(if
+.sm NIS
+is specified).
+If a list of
+.i spec s
+are provided,
+.i sendmail
+searches them in order.
+.ip b\fIN\fP/\fIM\fP
+Insist on at least
+.i N
+blocks free on the filesystem that holds the queue files
+before accepting email via SMTP.
+If there is insufficient space
+.i sendmail
+gives a 452 response
+to the MAIL command.
+This invites the sender to try again later.
+The optional
+.i M
+is a maximum message size advertised in the ESMTP EHLO response.
+It is currently otherwise unused.
+.ip B\fIc\fP
+Set the blank substitution character to
+.i c .
+Unquoted spaces in addresses are replaced by this character.
+Defaults to space (i.e., no change is made).
+.ip c
+If an outgoing mailer is marked as being expensive,
+don't connect immediately.
+This requires that queueing be compiled in,
+since it will depend on a queue run process to
+actually send the mail.
+.ip C\fIN\fP
+Checkpoints the queue every
+.i N
+(default 10)
+addresses sent.
+If your system crashes during delivery to a large list,
+this prevents retransmission to any but the last
+.I N
+recipients.
+.ip d\fIx\fP
+Deliver in mode
+.i x .
+Legal modes are:
+.(b
+.ta 4n
+i Deliver interactively (synchronously)
+b Deliver in background (asynchronously)
+q Just queue the message (deliver during queue run)
+.)b
+Defaults to ``b'' if no option is specified,
+``i'' if it is specified but given no argument
+(i.e., ``Od'' is equivalent to ``Odi'').
+.ip D
+If set,
+rebuild the alias database if necessary and possible.
+If this option is not set,
+.i sendmail
+will never rebuild the alias database
+unless explicitly requested
+using
+.b \-bi .
+.ip e\fIx\fP
+Dispose of errors using mode
+.i x .
+The values for
+.i x
+are:
+.(b
+p Print error messages (default)
+q No messages, just give exit status
+m Mail back errors
+w Write back errors (mail if user not logged in)
+e Mail back errors and give zero exit stat always
+.)b
+.ip E\fIfile/message\fP
+Prepend error messages with the indicated message.
+If it begins with a slash,
+it is assumed to be the pathname of a file
+containing a message (this is the recommended setting).
+Otherwise, it is a literal message.
+The error file might contain the name, email address, and/or phone number
+of a local postmaster who could provide assistance
+in to end users.
+If the option is missing or null,
+or if it names a file which does not exist or which is not readable,
+no message is printed.
+.ip f
+Save
+Unix-style
+.q From
+lines at the front of headers.
+Normally they are assumed redundant
+and discarded.
+.ip F\fImode\fP
+The file mode for queue files.
+.ip g\fIn\fP
+Set the default group id
+for mailers to run in
+to
+.i n .
+Defaults to 1.
+The value can also be given as a symbolic group name.
+.ip G
+Allow fuzzy matching on the GECOS field.
+If this flag is set,
+and the usual user name lookups fail
+(that is, there is no alias with this name and a
+.i getpwnam
+fails),
+sequentially search the password file
+for a matching entry in the GECOS field.
+This also requires that MATCHGECOS
+be turned on during compilation.
+This option is not recommended.
+.ip h\fIN\fP
+The maximum hop count.
+Messages that have been processed more than
+.i N
+times are assumed to be in a loop and are rejected.
+Defaults to 25.
+.ip H\fIfile\fP
+Specify the help file
+for SMTP.
+.ip i
+Ignore dots in incoming messages.
+This is always disabled (that is, dots are always accepted)
+when reading SMTP mail.
+.ip I
+Insist that the BIND name server be running
+to resolve host names.
+If this is not set and the name server is not running,
+the
+.i /etc/hosts
+file will be considered complete.
+In general, you do want to set this option
+if your
+.i /etc/hosts
+file does not include all hosts known to you
+or if you are using the MX (mail forwarding) feature of the BIND name server.
+The name server will still be consulted
+even if this option is not set, but
+.i sendmail
+will feel free to resort to reading
+.i /etc/hosts
+if the name server is not available.
+Thus, you should
+.i never
+set this option if you do not run the name server.
+.ip j
+If set, send error messages in MIME format
+(see RFC1341 and RFC1344 for details).
+.ip J\fIpath\fP
+Set the path for searching for users' .forward files.
+The default is
+.q $z/.forward .
+Some sites that use the automounter may prefer to change this to
+.q /var/forward/$u
+to search a file with the same name as the user in a system directory.
+It can also be set to a sequence of paths separated by colons;
+.i sendmail
+stops at the first file it can successfully and safely open.
+For example,
+.q /var/forward/$u:$z/.forward
+will search first in /var/forward/\c
+.i username
+and then in
+.i ~username /.forward
+(but only if the first file does not exist).
+.ip k\fIN\fP
+The maximum number of open connections that will be cached at a time.
+The default is one.
+This delays closing the current connection until
+either this invocation of
+.i sendmail
+needs to connect to another host
+or it terminates.
+Setting it to zero defaults to the old behavior,
+that is, connections are closed immediately.
+.ip K\fItimeout\fP
+The maximum amount of time a cached connection will be permitted to idle
+without activity.
+If this time is exceeded,
+the connection is immediately closed.
+This value should be small (on the order of ten minutes).
+Before
+.i sendmail
+uses a cached connection,
+it always sends a NOOP (no operation) command
+to check the connection;
+if this fails, it reopens the connection.
+This keeps your end from failing if the other end times out.
+The point of this option is to be a good network neighbor
+and avoid using up excessive resources
+on the other end.
+The default is five minutes.
+.ip l
+If there is an
+.q Errors-To:
+header, send error messages to the addresses listed there.
+They normally go to the envelope sender.
+Use of this option causes
+.i sendmail
+to violate RFC 1123.
+.ip L\fIn\fP
+Set the default log level to
+.i n .
+Defaults to 9.
+.ip m
+Send to me too,
+even if I am in an alias expansion.
+.ip M\fIx\|value\fP
+Set the macro
+.i x
+to
+.i value .
+This is intended only for use from the command line.
+.ip n
+Validate the RHS of aliases when rebuilding the alias database.
+.ip o
+Assume that the headers may be in old format,
+i.e.,
+spaces delimit names.
+This actually turns on
+an adaptive algorithm:
+if any recipient address contains a comma, parenthesis,
+or angle bracket,
+it will be assumed that commas already exist.
+If this flag is not on,
+only commas delimit names.
+Headers are always output with commas between the names.
+.ip O\fIoptions\fP
+Set server SMTP options.
+The options are
+.i key=value
+pairs.
+Known keys are:
+.(b
+.ta 1i
+Port Name/number of listening port (defaults to "smtp")
+Addr Address mask (defaults INADDR_ANY)
+Family Address family (defaults to INET)
+Listen Size of listen queue (defaults to 10)
+.)b
+The
+.i Addr ess
+mask may be a numeric address in dot notation
+or a network name.
+.ip p\fI\|opt,opt,...\fP
+Set the privacy
+.i opt ions.
+``Privacy'' is really a misnomer;
+many of these are just a way of insisting on stricter adherence
+to the SMTP protocol.
+The
+.i opt ions
+can be selected from:
+.(b
+.ta \w'needvrfyhelo'u+3n
+public Allow open access
+needmailhelo Insist on HELO or EHLO command before MAIL
+needexpnhelo Insist on HELO or EHLO command before EXPN
+noexpn Disallow EXPN entirely
+needvrfyhelo Insist on HELO or EHLO command before VRFY
+novrfy Disallow VRFY entirely
+restrictmailq Restrict mailq command
+restrictqrun Restrict \-q command line flag
+noreceipts Ignore Return-Receipt-To: header
+goaway Disallow essentially all SMTP status queries
+authwarnings Put X-Authentication-Warning: headers in messages
+.)b
+The
+.q goaway
+pseudo-flag sets all flags except
+.q restrictmailq
+and
+.q restrictqrun .
+If mailq is restricted,
+only people in the same group as the queue directory
+can print the queue.
+If queue runs are restricted,
+only root and the owner of the queue directory
+can run the queue.
+Authentication Warnings add warnings about various conditions
+that may indicate attempts to spoof the mail system,
+such as using an non-standard queue directory.
+.ip P\fIpostmaster\fP
+If set,
+copies of error messages will be sent to the named
+.i postmaster .
+Only the header of the failed message is sent.
+Since most errors are user problems,
+this is probably not a good idea on large sites,
+and arguably contains all sorts of privacy violations,
+but it seems to be popular with certain operating systems vendors.
+.ip q\fIfactor\fP
+Use
+.i factor
+as the multiplier in the map function
+to decide when to just queue up jobs rather than run them.
+This value is divided by the difference between the current load average
+and the load average limit
+(\c
+.b x
+flag)
+to determine the maximum message priority
+that will be sent.
+Defaults to 600000.
+.ip Q\fIdir\fP
+Use the named
+.i dir
+as the queue directory.
+.ip r\|\fItimeouts\fP
+Timeout reads after
+.i time
+interval.
+The
+.i timeouts
+argument is a list of
+.i keyword=value
+pairs.
+The recognized timeouts and their default values, and their
+minimum values specified in RFC 1123 section 5.3.2 are:
+.(b
+.ta \w'datafinal'u+3n
+initial wait for initial greeting message [5m, 5m]
+helo reply to HELO or EHLO command [5m, none]
+mail reply to MAIL command [10m, 5m]
+rcpt reply to RCPT command [1h, 5m]
+datainit reply to DATA command [5m, 2m]
+datablock data block read [1h, 3m]
+datafinal reply to final ``.'' in data [1h, 10m]
+rset reply to RSET command [5m, none]
+quit reply to QUIT command [2m, none]
+misc reply to NOOP and VERB commands [2m, none]
+command command read [1h, 5m]
+ident IDENT protocol timeout [30s, none]
+.)b
+All but
+.q command
+apply to client SMTP.
+For back compatibility,
+a timeout with no ``keyword='' part
+will set all of the longer values.
+.ip R
+Normally,
+.i sendmail
+tries to eliminate any unnecessary explicit routes
+when sending an error message
+(as discussed in RFC 1123 \(sc 5.2.6).
+For example,
+when sending an error message to
+.(b
+<@known1,@known2,@unknown:user@known3>
+.)b
+.i sendmail
+will strip off the
+.q @known1
+in order to make the route as direct as possible.
+However, if the
+.b R
+option is set, this will be disabled,
+and the mail will be sent to the first address in the route,
+even if later addresses are known.
+This may be useful if you are caught behind a firewall.
+.ip s
+Be super-safe when running things,
+i.e.,
+always instantiate the queue file,
+even if you are going to attempt immediate delivery.
+.i Sendmail
+always instantiates the queue file
+before returning control the client
+under any circumstances.
+.ip S\fIfile\fP
+Log statistics in the named
+.i file .
+.ip t\fItzinfo\fP
+Set the local time zone info to
+.i tzinfo
+\*- for example,
+.q PST8PDT .
+Actually, if this is not set,
+the TZ environment variable is cleared (so the system default is used);
+if set but null, the user's TZ variable is used,
+and if set and non-null the TZ variable is set to this value.
+.ip T\fIrtime/wtime\fP
+Set the queue timeout to
+.i rtime .
+After this interval,
+messages that have not been successfully sent
+will be returned to the sender.
+Defaults to five days.
+The optional
+.i wtime
+is the time after which a warning message is sent.
+If it is missing or zero
+then no warning messages are sent.
+.ip u\fIn\fP
+Set the default userid for mailers to
+.i n .
+Mailers without the
+.i S
+flag in the mailer definition
+will run as this user.
+Defaults to 1.
+The value can also be given as a symbolic user name.
+.ip U\fIudbspec\fP
+The user database specification.
+.ip v
+Run in verbose mode.
+If this is set,
+.i sendmail
+adjusts options
+.b c
+(don't connect to expensive mailers)
+and
+.b d
+(delivery mode)
+so that all mail is delivered completely
+in a single job
+so that you can see the entire delivery process.
+Option
+.b v
+should
+.i never
+be set in the configuration file;
+it is intended for command line use only.
+.ip V\fIfallbackhost\fP
+If specified, the
+.i fallbackhost
+acts like a very low priority MX
+on every host.
+This is intended to be used by sites with poor network connectivity.
+.ip w
+If you are the
+.q best
+(that is, lowest preference)
+MX for a given host,
+you should normally detect this situation
+and treat that condition specially,
+by forwarding the mail to a UUCP feed,
+treating it as local,
+or whatever.
+However, in some cases (such as Internet firewalls)
+you may want to try to connect directly to that host
+as though it had no MX records at all.
+Setting this option causes
+.i sendmail
+to try this.
+The downside is that errors in your configuration
+are likely to be diagnosed as
+.q "host unknown"
+or
+.q "message timed out"
+instead of something more meaningful.
+This option is disrecommended.
+.ip x\fILA\fP
+When the system load average exceeds
+.i LA ,
+just queue messages
+(i.e., don't try to send them).
+Defaults to 8.
+.ip X\fILA\fP
+When the system load average exceeds
+.i LA ,
+refuse incoming SMTP connections.
+Defaults to 12.
+.ip y\fIfact\fP
+The indicated
+.i fact or
+is added to the priority (thus
+.i lowering
+the priority of the job)
+for each recipient,
+i.e., this value penalizes jobs with large numbers of recipients.
+Defaults to 30000.
+.ip Y
+If set,
+deliver each job that is run from the queue in a separate process.
+Use this option if you are short of memory,
+since the default tends to consume considerable amounts of memory
+while the queue is being processed.
+.ip z\fIfact\fP
+The indicated
+.i fact or
+is multiplied by the message class
+(determined by the Precedence: field in the user header
+and the
+.b P
+lines in the configuration file)
+and subtracted from the priority.
+Thus, messages with a higher Priority: will be favored.
+Defaults to 1800.
+.ip Z\fIfact\fP
+The
+.i fact or
+is added to the priority
+every time a job is processed.
+Thus,
+each time a job is processed,
+its priority will be decreased by the indicated value.
+In most environments this should be positive,
+since hosts that are down are all too often down for a long time.
+Defaults to 90000.
+.ip 7
+Strip input to seven bits for compatibility with old systems.
+This shouldn't be necessary.
+.lp
+All options can be specified on the command line using the
+\-o flag,
+but most will cause
+.i sendmail
+to relinquish its setuid permissions.
+The options that will not cause this are
+b, d, e, i, L, m, o, p, r, s, v, C, and 7.
+Also, M (define macro) when defining the r or s macros
+is also considered
+.q safe .
+.sh 3 "P \*- precedence definitions"
+.pp
+Values for the
+.q "Precedence:"
+field may be defined using the
+.b P
+control line.
+The syntax of this field is:
+.(b
+\fBP\fP\fIname\fP\fB=\fP\fInum\fP
+.)b
+When the
+.i name
+is found in a
+.q Precedence:
+field,
+the message class is set to
+.i num .
+Higher numbers mean higher precedence.
+Numbers less than zero
+have the special property
+that if an error occurs during processing
+the body of the message will not be returned;
+this is expected to be used for
+.q "bulk"
+mail such as through mailing lists.
+The default precedence is zero.
+For example,
+our list of precedences is:
+.(b
+Pfirst-class=0
+Pspecial-delivery=100
+Plist=\-30
+Pbulk=\-60
+Pjunk=\-100
+.)b
+People writing mailing list exploders
+are encouraged to use
+.q "Precedence: list" .
+Older versions of
+.i sendmail
+(which discarded all error returns for negative precedences)
+didn't recognize this name, giving it a default precedence of zero.
+This allows list maintainers to see error returns
+on both old and new versions of
+.i sendmail .
+.sh 3 "V \*- configuration version level"
+.pp
+To provide compatibility with old configuration files,
+the
+.b V
+line has been added to define some very basic semantics
+of the configuration file.
+These are not intended to be long term supports;
+rather, they describe compatibility features
+which will probably be removed in future releases.
+.pp
+.b N.B.:
+these version
+.i levels
+have nothing
+to do with the version
+.i number
+on the files.
+For example,
+as of this writing
+version 8 config files
+(specifically, 8.6)
+used version level 5 configurations.
+.pp
+.q Old
+configuration files are defined as version level one.
+Version level two files make the following changes:
+.np
+Host name canonification ($[ ... $])
+appends a dot if the name is recognized;
+this gives the config file a way of finding out if anything matched.
+(Actually, this just initializes the
+.q host
+map with the
+.q \-a.
+flag \*- you can reset it to anything you prefer
+by declaring the map explicitly.)
+.np
+Default host name extension is consistent throughout processing;
+version level one configurations turned off domain extension
+(that is, adding the local domain name)
+during certain points in processing.
+Version level two configurations are expected to include a trailing dot
+to indicate that the name is already canonical.
+.np
+Local names that are not aliases
+are passed through a new distinguished ruleset five;
+this can be used to append a local relay.
+This behaviour can be prevented by resolving the local name
+with an initial `@'.
+That is, something that resolves to a local mailer and a user name of
+.q vikki
+will be passed through ruleset five,
+but a user name of
+.q @vikki
+will have the `@' stripped,
+will not be passed through ruleset five,
+but will otherwise be treated the same as the prior example.
+The expectation is that this might be used to implement a policy
+where mail sent to
+.q vikki
+was handled by a central hub,
+but mail sent to
+.q vikki@localhost
+was delivered directly.
+.pp
+Version level three files
+allow # initiated comments on all lines.
+Exceptions are backslash escaped # marks
+and the $# syntax.
+.pp
+Version level four configurations
+are completely equivalent to level three
+for historical reasons.
+.pp
+Version level five configuration files
+change the default definition of
+.b $w
+to be just the first component of the hostname.
+.pp
+The
+.b V
+line may have an optional
+.b / \c
+.i vendor
+to indicate that this configuration file uses modifications
+specific to a particular vendor\**.
+.(f
+\**And of course, vendors are encouraged to add themselves
+to the list of recognized vendors by editing the routine
+.i setvendor
+in
+.i conf.c .
+.)f
+.sh 3 "K \*- key file declaration"
+.pp
+Special maps can be defined using the line:
+.(b
+Kmapname mapclass arguments
+.)b
+The
+.i mapname
+is the handle by which this map is referenced in the rewriting rules.
+The
+.i mapclass
+is the name of a type of map;
+these are compiled in to
+.i sendmail .
+The
+.i arguments
+are interpreted depending on the class;
+typically,
+there would be a single argument naming the file containing the map.
+.pp
+Maps are referenced using the syntax:
+.(b
+$( \fImap\fP \fIkey\fP $@ \fIarguments\fP $: \fIdefault\fP $)
+.)b
+where either or both of the
+.i arguments
+or
+.i default
+portion may be omitted.
+The
+.i arguments
+may appear more than once.
+The indicated
+.i key
+and
+.i arguments
+are passed to the appropriate mapping function.
+If it returns a value, it replaces the input.
+If it does not return a value and the
+.i default
+is specified, the
+.i default
+replaces the input.
+Otherwise, the input is unchanged.
+.pp
+During replacement of either a map value or default
+the string
+.q %\fIn\fP
+(where
+.i n
+is a digit)
+is replaced by the corresponding
+.i argument .
+Argument zero
+is always the database key.
+For example, the rule
+.(b
+.ta 1.5i
+R$- ! $+ $: $(uucp $1 $@ $2 $: %1 @ %0 . UUCP $)
+.)b
+Looks up the UUCP name in a (user defined) UUCP map;
+if not found it turns it into
+.q \&.UUCP
+form.
+The database might contain records like:
+.(b
+decvax %1@%0.DEC.COM
+research %1@%0.ATT.COM
+.)b
+.pp
+The built in map with both name and class
+.q host
+is the host name canonicalization lookup.
+Thus,
+the syntax:
+.(b
+$(host \fIhostname\fP$)
+.)b
+is equivalent to:
+.(b
+$[\fIhostname\fP$]
+.)b
+.pp
+There are four predefined database lookup classes:
+.q dbm ,
+.q btree ,
+.q hash ,
+and
+.q nis .
+The first requires that
+.i sendmail
+be compiled with the
+.b ndbm
+library;
+the second two require the
+.b db
+library,
+and the third requires that
+.i sendmail
+be compiled with NIS support.
+All four accept as arguments the same optional flags
+and a filename
+(or a mapname for NIS;
+the filename is the root of the database path,
+so that
+.q .db
+or some other extension appropriate for the database type
+will be added to get the actual database name).
+Known flags are:
+.ip "\-o"
+Indicates that this map is optional \*- that is,
+if it cannot be opened,
+no error is produced,
+and
+.i sendmail
+will behave as if the map existed but was empty.
+.ip "\-N"
+Normally when maps are written,
+the trailing null byte is not included as part of the key.
+If this flag is indicated it will be included.
+During lookups, only the null-byte-included form will be searched.
+See also
+.b \-O.
+.ip "\-O"
+If neither
+.b \-N
+or
+.b \-O
+are specified,
+.i sendmail
+uses an adaptive algorithm to decide whether or not to look for null bytes
+on the end of keys.
+It starts by trying both;
+if it finds any key with a null byte it never tries again without a null byte
+and vice versa.
+If this flag is specified,
+it never tries with a null byte;
+this can speed matches but is never necessary.
+If both
+.b \-N
+and
+.b \-O
+are specified,
+.i sendmail
+will never try any matches at all \(em
+that is, everything will appear to fail.
+.ip "\-a\fIx\fP"
+Append the string
+.i x
+on successful matches.
+For example, the default
+.i host
+map appends a dot on successful matches.
+.ip "\-f"
+Do not fold upper to lower case before looking up the key.
+.ip "\-m"
+Match only (without replacing the value).
+If you only care about the existence of a key and not the value
+(as you might when searching the NIS map
+.q hosts.byname
+for example),
+this flag prevents the map from substituting the value.
+However,
+The \-a argument is still appended on a match,
+and the default is still taken if the match fails.
+.pp
+The
+.i dbm
+map appends the strings
+.q \&.pag
+and
+.q \&.dir
+to the given filename;
+the two
+.i db -based
+maps append
+.q \&.db .
+For example, the map specification
+.(b
+Kuucp dbm \-o \-N /usr/lib/uucpmap
+.)b
+specifies an optional map named
+.q uucp
+of class
+.q dbm ;
+it always has null bytes at the end of every string,
+and the data is located in
+/usr/lib/uucpmap.{dir,pag}.
+.pp
+The program
+.i makemap (8)
+can be used to build any of the three database-oriented maps.
+It takes the following flags:
+.ip \-f
+Fold upper to lower case in the map.
+.ip \-N
+Include null bytes in keys.
+.ip \-o
+Append to an existing (old) file.
+.ip \-r
+Allow replacement of existing keys;
+normally, re-inserting an existing key is an error.
+.ip \-v
+Print what is happening.
+.lp
+The
+.i sendmail
+daemon does not have to be restarted to read the new maps
+as long as you change them in place;
+file locking is used so that the maps won't be read
+while they are being updated.\**
+.(f
+\**That is, don't create new maps and then use
+.i mv (1)
+to move them into place.
+I consider this a shortfall (a.k.a. bug) in
+.i sendmail
+which should be fixed in a future release.
+.)f
+.pp
+There are also two builtin maps that are,
+strictly speaking,
+not database lookups.
+.pp
+The
+.q host
+map does host domain canonification;
+given a host name it calls the name server
+to find the canonical name for that host.
+.pp
+The
+.q dequote
+map strips double quotes (") from a name.
+It does not strip backslashes.
+It will not strip quotes if the resulting string
+would contain unscannable syntax
+(that is, basic errors like unbalanced angle brackets;
+more sophisticated errors such as unknown hosts are not checked).
+The intent is for use when trying to accept mail from systems such as
+DECnet
+that routinely quote odd syntax such as
+.(b
+"49ers::ubell"
+.)b
+A typical usage is probably something like:
+.(b
+Kdequote dequote
+
+\&...
+
+R$\- $: $(dequote $1 $)
+R$\- $+ $: $>3 $1 $2
+.)b
+Care must be taken to prevent unexpected results;
+for example,
+.(b
+"|someprogram < input > output"
+.)b
+will have quotes stripped,
+but the result is probably not what you had in mind.
+Fortunately these cases are rare.
+.pp
+New classes can be added in the routine
+.b setupmaps
+in file
+.b conf.c .
+.sh 2 "Building a Configuration File From Scratch"
+.pp
+Building a configuration table from scratch is an extremely difficult job.
+Fortunately,
+it is almost never necessary to do so;
+nearly every situation that may come up
+may be resolved by changing an existing table.
+In any case,
+it is critical that you understand what it is that you are trying to do
+and come up with a philosophy for the configuration table.
+This section is intended to explain what the real purpose
+of a configuration table is
+and to give you some ideas
+for what your philosophy might be.
+.pp
+.b "Do not even consider"
+writing your own configuration file
+without carefully studying
+RFC 821, 822, and 1123.
+You should also read RFC 976
+if you are doing UUCP exchange.
+.sh 3 "What you are trying to do"
+.pp
+The configuration table has three major purposes.
+The first and simplest
+is to set up the environment for
+.i sendmail .
+This involves setting the options,
+defining a few critical macros,
+etc.
+Since these are described in other places,
+we will not go into more detail here.
+.pp
+The second purpose is to rewrite addresses in the message.
+This should typically be done in two phases.
+The first phase maps addresses in any format
+into a canonical form.
+This should be done in ruleset three.
+The second phase maps this canonical form
+into the syntax appropriate for the receiving mailer.
+.i Sendmail
+does this in three subphases.
+Rulesets one and two
+are applied to all sender and recipient addresses respectively.
+After this,
+you may specify per-mailer rulesets
+for both sender and recipient addresses;
+this allows mailer-specific customization.
+Finally,
+ruleset four is applied to do any default conversion
+to external form.
+.pp
+The third purpose
+is to map addresses into the actual set of instructions
+necessary to get the message delivered.
+Ruleset zero must resolve to the internal form,
+which is in turn used as a pointer to a mailer descriptor.
+The mailer descriptor describes the interface requirements
+of the mailer.
+.sh 3 "Philosophy"
+.pp
+The particular philosophy you choose will depend heavily
+on the size and structure of your organization.
+I will present a few possible philosophies here.
+There are as many philosophies as there are config designers;
+feel free to develop your own.
+.pp
+One general point applies to all of these philosophies:
+it is almost always a mistake
+to try to do full host route resolution.
+For example,
+if you are on a UUCP-only site
+and you are trying to get names of the form
+.q user@host
+to the Internet,
+it does not pay to route them to
+.q xyzvax!decvax!ucbvax!c70!user@host
+since you then depend on several links not under your control,
+some of which are likely to misparse it anyway.
+The best approach to this problem
+is to simply forward the message for
+.q user@host
+to
+.q xyzvax
+and let xyzvax
+worry about it from there.
+In summary,
+just get the message closer to the destination,
+rather than determining the full path.
+.sh 4 "Large site, many hosts \*- minimum information"
+.pp
+Berkeley is an example of a large site,
+i.e., more than two or three hosts
+and multiple mail connections.
+We have decided that the only reasonable philosophy
+in our environment
+is to designate one host as the guru for our site.
+It must be able to resolve any piece of mail it receives.
+The other sites should have the minimum amount of information
+they can get away with.
+In addition,
+any information they do have
+should be hints rather than solid information.
+.pp
+For example,
+a typical site on our local ether network is
+.q monet
+(actually
+.q monet.CS.Berkeley.EDU ).
+When monet receives mail for delivery,
+it checks whether it knows
+that the destination host is directly reachable;
+if so, mail is sent to that host.
+If it receives mail for any unknown host,
+it just passes it directly to
+.q ucbvax.CS.Berkeley.EDU ,
+our master host.
+Ucbvax may determine that the host name is illegal
+and reject the message,
+or may be able to do delivery.
+However, it is important to note that when a new mail connection is added,
+the only host that
+.i must
+have its tables updated
+is ucbvax;
+the others
+.i may
+be updated if convenient,
+but this is not critical.
+.pp
+This picture is slightly muddied
+due to network connections that are not actually located
+on ucbvax.
+For example,
+some UUCP connections are currently on
+.q ucbarpa.
+However,
+monet
+.i "does not"
+know about this;
+the information is hidden totally between ucbvax and ucbarpa.
+Mail going from monet to a UUCP host
+is transferred via the ethernet
+from monet to ucbvax,
+then via the ethernet from ucbvax to ucbarpa,
+and then is submitted to UUCP.
+Although this involves some extra hops,
+we feel this is an acceptable tradeoff.
+.pp
+An interesting point is that it would be possible
+to update monet
+to send appropriate UUCP mail directly to ucbarpa
+if the load got too high;
+if monet failed to note a host as connected to ucbarpa
+it would go via ucbvax as before,
+and if monet incorrectly sent a message to ucbarpa
+it would still be sent by ucbarpa
+to ucbvax as before.
+The only problem that can occur is loops,
+for example,
+if ucbarpa thought that ucbvax had the UUCP connection
+and vice versa.
+For this reason,
+updates should
+.i always
+happen to the master host first.
+.pp
+This philosophy results as much from the need
+to have a single source for the configuration files
+(typically built using
+.i m4 \|(1)
+or some similar tool)
+as any logical need.
+Maintaining more than three separate tables by hand
+is essentially an impossible job.
+.sh 4 "Small site \*- complete information"
+.pp
+A small site
+(two or three hosts and few external connections)
+may find it more reasonable to have complete information
+at each host.
+This would require that each host
+know exactly where each network connection is,
+possibly including the names of each host on that network.
+As long as the site remains small
+and the configuration remains relatively static,
+the update problem will probably not be too great.
+.sh 4 "Single host"
+.pp
+This is in some sense the trivial case.
+The only major issue is trying to insure that you don't
+have to know too much about your environment.
+For example,
+if you have a UUCP connection
+you might find it useful to know about the names of hosts
+connected directly to you,
+but this is really not necessary
+since this may be determined from the syntax.
+.sh 4 "A completely different philosophy"
+.pp
+This is adapted from Bruce Lilly.
+Any errors in interpretation are mine.
+.pp
+Do minimal changes in ruleset 3:
+fix some common but unambiguous errors (e.g. trailing dot on domains) and
+hide bang paths foo!bar into bar@foo.UUCP.
+The resulting "canonical" form is any valid RFC822/RFC1123/RFC976 address.
+.pp
+Ruleset 0 does the bulk of the work.
+It removes the trailing "@.UUCP" that hides bang paths,
+strips anything not needed to resolve,
+e.g. the phrase from phrase <route-addr> and from named groups,
+rejects unparseable addresses using $#error,
+and finally
+resolves to a mailer/host/user triple.
+Ruleset 0 is rather lengthy
+as it has to handle 3 basic address forms:
+RFC976 bang paths,
+RFC1123 %-hacks
+(including vanilla RFC822 local-part@domain),
+and RFC822 source routes.
+It's also complicated by having to handle named lists.
+.pp
+The header rewriting rulesets 1 and 2
+remove the trailing "@.UUCP" that hides bang paths.
+Ruleset 2 also strips the $# mailer $@ host (for test mode).
+.pp
+Ruleset 4 does absolutely nothing.
+.pp
+The per-mailer rewriting rulesets conform the envelope and
+header addresses to the requirements of the specific
+mailer.
+.pp
+Lots of rulesets-as-subroutines are used.
+.pp
+As a result, header addresses are subject to minimal munging
+(per RFC1123), and the general plan is per RFC822 sect. 3.4.10.
+.sh 3 "Relevant issues"
+.pp
+The canonical form you use
+should almost certainly be as specified in
+the Internet protocols
+RFC819 and RFC822.
+Copies of these RFC's are included on the
+.i sendmail
+tape
+as
+.i doc/rfc819.lpr
+and
+.i doc/rfc822.lpr .
+.pp
+RFC822
+describes the format of the mail message itself.
+.i Sendmail
+follows this RFC closely,
+to the extent that many of the standards described in this document
+can not be changed without changing the code.
+In particular,
+the following characters have special interpretations:
+.(b
+< > ( ) " \e
+.)b
+Any attempt to use these characters for other than their RFC822
+purpose in addresses is probably doomed to disaster.
+.pp
+RFC819
+describes the specifics of the domain-based addressing.
+This is touched on in RFC822 as well.
+Essentially each host is given a name
+which is a right-to-left dot qualified pseudo-path
+from a distinguished root.
+The elements of the path need not be physical hosts;
+the domain is logical rather than physical.
+For example,
+at Berkeley
+one legal host might be
+.q a.CC.Berkeley.EDU ;
+reading from right to left,
+.q EDU
+is a top level domain
+comprising educational institutions,
+.q Berkeley
+is a logical domain name,
+.q CC
+represents the Computer Center,
+(in this case a strictly logical entity),
+and
+.q a
+is a host in the Computer Center.
+.pp
+Beware when reading RFC819
+that there are a number of errors in it.
+.sh 3 "How to proceed"
+.pp
+Once you have decided on a philosophy,
+it is worth examining the available configuration tables
+to decide if any of them are close enough
+to steal major parts of.
+Even under the worst of conditions,
+there is a fair amount of boiler plate that can be collected safely.
+.pp
+The next step is to build ruleset three.
+This will be the hardest part of the job.
+Beware of doing too much to the address in this ruleset,
+since anything you do will reflect through
+to the message.
+In particular,
+stripping of local domains is best deferred,
+since this can leave you with addresses with no domain spec at all.
+Since
+.i sendmail
+likes to append the sending domain to addresses with no domain,
+this can change the semantics of addresses.
+Also try to avoid
+fully qualifying domains in this ruleset.
+Although technically legal,
+this can lead to unpleasantly and unnecessarily long addresses
+reflected into messages.
+The Berkeley configuration files
+define ruleset nine
+to qualify domain names and strip local domains.
+This is called from ruleset zero
+to get all addresses into a cleaner form.
+.pp
+Once you have ruleset three finished,
+the other rulesets should be relatively trivial.
+If you need hints,
+examine the supplied configuration tables.
+.sh 3 "Testing the rewriting rules \*- the \-bt flag"
+.pp
+When you build a configuration table,
+you can do a certain amount of testing
+using the
+.q "test mode"
+of
+.i sendmail .
+For example,
+you could invoke
+.i sendmail
+as:
+.(b
+sendmail \-bt \-Ctest.cf
+.)b
+which would read the configuration file
+.q test.cf
+and enter test mode.
+In this mode,
+you enter lines of the form:
+.(b
+rwset address
+.)b
+where
+.i rwset
+is the rewriting set you want to use
+and
+.i address
+is an address to apply the set to.
+Test mode shows you the steps it takes
+as it proceeds,
+finally showing you the address it ends up with.
+You may use a comma separated list of rwsets
+for sequential application of rules to an input.
+For example:
+.(b
+3,1,21,4 monet:bollard
+.)b
+first applies ruleset three to the input
+.q monet:bollard.
+Ruleset one is then applied to the output of ruleset three,
+followed similarly by rulesets twenty-one and four.
+.pp
+If you need more detail,
+you can also use the
+.q \-d21
+flag to turn on more debugging.
+For example,
+.(b
+sendmail \-bt \-d21.99
+.)b
+turns on an incredible amount of information;
+a single word address
+is probably going to print out several pages worth of information.
+.pp
+You should be warned that internally,
+.i sendmail
+applies ruleset 3 to all addresses.
+In this version of
+.i sendmail ,
+you will have to do that manually.
+For example, older versions allowed you to use
+.(b
+0 bruce@broadcast.sony.com
+.)b
+This version requires that you use:
+.(b
+3,0 bruce@broadcast.sony.com
+.)b
+.sh 3 "Building mailer descriptions"
+.pp
+To add an outgoing mailer to your mail system,
+you will have to define the characteristics of the mailer.
+.pp
+Each mailer must have an internal name.
+This can be arbitrary,
+except that the names
+.q local
+and
+.q prog
+must be defined.
+.pp
+The pathname of the mailer must be given in the P field.
+If this mailer should be accessed via an IPC connection,
+use the string
+.q [IPC]
+instead.
+.pp
+The F field defines the mailer flags.
+You should specify an
+.q f
+or
+.q r
+flag to pass the name of the sender as a
+.b \-f
+or
+.b \-r
+flag respectively.
+These flags are only passed if they were passed to
+.i sendmail ,
+so that mailers that give errors under some circumstances
+can be placated.
+If the mailer is not picky
+you can just specify
+.q "\-f $g"
+in the argv template.
+If the mailer must be called as
+.b root
+the
+.q S
+flag should be given;
+this will not reset the userid
+before calling the mailer\**.
+.(f
+\**\c
+.i Sendmail
+must be running setuid to root
+for this to work.
+.)f
+If this mailer is local
+(i.e., will perform final delivery
+rather than another network hop)
+the
+.q l
+flag should be given.
+Quote characters
+(backslashes and " marks)
+can be stripped from addresses if the
+.q s
+flag is specified;
+if this is not given
+they are passed through.
+If the mailer is capable of sending to more than one user
+on the same host
+in a single transaction
+the
+.q m
+flag should be stated.
+If this flag is on,
+then the argv template containing
+.b $u
+will be repeated for each unique user
+on a given host.
+The
+.q e
+flag will mark the mailer as being
+.q expensive,
+which will cause
+.i sendmail
+to defer connection
+until a queue run\**.
+.(f
+\**The
+.q c
+configuration option must be given
+for this to be effective.
+.)f
+.pp
+An unusual case is the
+.q C
+flag.
+This flag applies to the mailer that the message is received from,
+rather than the mailer being sent to;
+if set,
+the domain spec of the sender
+(i.e., the
+.q @host.domain
+part)
+is saved
+and is appended to any addresses in the message
+that do not already contain a domain spec.
+For example,
+a message of the form:
+.(b
+From: eric@vangogh.CS.Berkeley.EDU
+To: wnj@monet.CS.Berkeley.EDU, mckusick
+.)b
+will be modified to:
+.(b
+From: eric@vangogh.CS.Berkeley.EDU
+To: wnj@monet.CS.Berkeley.EDU, mckusick@vangogh.CS.Berkeley.EDU
+.)b
+.i "if and only if"
+the
+.q C
+flag is defined in the mailer resolved to
+by running
+.q eric@vangogh.CS.Berkeley.EDU
+through rulesets 3 and 0.
+.pp
+Other flags are described
+in Appendix C.
+.pp
+The S and R fields in the mailer description
+are per-mailer rewriting sets
+to be applied to sender and recipient addresses
+respectively.
+These are applied after the sending domain is appended
+and the general rewriting sets
+(numbers one and two)
+are applied,
+but before the output rewrite
+(ruleset four)
+is applied.
+A typical use is to append the current domain
+to addresses that do not already have a domain.
+For example,
+a header of the form:
+.(b
+From: eric
+.)b
+might be changed to be:
+.(b
+From: eric@vangogh.CS.Berkeley.EDU
+.)b
+or
+.(b
+From: ucbvax!eric
+.)b
+depending on the domain it is being shipped into.
+These sets can also be used
+to do special purpose output rewriting
+in cooperation with ruleset four.
+.pp
+The S and R fields
+can be specified as two numbers separated by a slash
+(e.g.,
+.q "S=10/11" ),
+meaning that all envelope addresses will be processed through ruleset 10
+and all header addresses will be processed through ruleset 11.
+With only one number specified,
+both envelope and header rewriting sets are set to the indicated ruleset.
+.pp
+The E field defines the string to use
+as an end-of-line indication.
+A string containing only newline is the default.
+The usual backslash escapes
+(\er, \en, \ef, \eb)
+may be used.
+.pp
+Finally,
+an argv template is given as the A field.
+It may have embedded spaces.
+If there is no argv with a
+.b $u
+macro in it,
+.i sendmail
+will speak SMTP
+to the mailer.
+If the pathname for this mailer is
+.q [IPC],
+the argv should be
+.(b
+IPC $h [ \fIport\fP ]
+.)b
+where
+.i port
+is the optional port number
+to connect to.
+.pp
+For example,
+the specifications:
+.(b
+.ta \w'Mlocal, 'u +\w'P=/bin/mail, 'u +\w'F=rlsm, 'u +\w'S=10, 'u +\w'R=20, 'u
+Mlocal, P=/bin/mail, F=rlsm S=10, R=20, A=mail \-d $u
+Mether, P=[IPC], F=meC, S=11, R=21, A=IPC $h, M=100000
+.)b
+specifies a mailer to do local delivery
+and a mailer for ethernet delivery.
+The first is called
+.q local,
+is located in the file
+.q /bin/mail,
+takes a picky
+.b \-r
+flag,
+does local delivery,
+quotes should be stripped from addresses,
+and multiple users can be delivered at once;
+ruleset ten
+should be applied to sender addresses in the message
+and ruleset twenty
+should be applied to recipient addresses;
+the argv to send to a message will be the word
+.q mail,
+the word
+.q \-d,
+and words containing the name of the receiving user.
+If a
+.b \-r
+flag is inserted
+it will be between the words
+.q mail
+and
+.q \-d.
+The second mailer is called
+.q ether,
+it should be connected to via an IPC connection,
+it can handle multiple users at once,
+connections should be deferred,
+and any domain from the sender address
+should be appended to any receiver name
+without a domain;
+sender addresses should be processed by ruleset eleven
+and recipient addresses by ruleset twenty-one.
+There is a 100,000 byte limit on messages passed through this mailer.
+.sh 2 "The User Database"
+.pp
+If you have a version of
+.i sendmail
+with the user database package
+compiled in,
+the handling of sender and recipient addresses
+is modified.
+.pp
+The location of this database is controlled with the
+.b U
+option.
+.sh 3 "Structure of the user database"
+.pp
+The database is a sorted (BTree-based) structure.
+User records are stored with the key:
+.(b
+\fIuser-name\fP\fB:\fP\fIfield-name\fP
+.)b
+The sorted database format ensures that user records are clustered together.
+Meta-information is always stored with a leading colon.
+.pp
+Field names define both the syntax and semantics of the value.
+Defined fields include:
+.nr ii 1i
+.ip maildrop
+The delivery address for this user.
+There may be multiple values of this record.
+In particular,
+mailing lists will have one
+.i maildrop
+record for each user on the list.
+.ip "mailname"
+The outgoing mailname for this user.
+For each outgoing name,
+there should be an appropriate
+.i maildrop
+record for that name to allow return mail.
+See also
+.i :default:mailname .
+.ip mailsender
+Changes any mail sent to this address to have the indicated envelope sender.
+This is intended for mailing lists,
+and will normally be the name of an appropriate -request address.
+It is very similar to the owner-\c
+.i list
+syntax in the alias file.
+.ip fullname
+The full name of the user.
+.ip office-address
+The office address for this user.
+.ip office-phone
+The office phone number for this user.
+.ip office-fax
+The office FAX number for this user.
+.ip home-address
+The home address for this user.
+.ip home-phone
+The home phone number for this user.
+.ip home-fax
+The home FAX number for this user.
+.ip project
+A (short) description of the project this person is affiliated with.
+In the University this is often just the name of their graduate advisor.
+.ip plan
+A pointer to a file from which plan information can be gathered.
+.pp
+As of this writing,
+only a few of these fields are actually being used by
+.i sendmail :
+.i maildrop
+and
+.i mailname .
+A
+.i finger
+program that uses the other fields is planned.
+.sh 3 "User database semantics"
+.pp
+When the rewriting rules submit an address to the local mailer,
+the user name is passed through the alias file.
+If no alias is found (or if the alias points back to the same address),
+the name (with
+.q :maildrop
+appended)
+is then used as a key in the user database.
+If no match occurs (or if the maildrop points at the same address),
+forwarding is tried.
+.pp
+If the first token of the user name returned by ruleset 0
+is an
+.q @
+sign, the user database lookup is skipped.
+The intent is that the user database will act as a set of defaults
+for a cluster (in our case, the Computer Science Division);
+mail sent to a specific machine should ignore these defaults.
+.pp
+When mail is sent,
+the name of the sending user is looked up in the database.
+If that user has a
+.q mailname
+record,
+the value of that record is used as their outgoing name.
+For example, I might have a record:
+.(b
+eric:mailname Eric.Allman@CS.Berkeley.EDU
+.)b
+This would cause my outgoing mail to be sent as Eric.Allman.
+.pp
+If a
+.q maildrop
+is found for the user,
+but no corresponding
+.q mailname
+record exists,
+the record
+.q :default:mailname
+is consulted.
+If present, this is the name of a host to override the local host.
+For example, in our case we would set it to
+.q CS.Berkeley.EDU .
+The effect is that anyone known in the database
+gets their outgoing mail stamped as
+.q user@CS.Berkeley.EDU ,
+but people not listed in the database use the local hostname.
+.sh 3 "Creating the database\**"
+.(f
+\**These instructions are known to be incomplete.
+A future version of the user database is planned
+including things such as finger service \*- and good documentation.
+.)f
+.pp
+The user database is built from a text file
+using the
+.i makemap
+utility
+(in the distribution in the makemap subdirectory).
+The text file is a series of lines corresponding to userdb records;
+each line has a key and a value separated by white space.
+The key is always in the format described above \*-
+for example:
+.(b
+eric:maildrop
+.)b
+This file is normally installed in a system directory;
+for example, it might be called
+.i /etc/userdb .
+To make the database version of the map, run the program:
+.(b
+makemap btree /etc/userdb.db < /etc/userdb
+.)b
+Then create a config file that uses this.
+For example, using the V8 M4 configuration, include the
+following line in your .mc file:
+.(b
+define(\`confUSERDB_SPEC\', /etc/userdb.db)
+.)b
+.sh 1 "OTHER CONFIGURATION"
+.pp
+There are some configuration changes that can be made by
+recompiling
+.i sendmail .
+This section describes what changes can be made
+and what has to be modified to make them.
+.sh 2 "Parameters in src/Makefile"
+.pp
+These parameters are intended to describe the compilation environment,
+not site policy,
+and should normally be defined in src/Makefile.
+.ip NDBM
+If set,
+the new version of the DBM library
+that allows multiple databases will be used.
+If neither NDBM nor NEWDB are set,
+a much less efficient method of alias lookup is used.
+.ip NEWDB
+If set, use the new database package from Berkeley (from 4.4BSD).
+This package is substantially faster than DBM or NDBM.
+If NEWDB and NDBM are both set,
+.i sendmail
+will read DBM files,
+but will create and use NEWDB files.
+.ip NIS
+Include support for NIS.
+If set together with
+.i both
+NEWDB and NDBM,
+.i sendmail
+will create both DBM and NEWDB files if and only if
+the file /var/yp/Makefile
+exists and is readable.
+This is intended for compatibility with Sun Microsystems'
+.i mkalias
+program used on YP masters.
+.ip SYSTEM5
+Set all of the compilation parameters appropriate for System V.
+.ip LOCKF
+Use System V
+.b lockf
+instead of Berkeley
+.b flock .
+Due to the highly unusual semantics of locks
+across forks in
+.b lockf ,
+this should never be used unless absolutely necessary.
+Set by default if
+SYSTEM5 is set.
+.ip SYS5TZ
+Use System V
+time zone semantics.
+.ip HASINITGROUPS
+Set this if your system has the
+.i initgroups()
+call
+(if you have multiple group support).
+This is the default if SYSTEM5 is
+.i not
+defined or if you are on HPUX.
+.ip HASUNAME
+Set this if you have the
+.i uname (2)
+system call (or corresponding library routine).
+Set by default if
+SYSTEM5
+is set.
+.ip HASSTATFS
+Set this if you have the
+.i statfs (2)
+system call.
+This will allow you to give a temporary failure
+message to incoming SMTP email
+when you are low on disk space.
+It is set by default on 4.4BSD and OSF/1 systems.
+.ip HASUSTAT
+Set if you have the
+.i ustat (2)
+system call.
+This is an alternative implementation of disk space control.
+You should only set one of HASSTATFS or HASUSTAT;
+the first is preferred.
+.ip _PATH_SENDMAILCF
+The pathname of the sendmail.cf file.
+.ip _PATH_SENDMAILPID
+The pathname of the sendmail.pid file.
+.ip LA_TYPE
+The load average type.
+Details are described below.
+.lp
+The are several built-in ways of computing the load average.
+.i Sendmail
+tries to auto-configure them based on imperfect guesses;
+you can select one using the
+.i cc
+option
+.b \-DLA_TYPE= \c
+.i type ,
+where
+.i type
+is:
+.ip LA_INT
+The kernel stores the load average in the kernel as an array of long integers.
+The actual values are scaled by a factor FSCALE
+(default 256).
+.ip LA_SHORT
+The kernel stores the load average in the kernel as an array of short integers.
+The actual values are scaled by a factor FSCALE
+(default 256).
+.ip LA_FLOAT
+The kernel stores the load average in the kernel as an array of
+double precision floats.
+.ip LA_MACH
+Use MACH-style load averages.
+.ip LA_SUBR
+Call the
+.i getloadavg
+routine to get the load average as an array of doubles.
+.ip LA_ZERO
+Always return zero as the load average.
+This is the fallback case.
+.lp
+If type
+.sm LA_INT ,
+.sm LA_SHORT ,
+or
+.sm LA_FLOAT
+is specified,
+you may also need to specify
+.sm _PATH_UNIX
+(the path to your system binary)
+and
+.sm LA_AVENRUN
+(the name of the variable containing the load average in the kernel;
+usually
+.q _avenrun
+or
+.q avenrun ).
+.pp
+There are also several compilation flags to indicate the environment
+such as
+.q _AIX3
+and
+.q _SCO_unix_ .
+See the READ_ME
+file for the latest scoop on these flags.
+.sh 2 "Parameters in src/conf.h"
+.pp
+Parameters and compilation options
+are defined in conf.h.
+Most of these need not normally be tweaked;
+common parameters are all in sendmail.cf.
+However, the sizes of certain primitive vectors, etc.,
+are included in this file.
+The numbers following the parameters
+are their default value.
+.nr ii 1.2i
+.ip "MAXLINE [1024]"
+The maximum line length of any input line.
+If message lines exceed this length
+they will still be processed correctly;
+however, header lines,
+configuration file lines,
+alias lines,
+etc.,
+must fit within this limit.
+.ip "MAXNAME [256]"
+The maximum length of any name,
+such as a host or a user name.
+.ip "MAXPV [40]"
+The maximum number of parameters to any mailer.
+This limits the number of recipients that may be passed in one transaction.
+It can be set to any arbitrary number above about 10,
+since
+.i sendmail
+will break up a delivery into smaller batches as needed.
+A higher number may reduce load on your system, however.
+.ip "MAXATOM [100]"
+The maximum number of atoms
+(tokens)
+in a single address.
+For example,
+the address
+.q "eric@CS.Berkeley.EDU"
+is seven atoms.
+.ip "MAXMAILERS [25]"
+The maximum number of mailers that may be defined
+in the configuration file.
+.ip "MAXRWSETS [100]"
+The maximum number of rewriting sets
+that may be defined.
+.ip "MAXPRIORITIES [25]"
+The maximum number of values for the
+.q Precedence:
+field that may be defined
+(using the
+.b P
+line in sendmail.cf).
+.ip "MAXUSERENVIRON [40]"
+The maximum number of items in the user environment
+that will be passed to subordinate mailers.
+.ip "QUEUESIZE [1000]"
+The maximum number of entries that will be processed
+in a single queue run.
+.ip "MAXMXHOSTS [20]"
+The maximum number of MX records we will accept for any single host.
+.lp
+A number of other compilation options exist.
+These specify whether or not specific code should be compiled in.
+.nr ii 1.2i
+.ip DEBUG
+If set, debugging information is compiled in.
+To actually get the debugging output,
+the
+.b \-d
+flag must be used.
+.b "WE STRONGLY RECOMMEND THAT THIS BE LEFT ON."
+Some people, believing that it was a security hole
+(it was, once)
+have turned it off and thus crippled debuggers.
+.ip NETINET
+If set,
+support for Internet protocol networking is compiled in.
+Previous versions of
+.i sendmail
+referred to this as
+.sm DAEMON ;
+this old usage is now incorrect.
+.ip NETISO
+If set,
+support for ISO protocol networking is compiled in
+(it may be appropriate to #define this in the Makefile instead of conf.h).
+.ip LOG
+If set,
+the
+.i syslog
+routine in use at some sites is used.
+This makes an informational log record
+for each message processed,
+and makes a higher priority log record
+for internal system errors.
+.ip MATCHGECOS
+Compile in the code to do ``fuzzy matching'' on the GECOS field
+in /etc/passwd.
+This also requires that option G be turned on.
+.ip NAMED_BIND
+Compile in code to use the
+Berkeley Internet Name Domain (BIND) server
+to resolve TCP/IP host names.
+.ip NOTUNIX
+If you are using a non-UNIX mail format,
+you can set this flag to turn off special processing
+of UNIX-style
+.q "From "
+lines.
+.ip QUEUE
+This flag should be set to compile in the queueing code.
+If this is not set,
+mailers must accept the mail immediately
+or it will be returned to the sender.
+.ip SETPROCTITLE
+If defined,
+.i sendmail
+will change its
+.i argv
+array to indicate its current status.
+This can be used in conjunction with the
+.i ps
+command to find out just what it's up to.
+.ip SMTP
+If set,
+the code to handle user and server SMTP will be compiled in.
+This is only necessary if your machine has some mailer
+that speaks SMTP
+(this means most machines everywhere).
+.ip UGLYUUCP
+If you have a UUCP host adjacent to you which is not running
+a reasonable version of
+.i rmail ,
+you will have to set this flag to include the
+.q "remote from sysname"
+info on the from line.
+Otherwise, UUCP gets confused about where the mail came from.
+.ip USERDB
+Include the
+.b experimental
+Berkeley user information database package.
+This adds a new level of local name expansion
+between aliasing and forwarding.
+It also uses the NEWDB package.
+This may change in future releases.
+.ip IDENTPROTO
+Compile in the IDENT protocol as defined in RFC 1413.
+This defaults on for all systems except Ultrix,
+which apparently has the interesting
+.q feature
+that when it receives a
+.q "host unreachable"
+message it closes all open connections to that host.
+Since some firewall gateways send this error code
+when you access an unauthorized port (such as 113, used by IDENT),
+Ultrix cannot receive email from such hosts.
+.sh 2 "Configuration in src/conf.c"
+.pp
+The following changes can be made in conf.c.
+.sh 3 "Built-in Header Semantics"
+.pp
+Not all header semantics are defined in the configuration file.
+Header lines that should only be included by certain mailers
+(as well as other more obscure semantics)
+must be specified in the
+.i HdrInfo
+table in
+.i conf.c .
+This table contains the header name
+(which should be in all lower case)
+and a set of header control flags (described below),
+The flags are:
+.ip H_ACHECK
+Normally when the check is made to see if a header line is compatible
+with a mailer,
+.i sendmail
+will not delete an existing line.
+If this flag is set,
+.i sendmail
+will delete
+even existing header lines.
+That is,
+if this bit is set and the mailer does not have flag bits set
+that intersect with the required mailer flags
+in the header definition in
+sendmail.cf,
+the header line is
+.i always
+deleted.
+.ip H_EOH
+If this header field is set,
+treat it like a blank line,
+i.e.,
+it will signal the end of the header
+and the beginning of the message text.
+.ip H_FORCE
+Add this header entry
+even if one existed in the message before.
+If a header entry does not have this bit set,
+.i sendmail
+will not add another header line if a header line
+of this name already existed.
+This would normally be used to stamp the message
+by everyone who handled it.
+.ip H_TRACE
+If set,
+this is a timestamp
+(trace)
+field.
+If the number of trace fields in a message
+exceeds a preset amount
+the message is returned
+on the assumption that it has an aliasing loop.
+.ip H_RCPT
+If set,
+this field contains recipient addresses.
+This is used by the
+.b \-t
+flag to determine who to send to
+when it is collecting recipients from the message.
+.ip H_FROM
+This flag indicates that this field
+specifies a sender.
+The order of these fields in the
+.i HdrInfo
+table specifies
+.i sendmail 's
+preference
+for which field to return error messages to.
+.nr ii 5n
+.lp
+Let's look at a sample
+.i HdrInfo
+specification:
+.(b
+.ta 4n +\w'"return-receipt-to", 'u
+struct hdrinfo HdrInfo[] =
+\&{
+ /* originator fields, most to least significant */
+ "resent-sender", H_FROM,
+ "resent-from", H_FROM,
+ "sender", H_FROM,
+ "from", H_FROM,
+ "full-name", H_ACHECK,
+ /* destination fields */
+ "to", H_RCPT,
+ "resent-to", H_RCPT,
+ "cc", H_RCPT,
+ /* message identification and control */
+ "message", H_EOH,
+ "text", H_EOH,
+ /* trace fields */
+ "received", H_TRACE|H_FORCE,
+
+ NULL, 0,
+};
+.)b
+This structure indicates that the
+.q To: ,
+.q Resent-To: ,
+and
+.q Cc:
+fields
+all specify recipient addresses.
+Any
+.q Full-Name:
+field will be deleted unless the required mailer flag
+(indicated in the configuration file)
+is specified.
+The
+.q Message:
+and
+.q Text:
+fields will terminate the header;
+these are used by random dissenters around the network world.
+The
+.q Received:
+field will always be added,
+and can be used to trace messages.
+.pp
+There are a number of important points here.
+First,
+header fields are not added automatically just because they are in the
+.i HdrInfo
+structure;
+they must be specified in the configuration file
+in order to be added to the message.
+Any header fields mentioned in the configuration file but not
+mentioned in the
+.i HdrInfo
+structure have default processing performed;
+that is,
+they are added unless they were in the message already.
+Second,
+the
+.i HdrInfo
+structure only specifies cliched processing;
+certain headers are processed specially by ad hoc code
+regardless of the status specified in
+.i HdrInfo .
+For example,
+the
+.q Sender:
+and
+.q From:
+fields are always scanned on ARPANET mail
+to determine the sender\**;
+.(f
+\**Actually, this is no longer true in SMTP;
+this information is contained in the envelope.
+The older ARPANET protocols did not completely distinguish
+envelope from header.
+.)f
+this is used to perform the
+.q "return to sender"
+function.
+The
+.q "From:"
+and
+.q "Full-Name:"
+fields are used to determine the full name of the sender
+if possible;
+this is stored in the macro
+.b $x
+and used in a number of ways.
+.sh 3 "Restricting Use of Email"
+.pp
+If it is necessary to restrict mail through a relay,
+the
+.i checkcompat
+routine can be modified.
+This routine is called for every recipient address.
+It returns an exit status
+indicating the status of the message.
+The status
+.sm EX_OK
+accepts the address,
+.sm EX_TEMPFAIL
+queues the message for a later try,
+and other values
+(commonly
+.sm EX_UNAVAILABLE )
+reject the message.
+It is up to
+.i checkcompat
+to print an error message
+(using
+.i usrerr )
+if the message is rejected.
+For example,
+.i checkcompat
+could read:
+.(b
+.re
+.sz -1
+.ta 4n +4n +4n +4n +4n +4n +4n
+int
+checkcompat(to, e)
+ register ADDRESS *to;
+ register ENVELOPE *e;
+\&{
+ register STAB *s;
+
+ s = stab("private", ST_MAILER, ST_FIND);
+ if (s != NULL && e\->e_from.q_mailer != LocalMailer &&
+ to->q_mailer == s->s_mailer)
+ {
+ usrerr("No private net mail allowed through this machine");
+ return (EX_UNAVAILABLE);
+ }
+ if (MsgSize > 50000 && to\->q_mailer != LocalMailer)
+ {
+ usrerr("Message too large for non-local delivery");
+ NoReturn = TRUE;
+ return (EX_UNAVAILABLE);
+ }
+ return (EX_OK);
+}
+.sz
+.)b
+This would reject messages greater than 50000 bytes
+unless they were local.
+The
+.i NoReturn
+flag can be sent to suppress the return of the actual body
+of the message in the error return.
+The actual use of this routine is highly dependent on the
+implementation,
+and use should be limited.
+.sh 3 "Load Average Computation"
+.pp
+The routine
+.i getla
+should return an approximation of the current system load average
+as an integer.
+There are four versions included on compilation flags
+as described above.
+.sh 3 "New Database Map Classes"
+.pp
+New key maps can be added by creating a class initialization function
+and a lookup function.
+These are then added to the routine
+.i setupmaps.
+.pp
+The initialization function is called as
+.(b
+\fIxxx\fP_map_init(MAP *map, char *mapname, char *args)
+.)b
+The
+.i map
+is an internal data structure.
+The
+.i mapname
+is the name of the map (used for error messages).
+The
+.i args
+is a pointer to the rest of the configuration file line;
+flags and filenames can be extracted from this line.
+The initialization function must return
+.sm TRUE
+if it successfully opened the map,
+.sm FALSE
+otherwise.
+.pp
+The lookup function is called as
+.(b
+\fIxxx\fP_map_lookup(MAP *map, char buf[], int bufsize, char **av, int *statp)
+.)b
+The
+.i map
+defines the map internally.
+The parameters
+.i buf
+and
+.i bufsize
+have the input key.
+This may be (and often is) used destructively.
+The
+.i av
+is a list of arguments passed in from the rewrite line.
+The lookup function should return a pointer to the new value.
+IF the map lookup fails,
+.i *statp
+should be set to an exit status code;
+in particular, it should be set to
+.sm EX_TEMPFAIL
+if recovery is to be attempted by the higher level code.
+.sh 3 "Queueing Function"
+.pp
+The routine
+.i shouldqueue
+is called to decide if a message should be queued
+or processed immediately.
+Typically this compares the message priority to the current load average.
+The default definition is:
+.(b
+bool
+shouldqueue(pri, ctime)
+ long pri;
+ time_t ctime;
+{
+ if (CurrentLA < QueueLA)
+ return (FALSE);
+ if (CurrentLA >= RefuseLA)
+ return (TRUE);
+ return (pri > (QueueFactor / (CurrentLA \- QueueLA + 1)));
+}
+.)b
+If the current load average
+(global variable
+.i CurrentLA ,
+which is set before this function is called)
+is less than the low threshold load average
+(option
+.b x ,
+variable
+.i QueueLA ),
+.i shouldqueue
+returns
+.sm FALSE
+immediately
+(that is, it should
+.i not
+queue).
+If the current load average exceeds the high threshold load average
+(option
+.b X ,
+variable
+.i RefuseLA ),
+.i shouldqueue
+returns
+.sm TRUE
+immediately.
+Otherwise, it computes the function based on the message priority,
+the queue factor
+(option
+.b q ,
+global variable
+.i QueueFactor ),
+and the current and threshold load averages.
+.pp
+An implementation wishing to take the actual age of the message into account
+can also use the
+.i ctime
+parameter,
+which is the time that the message was first submitted to
+.i sendmail .
+Note that the
+.i pri
+parameter is already weighted
+by the number of times the message has been tried
+(although this tends to lower the priority of the message with time);
+the expectation is that the
+.i ctime
+would be used as an
+.q "escape clause"
+to ensure that messages are eventually processed.
+.sh 3 "Refusing Incoming SMTP Connections"
+.pp
+The function
+.i refuseconnections
+returns
+.sm TRUE
+if incoming SMTP connections should be refused.
+The current implementation is based exclusively on the current load average
+and the refuse load average option
+(option
+.b X ,
+global variable
+.i RefuseLA ):
+.(b
+bool
+refuseconnections()
+{
+ return (CurrentLA >= RefuseLA);
+}
+.)b
+A more clever implementation
+could look at more system resources.
+.sh 3 "Load Average Computation"
+.pp
+The routine
+.i getla
+returns the current load average (as a rounded integer).
+The distribution includes several possible implementations.
+.sh 2 "Configuration in src/daemon.c"
+.pp
+The file
+.i src/daemon.c
+contains a number of routines that are dependent
+on the local networking environment.
+The version supplied assumes you have BSD style sockets.
+.pp
+In previous releases,
+we recommended that you modify the routine
+.i maphostname
+if you wanted to generalize
+.b $[
+\&...\&
+.b $]
+lookups.
+We now recommend that you create a new keyed map instead.
+.sh 1 "CHANGES IN VERSION 8"
+.pp
+The following summarizes changes
+since the last commonly available version of
+.i sendmail
+(5.67):
+.sh 2 "Connection Caching"
+.pp
+Instead of closing SMTP connections immediately,
+those connections are cached for possible future use.
+The advent of MX records made this effective for mailing lists;
+in addition,
+substantial performance improvements can be expected for queue processing.
+.sh 2 "MX Piggybacking"
+.pp
+If two hosts with different names in a single message
+happen to have the same set of MX hosts,
+they can be sent in the same transaction.
+Version 8 notices this and tries to batch the messages.
+.sh 2 "RFC 1123 Compliance"
+.pp
+A number of changes have been made to make
+.i sendmail
+.q "conditionally compliant"
+(that is,
+.i sendmail
+satisfies all of the
+.q MUST
+clauses and most but not all of the
+.q SHOULD
+clauses in RFC 1123).
+.pp
+The major areas of change are (numbers are RFC 1123 section numbers):
+.nr ii \w'5.3.1.1\0\0'u
+.ip 5.2.7
+Response to RCPT command is fast.
+.ip 5.2.8
+Numeric IP addresses are logged in Received: lines.
+.ip 5.2.17
+Self domain literal is properly handled.
+.ip 5.3.2
+Better control over individual timeouts.
+.ip 5.3.3
+Error messages are sent as
+.q From:<> .
+.ip 5.3.3
+Error messages are never sent to
+.q <> .
+.ip 5.3.3
+Route-addrs are pruned.
+.lp
+The areas in which
+.i sendmail
+is not
+.q "unconditionally compliant"
+are:
+.ip 5.2.6
+.i Sendmail
+does do header munging.
+.ip 5.2.10
+.i Sendmail
+doesn't always use the exact SMTP message text
+as listed in RFC 821.
+.ip 5.3.1.1
+.i Sendmail
+doesn't guarantee only one connect for each host in queue runs.
+.ip 5.3.1.1
+.i Sendmail
+doesn't always provide adequate concurrency limits.
+.sh 2 "Extended SMTP Support"
+.pp
+Version 8 includes both sending and receiving support for Extended
+SMTP support as defined by RFC 1425 (basic) and RFC 1427 (SIZE);
+and limited support for RFC 1426 (BODY).
+.sh 2 "Eight-Bit Clean"
+.pp
+Previous versions of
+.i sendmail
+used the 0200 bit for quoting.
+This version avoids that use.
+However, for compatibility with RFC 822,
+you can set option `7' to get seven bit stripping.
+.pp
+Individual mailers can still produce seven bit output using the
+`7' mailer flag.
+.sh 2 "User Database"
+.pp
+The user database is an as-yet experimental attempt
+to provide unified large-site name support.
+We are installing it at Berkeley;
+future versions may show significant modifications.
+.sh 2 "Improved BIND Support"
+.pp
+The BIND support,
+particularly for MX records,
+had a number of annoying
+.q features
+which have been removed in this release.
+In particular,
+these more tightly bind (pun intended) the name server to
+.i sendmail ,
+so that the name server resolution rules are incorporated directly into
+.b sendmail .
+.sh 2 "Keyed Files"
+.pp
+Generalized keyed files is an idea taken directly from
+.sm IDA
+.i sendmail
+(albeit with a completely different implementation).
+They can be useful on large sites.
+.pp
+Version 8 also understands YP.
+.sh 2 "Multi-Word Classes"
+.pp
+Classes can now be multiple words.
+For example,
+.(b
+CShofmann.CS.Berkeley.EDU
+.)b
+allows you to match the entire string
+.q hofmann.CS.Berkeley.EDU
+using the single construct
+.q $=S .
+.sh 2 "Deferred Macro Expansion"
+.pp
+The
+.b $& \c
+.i x
+construct has been adopted from
+.sm IDA .
+.sh 2 "IDENT Protocol Support"
+.pp
+The IDENT protocol as defined in RFC 1413 is supported.
+.sh 2 "Parsing Bug Fixes"
+.pp
+A number of small bugs having to do with things like
+backslash-escaped quotes inside of comments
+have been fixed.
+.sh 2 "Separate Envelope/Header Processing"
+.pp
+Since the From: line is passed in separately from the envelope sender,
+these have both been made visible;
+the
+.b $g
+macro is set to the envelope sender during processing
+of mailer argument vectors
+and the header sender during processing of headers.
+.pp
+It is also possible to specify separate per-mailer
+envelope and header processing.
+The
+.b S enderRWSet
+and
+.b R ecipientRWset
+arguments for mailers
+can be specified as
+.i envelope/header
+to give different rewritings for envelope versus header addresses.
+.sh 2 "Owner-List Propagates to Envelope"
+.pp
+When an alias has an associated owner\-list name,
+that alias is used to change the envelope sender address.
+This will cause downstream errors to be returned to that owner.
+.sh 2 "Dynamic Header Allocation"
+.pp
+The fixed size limit on header lines has been eliminated.
+.sh 2 "New Command Line Flags"
+.pp
+The
+.b \-B
+flag has been added to pass in body type information.
+.pp
+The
+.b \-p
+flag has been added
+to pass in protocol information.
+.pp
+The
+.b \-X
+flag has been added
+to allow logging of all protocol in and out of
+.i sendmail
+for debugging.
+.sh 2 "Enhanced Command Line Flags"
+.pp
+The
+.b \-q
+flag can limit limit a queue run to specific recipients, senders, or queue ids
+using
+.b \-qR\c
+.i substring ,
+.b \-qS\c
+.i substring ,
+or
+.b \-qI\c
+.i substring
+respectively.
+.sh 2 "New and Old Configuration Line Types"
+.pp
+The
+.b T
+(Trusted users) configuration line has been deleted.
+It will still be accepted but will be ignored.
+.pp
+The
+.b K
+line has been added to declare database maps.
+.pp
+The
+.b V
+line has been added to declare the configuration version level.
+.pp
+The
+.b M
+line has a
+.q D=
+field that lets you change into a temporary directory while that mailer
+is running.
+.sh 2 "New Options"
+.pp
+Several new options have been added,
+many to support new features,
+others to allow tuning that was previously available
+only by recompiling.
+They are described in detail in Section 5.1.5.
+Briefly,
+.nr ii 0.5i
+.ip b
+Insist on a minimum number of disk blocks.
+.ip C
+Set checkpoint interval.
+.ip E
+Default error message.
+.ip G
+Enable GECOS matching.
+.ip h
+Maximum hop count.
+.ip j
+Send errors in MIME-encapsulated format.
+.ip J
+Forward file path.
+.ip k
+Connection cache size
+.ip K
+Connection cache lifetime.
+.ip l
+Enable Errors-To: header.
+These headers violate RFC 1123;
+this option is included to provide back compatibility
+with old versions of
+.i sendmail .
+.ip O
+Set incoming SMTP daemon options, such as an alternate SMTP port.
+.ip p
+Privacy options.
+.ip R
+Don't prune route-addrs.
+.ip U
+User database spec.
+.ip V
+Fallback
+.q MX
+host.
+.ip w
+.q "Best MX"
+handling technique.
+.ip 7
+Do not run eight bit clean.
+.sh 2 "Extended Options"
+.pp
+The
+.b r
+(read timeout),
+.b I
+(use BIND),
+and
+.b T
+(queue timeout)
+options have been extended to pass in more information.
+.sh 2 "New Mailer Flags"
+.pp
+Several new mailer flags have been added.
+.ip a
+Try to use ESMTP when creating a connection.
+If this is not set,
+.i sendmail
+will still try if the other end hints that it knows about ESMTP
+in its greeting message;
+this flag says to try even if it doesn't hint.
+If the EHLO (extended hello)
+command fails,
+.i sendmail
+falls back to old SMTP.
+.ip b
+Ensure that there is a blank line at the end of all messages.
+.ip c
+Strip all comments from addresses;
+this should only be used as a last resort
+when dealing with cranky mailers.
+.ip g
+Never use the null sender as the envelope sender,
+even when running SMTP.
+Although this violates RFC 1123,
+it may be necessary when you must deal with some obnoxious old hosts.
+.ip 7
+Strip all output to 7 bits.
+.sh 2 "New Pre-Defined Macros"
+.pp
+The following macros are pre-defined:
+.ip $k
+The UUCP node name,
+nominally from
+.i uname (2)
+call.
+.ip $m
+The domain part of our full hostname.
+.ip $_
+The RFC 1413-provided sender address.
+.sh 2 "New LHS Token"
+.pp
+Version 8 allows
+.b $@
+on the Left Hand Side of an
+.q R
+line to match zero tokens.
+This is intended to be used to match the null input.
+.sh 2 "Bigger Defaults"
+.pp
+Version 8 allows up to 100 rulesets instead of 30.
+It is recommended that rulesets 0\-9 be reserved for
+.i sendmail 's
+dedicated use in future releases.
+.pp
+The total number of MX records that can be used has been raised to 20.
+.pp
+The number of queued messages that can be handled at one time
+has been raised from 600 to 1000.
+.sh 2 "Different Default Tuning Parameters"
+.pp
+Version 8 has changed the default parameters
+for tuning queue costs
+to make the number of recipients more important
+than the size of the message (for small messages).
+This is reasonable if you are connected with reasonably fast links.
+.sh 2 "Auto-Quoting in Addresses"
+.pp
+Previously, the
+.q "Full Name <email address>"
+syntax would generate incorrect protocol output
+if
+.q "Full Name"
+had special characters such as dot.
+This version puts quotes around such names.
+.sh 2 "Symbolic Names On Error Mailer"
+.pp
+Several names have been built in to the $@ portion of the $#error
+mailer.
+.sh 2 "SMTP VRFY Doesn't Expand"
+.pp
+Previous versions of
+.i sendmail
+treated VRFY and EXPN the same.
+In this version,
+VRFY doesn't expand aliases or follow .forward files.
+EXPN still does.
+.pp
+As an optimization, if you run with your default delivery mode being
+queue-only or deliver-in-background,
+the RCPT command will also not chase aliases and .forward files.
+It will chase them when it processes the queue.
+.sh 2 "[IPC] Mailers Allow Multiple Hosts"
+.pp
+When an address resolves to a mailer that has
+.q [IPC]
+as its
+.q Path ,
+the $@ part (host name)
+can be a colon-separated list of hosts instead of a single hostname.
+This asks
+.i sendmail
+to search the list for the first entry that is available
+exactly as though it were an MX record.
+The intent is to route internal traffic through internal networks
+without publishing an MX record to the net.
+MX expansion is still done on the individual items.
+.sh 2 "Aliases Extended"
+.pp
+The implementation has been merged with maps.
+Among other things,
+this supports NIS-based aliases.
+.sh 2 "Portability and Security Enhancements"
+.pp
+A number of internal changes have been made to enhance portability.
+.pp
+Several fixes have been made to increase the paranoia factor.
+.sh 2 "Miscellaneous Changes"
+.pp
+.i Sendmail
+writes a
+.i /etc/sendmail.pid
+file with the current process id of the SMTP daemon.
+.pp
+Two people using the same program in their .forward file
+are considered different
+so that duplicate elimination doesn't delete one of them.
+.pp
+The
+.i mailstats
+program prints mailer names
+and gets the location of the
+.i sendmail.st
+file from
+.i /etc/sendmail.cf .
+.pp
+Many minor bugs have been fixed, such as handling of backslashes
+inside of quotes.
+.pp
+A hook (ruleset 5) has been added
+to allow rewriting of local addresses after aliasing.
+.sh 1 "ACKNOWLEDGEMENTS"
+.pp
+I've worked on
+.i sendmail
+for many years,
+and many employers have been remarkably patient
+about letting me work on a large project
+that was not part of my official job.
+This includes time on the INGRES Project at Berkeley,
+at Britton Lee,
+and again on the Mammoth Project at Berkeley.
+.pp
+Much of the second wave of improvements
+should be credited to Bryan Costales of ICSI.
+As he passed me drafts of his book on
+.i sendmail
+I was inspired to start working on things again.
+Bryan was also available to bounce ideas off of.
+.pp
+Many, many people contributed chunks of code and ideas to
+.i sendmail .
+It has proven to be a group network effort.
+Version 8 in particular was a group project.
+The following people made notable contributions:
+.(l
+Keith Bostic, CSRG, University of California, Berkeley
+Michael J. Corrigan, University of California, San Diego
+Bryan Costales, International Computer Science Institute
+Pa\*:r (Pell) Emanuelsson
+Craig Everhart, Transarc Corporation
+Tom Ivar Helbekkmo, Norwegian School of Economics
+Allan E. Johannesen, WPI
+Jonathan Kamens, OpenVision Technologies, Inc.
+Takahiro Kanbe, Fuji Xerox Information Systems Co., Ltd.
+Brian Kantor, University of California, San Diego
+Murray S. Kucherawy, HookUp Communication Corp.
+Bruce Lilly, Sony U.S.
+Karl London
+Nakamura Motonori, Kyoto University
+John Gardiner Myers, Carnegie Mellon University
+Neil Rickert, Northern Illinois University
+Eric Schnoebelen, Convex Computer Corp.
+Eric Wassenaar, National Institute for Nuclear and High Energy Physics, Amsterdam
+Christophe Wolfhugel, Herve Schauer Consultants (Paris)
+.)l
+I apologize for anyone I have omitted, misspelled, misattributed, or
+otherwise missed.
+Many other people have contributed ideas, comments, and encouragement.
+I appreciate their contribution as well.
+.++ A
+.+c "COMMAND LINE FLAGS"
+.ba 0
+.nr ii 1i
+.pp
+Arguments must be presented with flags before addresses.
+The flags are:
+.ip \-b\fIx\fP
+Set operation mode to
+.i x .
+Operation modes are:
+.(b
+.ta 4n
+m Deliver mail (default)
+s Speak SMTP on input side
+d Run as a daemon
+t Run in test mode
+v Just verify addresses, don't collect or deliver
+i Initialize the alias database
+p Print the mail queue
+.)b
+.ip \-B\fItype\fP
+Indicate body type.
+.ip \-C\fIfile\fP
+Use a different configuration file.
+.i Sendmail
+runs as the invoking user (rather than root)
+when this flag is specified.
+.ip \-d\fIlevel\fP
+Set debugging level.
+.ip "\-f\ \fIaddr\fP"
+The sender's machine address is
+.i addr .
+.ip \-F\fIname\fP
+Sets the full name of this user to
+.i name .
+.ip "\-h\ \fIcnt\fP"
+Sets the
+.q "hop count"
+to
+.i cnt .
+This represents the number of times this message has been processed
+by
+.i sendmail
+(to the extent that it is supported by the underlying networks).
+.i Cnt
+is incremented during processing,
+and if it reaches
+MAXHOP
+(currently 30)
+.i sendmail
+throws away the message with an error.
+.ip \-n
+Don't do aliasing or forwarding.
+.ip "\-r\ \fIaddr\fP"
+An obsolete form of
+.b \-f .
+.ip \-o\fIx\|value\fP
+Set option
+.i x
+to the specified
+.i value .
+These options are described in Appendix B.
+.ip \-p\fIprotocol\fP
+Set the sending protocol.
+Programs are encouraged to set this.
+The protocol field can be in the form
+.i protocol \c
+.b : \c
+.i host
+to set both the sending protocol and sending host.
+For example,
+.q \-pUUCP:uunet
+sets the sending protocol to UUCP
+and the sending host to uunet.
+(Some existing programs use \-oM to set the r and s macros;
+this is equivalent to using \-p.)
+.ip \-q\fItime\fP
+Try to process the queued up mail.
+If the time is given,
+a
+.i sendmail
+will run through the queue at the specified interval
+to deliver queued mail;
+otherwise, it only runs once.
+.ip \-q\fIXstring\fP
+Run the queue once,
+limiting the jobs to those matching
+.i Xstring .
+The key letter
+.i X
+can be
+.b I
+to limit based on queue identifier,
+.b R
+to limit based on recipient,
+or
+.b S
+to limit based on sender.
+A particular queued job is accepted if one of the corresponding addresses
+contains the indicated
+.i string .
+.ip \-t
+Read the header for
+.q To: ,
+.q Cc: ,
+and
+.q Bcc:
+lines, and send to everyone listed in those lists.
+The
+.q Bcc:
+line will be deleted before sending.
+Any addresses in the argument vector will be deleted
+from the send list.
+.ip "\-X \fIlogfile\fP"
+Log all traffic in and out of
+.i sendmail
+in the indicated
+.i logfile
+for debugging mailer problems.
+This produces a lot of data very quickly and should be used sparingly.
+.pp
+There are a number of options that may be specified as
+primitive flags.
+These are the e, i, m, and v options.
+Also,
+the f option
+may be specified as the
+.b \-s
+flag.
+.+c "QUEUE FILE FORMATS"
+.pp
+This appendix describes the format of the queue files.
+These files live in the directory defined by the
+.b Q
+option in the
+.i sendmail.cf
+file, usually
+.i /var/spool/mqueue
+or
+.i /usr/spool/mqueue .
+.pp
+All queue files have the name
+\fIx\fP\|\fBf\fP\fIAAA99999\fP
+where
+.i AAA99999
+is the
+.i id
+for this message
+and the
+.i x
+is a type.
+The first letter of the id encodes the hour of the day
+that the message was received by the system
+(with A being the hour between midnight and 1:00AM).
+All files with the same id collectively define one message.
+.pp
+The types are:
+.nr ii 0.5i
+.ip d
+The data file.
+The message body (excluding the header) is kept in this file.
+.ip l
+The lock file.
+If this file exists,
+the job is currently being processed,
+and a queue run will not process the file.
+For that reason,
+an extraneous
+.b lf
+file can cause a job to apparently disappear
+(it will not even time out!).
+[Actually, this file is obsolete on most systems that support the
+.b flock
+or
+.b lockf
+system calls.]
+.ip n
+This file is created when an id is being created.
+It is a separate file to insure that no mail can ever be destroyed
+due to a race condition.
+It should exist for no more than a few milliseconds
+at any given time.
+[This is only used on old versions of
+.i sendmail ;
+it is not used
+on newer versions.]
+.ip q
+The queue control file.
+This file contains the information necessary to process the job.
+.ip t
+A temporary file.
+These are an image of the
+.b qf
+file when it is being rebuilt.
+It should be renamed to a
+.b qf
+file very quickly.
+.ip x
+A transcript file,
+existing during the life of a session
+showing everything that happens
+during that session.
+.pp
+The
+.b qf
+file is structured as a series of lines
+each beginning with a code letter.
+The lines are as follows:
+.ip D
+The name of the data file.
+There may only be one of these lines.
+.ip H
+A header definition.
+There may be any number of these lines.
+The order is important:
+they represent the order in the final message.
+These use the same syntax
+as header definitions in the configuration file.
+.ip C
+The controlling address.
+The syntax is
+.q localuser:aliasname .
+Recipient addresses following this line
+will be flagged so that deliveries will be run as the
+.i localuser
+(a user name from the /etc/passwd file);
+.i aliasname
+is the name of the alias that expanded to this address
+(used for printing messages).
+.ip R
+A recipient address.
+This will normally be completely aliased,
+but is actually realiased when the job is processed.
+There will be one line
+for each recipient.
+.ip S
+The sender address.
+There may only be one of these lines.
+.ip E
+An error address.
+If any such lines exist,
+they represent the addresses that should receive error messages.
+.ip T
+The job creation time.
+This is used to compute when to time out the job.
+.ip P
+The current message priority.
+This is used to order the queue.
+Higher numbers mean lower priorities.
+The priority changes
+as the message sits in the queue.
+The initial priority depends on the message class
+and the size of the message.
+.ip M
+A message.
+This line is printed by the
+.i mailq
+command,
+and is generally used to store status information.
+It can contain any text.
+.ip F
+Flag bits, represented as one letter per flag.
+Defined flag bits are
+.b r
+indicating that this is a response message
+and
+.b w
+indicating that a warning message has been sent
+announcing that the mail has been delayed.
+.ip $
+A macro definition.
+The values of certain macros
+(as of this writing, only
+.b $r
+and
+.b $s )
+are passed through to the queue run phase.
+.ip B
+The body type.
+The remainder of the line is a text string defining the body type.
+If this field is missing,
+the body type is assumed to be
+.q "undefined"
+and no special processing is attempted.
+Legal values are
+.q 7BIT
+and
+.q 8BITMIME .
+.pp
+As an example,
+the following is a queue file sent to
+.q eric@mammoth.Berkeley.EDU
+and
+.q bostic@okeeffe.CS.Berkeley.EDU \**:
+.(f
+\**This example is contrived and probably inaccurate for your environment.
+Glance over it to get an idea;
+nothing can replace looking at what your own system generates.
+.)f
+.(b
+P835771
+T404261372
+DdfAAA13557
+Seric
+Eowner-sendmail@vangogh.CS.Berkeley.EDU
+Ceric:sendmail@vangogh.CS.Berkeley.EDU
+Reric@mammoth.Berkeley.EDU
+Rbostic@okeeffe.CS.Berkeley.EDU
+H?P?return-path: <owner-sendmail@vangogh.CS.Berkeley.EDU>
+Hreceived: by vangogh.CS.Berkeley.EDU (5.108/2.7) id AAA06703;
+ Fri, 17 Jul 92 00:28:55 -0700
+Hreceived: from mail.CS.Berkeley.EDU by vangogh.CS.Berkeley.EDU (5.108/2.7)
+ id AAA06698; Fri, 17 Jul 92 00:28:54 -0700
+Hreceived: from [128.32.31.21] by mail.CS.Berkeley.EDU (5.96/2.5)
+ id AA22777; Fri, 17 Jul 92 03:29:14 -0400
+Hreceived: by foo.bar.baz.de (5.57/Ultrix3.0-C)
+ id AA22757; Fri, 17 Jul 92 09:31:25 GMT
+H?F?from: eric@foo.bar.baz.de (Eric Allman)
+H?x?full-name: Eric Allman
+Hmessage-id: <9207170931.AA22757@foo.bar.baz.de>
+HTo: sendmail@vangogh.CS.Berkeley.EDU
+Hsubject: this is an example message
+.)b
+This shows the name of the data file,
+the person who sent the message,
+the submission time
+(in seconds since January 1, 1970),
+the message priority,
+the message class,
+the recipients,
+and the headers for the message.
+.+c "SUMMARY OF SUPPORT FILES"
+.pp
+This is a summary of the support files
+that
+.i sendmail
+creates or generates.
+Many of these can be changed by editing the sendmail.cf file;
+check there to find the actual pathnames.
+.nr ii 1i
+.ip "/usr/\*(SD/sendmail"
+The binary of
+.i sendmail .
+.ip /usr/\*(SB/newaliases
+A link to /usr/\*(SD/sendmail;
+causes the alias database to be rebuilt.
+Running this program is completely equivalent to giving
+.i sendmail
+the
+.b \-bi
+flag.
+.ip /usr/\*(SB/mailq
+Prints a listing of the mail queue.
+This program is equivalent to using the
+.b \-bp
+flag to
+.i sendmail .
+.ip /etc/sendmail.cf
+The configuration file,
+in textual form.
+.ip /usr/lib/sendmail.hf
+The SMTP help file.
+.ip /etc/sendmail.st
+A statistics file; need not be present.
+.ip /etc/sendmail.pid
+Created in daemon mode;
+it contains the process id of the current SMTP daemon.
+If you use this in scripts;
+use ``head \-1'' to get just the first line;
+later versions of
+.i sendmail
+may add information to subsequent lines.
+.ip /etc/aliases
+The textual version of the alias file.
+.ip /etc/aliases.{pag,dir}
+The alias file in
+.i dbm \|(3)
+format.
+.ip /var/spool/mqueue
+The directory in which the mail queue
+and temporary files reside.
+.ip /var/spool/mqueue/qf*
+Control (queue) files for messages.
+.ip /var/spool/mqueue/df*
+Data files.
+.ip /var/spool/mqueue/tf*
+Temporary versions of the qf files,
+used during queue file rebuild.
+.ip /var/spool/mqueue/xf*
+A transcript of the current session.
+.\".ro
+.\".ls 1
+.\".tp
+.\".sp 2i
+.\".in 0
+.\".ce 100
+.\".sz 24
+.\".b SENDMAIL
+.\".sz 14
+.\".sp
+.\"INSTALLATION AND OPERATION GUIDE
+.\".sp
+.\".sz 10
+.\"Eric Allman
+.\"Britton-Lee, Inc.
+.\".sp
+.\"Version 8.36
+.\".ce 0
+.bp 2
+.rs
+.sp |4i
+.ce 2
+This page intentionally left blank;
+replace it with a blank sheet for double-sided output.
+.bp 3
+.ce
+.sz 12
+TABLE OF CONTENTS
+.sz 10
+.sp
+.\" remove some things to avoid "out of temp file space" problem
+.rm sh
+.rm (x
+.rm )x
+.rm ip
+.rm pp
+.rm lp
+.rm he
+.rm fo
+.rm eh
+.rm oh
+.rm ef
+.rm of
+.xp
diff --git a/usr.sbin/sendmail/doc/op/op.ps b/usr.sbin/sendmail/doc/op/op.ps
new file mode 100644
index 0000000..d0abd0c
--- /dev/null
+++ b/usr.sbin/sendmail/doc/op/op.ps
@@ -0,0 +1,5477 @@
+%!PS-Adobe-3.0
+%%Creator: groff version 1.08
+%%DocumentNeededResources: font Times-Bold
+%%+ font Times-Roman
+%%+ font Times-Italic
+%%+ font Symbol
+%%DocumentSuppliedResources: procset grops 1.08 0
+%%Pages: 64
+%%PageOrder: Ascend
+%%Orientation: Portrait
+%%EndComments
+%%BeginProlog
+%%BeginResource: procset grops 1.08 0
+/setpacking where{
+pop
+currentpacking
+true setpacking
+}if
+/grops 120 dict dup begin
+/SC 32 def
+/A/show load def
+/B{0 SC 3 -1 roll widthshow}bind def
+/C{0 exch ashow}bind def
+/D{0 exch 0 SC 5 2 roll awidthshow}bind def
+/E{0 rmoveto show}bind def
+/F{0 rmoveto 0 SC 3 -1 roll widthshow}bind def
+/G{0 rmoveto 0 exch ashow}bind def
+/H{0 rmoveto 0 exch 0 SC 5 2 roll awidthshow}bind def
+/I{0 exch rmoveto show}bind def
+/J{0 exch rmoveto 0 SC 3 -1 roll widthshow}bind def
+/K{0 exch rmoveto 0 exch ashow}bind def
+/L{0 exch rmoveto 0 exch 0 SC 5 2 roll awidthshow}bind def
+/M{rmoveto show}bind def
+/N{rmoveto 0 SC 3 -1 roll widthshow}bind def
+/O{rmoveto 0 exch ashow}bind def
+/P{rmoveto 0 exch 0 SC 5 2 roll awidthshow}bind def
+/Q{moveto show}bind def
+/R{moveto 0 SC 3 -1 roll widthshow}bind def
+/S{moveto 0 exch ashow}bind def
+/T{moveto 0 exch 0 SC 5 2 roll awidthshow}bind def
+/SF{
+findfont exch
+[exch dup 0 exch 0 exch neg 0 0]makefont
+dup setfont
+[exch/setfont cvx]cvx bind def
+}bind def
+/MF{
+findfont
+[5 2 roll
+0 3 1 roll
+neg 0 0]makefont
+dup setfont
+[exch/setfont cvx]cvx bind def
+}bind def
+/level0 0 def
+/RES 0 def
+/PL 0 def
+/LS 0 def
+/PLG{
+gsave newpath clippath pathbbox grestore
+exch pop add exch pop
+}bind def
+/BP{
+/level0 save def
+1 setlinecap
+1 setlinejoin
+72 RES div dup scale
+LS{
+90 rotate
+}{
+0 PL translate
+}ifelse
+1 -1 scale
+}bind def
+/EP{
+level0 restore
+showpage
+}bind def
+/DA{
+newpath arcn stroke
+}bind def
+/SN{
+transform
+.25 sub exch .25 sub exch
+round .25 add exch round .25 add exch
+itransform
+}bind def
+/DL{
+SN
+moveto
+SN
+lineto stroke
+}bind def
+/DC{
+newpath 0 360 arc closepath
+}bind def
+/TM matrix def
+/DE{
+TM currentmatrix pop
+translate scale newpath 0 0 .5 0 360 arc closepath
+TM setmatrix
+}bind def
+/RC/rcurveto load def
+/RL/rlineto load def
+/ST/stroke load def
+/MT/moveto load def
+/CL/closepath load def
+/FL{
+currentgray exch setgray fill setgray
+}bind def
+/BL/fill load def
+/LW/setlinewidth load def
+/RE{
+findfont
+dup maxlength 1 index/FontName known not{1 add}if dict begin
+{
+1 index/FID ne{def}{pop pop}ifelse
+}forall
+/Encoding exch def
+dup/FontName exch def
+currentdict end definefont pop
+}bind def
+/DEFS 0 def
+/EBEGIN{
+moveto
+DEFS begin
+}bind def
+/EEND/end load def
+/CNT 0 def
+/level1 0 def
+/PBEGIN{
+/level1 save def
+translate
+div 3 1 roll div exch scale
+neg exch neg exch translate
+0 setgray
+0 setlinecap
+1 setlinewidth
+0 setlinejoin
+10 setmiterlimit
+[]0 setdash
+/setstrokeadjust where{
+pop
+false setstrokeadjust
+}if
+/setoverprint where{
+pop
+false setoverprint
+}if
+newpath
+/CNT countdictstack def
+userdict begin
+/showpage{}def
+}bind def
+/PEND{
+clear
+countdictstack CNT sub{end}repeat
+level1 restore
+}bind def
+end def
+/setpacking where{
+pop
+setpacking
+}if
+%%EndResource
+%%IncludeResource: font Times-Bold
+%%IncludeResource: font Times-Roman
+%%IncludeResource: font Times-Italic
+%%IncludeResource: font Symbol
+grops begin/DEFS 1 dict def DEFS begin/u{.001 mul}bind def end/RES 72 def/PL
+792 def/LS false def/ENC0[/asciicircum/asciitilde/Scaron/Zcaron/scaron/zcaron
+/Ydieresis/trademark/quotesingle/.notdef/.notdef/.notdef/.notdef/.notdef
+/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef
+/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/space
+/exclam/quotedbl/numbersign/dollar/percent/ampersand/quoteright/parenleft
+/parenright/asterisk/plus/comma/hyphen/period/slash/zero/one/two/three/four
+/five/six/seven/eight/nine/colon/semicolon/less/equal/greater/question/at/A/B/C
+/D/E/F/G/H/I/J/K/L/M/N/O/P/Q/R/S/T/U/V/W/X/Y/Z/bracketleft/backslash
+/bracketright/circumflex/underscore/quoteleft/a/b/c/d/e/f/g/h/i/j/k/l/m/n/o/p/q
+/r/s/t/u/v/w/x/y/z/braceleft/bar/braceright/tilde/.notdef/quotesinglbase
+/guillemotleft/guillemotright/bullet/florin/fraction/perthousand/dagger
+/daggerdbl/endash/emdash/ff/fi/fl/ffi/ffl/dotlessi/dotlessj/grave/hungarumlaut
+/dotaccent/breve/caron/ring/ogonek/quotedblleft/quotedblright/oe/lslash
+/quotedblbase/OE/Lslash/.notdef/exclamdown/cent/sterling/currency/yen/brokenbar
+/section/dieresis/copyright/ordfeminine/guilsinglleft/logicalnot/minus
+/registered/macron/degree/plusminus/twosuperior/threesuperior/acute/mu
+/paragraph/periodcentered/cedilla/onesuperior/ordmasculine/guilsinglright
+/onequarter/onehalf/threequarters/questiondown/Agrave/Aacute/Acircumflex/Atilde
+/Adieresis/Aring/AE/Ccedilla/Egrave/Eacute/Ecircumflex/Edieresis/Igrave/Iacute
+/Icircumflex/Idieresis/Eth/Ntilde/Ograve/Oacute/Ocircumflex/Otilde/Odieresis
+/multiply/Oslash/Ugrave/Uacute/Ucircumflex/Udieresis/Yacute/Thorn/germandbls
+/agrave/aacute/acircumflex/atilde/adieresis/aring/ae/ccedilla/egrave/eacute
+/ecircumflex/edieresis/igrave/iacute/icircumflex/idieresis/eth/ntilde/ograve
+/oacute/ocircumflex/otilde/odieresis/divide/oslash/ugrave/uacute/ucircumflex
+/udieresis/yacute/thorn/ydieresis]def/Times-Italic@0 ENC0/Times-Italic RE
+/Times-Roman@0 ENC0/Times-Roman RE/Times-Bold@0 ENC0/Times-Bold RE
+%%EndProlog
+%%Page: 1 1
+%%BeginPageSetup
+BP
+%%EndPageSetup
+/F0 16/Times-Bold@0 SF(SENDMAIL)244.888 143.4 Q/F1 12/Times-Bold@0 SF(INST)
+170.172 172.2 Q(ALLA)-1.08 E(TION AND OPERA)-1.14 E(TION GUIDE)-1.14 E/F2 10
+/Times-Roman@0 SF(Eric Allman)263.42 196.2 Q(Uni)219.725 208.2 Q -.15(ve)-.25 G
+(rsity of California, Berk).15 E(ele)-.1 E(y)-.15 E(Mammoth Project)251.75
+220.2 Q(eric@CS.Berk)239.41 232.2 Q(ele)-.1 E -.65(y.)-.15 G(EDU).65 E -1.11
+(Ve)262.725 256.2 S(rsion 8.36)1.11 E -.15(Fo)236.965 280.2 S 2.5(rS).15 G
+(endmail V)258.765 280.2 Q(ersion 8.6)-1.11 E/F3 10/Times-Italic@0 SF(Sendmail)
+97 324.6 Q F2 .699(implements a general purpose internetw)3.199 F .698
+(ork mail routing f)-.1 F .698(acility under the UNIX* operat-)-.1 F .378
+(ing system.)72 336.6 R .378(It is not tied to an)5.378 F 2.878(yo)-.15 G .378
+(ne transport protocol \212 its function may be lik)208.214 336.6 R .378
+(ened to a crossbar switch,)-.1 F 1.036
+(relaying messages from one domain into another)72 348.6 R 6.036(.I)-.55 G
+3.536(nt)284.502 348.6 S 1.036
+(he process, it can do a limited amount of message)295.818 348.6 R .604(header\
+ editing to put the message into a format that is appropriate for the recei)72
+360.6 R .604(ving domain.)-.25 F .604(All of this is)5.604 F
+(done under the control of a con\214guration \214le.)72 372.6 Q .711
+(Due to the requirements of \215e)97 388.8 R .711(xibility for)-.15 F F3
+(sendmail)3.211 E F2 3.211(,t)C .71(he con\214guration \214le can seem some)
+311.688 388.8 R .71(what unap-)-.25 F 2.893(proachable. Ho)72 400.8 R(we)-.25 E
+-.15(ve)-.25 G 1.193 -.4(r, t).15 H .393(here are only a fe).4 F 2.893(wb)-.25
+G .394(asic con\214gurations for most sites, for which standard con\214gu-)
+253.381 400.8 R .646(ration \214les ha)72 412.8 R .946 -.15(ve b)-.2 H .646
+(een supplied.).15 F .645(Most other con\214gurations can be b)5.646 F .645
+(uilt by adjusting an e)-.2 F .645(xisting con\214gura-)-.15 F
+(tion \214les incrementally)72 424.8 Q(.)-.65 E F3(Sendmail)97 441 Q F2 .15
+(is based on RFC822 \(Internet Mail F)2.65 F .15
+(ormat Protocol\), RFC821 \(Simple Mail T)-.15 F .15(ransport Pro-)-.35 F .129
+(tocol\), RFC1123 \(Internet Host Requirements\), and RFC1425 \(SMTP Service E\
+xtensions\).)72 453 R(Ho)5.129 E(we)-.25 E -.15(ve)-.25 G .929 -.4(r, s).15 H
+(ince).4 E F3(sendmail)72 465 Q F2 .749(is designed to w)3.249 F .749
+(ork in a wider w)-.1 F .749(orld, in man)-.1 F 3.25(yc)-.15 G .75
+(ases it can be con\214gured to e)309.31 465 R .75(xceed these proto-)-.15 F
+2.5(cols. These)72 477 R(cases are described herein.)2.5 E(Although)97 493.2 Q
+F3(sendmail)3.548 E F2 1.047(is intended to run without the need for monitorin\
+g, it has a number of features)3.548 F 1.972(that may be used to monitor or ad\
+just the operation under unusual circumstances.)72 505.2 R 1.972
+(These features are)6.972 F(described.)72 517.2 Q .817
+(Section one describes ho)97 533.4 R 3.317(wt)-.25 G 3.317(od)211.668 533.4 S
+3.317(oa)224.985 533.4 S(basic)-.001 E F3(sendmail)3.316 E F2 3.316
+(installation. Section)3.316 F(tw)3.316 E 3.316(oe)-.1 G .816
+(xplains the day-to-day)412.938 533.4 R .282(information you should kno)72
+545.4 R 2.782(wt)-.25 G 2.782(om)196.768 545.4 S .282
+(aintain your mail system.)212.33 545.4 R .282(If you ha)5.282 F .583 -.15
+(ve a r)-.2 H(elati).15 E -.15(ve)-.25 G .283(ly normal site, these tw).15 F(o)
+-.1 E .635(sections should contain suf)72 557.4 R .635
+(\214cient information for you to install)-.25 F F3(sendmail)3.135 E F2 .634
+(and k)3.135 F .634(eep it happ)-.1 F 4.434 -.65(y. S)-.1 H .634(ection three)
+.65 F .925(describes some parameters that may be safely tweak)72 569.4 R 3.425
+(ed. Section)-.1 F .925(four has information re)3.425 F -.05(ga)-.15 G .925
+(rding the com-).05 F .886(mand line ar)72 581.4 R 3.386(guments. Section)-.18
+F<8c76>3.386 E 3.386(ec)-.15 G .885
+(ontains the nitty-gritty information about the con\214guration \214le.)221.92
+581.4 R(This)5.885 E .004
+(section is for masochists and people who must write their o)72 593.4 R .005
+(wn con\214guration \214le.)-.25 F .005(Section six describes con-)5.005 F .886
+(\214guration that can be done at compile time.)72 605.4 R .886(Section se)
+5.886 F -.15(ve)-.25 G 3.386(ng).15 G -2.15 -.25(iv e)322.1 605.4 T 3.386(sab)
+.25 G .886(rief description of dif)354.022 605.4 R .885(ferences in this)-.25 F
+-.15(ve)72 617.4 S 1.619(rsion of).15 F F3(sendmail)4.119 E F2 6.619(.T)C 1.619
+(he appendix)169.197 617.4 R 1.619(es gi)-.15 F 1.919 -.15(ve a b)-.25 H 1.619
+(rief b).15 F 1.619(ut detailed e)-.2 F 1.62
+(xplanation of a number of features not)-.15 F
+(described in the rest of the paper)72 629.4 Q(.)-.55 E .32 LW 76 680.4 72
+680.4 DL 80 680.4 76 680.4 DL 84 680.4 80 680.4 DL 88 680.4 84 680.4 DL 92
+680.4 88 680.4 DL 96 680.4 92 680.4 DL 100 680.4 96 680.4 DL 104 680.4 100
+680.4 DL 108 680.4 104 680.4 DL 112 680.4 108 680.4 DL 116 680.4 112 680.4 DL
+120 680.4 116 680.4 DL 124 680.4 120 680.4 DL 128 680.4 124 680.4 DL 132 680.4
+128 680.4 DL 136 680.4 132 680.4 DL 140 680.4 136 680.4 DL 144 680.4 140 680.4
+DL 148 680.4 144 680.4 DL 152 680.4 148 680.4 DL 156 680.4 152 680.4 DL 160
+680.4 156 680.4 DL 164 680.4 160 680.4 DL 168 680.4 164 680.4 DL 172 680.4 168
+680.4 DL 176 680.4 172 680.4 DL 180 680.4 176 680.4 DL 184 680.4 180 680.4 DL
+188 680.4 184 680.4 DL 192 680.4 188 680.4 DL 196 680.4 192 680.4 DL 200 680.4
+196 680.4 DL 204 680.4 200 680.4 DL 208 680.4 204 680.4 DL 212 680.4 208 680.4
+DL 216 680.4 212 680.4 DL/F4 8/Times-Roman@0 SF
+(*UNIX is a trademark of Unix Systems Laboratories.)93.6 692.4 Q/F5 10
+/Times-Bold@0 SF(Sendmail Installation and Operation Guide)72 756 Q(SMM:08-1)
+457.9 756 Q EP
+%%Page: 7 2
+%%BeginPageSetup
+BP
+%%EndPageSetup
+/F0 10/Times-Bold@0 SF(Sendmail Installation and Operation Guide)72 60 Q
+(SMM:08-7)457.9 60 Q 2.5(1. B)72 96 R(ASIC INST)-.3 E(ALLA)-.9 E(TION)-.95 E/F1
+10/Times-Roman@0 SF .234(There are tw)112 112.2 R 2.733(ob)-.1 G .233
+(asic steps to installing)175.631 112.2 R/F2 10/Times-Italic@0 SF(sendmail)
+2.733 E F1 5.233(.T)C .233(he hard part is to b)317.076 112.2 R .233
+(uild the con\214guration table.)-.2 F 1.185(This is a \214le that)87 124.2 R
+F2(sendmail)3.686 E F1 1.186
+(reads when it starts up that describes the mailers it kno)3.686 F 1.186
+(ws about, ho)-.25 F 3.686(wt)-.25 G(o)499 124.2 Q .715(parse addresses, ho)87
+136.2 R 3.215(wt)-.25 G 3.215(or)178.315 136.2 S -.25(ew)189.86 136.2 S .715
+(rite the message header).25 F 3.215(,a)-.4 G .715(nd the settings of v)306.75
+136.2 R .714(arious options.)-.25 F .714(Although the)5.714 F .852
+(con\214guration table is quite comple)87 148.2 R .852
+(x, a con\214guration can usually be b)-.15 F .852(uilt by adjusting an e)-.2 F
+.852(xisting of)-.15 F(f-)-.25 E 1.078(the-shelf con\214guration.)87 160.2 R
+1.078(The second part is actually doing the installation, i.e., creating the n\
+ecessary)6.078 F(\214les, etc.)87 172.2 Q .192
+(The remainder of this section will describe the installation of)112 188.4 R F2
+(sendmail)2.692 E F1 .192(assuming you can use one)2.692 F 1.432(of the e)87
+200.4 R 1.432(xisting con\214gurations and that the standard installation para\
+meters are acceptable.)-.15 F 1.431(All path-)6.431 F 8.62(names and e)87 212.4
+R 8.62(xamples are gi)-.15 F -.15(ve)-.25 G 11.12(nf).15 G 8.62
+(rom the root of the)257.57 212.4 R F2(sendmail)378.16 212.4 Q F1 8.62
+(subtree, normally)425.39 212.4 R F2(/usr/sr)87 224.4 Q(c/usr)-.37 E
+(.sbin/sendmail)-1.11 E F1(on 4.4BSD.)2.5 E .543(If you are loading this of)112
+240.6 R 3.042(ft)-.25 G .542(he tape, continue with the ne)222.766 240.6 R .542
+(xt section.)-.15 F .542(If you ha)5.542 F .842 -.15(ve a r)-.2 H .542
+(unning binary).15 F
+(already on your system, you should probably skip to section 1.2.)87 252.6 Q F0
+2.5(1.1. Compiling)87 276.6 R(Sendmail)2.5 E F1(All)127 292.8 Q F2(sendmail)
+2.934 E F1 .434(source is in the)2.934 F F2(sr)2.934 E(c)-.37 E F1
+(subdirectory)2.934 E 5.434(.I)-.65 G 2.934(fy)321.652 292.8 S .435
+(ou are running on a 4.4BSD system, com-)332.916 292.8 R
+(pile by typing \231mak)102 304.8 Q 2.5(e\232. On)-.1 F
+(other systems, you may ha)2.5 E .3 -.15(ve t)-.2 H 2.5(om).15 G(ak)348.75
+304.8 Q 2.5(es)-.1 G(ome other adjustments.)368.92 304.8 Q F0 2.5(1.1.1. Old)
+102 328.8 R -.1(ve)2.5 G(rsions of mak).1 E(e)-.1 E F1
+(If you are not running the ne)142 345 Q 2.5(wv)-.25 G(ersion of)270.74 345 Q
+F0(mak)2.5 E(e)-.1 E F1(you will probably ha)2.5 E .3 -.15(ve t)-.2 H 2.5(ou)
+.15 G(se)444.16 345 Q(mak)157 361.2 Q 2.5<65ad>-.1 G 2.5(fM)186.7 361.2 S(ak)
+201.42 361.2 Q(e\214le.dist)-.1 E .885(This \214le does not assume se)117 377.4
+R -.15(ve)-.25 G .885(ral ne).15 F 3.385(ws)-.25 G(yntax)280.025 377.4 Q .885
+(es, including the \231+=\232 syntax in macro de\214nition)-.15 F
+(and the \231.include\232 syntax.)117 389.4 Q F0 2.5(1.1.2. Compilation)102
+413.4 R(\215ags)2.5 E F2(Sendmail)142 429.6 Q F1(supports tw)2.5 E 2.5(od)-.1 G
+(if)240.51 429.6 Q(ferent formats for the)-.25 E F2(aliases)2.5 E F1 2.5
+(database. These)2.5 F(formats are:)2.5 E 39.5(NDBM The)117 445.8 R -.74(``)
+3.166 G(ne).74 E 3.166(wD)-.25 G(BM')240.432 445.8 Q 3.166('f)-.74 G .666
+(ormat, a)268.408 445.8 R -.25(va)-.2 G .666
+(ilable on nearly all systems around today).25 F 5.667(.T)-.65 G(his)492.33
+445.8 Q -.1(wa)189 457.8 S 3.541(st).1 G 1.041
+(he preferred format prior to 4.4BSD.)210.771 457.8 R 1.041(It allo)6.041 F
+1.041(ws such comple)-.25 F 3.54(xt)-.15 G 1.04(hings as)470.46 457.8 R
+(multiple databases and closing a currently open database.)189 469.8 Q 32.84
+(NEWDB The)117 486 R(ne)3.323 E 3.323(wd)-.25 G .824(atabase package from Berk)
+232.606 486 R(ele)-.1 E 4.624 -.65(y. I)-.15 H 3.324(fy).65 G .824(ou ha)
+382.716 486 R 1.124 -.15(ve t)-.2 H .824(his, use it.).15 F .824(It allo)5.824
+F(ws)-.25 E .839
+(long records, multiple open databases, real in-memory caching, and so forth.)
+189 498 R -1.1(Yo)189 510 S 3.581(uc)1.1 G 1.081
+(an de\214ne this in conjunction with one of the other tw)213.141 510 R 1.082
+(o; if you do, old)-.1 F .693(databases are read, b)189 522 R .693
+(ut when a ne)-.2 F 3.193(wd)-.25 G .693
+(atabase is created it will be in NEWDB)341.681 522 R 2.851(format. As)189 534
+R 2.851(an)2.851 G .351(asty hack, if you ha)249.763 534 R .652 -.15(ve N)-.2 H
+.352(EWDB, NDBM, and NIS de\214ned, and).15 F 1.593(if the \214le)189 546 R F2
+(/var/yp/Mak)4.093 E(e\214le)-.1 E F1 -.15(ex)4.093 G 1.593
+(ists and is readable,).15 F F2(sendmail)4.093 E F1 1.592(will create both)
+4.092 F(ne)189 558 Q 3.975(wa)-.25 G 1.475(nd old v)213.825 558 R 1.475
+(ersions of the alias \214le during a)-.15 F F2(ne)3.976 E(walias)-.15 E F1
+3.976(command. This)3.976 F(is)3.976 E .711
+(required because the Sun NIS/YP system reads the DBM v)189 570 R .71
+(ersion of the alias)-.15 F 2.5(\214le. It')189 582 R 2.5(su)-.55 G
+(gly as sin, b)229.56 582 Q(ut it w)-.2 E(orks.)-.1 E 1.112
+(If neither of these are de\214ned,)117 598.2 R F2(sendmail)3.612 E F1 1.112
+(reads the alias \214le into memory on e)3.612 F -.15(ve)-.25 G 1.112(ry in).15
+F -.2(vo)-.4 G(cation.).2 E(This can be slo)117 610.2 Q 2.5(wa)-.25 G
+(nd should be a)191.18 610.2 Q -.2(vo)-.2 G(ided.).2 E .719
+(System V based systems can de\214ne SYSTEM5 to mak)142 626.4 R 3.219(es)-.1 G
+-2.15 -.25(ev e)378.083 626.4 T .719(ral small adjustments.).25 F(This)5.719 E
+1.076(changes the handling of timezones and uses the much less ef)117 638.4 R
+(\214cient)-.25 E F2(loc)3.576 E(kf)-.2 E F1 1.076(call in preference to)3.576
+F F2(\215oc)117 650.4 Q(k)-.2 E F1 7.225(.T)C 2.224(hese can be speci\214ed se\
+parately using the compilation \215ags SYS5TZ and LOCKF)151.515 650.4 R
+(respecti)117 662.4 Q -.15(ve)-.25 G(ly).15 E(.)-.65 E 1.646(If you don')142
+678.6 R 4.147(th)-.18 G -2.25 -.2(av e)202.03 678.6 T(the)4.347 E F2(unseten)
+4.147 E(v)-.4 E F1 1.647(routine in your system library)4.147 F 4.147(,d)-.65 G
+1.647(e\214ne the UNSETENV)411.276 678.6 R(compilation \215ag.)117 690.6 Q -1.1
+(Yo)142 706.8 S 3.855(um)1.1 G 1.355(ay also ha)169.755 706.8 R 1.655 -.15
+(ve t)-.2 H 3.855(od).15 G 1.355(e\214ne the compilation v)242.035 706.8 R
+1.354(ariable LA_TYPE to describe ho)-.25 F 3.854(wy)-.25 G(our)490.67 706.8 Q
+(load a)117 718.8 Q -.15(ve)-.2 G(rage is computed.).15 E
+(This and other \215ags are detailed in section 6.1.)5 E EP
+%%Page: 8 3
+%%BeginPageSetup
+BP
+%%EndPageSetup
+/F0 10/Times-Bold@0 SF 198.36(SMM:08-8 Sendmail)72 60 R
+(Installation and Operation Guide)2.5 E 2.5(1.1.3. Compilation)102 96 R
+(and installation)2.5 E/F1 10/Times-Roman@0 SF .308
+(After making the local system con\214guration described abo)142 112.2 R -.15
+(ve)-.15 G 2.809(,Y).15 G .309(ou should be able to com-)398.855 112.2 R .87
+(pile and install the system.)117 126.2 R .87
+(Compilation can be performed using \231mak)5.87 F(e)-.1 E/F2 7/Times-Roman@0
+SF(1)412.24 122.2 Q F1 3.37<9a69>415.74 126.2 S 3.37(nt)426.33 126.2 S(he)
+437.48 126.2 Q F0(sendmail/sr)3.37 E(c)-.18 E F1(directory)117 138.2 Q 5(.Y)
+-.65 G(ou may be able to install using)166.07 138.2 Q(mak)157 154.4 Q 2.5(ei)
+-.1 G(nstall)183.84 154.4 Q 3.346
+(This should install the binary in /usr/sbin and create links from /usr/bin/ne)
+117 170.6 R -.1(wa)-.25 G 3.346(liases and).1 F 1.577
+(/usr/bin/mailq to /usr/sbin/sendmail.)117 182.6 R 1.577
+(On 4.4BSD systems it will also format and install man)6.577 F(pages.)117 194.6
+Q F0 2.5(1.2. Con\214guration)87 218.6 R(Files)2.5 E/F3 10/Times-Italic@0 SF
+(Sendmail)127 234.8 Q F1 .355(cannot operate without a con\214guration \214le.)
+2.855 F .355(The con\214guration de\214nes the mail sys-)5.355 F .286
+(tems understood at this site, ho)102 246.8 R 2.786(wt)-.25 G 2.786(oa)239.856
+246.8 S .286(ccess them, ho)252.082 246.8 R 2.786(wt)-.25 G 2.786(of)323.79
+246.8 S(orw)334.906 246.8 Q .286(ard email to remote mail systems, and)-.1 F
+3.113(an)102 258.8 S .613(umber of tuning parameters.)114.553 258.8 R .614
+(This con\214guration \214le is detailed in the later portion of this docu-)
+5.614 F(ment.)102 270.8 Q(The)127 287 Q F3(sendmail)2.764 E F1 .264
+(con\214guration can be daunting at \214rst.)2.764 F .264(The w)5.264 F .264
+(orld is comple)-.1 F .264(x, and the mail con-)-.15 F .108
+(\214guration re\215ects that.)102 299 R .108(The distrib)5.108 F .109
+(ution includes an m4-based con\214guration package that hides a lot)-.2 F
+(of the comple)102 311 Q(xity)-.15 E(.)-.65 E .47
+(These con\214guration \214les are simpler than old v)127 327.2 R .47
+(ersions lar)-.15 F .47(gely because the w)-.18 F .47(orld has become)-.1 F
+1.448(simpler; in particular)102 339.2 R 3.948(,t)-.4 G -.15(ex)197.604 339.2 S
+1.448(t-based host \214les are of).15 F 1.449(\214cially eliminated, ob)-.25 F
+1.449(viating the need to \231hide\232)-.15 F(hosts behind a re)102 351.2 Q
+(gistered internet g)-.15 E(ate)-.05 E -.1(wa)-.25 G -.65(y.).1 G .092(These \
+\214les also assume that most of your neighbors use domain-based UUCP addressi\
+ng; that)127 367.4 R .361(is, instead of naming hosts as \231host!user\232 the)
+102 379.4 R 2.861(yw)-.15 G .361(ill use \231host.domain!user\232.)299.435
+379.4 R .361(The con\214guration \214les)5.361 F(can be customized to w)102
+391.4 Q(ork around this, b)-.1 E(ut it is more comple)-.2 E(x.)-.15 E 2.828(Ih)
+127 407.6 S -2.25 -.2(av e)138.158 407.6 T(n').2 E 2.828(tt)-.18 G .328
+(ested these yet on an isolated LAN en)168.226 407.6 R .328
+(vironment with a single UUCP connection to)-.4 F 4.408(the outside w)102 419.6
+R 6.908(orld. If)-.1 F 4.409(you are in such an en)6.908 F 4.409
+(vironment, please send comments to send-)-.4 F(mail@CS.Berk)102 431.6 Q(ele)
+-.1 E -.65(y.)-.15 G(EDU.).65 E .658
+(Our con\214guration \214les are processed by)127 447.8 R F3(m4)3.158 E F1 .658
+(to f)3.158 F .657(acilitate local customization; the directory)-.1 F F3(cf)
+3.157 E F1 .396(of the)102 459.8 R F3(sendmail)2.896 E F1(distrib)2.896 E .396
+(ution directory contains the source \214les.)-.2 F .396
+(This directory contains se)5.396 F -.15(ve)-.25 G .397(ral sub-).15 F
+(directories:)102 471.8 Q 61.73(cf Both)102 488 R .56
+(site-dependent and site-independent descriptions of hosts.)3.06 F .56
+(These can be lit-)5.56 F .445(eral host names \(e.g., \231ucb)174 500 R -.25
+(va)-.15 G .445(x.mc\232\) when the hosts are g).25 F(ate)-.05 E -.1(wa)-.25 G
+.445(ys or more general).1 F 3.589(descriptions \(such as \231tcpproto.mc\232 \
+as a general description of an SMTP-)174 512 R .536(connected host or \231uucp\
+proto.mc\232 as a general description of a UUCP-connected)174 524 R 3.291
+(host\). Files)174 536 R(ending)3.291 E F0(.mc)3.291 E F1(\(`)3.291 E .791
+(`Master Con\214guration')-.74 F .791('\) are the input descriptions; the)-.74
+F 2.14(output is in the corresponding)174 548 R F0(.cf)4.64 E F1 4.64
+(\214le. The)4.64 F 2.14(general structure of these \214les is)4.64 F
+(described belo)174 560 Q -.65(w.)-.25 G 39.5(domain Site-dependent)102 576.2 R
+.428(subdomain descriptions.)2.928 F .428(These are tied to the w)5.428 F .428
+(ay your or)-.1 F -.05(ga)-.18 G(niza-).05 E .292(tion w)174 588.2 R .292
+(ants to do addressing.)-.1 F -.15(Fo)5.292 G 2.792(re).15 G(xample,)313.122
+588.2 Q F0(domain/cs.exposed.m4)2.792 E F1 .292(is our descrip-)2.792 F .443
+(tion for hosts in the CS.Berk)174 600.2 R(ele)-.1 E -.65(y.)-.15 G .443
+(EDU subdomain that w).65 F .442(ant their indi)-.1 F .442(vidual host-)-.25 F
+.962(name to be e)174 612.2 R .963(xternally visible;)-.15 F F0
+(domain/cs.hidden.m4)3.463 E F1 .963(is the same e)3.463 F .963(xcept that the)
+-.15 F 2.628(hostname is hidden \(e)174 624.2 R -.15(ve)-.25 G 2.628
+(rything looks lik).15 F 5.128(ei)-.1 G 5.128(tc)362.038 624.2 S 2.627
+(omes from CS.Berk)374.386 624.2 R(ele)-.1 E -.65(y.)-.15 G(EDU\).).65 E
+(These are referenced using the)174 636.2 Q/F4 9/Times-Roman@0 SF(DOMAIN)2.5 E
+F0(m4)2.5 E F1(macro in the)2.5 E F0(.mc)2.5 E F1(\214le.)2.5 E 41.74
+(feature De\214nitions)102 652.4 R .728
+(of speci\214c features that some particular host in your site might w)3.228 F
+(ant.)-.1 E 2.467(These are referenced using the)174 664.4 R F4(FEA)4.966 E
+(TURE)-.999 E F0(m4)4.966 E F1 4.966(macro. An)4.966 F -.15(ex)4.966 G 2.466
+(ample feature is).15 F 1.316(use_cw_\214le \(which tells)174 676.4 R F3
+(sendmail)3.816 E F1 1.317(to read an /etc/sendmail.cw \214le on startup to)
+3.816 F .32 LW 76 686 72 686 DL 80 686 76 686 DL 84 686 80 686 DL 88 686 84 686
+DL 92 686 88 686 DL 96 686 92 686 DL 100 686 96 686 DL 104 686 100 686 DL 108
+686 104 686 DL 112 686 108 686 DL 116 686 112 686 DL 120 686 116 686 DL 124 686
+120 686 DL 128 686 124 686 DL 132 686 128 686 DL 136 686 132 686 DL 140 686 136
+686 DL 144 686 140 686 DL 148 686 144 686 DL 152 686 148 686 DL 156 686 152 686
+DL 160 686 156 686 DL 164 686 160 686 DL 168 686 164 686 DL 172 686 168 686 DL
+176 686 172 686 DL 180 686 176 686 DL 184 686 180 686 DL 188 686 184 686 DL 192
+686 188 686 DL 196 686 192 686 DL 200 686 196 686 DL 204 686 200 686 DL 208 686
+204 686 DL 212 686 208 686 DL 216 686 212 686 DL/F5 5/Times-Roman@0 SF(1)93.6
+696.4 Q/F6 8/Times-Roman@0 SF(where you may ha)3.2 I .24 -.12(ve t)-.16 H 2(or)
+.12 G(eplace \231mak)175.132 699.6 Q(e\232 with \231mak)-.08 E 2<65ad>-.08 G 2
+(fM)267.452 699.6 S(ak)279.228 699.6 Q(e\214le.dist\232 as appropriate.)-.08 E
+EP
+%%Page: 9 4
+%%BeginPageSetup
+BP
+%%EndPageSetup
+/F0 10/Times-Bold@0 SF(Sendmail Installation and Operation Guide)72 60 Q
+(SMM:08-9)457.9 60 Q/F1 10/Times-Roman@0 SF(\214nd the set of local names\).)
+174 96 Q 50.62(hack Local)102 112.2 R 1.886(hacks, referenced using the)4.387 F
+/F2 9/Times-Roman@0 SF(HA)4.386 E(CK)-.36 E F0(m4)4.386 E F1 4.386(macro. T)
+4.386 F 1.886(ry to a)-.35 F -.2(vo)-.2 G 1.886(id these.).2 F(The)6.886 E
+(point of ha)174 124.2 Q(ving them here is to mak)-.2 E 2.5(ei)-.1 G 2.5(tc)
+325.91 124.2 S(lear that the)335.63 124.2 Q 2.5(ys)-.15 G(mell.)394.08 124.2 Q
+56.72(m4 Site-independent)102 140.4 R/F3 10/Times-Italic@0 SF(m4)2.538 E F1
+.038(\(1\) include \214les that ha)B .338 -.15(ve i)-.2 H .038
+(nformation common to all con\214gu-).15 F(ration \214les.)174 152.4 Q
+(This can be thought of as a \231#include\232 directory)5 E(.)-.65 E 43.95
+(mailer De\214nitions)102 168.6 R .918(of mailers, referenced using the)3.418 F
+F2(MAILER)3.417 E F0(m4)3.417 E F1 3.417(macro. De\214ned)3.417 F(mailer)3.417
+E(types in this distrib)174 180.6 Q(ution are f)-.2 E
+(ax, local, smtp, uucp, and usenet.)-.1 E 43.39(ostype De\214nitions)102 196.8
+R 1.156(describing v)3.656 F 1.157(arious operating system en)-.25 F 1.157
+(vironments \(such as the loca-)-.4 F(tion of support \214les\).)174 208.8 Q
+(These are referenced using the)5 E F2(OSTYPE)2.5 E F0(m4)2.5 E F1(macro.)2.5 E
+60.61(sh Shell)102 225 R(\214les used by the)2.5 E F0(m4)2.5 E F1 -.2(bu)2.5 G
+(ild process.).2 E -1.1(Yo)5 G 2.5(us)1.1 G(houldn')362.97 225 Q 2.5(th)-.18 G
+-2.25 -.2(av e)404.18 225 T(to mess with these.)2.7 E 30.61(sitecon\214g Local)
+102 241.2 R .49(site con\214guration information, such as UUCP connecti)2.99 F
+(vity)-.25 E 5.49(.T)-.65 G(he)450.61 241.2 Q 2.99(yn)-.15 G(ormally)472.89
+241.2 Q(contain lists of site information, for e)174 253.2 Q(xample:)-.15 E
+(SITE\(contessa\))214 269.4 Q(SITE\(hoptoad\))214 281.4 Q(SITE\(nkainc\))214
+293.4 Q(SITE\(well\))214 305.4 Q(The)174 321.6 Q 2.5(ya)-.15 G
+(re referenced using the SITECONFIG macro:)201.34 321.6 Q
+(SITECONFIG\(site.con\214g.\214le, name_of_site, X\))214 337.8 Q(where)174 354
+Q F3(X)2.703 E F1 .203(is the macro/class name to use.)2.703 F .204
+(It can be U \(indicating locally connected)5.204 F(hosts\) or one of W)174 366
+Q 2.5(,X)-.92 G 2.5(,o)259.73 366 S 2.5(rYf)269.73 366 S
+(or up to three remote UUCP hubs.)288.61 366 Q .757(If you are in a ne)127
+382.2 R 3.257(wd)-.25 G .757(omain \(e.g., a compan)214.042 382.2 R .756
+(y\), you will probably w)-.15 F .756(ant to create a cf/domain)-.1 F .87
+(\214le for your domain.)102 394.2 R .871
+(This consists primarily of relay de\214nitions: for e)5.871 F .871
+(xample, Berk)-.15 F(ele)-.1 E(y')-.15 E 3.371(sd)-.55 G(omain)479 394.2 Q .16
+(de\214nition de\214nes relays for BitNET)102 406.2 R 2.66(,C)-.74 G(SNET)
+257.61 406.2 Q 2.66(,a)-.74 G .16(nd UUCP)291.47 406.2 R 5.16(.O)-1.11 G 2.66
+(ft)344.57 406.2 S .16(hese, only the UUCP relay is particu-)353.34 406.2 R .46
+(larly speci\214c to Berk)102 418.2 R(ele)-.1 E 4.26 -.65(y. A)-.15 H .46
+(ll of these are internet-style domain names.).65 F .46(Please check to mak)
+5.46 F 2.96(ec)-.1 G(er)493.1 418.2 Q(-)-.2 E(tain the)102 430.2 Q 2.5(ya)-.15
+G(re reasonable for your domain.)143.51 430.2 Q 1.407(Subdomains at Berk)127
+446.4 R(ele)-.1 E 3.907(ya)-.15 G 1.407
+(re also represented in the cf/domain directory)235.681 446.4 R 6.406(.F)-.65 G
+1.406(or e)439.408 446.4 R 1.406(xample, the)-.15 F 1.49(domain cs-e)102 458.4
+R 1.491(xposed is the Computer Science subdomain with the local hostname sho)
+-.15 F 1.491(wn to other)-.25 F 1.411(users; cs-hidden mak)102 470.4 R 1.411
+(es users appear to be from the CS.Berk)-.1 F(ele)-.1 E -.65(y.)-.15 G 1.41
+(EDU subdomain \(with no local).65 F 1.083(host information included\).)102
+482.4 R -1.1(Yo)6.083 G 3.583(uw)1.1 G 1.083(ill probably ha)246.332 482.4 R
+1.384 -.15(ve t)-.2 H 3.584(ou).15 G 1.084
+(pdate this directory to be appropriate for)335.866 482.4 R(your domain.)102
+494.4 Q -1.1(Yo)127 510.6 S 4.373(uw)1.1 G 1.873(ill ha)154.713 510.6 R 2.173
+-.15(ve t)-.2 H 4.373(ou).15 G 1.873(se or create)207.482 510.6 R F0(.mc)4.372
+E F1 1.872(\214les in the)4.372 F F3(cf/cf)4.372 E F1 1.872
+(subdirectory for your hosts.)4.372 F 1.872(This is)6.872 F
+(detailed in the cf/README \214le.)102 522.6 Q F0 2.5(1.3. Details)87 546.6 R
+(of Installation Files)2.5 E F1
+(This subsection describes the \214les that comprise the)127 562.8 Q F3
+(sendmail)2.5 E F1(installation.)2.5 E F0 2.5(1.3.1. /usr/sbin/sendmail)102
+586.8 R F1 .08(The binary for)142 605 R F3(sendmail)2.58 E F1 .079
+(is located in /usr/sbin)2.58 F/F4 7/Times-Roman@0 SF(2)326.708 601 Q F1 5.079
+(.I)330.208 605 S 2.579(ts)341.117 605 S .079(hould be setuid root.)350.366 605
+R -.15(Fo)5.079 G 2.579(rs).15 G .079(ecurity rea-)458.111 605 R(sons, /, /usr)
+117 619 Q 2.5(,a)-.4 G(nd /usr/sbin should be o)171.6 619 Q
+(wned by root, mode 755)-.25 E F4(3)364.4 615 Q F1(.)367.9 619 Q .32 LW 76 646
+72 646 DL 80 646 76 646 DL 84 646 80 646 DL 88 646 84 646 DL 92 646 88 646 DL
+96 646 92 646 DL 100 646 96 646 DL 104 646 100 646 DL 108 646 104 646 DL 112
+646 108 646 DL 116 646 112 646 DL 120 646 116 646 DL 124 646 120 646 DL 128 646
+124 646 DL 132 646 128 646 DL 136 646 132 646 DL 140 646 136 646 DL 144 646 140
+646 DL 148 646 144 646 DL 152 646 148 646 DL 156 646 152 646 DL 160 646 156 646
+DL 164 646 160 646 DL 168 646 164 646 DL 172 646 168 646 DL 176 646 172 646 DL
+180 646 176 646 DL 184 646 180 646 DL 188 646 184 646 DL 192 646 188 646 DL 196
+646 192 646 DL 200 646 196 646 DL 204 646 200 646 DL 208 646 204 646 DL 212 646
+208 646 DL 216 646 212 646 DL/F5 5/Times-Roman@0 SF(2)93.6 656.4 Q/F6 8
+/Times-Roman@0 SF .384(This is usually /usr/sbin on 4.4BSD and ne)3.2 J .384
+(wer systems; man)-.2 F 2.385(ys)-.12 G .385(ystems install it in /usr/lib)
+302.957 659.6 R 4.385(.I)-.32 G .385(understand it is in /usr/ucblib on)398.739
+659.6 R(System V Release 4.)72 669.2 Q F5(3)93.6 679.6 Q F6 .149(Some v)3.2 J
+.15(endors ship them o)-.12 F .15
+(wned by bin; this creates a security hole that is not actually related to)-.2
+F/F7 8/Times-Italic@0 SF(sendmail)2.15 E F6 4.15(.O)C .15(ther important di-)
+447.26 682.8 R(rectories that should ha)72 692.4 Q .24 -.12(ve r)-.16 H
+(estricti).12 E .24 -.12(ve o)-.2 H(wnerships and permissions are /bin, /usr/b\
+in, /etc, /usr/etc, /lib, and /usr/lib)-.08 E(.)-.32 E EP
+%%Page: 10 5
+%%BeginPageSetup
+BP
+%%EndPageSetup
+/F0 10/Times-Bold@0 SF 193.36(SMM:08-10 Sendmail)72 60 R
+(Installation and Operation Guide)2.5 E 2.5(1.3.2. /etc/sendmail.cf)102 96 R/F1
+10/Times-Roman@0 SF .025(This is the con\214guration \214le for)142 112.2 R/F2
+10/Times-Italic@0 SF(sendmail)2.525 E F1 5.025(.T)C .025
+(his is the only non-library \214le name compiled)321.335 112.2 R(into)117
+126.2 Q F2(sendmail)2.5 E/F3 7/Times-Roman@0 SF(4)171.17 122.2 Q F1 5(.S)174.67
+126.2 S(ome older systems install it in)187.73 126.2 Q F0(/usr/lib/sendmail.cf)
+2.5 E F1(.)A(If you w)142 142.4 Q(ant to mo)-.1 E .3 -.15(ve t)-.15 H
+(his \214le, change).15 E F2(sr)2.5 E(c/pathnames.h)-.37 E F1(.)A .721
+(The con\214guration \214le is normally created using the distrib)142 158.6 R
+.721(ution \214les described abo)-.2 F -.15(ve)-.15 G 5.72(.I).15 G(f)500.67
+158.6 Q .64(you ha)117 170.6 R .94 -.15(ve a p)-.2 H .64
+(articularly unusual system con\214guration you may need to create a special v)
+.15 F(ersion.)-.15 E
+(The format of this \214le is detailed in later sections of this document.)117
+182.6 Q F0 2.5(1.3.3. /usr/bin/newaliases)102 206.6 R F1(The)142 222.8 Q F2(ne)
+2.5 E(waliases)-.15 E F1(command should just be a link to)2.5 E F2(sendmail)2.5
+E F1(:)A(rm \255f /usr/bin/ne)157 239 Q -.1(wa)-.25 G(liases).1 E
+(ln \255s /usr/sbin/sendmail /usr/bin/ne)157 251 Q -.1(wa)-.25 G(liases).1 E
+(This can be installed in whate)117 267.2 Q -.15(ve)-.25 G 2.5(rs).15 G
+(earch path you prefer for your system.)254.91 267.2 Q F0 2.5(1.3.4. /v)102
+291.2 R(ar/spool/mqueue)-.1 E F1 .218(The directory)142 307.4 R F2
+(/var/spool/mqueue)2.718 E F1 .217(should be created to hold the mail queue.)
+2.718 F .217(This directory)5.217 F(should be mode 700 and o)117 319.4 Q
+(wned by root.)-.25 E(The actual path of this directory is de\214ned in the)142
+335.6 Q F0(Q)2.5 E F1(option of the)2.5 E F2(sendmail.cf)2.5 E F1(\214le.)2.5 E
+F0 2.5(1.3.5. /etc/aliases*)102 359.6 R F1 1.492
+(The system aliases are held in \231/etc/aliases\232.)142 375.8 R 3.992(As)
+6.492 G 1.492(ample is gi)350.006 375.8 R -.15(ve)-.25 G 3.993(ni).15 G 3.993
+<6e99>417.694 375.8 S 1.493(lib/aliases\232 which)431.127 375.8 R
+(includes some aliases which)117 387.8 Q F2(must)2.5 E F1(be de\214ned:)2.5 E
+(cp lib/aliases /etc/aliases)157 404 Q F2(edit /etc/aliases)157 416 Q F1 -1.1
+(Yo)117 432.2 S 2.5(us)1.1 G(hould e)139.51 432.2 Q(xtend this \214le with an)
+-.15 E 2.5(ya)-.15 G(liases that are apropos to your system.)267.54 432.2 Q
+(Normally)142 448.4 Q F2(sendmail)3.61 E F1 1.109(looks at a v)3.61 F 1.109
+(ersion of these \214les maintained by the)-.15 F F2(dbm)3.609 E F1 1.109
+(\(3\) or)1.666 F F2(db)3.609 E F1(\(3\))1.666 E 3.46(routines. These)117 460.4
+R .96(are stored either in \231/etc/aliases.dir\232 and \231/etc/aliases.pag\
+\232 or \231/etc/aliases.db\232)3.46 F 1.022
+(depending on which database package you are using.)117 472.4 R 1.022
+(These can initially be created as empty)6.022 F(\214les, b)117 484.4 Q(ut the)
+-.2 E 2.5(yw)-.15 G(ill ha)180.54 484.4 Q .3 -.15(ve t)-.2 H 2.5(ob).15 G 2.5
+(ei)227.69 484.4 S(nitialized promptly)237.41 484.4 Q 5(.T)-.65 G
+(hese should be mode 644:)326.76 484.4 Q(cp /de)157 500.6 Q
+(v/null /etc/aliases.dir)-.25 E(cp /de)157 512.6 Q(v/null /etc/aliases.pag)-.25
+E(chmod 644 /etc/aliases.*)157 524.6 Q(ne)157 536.6 Q -.1(wa)-.25 G(liases).1 E
+(The)117 552.8 Q F2(db)2.79 E F1 .29(routines preset the mode reasonably)2.79 F
+2.79(,s)-.65 G 2.79(ot)301.68 552.8 S .29(his step can be skipped.)312.25 552.8
+R .29(The actual path of this)5.29 F(\214le is de\214ned in the)117 564.8 Q F0
+(A)2.5 E F1(option of the)2.5 E F2(sendmail.cf)2.5 E F1(\214le.)2.5 E F0 2.5
+(1.3.6. /etc/r)102 588.8 R(c)-.18 E F1 .156
+(It will be necessary to start up the)142 605 R F2(sendmail)2.655 E F1 .155
+(daemon when your system reboots.)2.655 F .155(This dae-)5.155 F 1.537
+(mon performs tw)117 617 R 4.037(of)-.1 G 1.537
+(unctions: it listens on the SMTP sock)201.221 617 R 1.537
+(et for connections \(to recei)-.1 F 1.838 -.15(ve m)-.25 H(ail).15 E .442(fro\
+m a remote system\) and it processes the queue periodically to insure that mai\
+l gets deli)117 629 R -.15(ve)-.25 G(red).15 E(when hosts come up.)117 641 Q
+.505(Add the follo)142 657.2 R .505(wing lines to \231/etc/rc\232 \(or \231/et\
+c/rc.local\232 as appropriate\) in the area where it)-.25 F
+(is starting up the daemons:)117 669.2 Q .32 LW 76 678.8 72 678.8 DL 80 678.8
+76 678.8 DL 84 678.8 80 678.8 DL 88 678.8 84 678.8 DL 92 678.8 88 678.8 DL 96
+678.8 92 678.8 DL 100 678.8 96 678.8 DL 104 678.8 100 678.8 DL 108 678.8 104
+678.8 DL 112 678.8 108 678.8 DL 116 678.8 112 678.8 DL 120 678.8 116 678.8 DL
+124 678.8 120 678.8 DL 128 678.8 124 678.8 DL 132 678.8 128 678.8 DL 136 678.8
+132 678.8 DL 140 678.8 136 678.8 DL 144 678.8 140 678.8 DL 148 678.8 144 678.8
+DL 152 678.8 148 678.8 DL 156 678.8 152 678.8 DL 160 678.8 156 678.8 DL 164
+678.8 160 678.8 DL 168 678.8 164 678.8 DL 172 678.8 168 678.8 DL 176 678.8 172
+678.8 DL 180 678.8 176 678.8 DL 184 678.8 180 678.8 DL 188 678.8 184 678.8 DL
+192 678.8 188 678.8 DL 196 678.8 192 678.8 DL 200 678.8 196 678.8 DL 204 678.8
+200 678.8 DL 208 678.8 204 678.8 DL 212 678.8 208 678.8 DL 216 678.8 212 678.8
+DL/F4 5/Times-Roman@0 SF(4)93.6 689.2 Q/F5 8/Times-Roman@0 SF .588
+(The system libraries can reference other \214les; in particular)3.2 J 2.589
+(,s)-.32 G .589(ystem library subroutines that)294.805 692.4 R/F6 8
+/Times-Italic@0 SF(sendmail)2.589 E F5 .589(calls probably reference)2.589 F F6
+(/etc/passwd)72 702 Q F5(and)2 E F6(/etc/r)2 E(esolv)-.296 E(.conf)-.592 E F5
+(.)A EP
+%%Page: 11 6
+%%BeginPageSetup
+BP
+%%EndPageSetup
+/F0 10/Times-Bold@0 SF(Sendmail Installation and Operation Guide)72 60 Q
+(SMM:08-11)452.9 60 Q/F1 10/Times-Roman@0 SF
+(if [ \255f /usr/sbin/sendmail \255a \255f /etc/sendmail.cf ]; then)157 96 Q
+(\(cd /v)193 108 Q(ar/spool/mqueue; rm \255f [lnx]f*\))-.25 E
+(/usr/sbin/sendmail \255bd \255q30m &)193 120 Q(echo \255n ' sendmail' >/de)193
+132 Q(v/console)-.25 E<8c>157 144 Q .174
+(The \231cd\232 and \231rm\232 commands insure that all lock \214les ha)117
+160.2 R .473 -.15(ve b)-.2 H .173(een remo).15 F -.15(ve)-.15 G .173(d; e).15 F
+.173(xtraneous lock \214les)-.15 F .004
+(may be left around if the system goes do)117 172.2 R .005
+(wn in the middle of processing a message.)-.25 F .005(The line that)5.005 F
+2.294(actually in)117 184.2 R -.2(vo)-.4 G -.1(ke).2 G(s).1 E/F2 10
+/Times-Italic@0 SF(sendmail)4.794 E F1 2.294(has tw)4.794 F 4.794<6f8d>-.1 G
+2.293(ags: \231\255bd\232 causes it to listen on the SMTP port, and)272.94
+184.2 R(\231\255q30m\232 causes it to run the queue e)117 196.2 Q -.15(ve)-.25
+G(ry half hour).15 E(.)-.55 E .378(Some people use a more comple)142 212.4 R
+2.879(xs)-.15 G .379(tartup script, remo)285.209 212.4 R .379
+(ving zero length qf \214les and df \214les)-.15 F
+(for which there is no qf \214le.)117 224.4 Q -.15(Fo)5 G 2.5(re).15 G(xample:)
+253.9 224.4 Q 2.5(#r)157 240.6 S(emo)167.83 240.6 Q .3 -.15(ve z)-.15 H
+(ero length qf \214les).15 E(for qf)157 252.6 Q(\214le in qf*)-.25 E(do)157
+264.6 Q(if [ \255r $qf)193 276.6 Q(\214le ])-.25 E(then)193 288.6 Q
+(if [ ! \255s $qf)229 300.6 Q(\214le ])-.25 E(then)229 312.6 Q
+(echo \255n " <zero: $qf)265 324.6 Q(\214le>" > /de)-.25 E(v/console)-.25 E
+(rm \255f $qf)265 336.6 Q(\214le)-.25 E<8c>229 348.6 Q<8c>193 360.6 Q(done)157
+372.6 Q 2.5(#r)157 384.6 S(ename tf \214les to be qf if the qf does not e)
+167.83 384.6 Q(xist)-.15 E(for tf)157 396.6 Q(\214le in tf*)-.25 E(do)157 408.6
+Q(qf)193 420.6 Q(\214le=`echo $tf)-.25 E(\214le | sed ')-.25 E(s/t/q/'`)-.55 E
+(if [ \255r $tf)193 432.6 Q(\214le \255a ! \255f $qf)-.25 E(\214le ])-.25 E
+(then)193 444.6 Q(echo \255n " <reco)229 456.6 Q -.15(ve)-.15 G(ring: $tf).15 E
+(\214le>" > /de)-.25 E(v/console)-.25 E(mv $tf)229 468.6 Q(\214le $qf)-.25 E
+(\214le)-.25 E(else)193 480.6 Q(echo \255n " <e)229 492.6 Q(xtra: $tf)-.15 E
+(\214le>" > /de)-.25 E(v/console)-.25 E(rm \255f $tf)229 504.6 Q(\214le)-.25 E
+<8c>193 516.6 Q(done)157 528.6 Q 2.5(#r)157 540.6 S(emo)167.83 540.6 Q .3 -.15
+(ve d)-.15 H 2.5<668c>.15 G(les with no corresponding qf \214les)213.08 540.6 Q
+(for df)157 552.6 Q(\214le in df*)-.25 E(do)157 564.6 Q(qf)193 576.6 Q
+(\214le=`echo $df)-.25 E(\214le | sed ')-.25 E(s/d/q/'`)-.55 E(if [ \255r $df)
+193 588.6 Q(\214le \255a ! \255f $qf)-.25 E(\214le ])-.25 E(then)193 600.6 Q
+(echo \255n " <incomplete: $df)229 612.6 Q(\214le>" > /de)-.25 E(v/console)-.25
+E(mv $df)229 624.6 Q(\214le `echo $df)-.25 E(\214le | sed ')-.25 E(s/d/D/'`)
+-.55 E<8c>193 636.6 Q(done)157 648.6 Q 2.5(#a)157 660.6 S
+(nnounce \214les that ha)168.94 660.6 Q .3 -.15(ve b)-.2 H(een sa).15 E -.15
+(ve)-.2 G 2.5(dd).15 G(uring disaster reco)314.32 660.6 Q -.15(ve)-.15 G(ry).15
+E(for xf)157 672.6 Q(\214le in [A-Z]f*)-.25 E(do)157 684.6 Q
+(echo \255n " <panic: $xf)193 696.6 Q(\214le>" > /de)-.25 E(v/console)-.25 E
+(done)157 708.6 Q EP
+%%Page: 12 7
+%%BeginPageSetup
+BP
+%%EndPageSetup
+/F0 10/Times-Bold@0 SF 193.36(SMM:08-12 Sendmail)72 60 R
+(Installation and Operation Guide)2.5 E/F1 10/Times-Roman@0 SF .756
+(If you are not running a v)142 96 R .755(ersion of UNIX that supports Berk)
+-.15 F(ele)-.1 E 3.255(yT)-.15 G(CP/IP)416.725 96 Q 3.255(,d)-1.11 G 3.255(on)
+450.27 96 S .755(ot include)463.525 96 R(the)117 108 Q F0(\255bd)2.5 E F1
+(\215ag.)2.5 E F0 2.5(1.3.7. /usr/lib/sendmail.hf)102 132 R F1 2.078
+(This is the help \214le used by the SMTP)142 148.2 R F0(HELP)4.578 E F1 4.578
+(command. It)4.578 F 2.078(should be copied from)4.578 F
+(\231lib/sendmail.hf\232:)117 160.2 Q(cp lib/sendmail.hf /usr/lib)157 176.4 Q
+(The actual path of this \214le is de\214ned in the)117 192.6 Q F0(H)2.5 E F1
+(option of the)2.5 E/F2 10/Times-Italic@0 SF(sendmail.cf)2.5 E F1(\214le.)2.5 E
+F0 2.5(1.3.8. /etc/sendmail.st)102 216.6 R F1 3.04
+(If you wish to collect statistics about your mail traf)142 232.8 R 3.04
+(\214c, you should create the \214le)-.25 F(\231/etc/sendmail.st\232:)117 244.8
+Q(cp /de)157 261 Q(v/null /etc/sendmail.st)-.25 E(chmod 666 /etc/sendmail.st)
+157 273 Q .715(This \214le does not gro)117 289.2 R 4.516 -.65(w. I)-.25 H
+3.216(ti).65 G 3.216(sp)231.502 289.2 S .716
+(rinted with the program \231mailstats/mailstats.c.)243.608 289.2 R 5.716<9a54>
+-.7 G .716(he actual path)447.028 289.2 R(of this \214le is de\214ned in the)
+117 301.2 Q F0(S)2.5 E F1(option of the)2.5 E F2(sendmail.cf)2.5 E F1(\214le.)
+2.5 E F0 2.5(1.3.9. /usr/bin/newaliases)102 325.2 R F1(If)142 341.4 Q F2
+(sendmail)3.256 E F1 .756(is in)3.256 F -.2(vo)-.4 G -.1(ke).2 G 3.256(da).1 G
+3.256<7399>240.424 341.4 S(ne)252.01 341.4 Q -.1(wa)-.25 G(liases,).1 E 3.255
+<9a69>-.7 G 3.255(tw)307.255 341.4 S .755(ill simulate the)320.51 341.4 R F0
+(\255bi)3.255 E F1 .755(\215ag \(i.e., will reb)3.255 F .755(uild the)-.2 F
+(alias database; see belo)117 353.4 Q 2.5(w\). This)-.25 F
+(should be a link to /usr/sbin/sendmail.)2.5 E F0 2.5(1.3.10. /usr/bin/mailq)
+102 377.4 R F1(If)142 393.6 Q F2(sendmail)3.439 E F1 .939(is in)3.439 F -.2(vo)
+-.4 G -.1(ke).2 G 3.439(da).1 G 3.439<7399>241.156 393.6 S(mailq,)252.925 393.6
+Q 3.439<9a69>-.7 G 3.439(tw)288.164 393.6 S .939(ill simulate the)301.603 393.6
+R F0(\255bp)3.439 E F1 .94(\215ag \(i.e.,)3.44 F F2(sendmail)3.44 E F1 .94
+(will print)3.44 F(the contents of the mail queue; see belo)117 405.6 Q 2.5
+(w\). This)-.25 F(should be a link to /usr/sbin/sendmail.)2.5 E F0 2.5
+(2. NORMAL)72 429.6 R(OPERA)2.5 E(TIONS)-.95 E 2.5(2.1. The)87 453.6 R
+(System Log)2.5 E F1 1.511(The system log is supported by the)127 469.8 R F2
+(syslo)4.011 E(gd)-.1 E F1 1.511(\(8\) program.)1.666 F 1.511
+(All messages from)6.511 F F2(sendmail)4.011 E F1(are)4.011 E(logged under the)
+102 481.8 Q/F3 9/Times-Roman@0 SF(LOG_MAIL)2.5 E F1 -.1(fa)2.5 G(cility).1 E(.)
+-.65 E F0 2.5(2.1.1. F)102 505.8 R(ormat)-.25 E F1 .574(Each line in the syste\
+m log consists of a timestamp, the name of the machine that gener)142 522 R(-)
+-.2 E .849(ated it \(for logging from se)117 534 R -.15(ve)-.25 G .849
+(ral machines o).15 F -.15(ve)-.15 G 3.349(rt).15 G .848(he local area netw)
+316.942 534 R .848(ork\), the w)-.1 F .848(ord \231sendmail:\232,)-.1 F
+(and a message.)117 546 Q F0 2.5(2.1.2. Le)102 570 R -.1(ve)-.15 G(ls).1 E F1
+.204(If you ha)142 586.2 R -.15(ve)-.2 G F2(syslo)2.854 E(gd)-.1 E F1 .204
+(\(8\) or an equi)1.666 F -.25(va)-.25 G .205
+(lent installed, you will be able to do logging.).25 F .205(There is)5.205 F
+2.788(al)117 598.2 S(ar)127.008 598.2 Q .287
+(ge amount of information that can be logged.)-.18 F .287
+(The log is arranged as a succession of le)5.287 F -.15(ve)-.25 G(ls.).15 E .65
+(At the lo)117 610.2 R .65(west le)-.25 F -.15(ve)-.25 G 3.15(lo).15 G .65
+(nly e)201.72 610.2 R .651(xtremely strange situations are logged.)-.15 F .651
+(At the highest le)5.651 F -.15(ve)-.25 G .651(l, e).15 F -.15(ve)-.25 G 3.151
+(nt).15 G(he)494.56 610.2 Q .826(most mundane and uninteresting e)117 622.2 R
+-.15(ve)-.25 G .825(nts are recorded for posterity).15 F 5.825(.A)-.65 G 3.325
+(sac)400.27 622.2 S(on)419.69 622.2 Q -.15(ve)-.4 G .825(ntion, log le).15 F
+-.15(ve)-.25 G(ls).15 E .2
+(under ten are considered generally \231useful;\232 log le)117 634.2 R -.15(ve)
+-.25 G .201(ls abo).15 F .501 -.15(ve 6)-.15 H 2.701(4a).15 G .201(re reserv)
+381.566 634.2 R .201(ed for deb)-.15 F .201(ugging pur)-.2 F(-)-.2 E 2.5
+(poses. Le)117 646.2 R -.15(ve)-.25 G(ls from 11\25564 are reserv).15 E
+(ed for v)-.15 E(erbose information that some sites might w)-.15 E(ant.)-.1 E
+2.5(Ac)142 662.4 S(omplete description of the log le)156.16 662.4 Q -.15(ve)
+-.25 G(ls is gi).15 E -.15(ve)-.25 G 2.5(ni).15 G 2.5(ns)340.35 662.4 S
+(ection 4.6.)351.74 662.4 Q F0 2.5(2.2. The)87 686.4 R(Mail Queue)2.5 E F1 .263
+(The mail queue should be processed transparently)127 702.6 R 5.262(.H)-.65 G
+-.25(ow)342.868 702.6 S -2.15 -.25(ev e).25 H 1.062 -.4(r, y).25 H .262
+(ou may \214nd that manual inter).4 F(-)-.2 E -.15(ve)102 714.6 S .081
+(ntion is sometimes necessary).15 F 5.081(.F)-.65 G .081(or e)240.254 714.6 R
+.081(xample, if a major host is do)-.15 F .081
+(wn for a period of time the queue)-.25 F EP
+%%Page: 13 8
+%%BeginPageSetup
+BP
+%%EndPageSetup
+/F0 10/Times-Bold@0 SF(Sendmail Installation and Operation Guide)72 60 Q
+(SMM:08-13)452.9 60 Q/F1 10/Times-Roman@0 SF .268(may become clogged.)102 96 R
+(Although)5.268 E/F2 10/Times-Italic@0 SF(sendmail)2.768 E F1 .268
+(ought to reco)2.768 F -.15(ve)-.15 G 2.768(rg).15 G .268
+(racefully when the host comes up, you)348.254 96 R
+(may \214nd performance unacceptably bad in the meantime.)102 108 Q F0 2.5
+(2.2.1. Printing)102 132 R(the queue)2.5 E F1 .526
+(The contents of the queue can be printed using the)142 148.2 R F2(mailq)3.026
+E F1 .526(command \(or by specifying the)3.026 F F0(\255bp)117 160.2 Q F1
+(\215ag to)2.5 E F2(sendmail)2.5 E F1(\):)A(mailq)157 176.4 Q 1.673
+(This will produce a listing of the queue id')117 192.6 R 1.673
+(s, the size of the message, the date the message)-.55 F
+(entered the queue, and the sender and recipients.)117 204.6 Q F0 2.5(2.2.2. F)
+102 228.6 R(or)-.25 E(cing the queue)-.18 E F2(Sendmail)142 244.8 Q F1 1.137
+(should run the queue automatically at interv)3.637 F 3.638(als. The)-.25 F
+1.138(algorithm is to read and)3.638 F .355
+(sort the queue, and then to attempt to process all jobs in order)117 256.8 R
+5.355(.W)-.55 G .355(hen it attempts to run the job,)384.37 256.8 R F2
+(sendmail)117 268.8 Q F1(\214rst checks to see if the job is lock)2.5 E 2.5
+(ed. If)-.1 F(so, it ignores the job)2.5 E(.)-.4 E .338
+(There is no attempt to insure that only one queue processor e)142 285 R .338
+(xists at an)-.15 F 2.838(yt)-.15 G .339(ime, since there)440.282 285 R .095
+(is no guarantee that a job cannot tak)117 297 R 2.595(ef)-.1 G(ore)272.07 297
+Q -.15(ve)-.25 G 2.595(rt).15 G 2.595(op)302.585 297 S .094(rocess \(ho)315.18
+297 R(we)-.25 E -.15(ve)-.25 G -.4(r,).15 G F2(sendmail)2.994 E F1 .094
+(does include heuris-)2.594 F 1.086
+(tics to try to abort jobs that are taking absurd amounts of time; technically)
+117 309 R 3.587(,t)-.65 G 1.087(his violates RFC)435.146 309 R .462(821, b)117
+321 R .461(ut is blessed by RFC 1123\).)-.2 F .461
+(Due to the locking algorithm, it is impossible for one job to)5.461 F 1.086
+(freeze the entire queue.)117 333 R(Ho)6.086 E(we)-.25 E -.15(ve)-.25 G 1.886
+-.4(r, a).15 H 3.586(nu).4 G(ncooperati)279.346 333 Q 1.386 -.15(ve r)-.25 H
+1.086(ecipient host or a program recipient that).15 F(ne)117 345 Q -.15(ve)-.25
+G 3.351(rr).15 G .851(eturns can accumulate man)145.491 345 R 3.351(yp)-.15 G
+.851(rocesses in your system.)269.825 345 R(Unfortunately)5.851 E 3.351(,t)-.65
+G .85(here is no com-)439.52 345 R(pletely general w)117 357 Q(ay to solv)-.1 E
+2.5(et)-.15 G(his.)234.23 357 Q .082
+(In some cases, you may \214nd that a major host going do)142 373.2 R .083
+(wn for a couple of days may create)-.25 F 2.925(ap)117 385.2 S(rohibiti)
+129.365 385.2 Q -.15(ve)-.25 G .425(ly lar).15 F .425(ge queue.)-.18 F .424
+(This will result in)5.425 F F2(sendmail)2.924 E F1 .424
+(spending an inordinate amount of time)2.924 F 1.084(sorting the queue.)117
+397.2 R 1.084(This situation can be \214x)6.084 F 1.084(ed by mo)-.15 F 1.085
+(ving the queue to a temporary place and)-.15 F .023(creating a ne)117 409.2 R
+2.523(wq)-.25 G 2.523(ueue. The)182.629 409.2 R .022
+(old queue can be run later when the of)2.523 F .022
+(fending host returns to service.)-.25 F 1.6 -.8(To d)142 425.4 T 2.5(ot).8 G
+(his, it is acceptable to mo)170.09 425.4 Q .3 -.15(ve t)-.15 H
+(he entire queue directory:).15 E(cd /v)157 441.6 Q(ar/spool)-.25 E
+(mv mqueue omqueue; mkdir mqueue; chmod 700 mqueue)157 453.6 Q -1.1(Yo)117
+469.8 S 2.708(us)1.1 G .208(hould then kill the e)139.718 469.8 R .209
+(xisting daemon \(since it will still be processing in the old queue direc-)
+-.15 F(tory\) and create a ne)117 481.8 Q 2.5(wd)-.25 G(aemon.)213.1 481.8 Q
+1.6 -.8(To r)142 498 T(un the old mail queue, run the follo).8 E(wing command:)
+-.25 E(/usr/sbin/sendmail \255oQ/v)157 514.2 Q(ar/spool/omqueue \255q)-.25 E
+(The)117 530.4 Q F0(\255oQ)2.868 E F1 .367
+(\215ag speci\214es an alternate queue directory and the)2.868 F F0<ad71>2.867
+E F1 .367(\215ag says to just run e)2.867 F -.15(ve)-.25 G .367(ry job in).15 F
+.593(the queue.)117 542.4 R .593(If you ha)5.593 F .893 -.15(ve a t)-.2 H
+(endenc).15 E 3.093(yt)-.15 G -2.1 -.25(ow a)263.111 542.4 T .593(rd v).25 F
+-.1(oy)-.2 G .593(eurism, you can use the).1 F F0<ad76>3.094 E F1 .594
+(\215ag to w)3.094 F .594(atch what is)-.1 F(going on.)117 554.4 Q
+(When the queue is \214nally emptied, you can remo)142 570.6 Q .3 -.15(ve t)
+-.15 H(he directory:).15 E(rmdir /v)157 586.8 Q(ar/spool/omqueue)-.25 E F0 2.5
+(2.3. The)87 615 R(Alias Database)2.5 E F1 .361(The alias database e)127 631.2
+R .361(xists in tw)-.15 F 2.861(of)-.1 G 2.861(orms. One)261.116 631.2 R .361
+(is a te)2.861 F .36(xt form, maintained in the \214le)-.15 F F2(/etc/aliases.)
+2.86 E F1(The aliases are of the form)102 643.2 Q(name: name1, name2, ...)142
+659.4 Q(Only local names may be aliased; e.g.,)102 675.6 Q(eric@prep.ai.MIT)142
+691.8 Q(.EDU: eric@CS.Berk)-.74 E(ele)-.1 E -.65(y.)-.15 G(EDU).65 E .348
+(will not ha)102 708 R .648 -.15(ve t)-.2 H .348(he desired ef).15 F 2.849
+(fect. Aliases)-.25 F .349(may be continued by starting an)2.849 F 2.849(yc)
+-.15 G .349(ontinuation lines with a)408.783 708 R(space or a tab)102 720 Q 5
+(.B)-.4 G(lank lines and lines be)170.47 720 Q
+(ginning with a sharp sign \(\231#\232\) are comments.)-.15 E EP
+%%Page: 14 9
+%%BeginPageSetup
+BP
+%%EndPageSetup
+/F0 10/Times-Bold@0 SF 193.36(SMM:08-14 Sendmail)72 60 R
+(Installation and Operation Guide)2.5 E/F1 10/Times-Roman@0 SF 1.593
+(The second form is processed by the)127 96 R/F2 10/Times-Italic@0 SF(dbm)4.093
+E F1 1.593(\(3\) \(or)1.666 F F2(db)4.093 E F1 1.593(\(3\)\) library)1.666 F
+6.593(.T)-.65 G 1.593(his form is in the \214les)409.085 96 R F2
+(/etc/aliases.dir)102 108 Q F1(and)3.028 E F2(/etc/aliases.pa)3.028 E -.15(g.)
+-.1 G F1 .528(This is the form that)5.678 F F2(sendmail)3.029 E F1 .529
+(actually uses to resolv)3.029 F 3.029(ea)-.15 G(liases.)479.28 108 Q
+(This technique is used to impro)102 120 Q .3 -.15(ve p)-.15 H(erformance.).15
+E -1.1(Yo)127 136.2 S 2.5(uc)1.1 G(an also use)150.06 136.2 Q/F3 9
+/Times-Roman@0 SF(NIS)2.5 E F1(-based alias \214les.)A -.15(Fo)5 G 2.5(re).15 G
+(xample, the speci\214cation:)305.069 136.2 Q -.35(OA)142 152.4 S(/etc/aliases)
+.35 E -.35(OA)142 164.4 S(nis:mail.aliases@my).35 E(.nis.domain)-.65 E 1.725(w\
+ill \214rst search the /etc/aliases \214le and then the map named \231mail.ali\
+ases\232 in \231my)102 180.6 R(.nis.domain\232.)-.65 E -.8(Wa)102 192.6 S .589
+(rning: if you b).8 F .589(uild your o)-.2 F(wn)-.25 E F3(NIS)3.089 E F1 .589
+(-based alias \214les, be sure to pro)B .59(vide the)-.15 F F0<ad6c>3.09 E F1
+.59(\215ag to)3.09 F F2(mak)3.09 E(edbm)-.1 E F1(\(8\))A .159
+(to map upper case letters in the k)102 204.6 R -.15(ey)-.1 G 2.659(st).15 G
+2.659(ol)253.552 204.6 S -.25(ow)263.991 204.6 S .159
+(er case; otherwise, aliases with upper case letters in their).25 F(names w)102
+216.6 Q(on')-.1 E 2.5(tm)-.18 G(atch incoming addresses.)163.38 216.6 Q
+(Additional \215ags can be added after the colon e)127 232.8 Q(xactly lik)-.15
+E 2.5(ea)-.1 G F0(K)A F1(line \212 for e)2.5 E(xample:)-.15 E -.35(OA)142 249 S
+(nis:-N mail.aliases@my).35 E(.nis.domain)-.65 E
+(will search the appropriate NIS map and al)102 265.2 Q -.1(wa)-.1 G
+(ys include null bytes in the k).1 E -.15(ey)-.1 G(.)-.5 E F0 2.5(2.3.1. Reb)
+102 289.2 R(uilding the alias database)-.2 E F1 .542(The DB or DBM v)142 305.4
+R .542(ersion of the database may be reb)-.15 F .542(uilt e)-.2 F .542
+(xplicitly by e)-.15 F -.15(xe)-.15 G .542(cuting the com-).15 F(mand)117 317.4
+Q(ne)157 333.6 Q -.1(wa)-.25 G(liases).1 E(This is equi)117 349.8 Q -.25(va)
+-.25 G(lent to gi).25 E(ving)-.25 E F2(sendmail)2.5 E F1(the)2.5 E F0(\255bi)
+2.5 E F1(\215ag:)2.5 E(/usr/sbin/sendmail \255bi)157 366 Q .26
+(If the \231D\232 option is speci\214ed in the con\214guration,)142 386.4 R F2
+(sendmail)2.759 E F1 .259(will reb)2.759 F .259(uild the alias database)-.2 F
+1.92(automatically if possible when it is out of date.)117 398.4 R(Auto-reb)
+6.921 E 1.921(uild can be dangerous on hea)-.2 F(vily)-.2 E 1.451
+(loaded machines with lar)117 410.4 R 1.451(ge alias \214les; if it might tak)
+-.18 F 3.951(em)-.1 G 1.45(ore than \214v)355.66 410.4 R 3.95(em)-.15 G 1.45
+(inutes to reb)420.13 410.4 R 1.45(uild the)-.2 F
+(database, there is a chance that se)117 422.4 Q -.15(ve)-.25 G
+(ral processes will start the reb).15 E(uild process simultaneously)-.2 E(.)
+-.65 E 1.77(If you ha)142 438.6 R 2.07 -.15(ve m)-.2 H 1.77
+(ultiple aliases databases speci\214ed, the).15 F F0(\255bi)4.27 E F1 1.77
+(\215ag reb)4.27 F 1.77(uilds all the database)-.2 F
+(types it understands \(for e)117 450.6 Q(xample, it can reb)-.15 E
+(uild dbm databases b)-.2 E(ut not nis databases\).)-.2 E F0 2.5(2.3.2. P)102
+474.6 R(otential pr)-.2 E(oblems)-.18 E F1 1.131
+(There are a number of problems that can occur with the alias database.)142
+490.8 R(The)6.13 E 3.63(ya)-.15 G 1.13(ll result)472.59 490.8 R 1.103(from a)
+117 502.8 R F2(sendmail)3.603 E F1 1.103(process accessing the DBM v)3.603 F
+1.103(ersion while it is only partially b)-.15 F 3.604(uilt. This)-.2 F(can)
+3.604 E 1.249(happen under tw)117 514.8 R 3.749(oc)-.1 G 1.248
+(ircumstances: One process accesses the database while another process is)
+199.237 514.8 R(reb)117 526.8 Q .518(uilding it, or the process reb)-.2 F .518
+(uilding the database dies \(due to being killed or a system crash\))-.2 F
+(before completing the reb)117 538.8 Q(uild.)-.2 E .793(Sendmail has tw)142 555
+R 3.293(ot)-.1 G .792(echniques to try to relie)220.669 555 R 1.092 -.15(ve t)
+-.25 H .792(hese problems.).15 F .792(First, it ignores interrupts)5.792 F .045
+(while reb)117 567 R .045(uilding the database; this a)-.2 F -.2(vo)-.2 G .045
+(ids the problem of someone aborting the process lea).2 F .045(ving a)-.2 F
+(partially reb)117 579 Q(uilt database.)-.2 E(Second, at the end of the reb)5 E
+(uild it adds an alias of the form)-.2 E(@: @)157 595.2 Q .336
+(\(which is not normally le)117 611.4 R -.05(ga)-.15 G 2.836(l\). Before).05 F
+F2(sendmail)2.836 E F1 .336(will access the database, it checks to insure that)
+2.836 F(this entry e)117 625.4 Q(xists)-.15 E/F4 7/Times-Roman@0 SF(5)179.63
+621.4 Q F1(.)183.13 625.4 Q F0 2.5(2.3.3. List)102 649.4 R -.1(ow)2.5 G(ners).1
+E F1 .4(If an error occurs on sending to a certain address, say \231)142 665.6
+R F2(x)A F1<9a2c>A F2(sendmail)2.901 E F1 .401(will look for an alias)2.901 F
+.418(of the form \231o)117 677.6 R(wner)-.25 E(-)-.2 E F2(x)A F1 2.918<9a74>C
+2.918(or)212.632 677.6 S(ecei)223.88 677.6 Q .718 -.15(ve t)-.25 H .418
+(he errors.).15 F .417(This is typically useful for a mailing list where the)
+5.418 F .32 LW 76 687.2 72 687.2 DL 80 687.2 76 687.2 DL 84 687.2 80 687.2 DL
+88 687.2 84 687.2 DL 92 687.2 88 687.2 DL 96 687.2 92 687.2 DL 100 687.2 96
+687.2 DL 104 687.2 100 687.2 DL 108 687.2 104 687.2 DL 112 687.2 108 687.2 DL
+116 687.2 112 687.2 DL 120 687.2 116 687.2 DL 124 687.2 120 687.2 DL 128 687.2
+124 687.2 DL 132 687.2 128 687.2 DL 136 687.2 132 687.2 DL 140 687.2 136 687.2
+DL 144 687.2 140 687.2 DL 148 687.2 144 687.2 DL 152 687.2 148 687.2 DL 156
+687.2 152 687.2 DL 160 687.2 156 687.2 DL 164 687.2 160 687.2 DL 168 687.2 164
+687.2 DL 172 687.2 168 687.2 DL 176 687.2 172 687.2 DL 180 687.2 176 687.2 DL
+184 687.2 180 687.2 DL 188 687.2 184 687.2 DL 192 687.2 188 687.2 DL 196 687.2
+192 687.2 DL 200 687.2 196 687.2 DL 204 687.2 200 687.2 DL 208 687.2 204 687.2
+DL 212 687.2 208 687.2 DL 216 687.2 212 687.2 DL/F5 5/Times-Roman@0 SF(5)93.6
+697.6 Q/F6 8/Times-Roman@0 SF(The \231a\232 option is required in the con\214g\
+uration for this action to occur)3.2 I 4(.T)-.44 G
+(his should normally be speci\214ed.)329.18 700.8 Q EP
+%%Page: 15 10
+%%BeginPageSetup
+BP
+%%EndPageSetup
+/F0 10/Times-Bold@0 SF(Sendmail Installation and Operation Guide)72 60 Q
+(SMM:08-15)452.9 60 Q/F1 10/Times-Roman@0 SF 1.116
+(submitter of the list has no control o)117 96 R -.15(ve)-.15 G 3.617(rt).15 G
+1.117(he maintenance of the list itself; in this case the list)288.4 96 R
+(maintainer w)117 108 Q(ould be the o)-.1 E(wner of the list.)-.25 E -.15(Fo)5
+G 2.5(re).15 G(xample:)309.38 108 Q
+(unix-wizards: eric@ucbarpa, wnj@monet, nosuchuser)157 124.2 Q(,)-.4 E
+(sam@matisse)193 136.2 Q -.25(ow)157 148.2 S(ner).25 E
+(-unix-wizards: eric@ucbarpa)-.2 E -.1(wo)117 164.4 S 1.959(uld cause \231eric\
+@ucbarpa\232 to get the error that will occur when someone sends to unix-).1 F
+(wizards due to the inclusion of \231nosuchuser\232 on the list.)117 176.4 Q
+.958(List o)142 192.6 R .958(wners also cause the en)-.25 F -.15(ve)-.4 G .959
+(lope sender address to be modi\214ed.).15 F .959(The contents of the)5.959 F
+-.25(ow)117 204.6 S .429(ner alias are used if the).25 F 2.929(yp)-.15 G .429
+(oint to a single user)236.364 204.6 R 2.928(,o)-.4 G .428
+(therwise the name of the alias itself is used.)326.436 204.6 R -.15(Fo)117
+216.6 S 2.5(rt).15 G(his reason, and to obe)136.02 216.6 Q 2.5(yI)-.15 G
+(nternet con)233.63 216.6 Q -.15(ve)-.4 G(ntions, a typical scheme w).15 E
+(ould be:)-.1 E 18.49(list: some,)157 232.8 R(set, of, addresses)2.5 E 22.28
+(list-request: list-admin-1,)157 244.8 R(list-admin-2, ...)2.5 E -.25(ow)157
+256.8 S(ner).25 E 26.62(-list: list-request)-.2 F F0 2.5(2.4. User)87 285 R
+(Inf)2.5 E(ormation Database)-.25 E F1 1.059(If you ha)127 301.2 R 1.359 -.15
+(ve a ve)-.2 H 1.059(rsion of).15 F/F2 10/Times-Italic@0 SF(sendmail)3.559 E F1
+1.06(with the user information database compiled in, and you)3.559 F(ha)102
+313.2 Q 2.206 -.15(ve s)-.2 H 1.906(peci\214ed one or more databases using the)
+.15 F F0(U)4.406 E F1 1.905(option, the databases will be searched for a)4.406
+F F2(user)102 325.2 Q F1(:maildrop entry)A 5(.I)-.65 G 2.5(ff)191.34 325.2 S
+(ound, the mail will be sent to the speci\214ed address.)200.5 325.2 Q 1.288
+(If the \214rst tok)127 341.4 R 1.288(en passed to user part of the \231local\
+\232 mailer is an at sign, the at sign will be)-.1 F(stripped of)102 353.4 Q
+2.5(fa)-.25 G(nd this step will be skipped.)155.07 353.4 Q F0 2.5(2.5. P)87
+377.4 R(er)-.2 E(-User F)-.37 E(orwarding \(.f)-.25 E(orward Files\))-.25 E F1
+.121(As an alternati)127 393.6 R .421 -.15(ve t)-.25 H 2.621(ot).15 G .121
+(he alias database, an)210.404 393.6 R 2.621(yu)-.15 G .12
+(ser may put a \214le with the name \231.forw)304.878 393.6 R .12
+(ard\232 in his)-.1 F .205(or her home directory)102 405.6 R 5.205(.I)-.65 G
+2.705(ft)199.92 405.6 S .205(his \214le e)208.735 405.6 R(xists,)-.15 E F2
+(sendmail)2.705 E F1 .205
+(redirects mail for that user to the list of addresses)2.705 F .909
+(listed in the .forw)102 417.6 R .908(ard \214le.)-.1 F -.15(Fo)5.908 G 3.408
+(re).15 G .908
+(xample, if the home directory for user \231mckusick\232 has a .forw)233.98
+417.6 R(ard)-.1 E(\214le with contents:)102 429.6 Q(mckusick@ernie)142 445.8 Q
+(kirk@calder)142 457.8 Q(then an)102 474 Q 2.5(ym)-.15 G(ail arri)146.29 474 Q
+(ving for \231mckusick\232 will be redirected to the speci\214ed accounts.)-.25
+E(Actually)127 490.2 Q 3.374(,t)-.65 G .874
+(he con\214guration \214le de\214nes a sequence of \214lenames to check.)
+169.444 490.2 R .875(By def)5.875 F .875(ault, this is)-.1 F .688(the user')102
+502.2 R 3.188(s.)-.55 G(forw)146.426 502.2 Q .688(ard \214le, b)-.1 F .687
+(ut can be de\214ned to be more generally using the)-.2 F F0(J)3.187 E F1 3.187
+(option. If)3.187 F .687(you change)3.187 F .393(this, you will ha)102 514.2 R
+.693 -.15(ve t)-.2 H 2.893(oi).15 G .393
+(nform your user base of the change; .forw)193.064 514.2 R .393
+(ard is pretty well incorporated into)-.1 F(the collecti)102 526.2 Q .3 -.15
+(ve s)-.25 H(ubconscious.).15 E F0 2.5(2.6. Special)87 550.2 R(Header Lines)2.5
+E F1(Se)127 566.4 Q -.15(ve)-.25 G 1.898(ral header lines ha).15 F 2.197 -.15
+(ve s)-.2 H 1.897
+(pecial interpretations de\214ned by the con\214guration \214le.).15 F(Others)
+6.897 E(ha)102 578.4 Q 1.205 -.15(ve i)-.2 H .905(nterpretations b).15 F .905
+(uilt into)-.2 F F2(sendmail)3.405 E F1 .906
+(that cannot be changed without changing the code.)3.405 F(These)5.906 E -.2
+(bu)102 590.4 S(iltins are described here.).2 E F0 2.5(2.6.1. Retur)102 614.4 R
+(n-Receipt-T)-.15 E(o:)-.92 E F1 1.371
+(If this header is sent, a message will be sent to an)142 630.6 R 3.87(ys)-.15
+G 1.37(peci\214ed addresses when the \214nal)366.88 630.6 R(deli)117 642.6 Q
+-.15(ve)-.25 G .367(ry is complete, that is, when successfully deli).15 F -.15
+(ve)-.25 G .368(red to a mailer with the).15 F F0(l)2.868 E F1 .368
+(\215ag \(local deli)2.868 F(v-)-.25 E .024(ery\) set in the mailer descriptor)
+117 656.6 R/F3 7/Times-Roman@0 SF(6)242.37 652.6 Q F1 5.023(.T)245.87 656.6 S
+.023(his header can be disabled with the \231noreceipts\232 pri)259.503 656.6 R
+-.25(va)-.25 G .323 -.15(cy \215).25 H(ag.).15 E .32 LW 76 666.2 72 666.2 DL 80
+666.2 76 666.2 DL 84 666.2 80 666.2 DL 88 666.2 84 666.2 DL 92 666.2 88 666.2
+DL 96 666.2 92 666.2 DL 100 666.2 96 666.2 DL 104 666.2 100 666.2 DL 108 666.2
+104 666.2 DL 112 666.2 108 666.2 DL 116 666.2 112 666.2 DL 120 666.2 116 666.2
+DL 124 666.2 120 666.2 DL 128 666.2 124 666.2 DL 132 666.2 128 666.2 DL 136
+666.2 132 666.2 DL 140 666.2 136 666.2 DL 144 666.2 140 666.2 DL 148 666.2 144
+666.2 DL 152 666.2 148 666.2 DL 156 666.2 152 666.2 DL 160 666.2 156 666.2 DL
+164 666.2 160 666.2 DL 168 666.2 164 666.2 DL 172 666.2 168 666.2 DL 176 666.2
+172 666.2 DL 180 666.2 176 666.2 DL 184 666.2 180 666.2 DL 188 666.2 184 666.2
+DL 192 666.2 188 666.2 DL 196 666.2 192 666.2 DL 200 666.2 196 666.2 DL 204
+666.2 200 666.2 DL 208 666.2 204 666.2 DL 212 666.2 208 666.2 DL 216 666.2 212
+666.2 DL/F4 5/Times-Roman@0 SF(6)93.6 676.6 Q/F5 8/Times-Roman@0 SF .127
+(Some sites disable this header)3.2 J 2.127(,a)-.32 G .127(nd other \(non-)
+199.959 679.8 R/F6 8/Times-Italic@0 SF(sendmail)A F5 2.127(\)s)C .127
+(ystems do not implement it.)282.772 679.8 R .127(Do not assume that a f)4.127
+F .126(ailure to get a re-)-.08 F .317
+(turn receipt means that the mail did not arri)72 689.4 R -.12(ve)-.2 G 4.317
+(.A).12 G .318(lso, do not assume that getting a return receipt means that the\
+ mail has been read; it)232.509 689.4 R
+(just means that the message has been deli)72 699 Q -.12(ve)-.2 G
+(red to the recipient').12 E 2(sm)-.44 G(ailbox.)285.648 699 Q EP
+%%Page: 16 11
+%%BeginPageSetup
+BP
+%%EndPageSetup
+/F0 10/Times-Bold@0 SF 193.36(SMM:08-16 Sendmail)72 60 R
+(Installation and Operation Guide)2.5 E 2.5(2.6.2. Err)102 96 R(ors-T)-.18 E
+(o:)-.92 E/F1 10/Times-Roman@0 SF .22(If errors occur an)142 112.2 R .22
+(ywhere during processing, this header will cause error messages to go to)-.15
+F(the listed addresses.)117 124.2 Q(This is intended for mailing lists.)5 E
+.385(The Errors-T)142 140.4 R .385(o: header w)-.8 F .384
+(as created in the bad old days when UUCP didn')-.1 F 2.884(tu)-.18 G .384
+(nderstand the)450.016 140.4 R .889(distinction between an en)117 152.4 R -.15
+(ve)-.4 G .889(lope and a header; this w).15 F .889(as a hack to pro)-.1 F .89
+(vide what should no)-.15 F 3.39(wb)-.25 G(e)499.56 152.4 Q(passed as the en)
+117 164.4 Q -.15(ve)-.4 G(lope sender address.).15 E(It should go a)5 E -.1(wa)
+-.15 G 3.8 -.65(y. I).1 H 2.5(ti).65 G 2.5(so)365.22 164.4 S(nly used if the)
+376.61 164.4 Q F0(l)2.5 E F1(option is set.)2.5 E F0 2.5(2.6.3. A)102 188.4 R
+(ppar)-.25 E(ently-T)-.18 E(o:)-.92 E F1 .22
+(If a message comes in with no recipients listed in the message \(in a T)142
+204.6 R .22(o:, Cc:, or Bcc: line\))-.8 F(then)117 216.6 Q/F2 10/Times-Italic@0
+SF(sendmail)2.789 E F1 .289(will add an \231)2.789 F(Apparently-T)-.8 E .289
+(o:\232 header line for an)-.8 F 2.789(yr)-.15 G .29(ecipients it is a)378.08
+216.6 R -.1(wa)-.15 G .29(re of.).1 F .29(This is)5.29 F
+(not put in as a standard recipient line to w)117 228.6 Q(arn an)-.1 E 2.5(yr)
+-.15 G(ecipients that the list is not complete.)319.77 228.6 Q
+(At least one recipient line is required under RFC 822.)142 244.8 Q F0 2.5
+(2.7. IDENT)87 268.8 R(Pr)2.5 E(otocol Support)-.18 E F2(Sendmail)127 285 Q F1
+1.835(supports the IDENT protocol as de\214ned in RFC 1413.)4.335 F 1.835
+(Although this enhances)6.835 F .289
+(identi\214cation of the author of an email message by doing a `)102 297 R .29
+(`call back')-.74 F 2.79('t)-.74 G 2.79(ot)396.17 297 S .29
+(he originating system to)406.74 297 R .469(include the o)102 309 R .469(wner \
+of a particular TCP connection in the audit trail it is in no sense perfect; a\
+ deter)-.25 F(-)-.2 E 1.293(mined for)102 321 R 1.294
+(ger can easily spoof the IDENT protocol.)-.18 F 1.294(The follo)6.294 F 1.294
+(wing description is e)-.25 F 1.294(xcerpted from)-.15 F(RFC 1413:)102 333 Q
+2.5(6. Security)127 349.2 R(Considerations)2.5 E .006
+(The information returned by this protocol is at most as trustw)127 365.4 R
+(orth)-.1 E 2.505(ya)-.05 G 2.505(st)400.505 365.4 S .005(he host pro)409.68
+365.4 R .005(viding it OR)-.15 F .273(the or)127 377.4 R -.05(ga)-.18 G .273
+(nization operating the host.).05 F -.15(Fo)5.273 G 2.773(re).15 G .274
+(xample, a PC in an open lab has fe)295.308 377.4 R 2.774(wi)-.25 G 2.774(fa)
+448.612 377.4 S .574 -.15(ny c)459.156 377.4 T(ontrols).15 E .987(on it to pre)
+127 389.4 R -.15(ve)-.25 G .986(nt a user from ha).15 F .986
+(ving this protocol return an)-.2 F 3.486(yi)-.15 G .986
+(denti\214er the user w)378.056 389.4 R 3.486(ants. Lik)-.1 F(e-)-.1 E 1.441(w\
+ise, if the host has been compromised the information returned may be complete\
+ly erro-)127 401.4 R(neous and misleading.)127 413.4 Q .521(The Identi\214cati\
+on Protocol is not intended as an authorization or access control protocol.)127
+429.6 R(At)5.52 E 1.036(best, it pro)127 441.6 R 1.037
+(vides some additional auditing information with respect to TCP connections.)
+-.15 F(At)6.037 E -.1(wo)127 453.6 S(rst, it can pro).1 E
+(vide misleading, incorrect, or maliciously incorrect information.)-.15 E 1.006
+(The use of the information returned by this protocol for other than auditing \
+is strongly dis-)127 469.8 R 2.697(couraged. Speci\214cally)127 481.8 R 2.697
+(,u)-.65 G .197(sing Identi\214cation Protocol information to mak)228.114 481.8
+R 2.697(ea)-.1 G .197(ccess control deci-)429.186 481.8 R .514(sions - either \
+as the primary method \(i.e., no other checks\) or as an adjunct to other meth\
+ods)127 493.8 R(may result in a weak)127 505.8 Q(ening of normal host security)
+-.1 E(.)-.65 E 1.778(An Identi\214cation serv)127 522 R 1.778(er may re)-.15 F
+-.15(ve)-.25 G 1.778
+(al information about users, entities, objects or processes).15 F .337
+(which might normally be considered pri)127 534 R -.25(va)-.25 G 2.836(te. An)
+.25 F .336(Identi\214cation serv)2.836 F .336(er pro)-.15 F .336
+(vides service which)-.15 F .806
+(is a rough analog of the CallerID services pro)127 546 R .806
+(vided by some phone companies and man)-.15 F 3.306(yo)-.15 G(f)500.67 546 Q
+1.398(the same pri)127 558 R -.25(va)-.25 G 1.698 -.15(cy c).25 H 1.398
+(onsiderations and ar).15 F 1.398
+(guments that apply to the CallerID service apply to)-.18 F 3.545
+(Identi\214cation. If)127 570 R 1.045(you w)3.545 F(ouldn')-.1 E 3.545(tr)-.18
+G 1.045(un a "\214nger" serv)260.33 570 R 1.046(er due to pri)-.15 F -.25(va)
+-.25 G 1.346 -.15(cy c).25 H 1.046(onsiderations you may).15 F(not w)127 582 Q
+(ant to run this protocol.)-.1 E F0 2.5(3. ARGUMENTS)72 606 R F1 .018
+(The complete list of ar)112 622.2 R .018(guments to)-.18 F F2(sendmail)2.517 E
+F1 .017(is described in detail in Appendix A.)2.517 F .017(Some important)5.017
+F(ar)87 634.2 Q(guments are described here.)-.18 E F0 2.5(3.1. Queue)87 658.2 R
+(Inter)2.5 E -.1(va)-.1 G(l).1 E F1 .455(The amount of time between forking a \
+process to run through the queue is de\214ned by the)127 674.4 R F0<ad71>2.956
+E F1 2.706(\215ag. If)102 686.4 R .206(you run in mode)2.706 F F0(f)2.706 E F1
+(or)2.706 E F0(a)2.706 E F1 .206(this can be relati)2.706 F -.15(ve)-.25 G .206
+(ly lar).15 F .206(ge, since it will only be rele)-.18 F -.25(va)-.25 G .205
+(nt when a host).25 F .07(that w)102 698.4 R .07(as do)-.1 F .07
+(wn comes back up.)-.25 F .07(If you run in)5.07 F F0(q)2.57 E F1 .07
+(mode it should be relati)2.57 F -.15(ve)-.25 G .07
+(ly short, since it de\214nes the).15 F
+(maximum amount of time that a message may sit in the queue.)102 710.4 Q EP
+%%Page: 17 12
+%%BeginPageSetup
+BP
+%%EndPageSetup
+/F0 10/Times-Bold@0 SF(Sendmail Installation and Operation Guide)72 60 Q
+(SMM:08-17)452.9 60 Q/F1 10/Times-Roman@0 SF 1.336
+(RFC 1123 section 5.3.1.1 says that this v)127 96 R 1.335
+(alue should be at least 30 minutes \(although that)-.25 F(probably doesn')102
+108 Q 2.5(tm)-.18 G(ak)179.59 108 Q 2.5(es)-.1 G(ense if you use `)199.76 108 Q
+(`queue-only')-.74 E 2.5('m)-.74 G(ode\).)329.08 108 Q F0 2.5(3.2. Daemon)87
+132 R(Mode)2.5 E F1 .084(If you allo)127 148.2 R 2.584(wi)-.25 G .084
+(ncoming mail o)181.162 148.2 R -.15(ve)-.15 G 2.585(ra).15 G 2.585(nI)263.605
+148.2 S .085(PC connection, you should ha)274.52 148.2 R .385 -.15(ve a d)-.2 H
+.085(aemon running.).15 F(This)5.085 E .07(should be set by your)102 160.2 R/F2
+10/Times-Italic@0 SF(/etc/r)2.57 E(c)-.37 E F1 .07(\214le using the)2.57 F F0
+(\255bd)2.57 E F1 2.569(\215ag. The)2.57 F F0(\255bd)2.569 E F1 .069
+(\215ag and the)2.569 F F0<ad71>2.569 E F1 .069(\215ag may be combined)2.569 F
+(in one call:)102 172.2 Q(/usr/sbin/sendmail \255bd \255q30m)142 188.4 Q F0 2.5
+(3.3. F)87 216.6 R(or)-.25 E(cing the Queue)-.18 E F1 .04(In some cases you ma\
+y \214nd that the queue has gotten clogged for some reason.)127 232.8 R -1.1
+(Yo)5.04 G 2.54(uc)1.1 G .04(an force)471.48 232.8 R 3.185(aq)102 244.8 S .685
+(ueue run using the)114.625 244.8 R F0<ad71>3.184 E F1 .684(\215ag \(with no v)
+3.184 F 3.184(alue\). It)-.25 F .684(is entertaining to use the)3.184 F F0
+<ad76>3.184 E F1 .684(\215ag \(v)3.184 F .684(erbose\) when)-.15 F
+(this is done to w)102 256.8 Q(atch what happens:)-.1 E
+(/usr/sbin/sendmail \255q \255v)142 273 Q -1.1(Yo)127 293.4 S 4.004(uc)1.1 G
+1.504(an also limit the jobs to those with a particular queue identi\214er)
+151.564 293.4 R 4.004(,s)-.4 G(ender)428.362 293.4 Q 4.004(,o)-.4 G 4.004(rr)
+461.676 293.4 S(ecipient)472.34 293.4 Q .687
+(using one of the queue modi\214ers.)102 305.4 R -.15(Fo)5.687 G 3.187(re).15 G
+.687(xample, \231\255qRberk)265.659 305.4 R(ele)-.1 E .686
+(y\232 restricts the queue run to jobs that)-.15 F(ha)102 317.4 Q .525 -.15
+(ve t)-.2 H .225(he string \231berk).15 F(ele)-.1 E .225(y\232 some)-.15 F .225
+(where in one of the recipient addresses.)-.25 F(Similarly)5.226 E 2.726<2c99>
+-.65 G .226(\255qSstring\232 lim-)441.184 317.4 R(its the run to particular se\
+nders and \231\255qIstring\232 limits it to particular identi\214ers.)102 329.4
+Q F0 2.5(3.4. Deb)87 353.4 R(ugging)-.2 E F1 1.365(There are a f)127 369.6 R
+1.365(airly lar)-.1 F 1.365(ge number of deb)-.18 F 1.365(ug \215ags b)-.2 F
+1.365(uilt into)-.2 F F2(sendmail)3.865 E F1 6.365(.E)C 1.365(ach deb)417.65
+369.6 R 1.365(ug \215ag has a)-.2 F 1.116(number and a le)102 381.6 R -.15(ve)
+-.25 G 1.116(l, where higher le).15 F -.15(ve)-.25 G 1.116
+(ls means to print out more information.).15 F 1.116(The con)6.116 F -.15(ve)
+-.4 G 1.116(ntion is).15 F .294(that le)102 393.6 R -.15(ve)-.25 G .294
+(ls greater than nine are \231absurd,).15 F 2.794<9a69>-.7 G .294(.e., the)
+274.018 393.6 R 2.794(yp)-.15 G .293(rint out so much information that you w)
+313.616 393.6 R(ouldn')-.1 E(t)-.18 E .691(normally w)102 405.6 R .692
+(ant to see them e)-.1 F .692(xcept for deb)-.15 F .692
+(ugging that particular piece of code.)-.2 F(Deb)5.692 E .692
+(ug \215ags are set)-.2 F(using the)102 417.6 Q F0<ad64>2.5 E F1
+(option; the syntax is:)2.5 E(deb)142 433.8 Q(ug-\215ag:)-.2 E F0<ad64>200.13
+433.8 Q F1(deb)2.5 E(ug-list)-.2 E(deb)142 445.8 Q 13.05(ug-list: deb)-.2 F
+(ug-option [ , deb)-.2 E(ug-option ])-.2 E(deb)142 457.8 Q -.28(ug-option: deb)
+-.2 F(ug-range [ . deb)-.2 E(ug-le)-.2 E -.15(ve)-.25 G 2.5(l]).15 G(deb)142
+469.8 Q 3.07(ug-range: inte)-.2 F(ger | inte)-.15 E(ger \255 inte)-.15 E(ger)
+-.15 E(deb)142 481.8 Q(ug-le)-.2 E -.15(ve)-.25 G 6.24(l: inte).15 F(ger)-.15 E
+(where spaces are for reading ease only)102 498 Q 5(.F)-.65 G(or e)268.64 498 Q
+(xample,)-.15 E 34.99(\255d12 Set)142 514.2 R(\215ag 12 to le)2.5 E -.15(ve)
+-.25 G 2.5(l1).15 G 27.49(\255d12.3 Set)142 526.2 R(\215ag 12 to le)2.5 E -.15
+(ve)-.25 G 2.5(l3).15 G 26.66(\255d3-17 Set)142 538.2 R
+(\215ags 3 through 17 to le)2.5 E -.15(ve)-.25 G 2.5(l1).15 G 19.16
+(\255d3-17.4 Set)142 550.2 R(\215ags 3 through 17 to le)2.5 E -.15(ve)-.25 G
+2.5(l4).15 G -.15(Fo)102 566.4 S 4.066(rac).15 G 1.566(omplete list of the a)
+132.752 566.4 R -.25(va)-.2 G 1.565(ilable deb).25 F 1.565
+(ug \215ags you will ha)-.2 F 1.865 -.15(ve t)-.2 H 4.065(ol).15 G 1.565
+(ook at the code \(the)380.9 566.4 R 4.065(ya)-.15 G 1.565(re too)479.385 566.4
+R(dynamic to k)102 578.4 Q(eep this documentation up to date\).)-.1 E F0 2.5
+(3.5. T)87 602.4 R(rying a Differ)-.74 E(ent Con\214guration File)-.18 E F1
+(An alternati)127 618.6 Q .3 -.15(ve c)-.25 H
+(on\214guration \214le can be speci\214ed using the).15 E F0<ad43>2.5 E F1
+(\215ag; for e)2.5 E(xample,)-.15 E(/usr/sbin/sendmail \255Ctest.cf)142 634.8 Q
+.428(uses the con\214guration \214le)102 651 R F2(test.cf)2.928 E F1 .428
+(instead of the def)2.928 F(ault)-.1 E F2(/etc/sendmail.cf)2.928 E(.)-.15 E F1
+.428(If the)5.428 F F0<ad43>2.928 E F1 .429(\215ag has no v)2.928 F(alue)-.25 E
+(it def)102 663 Q(aults to)-.1 E F2(sendmail.cf)2.5 E F1
+(in the current directory)2.5 E(.)-.65 E F0 2.5(3.6. Changing)87 687 R(the V)
+2.5 E(alues of Options)-.92 E F1(Options can be o)127 703.2 Q -.15(ve)-.15 G
+(rridden using the).15 E F0<ad6f>2.5 E F1 2.5(\215ag. F)2.5 F(or e)-.15 E
+(xample,)-.15 E EP
+%%Page: 18 13
+%%BeginPageSetup
+BP
+%%EndPageSetup
+/F0 10/Times-Bold@0 SF 193.36(SMM:08-18 Sendmail)72 60 R
+(Installation and Operation Guide)2.5 E/F1 10/Times-Roman@0 SF
+(/usr/sbin/sendmail \255oT2m)142 96 Q(sets the)102 112.2 Q F0(T)2.5 E F1
+(\(timeout\) option to tw)2.5 E 2.5(om)-.1 G(inutes for this run only)246.63
+112.2 Q(.)-.65 E .182(Some options ha)127 128.4 R .482 -.15(ve s)-.2 H .182
+(ecurity implications.).15 F .182(Sendmail allo)5.182 F .181
+(ws you to set these, b)-.25 F .181(ut refuses to run)-.2 F(as root thereafter)
+102 140.4 Q(.)-.55 E F0 2.5(3.7. Logging)87 164.4 R -.74(Tr)2.5 G(af\214c).74 E
+F1(Man)127 180.6 Q 3.254(yS)-.15 G .754
+(MTP implementations do not fully implement the protocol.)158.994 180.6 R -.15
+(Fo)5.754 G 3.254(re).15 G .755(xample, some per)428.54 180.6 R(-)-.2 E 1.178(\
+sonal computer based SMTPs do not understand continuation lines in reply codes\
+.)102 192.6 R 1.177(These can be)6.178 F -.15(ve)102 204.6 S .13
+(ry hard to trace.).15 F .13(If you suspect such a problem, you can set traf)
+5.13 F .13(\214c logging using the)-.25 F F0<ad58>2.63 E F1 2.63(\215ag. F)2.63
+F(or)-.15 E -.15(ex)102 216.6 S(ample,).15 E
+(/usr/sbin/sendmail \255X /tmp/traf)142 232.8 Q(\214c -bd)-.25 E
+(will log all traf)102 249 Q(\214c in the \214le)-.25 E/F2 10/Times-Italic@0 SF
+(/tmp/tr)2.5 E(af)-.15 E<8c63>-.18 E F1(.)A .128(This logs a lot of data v)127
+265.2 R .128(ery quickly and should ne)-.15 F -.15(ve)-.25 G 2.628(rb).15 G
+2.628(eu)345.89 265.2 S .128(sed during normal operations.)357.958 265.2 R
+(After)5.128 E 1.326(starting up such a daemon, force the errant implementatio\
+n to send a message to your host.)102 277.2 R(All)6.327 E .505(message traf)102
+289.2 R .505(\214c in and out of)-.25 F F2(sendmail)3.005 E F1 3.004(,i)C .504
+(ncluding the incoming SMTP traf)265.264 289.2 R .504
+(\214c, will be logged in this)-.25 F(\214le.)102 301.2 Q F0 2.5(3.8. Dumping)
+87 325.2 R(State)2.5 E F1 -1.1(Yo)127 341.4 S 2.563(uc)1.1 G .063(an ask)
+150.123 341.4 R F2(sendmail)2.563 E F1 .064
+(to log a dump of the open \214les and the connection cache by sending it a)
+2.563 F/F3 9/Times-Roman@0 SF(SIGUSR1)102 353.4 Q F1 2.5(signal. The)2.5 F
+(results are logged at)2.5 E F3(LOG_DEB)2.5 E(UG)-.09 E F1(priority)2.5 E(.)
+-.65 E F0 2.5(4. TUNING)72 377.4 R F1 1.922
+(There are a number of con\214guration parameters you may w)112 393.6 R 1.922
+(ant to change, depending on the)-.1 F .366(requirements of your site.)87 405.6
+R .367(Most of these are set using an option in the con\214guration \214le.)
+5.366 F -.15(Fo)5.367 G 2.867(re).15 G(xample,)472.06 405.6 Q(the line \231O)87
+417.6 Q(T5d\232 sets option \231T\232 to the v)-.4 E(alue \2315d\232 \(\214v)
+-.25 E 2.5(ed)-.15 G(ays\).)312.55 417.6 Q .735(Most of these options ha)112
+433.8 R 1.035 -.15(ve a)-.2 H .735(ppropriate def).15 F .735
+(aults for most sites.)-.1 F(Ho)5.735 E(we)-.25 E -.15(ve)-.25 G 1.535 -.4
+(r, s).15 H .735(ites ha).4 F .735(ving v)-.2 F .735(ery high)-.15 F .045
+(mail loads may \214nd the)87 445.8 R 2.545(yn)-.15 G .046
+(eed to tune them as appropriate for their mail load.)193.465 445.8 R .046
+(In particular)5.046 F 2.546(,s)-.4 G .046(ites e)459.394 445.8 R(xperi-)-.15 E
+1.088(encing a lar)87 457.8 R 1.088(ge number of small messages, man)-.18 F
+3.588(yo)-.15 G 3.587(fw)294.504 457.8 S 1.087(hich are deli)308.641 457.8 R
+-.15(ve)-.25 G 1.087(red to man).15 F 3.587(yr)-.15 G 1.087
+(ecipients, may \214nd)425.996 457.8 R(that the)87 469.8 Q 2.5(yn)-.15 G
+(eed to adjust the parameters dealing with queue priorities.)129.07 469.8 Q F0
+2.5(4.1. T)87 493.8 R(imeouts)-.18 E F1 .582(All time interv)127 510 R .583
+(als are set using a scaled syntax.)-.25 F -.15(Fo)5.583 G 3.083(re).15 G .583
+(xample, \23110m\232 represents ten minutes,)346.138 510 R
+(whereas \2312h30m\232 represents tw)102 522 Q 2.5(oa)-.1 G(nd a half hours.)
+241.3 522 Q(The full set of scales is:)5 E 16.11(ss)142 538.2 S(econds)165.89
+538.2 Q 12.22(mm)142 550.2 S(inutes)169.78 550.2 Q 15(hh)142 562.2 S(ours)167
+562.2 Q 15(dd)142 574.2 S(ays)167 574.2 Q 12.78(ww)142 586.2 S(eeks)169.22
+586.2 Q F0 2.5(4.1.1. Queue)102 614.4 R(inter)2.5 E -.1(va)-.1 G(l).1 E F1 .18
+(The ar)142 630.6 R .18(gument to the)-.18 F F0<ad71>2.68 E F1 .18
+(\215ag speci\214es ho)2.68 F 2.68(wo)-.25 G .18
+(ften a sub-daemon will run the queue.)319.25 630.6 R .18(This is)5.18 F .967
+(typically set to between \214fteen minutes and one hour)117 642.6 R 5.968(.R)
+-.55 G .968(FC 1123 section 5.3.1.1 recommends)350.968 642.6 R
+(that this be at least 30 minutes.)117 654.6 Q F0 2.5(4.1.2. Read)102 678.6 R
+(timeouts)2.5 E F1 .51(It is possible to time out when reading the standard in\
+put or when reading from a remote)142 694.8 R .324(SMTP serv)117 706.8 R(er)
+-.15 E 5.324(.T)-.55 G .324(hese timeouts are set using the)183.608 706.8 R F0
+(r)2.824 E F1 .324(option in the con\214guration \214le.)2.824 F .324(The ar)
+5.324 F(gument)-.18 E 2.767(is a list of)117 718.8 R F2 -.1(ke)5.266 G(ywor)-.2
+E(d=value)-.37 E F1 5.266(pairs. The)5.266 F 2.766(recognized k)5.266 F -.15
+(ey)-.1 G -.1(wo).15 G 2.766(rds, their def).1 F 2.766(ault v)-.1 F 2.766
+(alues, and the)-.25 F EP
+%%Page: 19 14
+%%BeginPageSetup
+BP
+%%EndPageSetup
+/F0 10/Times-Bold@0 SF(Sendmail Installation and Operation Guide)72 60 Q
+(SMM:08-19)452.9 60 Q/F1 10/Times-Roman@0 SF(minimum v)117 96 Q(alues allo)-.25
+E(wed by RFC 1123 section 5.3.2 are:)-.25 E 46.16(initial The)117 112.2 R -.1
+(wa)2.5 G(it for the initial 220 greeting message [5m, 5m].).1 E 52.28
+(helo The)117 128.4 R -.1(wa)4.226 G 1.727
+(it for a reply from a HELO or EHLO command [5m, unspeci\214ed].).1 F .1
+(This may require a host name lookup, so \214v)189 140.4 R 2.6(em)-.15 G .1
+(inutes is probably a reasonable)380.29 140.4 R(minimum.)189 152.4 Q 46.72
+(mail\207 The)117 168.6 R -.1(wa)2.5 G
+(it for a reply from a MAIL command [10m, 5m].).1 E 48.95(rcpt\207 The)117
+184.8 R -.1(wa)3.481 G .981(it for a reply from a RCPT command [1h, 5m].).1 F
+.982(This should be long)5.982 F
+(because it could be pointing at a list that tak)189 196.8 Q
+(es a long time to e)-.1 E(xpand.)-.15 E 34.5(datainit\207 The)117 213 R -.1
+(wa)2.5 G(it for a reply from a D).1 E -1.21 -1.11(AT A)-.4 H
+(command [5m, 2m].)3.61 E 25.62(datablock\207 The)117 229.2 R -.1(wa)2.696 G
+.196(it for reading a data block \(that is, the body of the message\).).1 F
+.196([1h, 3m].)5.196 F .621
+(This should be long because it also applies to programs piping input to)189
+241.2 R/F2 10/Times-Italic@0 SF(send-)3.121 E(mail)189 253.2 Q F1(which ha)2.5
+E .3 -.15(ve n)-.2 H 2.5(og).15 G(uarantee of promptness.)274.75 253.2 Q 30.06
+(data\214nal\207 The)117 269.4 R -.1(wa)2.806 G .306
+(it for a reply from the dot terminating a message.).1 F .306([1h, 10m].)5.306
+F .306(If this is)5.306 F .883
+(shorter than the time actually needed for the recei)189 281.4 R -.15(ve)-.25 G
+3.384(rt).15 G 3.384(od)412.878 281.4 S(eli)426.262 281.4 Q -.15(ve)-.25 G
+3.384(rt).15 G .884(he message,)454.796 281.4 R(duplicates will be generated.)
+189 293.4 Q(This is discussed in RFC 1047.)5 E 55.06(rset The)117 309.6 R -.1
+(wa)2.5 G(it for a reply from a RSET command [5m, unspeci\214ed].).1 E 53.94
+(quit The)117 325.8 R -.1(wa)2.5 G(it for a reply from a Q).1 E
+(UIT command [2m, unspeci\214ed].)-.1 E 50.61(misc The)117 342 R -.1(wa)2.761 G
+.261(it for a reply from miscellaneous \(b).1 F .261
+(ut short\) commands such as NOOP)-.2 F(\(no-operation\) and VERB \(go into v)
+189 354 Q(erbose mode\).)-.15 E([2m, unspeci\214ed].)5 E 25.06(command\207 In)
+117 370.2 R(serv)2.5 E(er SMTP)-.15 E 2.5(,t)-1.11 G(he time to w)259.4 370.2 Q
+(ait for another command.)-.1 E([1h, 5m].)5 E 49.5(ident The)117 386.4 R
+(timeout w)2.5 E(aiting for a reply to an IDENT query [30s, unspeci\214ed].)-.1
+E -.15(Fo)117 402.6 S 3.633(rc).15 G 1.134
+(ompatibility with old con\214guration \214les, if no `)138.813 402.6 R(`k)-.74
+E -.15(ey)-.1 G -.1(wo).15 G(rd=').1 E 3.634('i)-.74 G 3.634(ss)390.854 402.6 S
+1.134(peci\214ed, all the timeouts)402.268 402.6 R(mark)117 414.6 Q
+(ed with \207 are set to the indicated v)-.1 E(alue.)-.25 E(Man)142 430.8 Q
+2.501(yo)-.15 G 2.501(ft)172.681 430.8 S .001(he RFC 1123 minimum v)181.292
+430.8 R .001(alues may well be too short.)-.25 F F2(Sendmail)5 E F1 -.1(wa)2.5
+G 2.5(sd).1 G(esigned to)463.17 430.8 Q .066
+(the RFC 822 protocols, which did not specify read timeouts; hence,)117 442.8 R
+F2(sendmail)2.567 E F1 .067(does not guarantee)2.567 F .438
+(to reply to messages promptly)117 454.8 R 5.438(.I)-.65 G 2.938(np)249.92
+454.8 S(articular)262.858 454.8 Q 2.938(,a\231)-.4 G .438
+(RCPT\232 command specifying a mailing list will)313.034 454.8 R -.15(ex)117
+468.8 S .205(pand and v).15 F .205(erify the entire list; a lar)-.15 F .205
+(ge list on a slo)-.18 F 2.705(ws)-.25 G .205(ystem may tak)339.81 468.8 R
+2.705(em)-.1 G .205(ore than \214v)413.375 468.8 R 2.705(em)-.15 G(inutes)
+474.11 468.8 Q/F3 7/Times-Roman@0 SF(7)498 464.8 Q F1(.)501.5 468.8 Q 3.036(Ir)
+117 480.8 S .536(ecommend a one hour timeout \212 since this f)126.696 480.8 R
+.536(ailure is rare, a long timeout is not onerous and)-.1 F
+(may ultimately help reduce netw)117 492.8 Q(ork load.)-.1 E -.15(Fo)142 509 S
+2.5(re).15 G(xample, the line:)162.53 509 Q(Orcommand=25m,datablock=3h)157
+525.2 Q .344(sets the serv)117 541.4 R .344(er SMTP command timeout to 25 minu\
+tes and the input data block timeout to three)-.15 F(hours.)117 553.4 Q F0 2.5
+(4.1.3. Message)102 577.4 R(timeouts)2.5 E F1 .237
+(After sitting in the queue for a fe)142 593.6 R 2.737(wd)-.25 G .237
+(ays, a message will time out.)289.726 593.6 R .238(This is to insure that at)
+5.238 F .283(least the sender is a)117 605.6 R -.1(wa)-.15 G .282
+(re of the inability to send a message.).1 F .282
+(The timeout is typically set to three)5.282 F 2.5(days. This)117 617.6 R
+(timeout is set using the)2.5 E F0(T)2.5 E F1
+(option in the con\214guration \214le.)2.5 E .413(The time of submission is se\
+t in the queue, rather than the amount of time left until time-)142 633.8 R
+3.263(out. As)117 645.8 R 3.263(ar)3.263 G .763
+(esult, you can \215ush messages that ha)163.449 645.8 R 1.062 -.15(ve b)-.2 H
+.762(een hanging for a short period by running).15 F
+(the queue with a short message timeout.)117 657.8 Q -.15(Fo)5 G 2.5(re).15 G
+(xample,)302.79 657.8 Q .32 LW 76 669.2 72 669.2 DL 80 669.2 76 669.2 DL 84
+669.2 80 669.2 DL 88 669.2 84 669.2 DL 92 669.2 88 669.2 DL 96 669.2 92 669.2
+DL 100 669.2 96 669.2 DL 104 669.2 100 669.2 DL 108 669.2 104 669.2 DL 112
+669.2 108 669.2 DL 116 669.2 112 669.2 DL 120 669.2 116 669.2 DL 124 669.2 120
+669.2 DL 128 669.2 124 669.2 DL 132 669.2 128 669.2 DL 136 669.2 132 669.2 DL
+140 669.2 136 669.2 DL 144 669.2 140 669.2 DL 148 669.2 144 669.2 DL 152 669.2
+148 669.2 DL 156 669.2 152 669.2 DL 160 669.2 156 669.2 DL 164 669.2 160 669.2
+DL 168 669.2 164 669.2 DL 172 669.2 168 669.2 DL 176 669.2 172 669.2 DL 180
+669.2 176 669.2 DL 184 669.2 180 669.2 DL 188 669.2 184 669.2 DL 192 669.2 188
+669.2 DL 196 669.2 192 669.2 DL 200 669.2 196 669.2 DL 204 669.2 200 669.2 DL
+208 669.2 204 669.2 DL 212 669.2 208 669.2 DL 216 669.2 212 669.2 DL/F4 5
+/Times-Roman@0 SF(7)93.6 679.6 Q/F5 8/Times-Roman@0 SF .344(This v)3.2 J .344
+(eri\214cation includes looking up e)-.12 F -.12(ve)-.2 G .344
+(ry address with the name serv).12 F .344(er; this in)-.12 F -.16(vo)-.32 G(lv)
+.16 E .344(es netw)-.12 F .343(ork delays, and can in some cases)-.08 F
+(can be considerable.)72 692.4 Q EP
+%%Page: 20 15
+%%BeginPageSetup
+BP
+%%EndPageSetup
+/F0 10/Times-Bold@0 SF 193.36(SMM:08-20 Sendmail)72 60 R
+(Installation and Operation Guide)2.5 E/F1 10/Times-Roman@0 SF
+(/usr/sbin/sendmail \255oT1d \255q)157 96 Q(will run the queue and \215ush an)
+117 112.2 Q(ything that is one day old.)-.15 E 1.077
+(Since this option is global, and since you can not)142 128.4 R/F2 10
+/Times-Italic@0 SF 3.577(ap)3.577 G(riori)364.395 128.4 Q F1(kno)3.577 E 3.577
+(wh)-.25 G 1.577 -.25(ow l)416.859 128.4 T 1.077(ong another host).25 F .476
+(outside your domain will be do)117 140.4 R .475(wn, a \214v)-.25 F 2.975(ed)
+-.15 G .475(ay timeout is recommended.)291.785 140.4 R .475(This allo)5.475 F
+.475(ws a recipient)-.25 F 1.579(to \214x the problem e)117 152.4 R -.15(ve)
+-.25 G 4.079(ni).15 G 4.079(fi)222.545 152.4 S 4.079(to)232.734 152.4 S 1.579
+(ccurs at the be)244.593 152.4 R 1.58(ginning of a long week)-.15 F 4.08
+(end. RFC)-.1 F 1.58(1123 section)4.08 F
+(5.3.1.1 says that this parameter should be `)117 164.4 Q
+(`at least 4\2555 days')-.74 E('.)-.74 E(The)142 180.6 Q F0(T)2.711 E F1 .211
+(option can also tak)2.711 F 2.711(eas)-.1 G .21
+(econd timeout indicating a time after which a w)263.637 180.6 R .21
+(arning mes-)-.1 F(sage should be sent; the tw)117 192.6 Q 2.5(ot)-.1 G
+(imeouts are separated by a slash.)234.67 192.6 Q -.15(Fo)5 G 2.5(re).15 G
+(xample, the v)391.28 192.6 Q(alue)-.25 E(5d/4h)157 208.8 Q .971
+(causes email to f)117 225 R .971(ail after \214v)-.1 F 3.471(ed)-.15 G .971
+(ays, b)245.326 225 R .971(ut a w)-.2 F .971
+(arning message will be sent after four hours.)-.1 F(This)5.972 E
+(should be lar)117 237 Q(ge enough that the message will ha)-.18 E .3 -.15
+(ve b)-.2 H(een tried se).15 E -.15(ve)-.25 G(ral times.).15 E F0 2.5(4.2. F)87
+261 R(orking During Queue Runs)-.25 E F1 .303(By setting the)127 277.2 R F0(Y)
+2.802 E F1(option,)2.802 E F2(sendmail)2.802 E F1 .302
+(will fork before each indi)2.802 F .302(vidual message while running the)-.25
+F 2.513(queue. This)102 289.2 R .013(will pre)2.513 F -.15(ve)-.25 G(nt).15 E
+F2(sendmail)2.513 E F1 .013(from consuming lar)2.513 F .013
+(ge amounts of memory)-.18 F 2.513(,s)-.65 G 2.513(oi)421.993 289.2 S 2.513(tm)
+432.286 289.2 S .014(ay be useful in)445.359 289.2 R .592(memory-poor en)102
+301.2 R 3.092(vironments. Ho)-.4 F(we)-.25 E -.15(ve)-.25 G 1.392 -.4(r, i).15
+H 3.092(ft).4 G(he)275.388 301.2 Q F0(Y)3.092 E F1 .591(option is not set,)
+3.091 F F2(sendmail)3.091 E F1 .591(will k)3.091 F .591(eep track of hosts)-.1
+F(that are do)102 313.2 Q(wn during a queue run, which can impro)-.25 E .3 -.15
+(ve p)-.15 H(erformance dramatically).15 E(.)-.65 E(If the)127 329.4 Q F0(Y)2.5
+E F1(option is set,)2.5 E F2(sendmail)2.5 E F1(can not use connection caching.)
+2.5 E F0 2.5(4.3. Queue)87 353.4 R(Priorities)2.5 E F1(Ev)127 369.6 Q 1.128(er\
+y message is assigned a priority when it is \214rst instantiated, consisting o\
+f the message)-.15 F .003(size \(in bytes\) of)102 381.6 R .002
+(fset by the message class times the \231w)-.25 F .002(ork class f)-.1 F .002
+(actor\232 and the number of recipients)-.1 F .637(times the \231w)102 393.6 R
+.637(ork recipient f)-.1 F(actor)-.1 E 4.537 -.7(.\232 T)-.55 H .638
+(he priority is used to order the queue.).7 F .638(Higher numbers for the)5.638
+F(priority mean that the message will be processed later when running the queu\
+e.)102 405.6 Q .329(The message size is included so that lar)127 421.8 R .328
+(ge messages are penalized relati)-.18 F .628 -.15(ve t)-.25 H 2.828(os).15 G
+.328(mall messages.)443.122 421.8 R .285(The message class allo)102 433.8 R
+.285(ws users to send \231high priority\232 messages by including a \231Preced\
+ence:\232 \214eld)-.25 F .008(in their message; the v)102 445.8 R .008
+(alue of this \214eld is look)-.25 F .007(ed up in the)-.1 F F0(P)2.507 E F1
+.007(lines of the con\214guration \214le.)2.507 F .007(Since the)5.007 F 1.966
+(number of recipients af)102 457.8 R 1.967
+(fects the amount of load a message presents to the system, this is also)-.25 F
+(included into the priority)102 469.8 Q(.)-.65 E .895
+(The recipient and class f)127 486 R .895
+(actors can be set in the con\214guration \214le using the)-.1 F F0(y)3.394 E
+F1(and)3.394 E F0(z)3.394 E F1(options)3.394 E(respecti)102 498 Q -.15(ve)-.25
+G(ly).15 E 5.962(.T)-.65 G(he)163.842 498 Q 3.462(yd)-.15 G(ef)186.594 498 Q
+.962(ault to 30000 \(for the recipient f)-.1 F .963
+(actor\) and 1800 \(for the class f)-.1 F 3.463(actor\). The)-.1 F
+(initial priority is:)102 510 Q F2(pri)223.76 528 Q/F3 10/Symbol SF(=)3.16 E F2
+(msgsize)3.18 E F3(-)2.38 E F1(\()2.2 E F2(class).2 E F3<b4>2.47 E F0(z\))2.2 E
+F3(+)2.2 E F1(\()2.2 E F2(nrcpt).36 E F3<b4>2.88 E F0(y\))2.2 E F1(\(Remember)
+102 546 Q 3.328(,h)-.4 G .828(igher v)159.638 546 R .828
+(alues for this parameter actually mean that the job will be treated with lo)
+-.25 F(wer)-.25 E(priority)102 558 Q(.\))-.65 E 1.519(The priority of a job ca\
+n also be adjusted each time it is processed \(that is, each time an)127 574.2
+R .256(attempt is made to deli)102 586.2 R -.15(ve)-.25 G 2.756(ri).15 G .256
+(t\) using the \231w)212.04 586.2 R .256(ork time f)-.1 F(actor)-.1 E 1.656 -.7
+(,\232 s)-.4 H .256(et by the).7 F F0(Z)2.756 E F1 2.756(option. This)2.756 F
+.256(is added to the)2.756 F(priority)102 598.2 Q 2.702(,s)-.65 G 2.703(oi)
+140.442 598.2 S 2.703(tn)150.925 598.2 S .203
+(ormally decreases the precedence of the job, on the grounds that jobs that ha)
+161.408 598.2 R .503 -.15(ve f)-.2 H(ailed).05 E(man)102 610.2 Q 2.5(yt)-.15 G
+(imes will tend to f)129.35 610.2 Q(ail ag)-.1 E(ain in the future.)-.05 E(The)
+5 E F0(Z)2.5 E F1(option def)2.5 E(aults to 90000.)-.1 E F0 2.5(4.4. Load)87
+634.2 R(Limiting)2.5 E F2(Sendmail)127 650.4 Q F1 .102(can be ask)2.602 F .101
+(ed to queue \(b)-.1 F .101(ut not deli)-.2 F -.15(ve)-.25 G .101
+(r\) mail if the system load a).15 F -.15(ve)-.2 G .101(rage gets too high).15
+F .626(using the)102 662.4 R F0(x)3.126 E F1 3.126(option. When)3.126 F .626
+(the load a)3.126 F -.15(ve)-.2 G .626(rage e).15 F .626(xceeds the v)-.15 F
+.626(alue of the)-.25 F F0(x)3.126 E F1 .626(option, the deli)3.126 F -.15(ve)
+-.25 G .627(ry mode is).15 F .987(set to)102 674.4 R F0(q)3.487 E F1 .987
+(\(queue only\) if the)3.487 F F2 .987(Queue F)3.487 F(actor)-.75 E F1(\()3.487
+E F0(q)A F1 .987(option\) di)3.487 F .986(vided by the dif)-.25 F .986
+(ference in the current load)-.25 F -2.25 -.2(av e)102 686.4 T 1.268
+(rage and the).2 F F0(x)3.769 E F1 1.269(option plus one e)3.769 F 1.269
+(xceeds the priority of the message \212 that is, the message is)-.15 F
+(queued if)102 698.4 Q(f:)-.25 E EP
+%%Page: 21 16
+%%BeginPageSetup
+BP
+%%EndPageSetup
+/F0 10/Times-Bold@0 SF(Sendmail Installation and Operation Guide)72 60 Q
+(SMM:08-21)452.9 60 Q/F1 10/Times-Italic@0 SF(pri)269.76 99.23 Q/F2 10
+/Times-Roman@0 SF(>)3.16 E F0(q)312.48 92.23 Q F1(LA)294.81 106.23 Q/F3 10
+/Symbol SF(-)2.23 E F0(x)2.2 E F3(+)2.2 E .4 LW 336.29 96.63 294.23 96.63 DL F2
+(1)331.29 106.23 Q(The)102 120.73 Q F0(q)3.143 E F2 .643(option def)3.143 F
+.642(aults to 600000, so each point of load a)-.1 F -.15(ve)-.2 G .642
+(rage is w).15 F .642(orth 600000 priority points \(as)-.1 F(described abo)102
+132.73 Q -.15(ve)-.15 G(\).).15 E -.15(Fo)127 148.93 S 2.886(rd).15 G .386
+(rastic cases, the)148.626 148.93 R F0(X)2.887 E F2 .387
+(option de\214nes a load a)2.887 F -.15(ve)-.2 G .387(rage at which).15 F F1
+(sendmail)2.887 E F2 .387(will refuse to accept)2.887 F(netw)102 160.93 Q
+(ork connections.)-.1 E
+(Locally generated mail \(including incoming UUCP mail\) is still accepted.)5 E
+F0 2.5(4.5. Deli)87 184.93 R -.1(ve)-.1 G(ry Mode).1 E F2 .417
+(There are a number of deli)127 201.13 R -.15(ve)-.25 G .416(ry modes that).15
+F F1(sendmail)2.916 E F2 .416
+(can operate in, set by the \231d\232 con\214gura-)2.916 F(tion option.)102
+213.13 Q(These modes specify ho)5 E 2.5(wq)-.25 G(uickly mail will be deli)
+263.96 213.13 Q -.15(ve)-.25 G 2.5(red. Le).15 F -.05(ga)-.15 G 2.5(lm).05 G
+(odes are:)418.9 213.13 Q 17.22(id)142 229.33 S(eli)167 229.33 Q -.15(ve)-.25 G
+2.5(ri).15 G(nteracti)194.65 229.33 Q -.15(ve)-.25 G(ly \(synchronously\)).15 E
+15(bd)142 241.33 S(eli)167 241.33 Q -.15(ve)-.25 G 2.5(ri).15 G 2.5(nb)194.65
+241.33 S(ackground \(asynchronously\))207.15 241.33 Q 15(qq)142 253.33 S
+(ueue only \(don')167 253.33 Q 2.5(td)-.18 G(eli)240.42 253.33 Q -.15(ve)-.25 G
+(r\)).15 E 1.49(There are tradeof)102 269.53 R 3.99(fs. Mode)-.25 F 1.491
+(\231i\232 passes the maximum amount of information to the sender)3.99 F 3.991
+(,b)-.4 G 1.491(ut is)485.559 269.53 R .433(hardly e)102 281.53 R -.15(ve)-.25
+G 2.933(rn).15 G(ecessary)155.226 281.53 Q 5.433(.M)-.65 G .433
+(ode \231q\232 puts the minimum load on your machine, b)205.269 281.53 R .432
+(ut means that deli)-.2 F -.15(ve)-.25 G(ry).15 E .437
+(may be delayed for up to the queue interv)102 293.53 R 2.937(al. Mode)-.25 F
+.437(\231b\232 is probably a good compromise.)2.937 F(Ho)5.437 E(we)-.25 E -.15
+(ve)-.25 G -.4(r,).15 G .033(this mode can cause lar)102 305.53 R .032
+(ge numbers of processes if you ha)-.18 F .332 -.15(ve a m)-.2 H .032
+(ailer that tak).15 F .032(es a long time to deli)-.1 F -.15(ve)-.25 G(r).15 E
+2.5(am)102 317.53 S(essage.)116.72 317.53 Q .337
+(If you run in mode \231q\232 \(queue only\) or \231b\232 \(deli)127 333.73 R
+-.15(ve)-.25 G 2.838(ri).15 G 2.838(nb)341.09 333.73 S(ackground\))353.928
+333.73 Q F1(sendmail)2.838 E F2 .338(will not e)2.838 F(xpand)-.15 E 1.314
+(aliases and follo)102 345.73 R 3.813(w.)-.25 G(forw)182.901 345.73 Q 1.313
+(ard \214les upon initial receipt of the mail.)-.1 F 1.313
+(This speeds up the response to)6.313 F(RCPT commands.)102 357.73 Q F0 2.5
+(4.6. Log)87 381.73 R(Le)2.5 E -.1(ve)-.15 G(l).1 E F2 .189(The le)127 397.93 R
+-.15(ve)-.25 G 2.689(lo).15 G 2.689(fl)171.968 397.93 S .189
+(ogging can be set for)180.767 397.93 R F1(sendmail)2.689 E F2 5.189(.T)C .189
+(he def)317.991 397.93 R .19(ault using a standard con\214guration table)-.1 F
+(is le)102 409.93 Q -.15(ve)-.25 G 2.5(l9).15 G 5(.T)137.71 409.93 S(he le)
+151.32 409.93 Q -.15(ve)-.25 G(ls are as follo).15 E(ws:)-.25 E 31(0N)102
+426.13 S 2.5(ol)145.22 426.13 S(ogging.)155.5 426.13 Q 31(1S)102 442.33 S
+(erious system f)143.56 442.33 Q(ailures and potential security problems.)-.1 E
+31(2L)102 458.53 S(ost communications \(netw)144.11 458.53 Q
+(ork problems\) and protocol f)-.1 E(ailures.)-.1 E 31(3O)102 474.73 S
+(ther serious f)145.22 474.73 Q(ailures.)-.1 E 31(4M)102 490.93 S(inor f)146.89
+490.93 Q(ailures.)-.1 E 31(5M)102 507.13 S(essage collection statistics.)146.89
+507.13 Q 31(6C)102 523.33 S(reation of error messages, VRFY and EXPN commands.)
+144.67 523.33 Q 31(7D)102 539.53 S(eli)145.22 539.53 Q -.15(ve)-.25 G(ry f).15
+E(ailures \(host or user unkno)-.1 E(wn, etc.\).)-.25 E 31(8S)102 555.73 S
+(uccessful deli)143.56 555.73 Q -.15(ve)-.25 G(ries.).15 E 31(9M)102 571.93 S
+(essages being deferred \(due to a host being do)146.89 571.93 Q(wn, etc.\).)
+-.25 E 23.5(10 Database)102 588.13 R -.15(ex)2.5 G(pansion \(alias, forw).15 E
+(ard, and userdb lookups\).)-.1 E 23.5(15 Automatic)102 604.33 R
+(alias database reb)2.5 E(uilds.)-.2 E 23.5(20 Logs)102 620.53 R .603
+(attempts to run lock)3.103 F .603(ed queue \214les.)-.1 F .603
+(These are not errors, b)5.603 F .603(ut can be useful to note if)-.2 F
+(your queue appears to be clogged.)138 632.53 Q 23.5(30 Lost)102 648.73 R
+(locks \(only if using lockf instead of \215ock\).)2.5 E(Additionally)102
+664.93 Q 3.683(,v)-.65 G 1.183(alues abo)162.843 664.93 R 1.483 -.15(ve 6)-.15
+H 3.683(4a).15 G 1.183(re reserv)232.462 664.93 R 1.183(ed for e)-.15 F 1.183
+(xtremely v)-.15 F 1.184(erbose deb)-.15 F 1.184(uggging output.)-.2 F 1.184
+(No normal)6.184 F(site w)102 676.93 Q(ould e)-.1 E -.15(ve)-.25 G 2.5(rs).15 G
+(et these.)168.99 676.93 Q EP
+%%Page: 22 17
+%%BeginPageSetup
+BP
+%%EndPageSetup
+/F0 10/Times-Bold@0 SF 193.36(SMM:08-22 Sendmail)72 60 R
+(Installation and Operation Guide)2.5 E 2.5(4.7. File)87 96 R(Modes)2.5 E/F1 10
+/Times-Roman@0 SF .813(There are a number of \214les that may ha)127 112.2 R
+1.113 -.15(ve a n)-.2 H .813(umber of modes.).15 F .813
+(The modes depend on what)5.813 F(functionality you w)102 124.2 Q
+(ant and the le)-.1 E -.15(ve)-.25 G 2.5(lo).15 G 2.5(fs)253.15 124.2 S
+(ecurity you require.)262.87 124.2 Q F0 2.5(4.7.1. T)102 148.2 R 2.5(os)-.92 G
+(uid or not to suid?)146.64 148.2 Q/F2 10/Times-Italic@0 SF(Sendmail)142 164.4
+Q F1 .933(can safely be made setuid to root.)3.433 F .934
+(At the point where it is about to)5.934 F F2 -.2(ex)3.434 G(ec).2 E F1 .934
+(\(2\) a)1.666 F(mailer)117 176.4 Q 2.583(,i)-.4 G 2.583(tc)150.013 176.4 S
+.082(hecks to see if the userid is zero; if so, it resets the userid and group\
+id to a def)159.816 176.4 R .082(ault \(set)-.1 F .576(by the)117 188.4 R F0(u)
+3.076 E F1(and)3.076 E F0(g)3.076 E F1 3.076(options\). \(This)3.076 F .576
+(can be o)3.076 F -.15(ve)-.15 G .576(rridden by setting the).15 F F0(S)3.076 E
+F1 .577(\215ag to the mailer for mailers)3.077 F 1.532
+(that are trusted and must be called as root.\))117 200.4 R(Ho)6.531 E(we)-.25
+E -.15(ve)-.25 G 2.331 -.4(r, t).15 H 1.531
+(his will cause mail processing to be).4 F(accounted \(using)117 212.4 Q F2(sa)
+2.5 E F1(\(8\)\) to root rather than to the user sending the mail.)1.666 E F0
+2.5(4.7.2. Should)102 236.4 R(my alias database be writable?)2.5 E F1 .058
+(At Berk)142 252.6 R(ele)-.1 E 2.558(yw)-.15 G 2.558(eh)200.186 252.6 S -2.25
+-.2(av e)212.184 252.6 T .058(the alias database \(/etc/aliases*\) mode 644.)
+2.758 F .058(While this is not as \215e)5.058 F(x-)-.15 E 1.719
+(ible as if the database were more 666, it a)117 264.6 R -.2(vo)-.2 G 1.718
+(ids potential security problems with a globally).2 F(writable database.)117
+276.6 Q 1.19(The database that)142 292.8 R F2(sendmail)3.69 E F1 1.191
+(actually used is represented by the tw)3.691 F 3.691<6f8c>-.1 G(les)429.118
+292.8 Q F2(aliases.dir)3.691 E F1(and)3.691 E F2(aliases.pa)117 304.8 Q(g)-.1 E
+F1 .159(\(both in /etc\) \(or)2.659 F F2(aliases.db)2.659 E F1 .159
+(if you are running with the ne)2.659 F 2.658(wB)-.25 G(erk)412.854 304.8 Q
+(ele)-.1 E 2.658(yd)-.15 G .158(atabase prim-)449.692 304.8 R(iti)117 316.8 Q
+-.15(ve)-.25 G 3.606(s\). The).15 F 1.107
+(mode on these \214les should match the mode on /etc/aliases.)3.606 F(If)6.107
+E F2(aliases)3.607 E F1 1.107(is writable)3.607 F 1.624(and the DBM \214les \()
+117 328.8 R F2(aliases.dir)A F1(and)4.124 E F2(aliases.pa)4.124 E(g)-.1 E F1
+4.124(\)a)C 1.624(re not, users will be unable to re\215ect their)324.648 328.8
+R .719(desired changes through to the actual database.)117 340.8 R(Ho)5.719 E
+(we)-.25 E -.15(ve)-.25 G 1.519 -.4(r, i).15 H(f).4 E F2(aliases)3.219 E F1 .72
+(is read-only and the DBM)3.219 F(\214les are writable, a slightly sophisticat\
+ed user can arrange to steal mail an)117 352.8 Q(yw)-.15 E(ay)-.1 E(.)-.65 E
+.621(If your DBM \214les are not writable by the w)142 369 R .62
+(orld or you do not ha)-.1 F .92 -.15(ve a)-.2 H(uto-reb).15 E .62
+(uild enabled)-.2 F .564(\(with the \231D\232 option\), then you must be caref\
+ul to reconstruct the alias database each time you)117 381 R(change the te)117
+393 Q(xt v)-.15 E(ersion:)-.15 E(ne)157 409.2 Q -.1(wa)-.25 G(liases).1 E
+(If this step is ignored or for)117 425.4 Q(gotten an)-.18 E 2.5(yi)-.15 G
+(ntended changes will also be ignored or for)273.32 425.4 Q(gotten.)-.18 E F0
+2.5(4.8. Connection)87 449.4 R(Caching)2.5 E F1 .642
+(When processing the queue,)127 465.6 R F2(sendmail)3.142 E F1 .642
+(will try to k)3.142 F .642(eep the last fe)-.1 F 3.142(wo)-.25 G .642
+(pen connections open to)405.144 465.6 R -.2(avo)102 477.6 S
+(id startup and shutdo).2 E(wn costs.)-.25 E
+(This only applies to IPC connections.)5 E .286
+(When trying to open a connection the cache is \214rst searched.)127 493.8 R
+.287(If an open connection is found,)5.286 F .92
+(it is probed to see if it is still acti)102 505.8 R 1.22 -.15(ve b)-.25 H 3.42
+(ys).15 G .92(ending a)270.892 505.8 R/F3 9/Times-Roman@0 SF(NOOP)3.42 E F1
+3.42(command. It)3.42 F .92(is not an error if this f)3.42 F(ails;)-.1 E
+(instead, the connection is closed and reopened.)102 517.8 Q -1 -.8(Tw o)127
+534 T .207(parameters control the connection cache.)3.506 F(The)5.207 E F0(k)
+2.707 E F1 .207(option de\214nes the number of simultane-)2.707 F 1.82
+(ous open connections that will be permitted.)102 546 R 1.819
+(If it is set to zero, connections will be closed as)6.82 F .795
+(quickly as possible.)102 558 R .796(The def)5.796 F .796(ault is one.)-.1 F
+.796(This should be set as appropriate for your system size; it)5.796 F
+(will limit the amount of system resources that)102 570 Q F2(sendmail)2.5 E F1
+(will use during queue runs.)2.5 E(The)127 586.2 Q F0(K)3.648 E F1 1.148
+(option speci\214es the maximum time that an)3.648 F 3.648(yc)-.15 G 1.148
+(ached connection will be permitted to)347.452 586.2 R 2.895(idle. When)102
+598.2 R .395(the idle time e)2.895 F .395(xceeds this v)-.15 F .396
+(alue the connection is closed.)-.25 F .396(This number should be small)5.396 F
+.163(\(under ten minutes\) to pre)102 610.2 R -.15(ve)-.25 G .163
+(nt you from grabbing too man).15 F 2.663(yr)-.15 G .162
+(esources from other hosts.)347.49 610.2 R .162(The def)5.162 F(ault)-.1 E
+(is \214v)102 622.2 Q 2.5(em)-.15 G(inutes.)136.3 622.2 Q F0 2.5(4.9. Name)87
+646.2 R(Ser)2.5 E -.1(ve)-.1 G 2.5(rA).1 G(ccess)172.33 646.2 Q F1 .421
+(If your system supports the name serv)127 662.4 R(er)-.15 E 2.921(,t)-.4 G
+.421(hen the probability is that)297.147 662.4 R F2(sendmail)2.921 E F1 .422
+(will be using it)2.922 F(re)102 674.4 Q -.05(ga)-.15 G 1.432(rdless of ho).05
+F 3.932(wy)-.25 G 1.432(ou con\214gure)184.436 674.4 R F2(sendmail)3.932 E F1
+6.432(.I)C 3.932(np)288.442 674.4 S(articular)302.374 674.4 Q 3.932(,t)-.4 G
+1.431(he system routine)344.506 674.4 R F2 -.1(ge)3.931 G(thostbyname).1 E F1
+1.431(\(3\) is)B .43(used to look up host names, and most v)102 686.4 R .431
+(endor v)-.15 F .431(ersions try some combination of DNS, NIS, and \214le)-.15
+F(lookup in /etc/hosts.)102 698.4 Q EP
+%%Page: 23 18
+%%BeginPageSetup
+BP
+%%EndPageSetup
+/F0 10/Times-Bold@0 SF(Sendmail Installation and Operation Guide)72 60 Q
+(SMM:08-23)452.9 60 Q/F1 10/Times-Roman@0 SF(Ho)127 96 Q(we)-.25 E -.15(ve)-.25
+G 2.12 -.4(r, i).15 H 3.82(fy).4 G 1.32(ou do not ha)183.85 96 R 1.62 -.15
+(ve a n)-.2 H(ameserv).15 E 1.32
+(er con\214gured at all, such as at a UUCP-only site,)-.15 F/F2 10
+/Times-Italic@0 SF(sendmail)102 108 Q F1 .14(will get a \231connection refused\
+\232 message when it tries to connect to the name serv)2.64 F .14(er \(either)
+-.15 F .915(indirectly by calling)102 120 R F2 -.1(ge)3.415 G(thostbyname).1 E
+F1 .915(or directly by looking up MX records\).)3.415 F .915(If the)5.915 F F0
+(I)3.415 E F1 .915(option is set,)3.415 F F2(sendmail)102 132 Q F1 .135
+(will interpret this to mean a temporary f)2.635 F .135
+(ailure and will queue the mail for later processing;)-.1 F .884
+(otherwise, it ignores the name serv)102 144 R .884(er data.)-.15 F .884
+(If your name serv)5.884 F .884(er is running properly)-.15 F 3.383(,t)-.65 G
+.883(he setting of)452.794 144 R 1.164(this option is not rele)102 156 R -.25
+(va)-.25 G 1.164(nt; ho).25 F(we)-.25 E -.15(ve)-.25 G 1.964 -.4(r, i).15 H
+3.664(ti).4 G 3.664(si)265.818 156 S 1.164
+(mportant that it be set properly to mak)276.152 156 R 3.665(ee)-.1 G 1.165
+(rror handling)450.345 156 R -.1(wo)102 168 S(rk properly).1 E(.)-.65 E .633
+(This option also allo)127 184.2 R .633(ws you to tweak name serv)-.25 F .633
+(er options.)-.15 F .632(The command line tak)5.633 F .632(es a series)-.1 F
+.442(of \215ags as documented in)102 196.2 R F2 -.37(re)2.942 G(solver).37 E F1
+.442(\(3\) \(with the leading \231RES_\232 deleted\).)B .442
+(Each can be preceded by)5.442 F(an optional `+' or `)102 208.2 Q/F3 10/Symbol
+SF(-)A F1 2.5('. F)B(or e)-.15 E(xample, the line)-.15 E(OIT)142 224.4 Q
+(rue +AA)-.35 E(ONL)-.55 E(Y)-1 E F3(-)2.5 E F1(DNSRCH)A .862(turns on the AA)
+102 240.6 R(ONL)-.55 E 3.362(Y\()-1 G .862(accept authoritati)201.658 240.6 R
+1.162 -.15(ve a)-.25 H .861(nswers only\) and turns of).15 F 3.361(ft)-.25 G
+.861(he DNSRCH \(search the)402.827 240.6 R 2.039(domain path\) options.)102
+252.6 R 2.039(Most resolv)7.039 F 2.039(er libraries def)-.15 F 2.039
+(ault DNSRCH, DEFN)-.1 F 2.039(AMES, and RECURSE)-.35 F .187
+(\215ags on and all others of)102 264.6 R 2.687(f. Note)-.25 F .186
+(the use of the initial `)2.686 F(`T)-.74 E(rue')-.35 E 2.686('\212t)-.74 G
+.186(his is for compatibility with pre)365.82 264.6 R(vi-)-.25 E(ous v)102
+276.6 Q(ersions of)-.15 E F2(sendmail)2.5 E F1 2.5(,b)C
+(ut is not otherwise necessary)210.81 276.6 Q(.)-.65 E -1.11(Ve)127 292.8 S
+2.256(rsion le)1.11 F -.15(ve)-.25 G 4.756(l1c).15 G 2.256
+(on\214gurations turn DNSRCH and DEFN)200.298 292.8 R 2.257(AMES of)-.35 F
+4.757(fw)-.25 G 2.257(hen doing deli)424.896 292.8 R -.15(ve)-.25 G(ry).15 E
+2.06(lookups, b)102 304.8 R 2.06(ut lea)-.2 F 2.36 -.15(ve t)-.2 H 2.06
+(hem on e).15 F -.15(ve)-.25 G 2.06(rywhere else.).15 F -1.11(Ve)7.06 G 2.06
+(rsion 8 of)1.11 F F2(sendmail)4.56 E F1 2.06(ignores them when doing)4.56 F
+.313(canoni\214cation lookups \(that is, when using $[ ... $]\), and al)102
+316.8 R -.1(wa)-.1 G .313(ys does the search.).1 F .313(If you don')5.313 F
+2.813(tw)-.18 G(ant)491.78 316.8 Q(to do automatic name e)102 328.8 Q
+(xtension, don')-.15 E 2.5(tc)-.18 G(all $[ ... $].)261.93 328.8 Q .189
+(The search rules for $[ ... $] are some)127 345 R .189(what dif)-.25 F .189
+(ferent than usual.)-.25 F .189(If the name \(that is, the `)5.189 F(`...)-.74
+E -.74('')-.7 G(\)).74 E .109(has at least one dot, it al)102 357 R -.1(wa)-.1
+G .109(ys tries the unmodi\214ed name \214rst.).1 F .11(If that f)5.11 F .11
+(ails, it tries the reduced search)-.1 F .124
+(path, and lastly tries the unmodi\214ed name \(b)102 369 R .124
+(ut only for names without a dot, since names with a dot)-.2 F(ha)102 381 Q
+.788 -.15(ve a)-.2 H .488(lready been tried\).).15 F .488(This allo)5.488 F
+.489(ws names such as `)-.25 F(`utc.CS')-.74 E 2.989('t)-.74 G 2.989(om)362.805
+381 S .489(atch the site in Czechoslo)378.574 381 R -.25(va)-.15 G(kia).25 E
+1.588(rather than the site in your local Computer Science department.)102 393 R
+1.587(It also prefers A and CN)6.587 F(AME)-.35 E .512(records o)102 405 R -.15
+(ve)-.15 G 3.012(rM).15 G 3.012(Xr)163.814 405 S .512
+(ecords \212 that is, if it \214nds an MX record it mak)177.376 405 R .513
+(es note of it, b)-.1 F .513(ut k)-.2 F .513(eeps looking.)-.1 F 1.542(This w)
+102 417 R(ay)-.1 E 4.042(,i)-.65 G 4.042(fy)149.054 417 S 1.541(ou ha)161.426
+417 R 1.841 -.15(ve a w)-.2 H 1.541
+(ildcard MX record matching your domain, it will not assume that all).15 F
+(names match.)102 429 Q F0 2.5(4.10. Mo)87 453 R(ving the P)-.1 E(er)-.2 E
+(-User F)-.37 E(orward Files)-.25 E F1 .772(Some sites mount each user')127
+469.2 R 3.272(sh)-.55 G .772(ome directory from a local disk on their w)256.13
+469.2 R .772(orkstation, so that)-.1 F .576(local access is f)102 481.2 R 3.076
+(ast. Ho)-.1 F(we)-.25 E -.15(ve)-.25 G 1.376 -.4(r, t).15 H .575
+(he result is that .forw).4 F .575(ard \214le lookups are slo)-.1 F 4.375 -.65
+(w. I)-.25 H 3.075(ns).65 G .575(ome cases, mail)439.25 481.2 R .216(can e)102
+493.2 R -.15(ve)-.25 G 2.716(nb).15 G 2.716(ed)144.792 493.2 S(eli)156.948
+493.2 Q -.15(ve)-.25 G .216
+(red on machines inappropriately because of a \214le serv).15 F .216
+(er being do)-.15 F 2.716(wn. The)-.25 F(perfor)2.716 E(-)-.2 E
+(mance can be especially bad if you run the automounter)102 505.2 Q(.)-.55 E
+(The)127 521.4 Q F0(J)2.5 E F1(option allo)2.5 E(ws you to set a path of forw)
+-.25 E(ard \214les.)-.1 E -.15(Fo)5 G 2.5(re).15 G
+(xample, the con\214g \214le line)366.6 521.4 Q(OJ/v)142 537.6 Q(ar/forw)-.25 E
+(ard/$u:$z/.forw)-.1 E(ard)-.1 E -.1(wo)102 553.8 S .208
+(uld \214rst look for a \214le with the same name as the user').1 F 2.707(sl)
+-.55 G .207(ogin in /v)343.191 553.8 R(ar/forw)-.25 E .207
+(ard; if that is not found)-.1 F .129
+(\(or is inaccessible\) the \214le \231.forw)102 565.8 R .129
+(ard\232 in the user')-.1 F 2.629(sh)-.55 G .13(ome directory is searched.)
+311.901 565.8 R 2.63(At)5.13 G .13(ruly perv)435.02 565.8 R .13(erse site)-.15
+F(could also search by sender by using $r)102 577.8 Q 2.5(,$)-.4 G(s, or $f.)
+269.07 577.8 Q .69(If you create a directory such as /v)127 594 R(ar/forw)-.25
+E .69(ard, it should be mode 1777 \(that is, the stick)-.1 F 3.19(yb)-.15 G(it)
+498.44 594 Q(should be set\).)102 606 Q
+(Users should create the \214les mode 644.)5 E F0 2.5(4.11. Fr)87 630 R
+(ee Space)-.18 E F1 1.122(On systems that ha)127 646.2 R 1.422 -.15(ve t)-.2 H
+(he).15 E F2(statfs)3.622 E F1 1.123
+(\(2\) system call, you can specify a minimum number of free)B .61
+(blocks on the queue \214lesystem using the)102 658.2 R F0(b)3.11 E F1 3.11
+(option. If)3.11 F .61(there are fe)3.11 F .61
+(wer than the indicated number of)-.25 F .406
+(blocks free on the \214lesystem on which the queue is mounted the SMTP serv)
+102 670.2 R .407(er will reject mail with)-.15 F(the 452 error code.)102 682.2
+Q(This in)5 E(vites the SMTP client to try ag)-.4 E(ain later)-.05 E(.)-.55 E
+(Be)127 698.4 Q -.1(wa)-.25 G .746(re of setting this option too high; it can \
+cause rejection of email when that mail w).1 F(ould)-.1 E
+(be processed without dif)102 710.4 Q(\214culty)-.25 E(.)-.65 E EP
+%%Page: 24 19
+%%BeginPageSetup
+BP
+%%EndPageSetup
+/F0 10/Times-Bold@0 SF 193.36(SMM:08-24 Sendmail)72 60 R
+(Installation and Operation Guide)2.5 E/F1 10/Times-Roman@0 SF 1.772
+(This option can also specify an adv)127 96 R 1.773
+(ertised \231maximum message size\232 for hosts that speak)-.15 F(ESMTP)102 108
+Q(.)-1.11 E F0 2.5(4.12. Pri)87 132 R -.1(va)-.1 G(cy Flags).1 E F1(The)127
+148.2 Q F0(p)3.591 E F1 1.091(option allo)3.591 F 1.091
+(ws you to set certain `)-.25 F(`pri)-.74 E -.25(va)-.25 G -.15(cy).25 G 2.571
+-.74('' \215).15 H 3.591(ags. Actually).74 F 3.59(,m)-.65 G(an)409.27 148.2 Q
+3.59(yo)-.15 G 3.59(ft)432.15 148.2 S 1.09(hem don')441.85 148.2 R 3.59(tg)-.18
+G -2.15 -.25(iv e)492.18 148.2 T .254(you an)102 160.2 R 2.754(ye)-.15 G .254
+(xtra pri)141.088 160.2 R -.25(va)-.25 G -.15(cy).25 G 2.754(,r)-.5 G .254
+(ather just insisting that client SMTP serv)196.666 160.2 R .254
+(ers use the HELO command before)-.15 F(using certain commands.)102 172.2 Q
+.124(The option tak)127 188.4 R .124
+(es a series of \215ag names; the \214nal pri)-.1 F -.25(va)-.25 G .424 -.15
+(cy i).25 H 2.624(st).15 G .124(he inclusi)367.708 188.4 R .424 -.15(ve o)-.25
+H 2.624(ro).15 G 2.624(ft)434.06 188.4 S .123(hose \215ags.)442.794 188.4 R
+-.15(Fo)5.123 G(r).15 E -.15(ex)102 200.4 S(ample:).15 E(Op needmailhelo, noe)
+142 216.6 Q(xpn)-.15 E .928(insists that the HELO or EHLO command be used befo\
+re a MAIL command is accepted and dis-)102 232.8 R(ables the EXPN command.)102
+244.8 Q .244(The \231restrictmailq\232 option restricts printing the queue to \
+the group that o)127 261 R .244(wns the queue direc-)-.25 F(tory)102 273 Q 5
+(.I)-.65 G 2.5(ti)128.29 273 S 2.5(sa)136.35 273 S
+(bsurd to set this if you don')147.18 273 Q 2.5(ta)-.18 G
+(lso protect the logs.)266.72 273 Q .83(The \231restrictqrun\232 option restri\
+cts people running the queue \(that is, using the)127 289.2 R F0<ad71>3.33 E F1
+(command)3.33 E(line \215ag\) to root and the o)102 301.2 Q
+(wner of the queue directory)-.25 E(.)-.65 E F0 2.5(4.13. Send)87 325.2 R
+(to Me T)2.5 E(oo)-.92 E F1(Normally)127 341.4 Q(,)-.65 E/F2 10/Times-Italic@0
+SF(sendmail)3.424 E F1 .924(deletes the \(en)3.424 F -.15(ve)-.4 G .923
+(lope\) sender from an).15 F 3.423(yl)-.15 G .923(ist e)375.488 341.4 R 3.423
+(xpansions. F)-.15 F .923(or e)-.15 F .923(xample, if)-.15 F .761(\231matt\232\
+ sends to a list that contains \231matt\232 as one of the members he w)102
+353.4 R(on')-.1 E 3.261(tg)-.18 G .761(et a cop)416.705 353.4 R 3.261(yo)-.1 G
+3.261(ft)462.488 353.4 S .761(he mes-)471.859 353.4 R 3.067(sage. If)102 365.4
+R(the)3.067 E F0<ad6d>3.067 E F1 .567
+(\(me too\) command line \215ag, or if the)3.067 F F0(m)3.066 E F1 .566
+(option is set in the con\214guration \214le, this)3.066 F(beha)102 377.4 Q
+(viour is supressed.)-.2 E(Some sites lik)5 E 2.5(et)-.1 G 2.5(or)265.58 377.4
+S(un the)276.41 377.4 Q/F3 9/Times-Roman@0 SF(SMTP)2.5 E F1(daemon with)2.5 E
+F0<ad6d>2.5 E F1(.)A F0 2.5(5. THE)72 401.4 R(WHOLE SCOOP ON THE CONFIGURA)2.5
+E(TION FILE)-.95 E F1 .264(This section describes the con\214guration \214le i\
+n detail, including hints on ho)112 417.6 R 2.764(wt)-.25 G 2.764(ow)426.294
+417.6 S .264(rite one of your)441.278 417.6 R -.25(ow)87 429.6 S 2.5(ni).25 G
+2.5(fy)109.25 429.6 S(ou ha)120.08 429.6 Q .3 -.15(ve t)-.2 H(o.).15 E .648(Th\
+ere is one point that should be made clear immediately: the syntax of the con\
+\214guration \214le is)112 445.8 R 1.076
+(designed to be reasonably easy to parse, since this is done e)87 457.8 R -.15
+(ve)-.25 G 1.077(ry time).15 F F2(sendmail)3.577 E F1 1.077
+(starts up, rather than)3.577 F(easy for a human to read or write.)87 469.8 Q
+(On the \231future project\232 list is a con\214guration-\214le compiler)5 E(.)
+-.55 E(An o)112 486 Q -.15(ve)-.15 G(rvie).15 E 2.5(wo)-.25 G 2.5(ft)170.88 486
+S(he con\214guration \214le is gi)179.49 486 Q -.15(ve)-.25 G 2.5<6e8c>.15 G
+(rst, follo)301.59 486 Q(wed by details of the semantics.)-.25 E F0 2.5
+(5.1. Con\214guration)87 510 R(File Lines)2.5 E F1 1.316
+(The con\214guration \214le is or)127 526.2 R -.05(ga)-.18 G 1.316
+(nized as a series of lines, each of which be).05 F 1.315(gins with a single)
+-.15 F .741(character de\214ning the semantics for the rest of the line.)102
+538.2 R .742(Lines be)5.742 F .742(ginning with a space or a tab are)-.15 F
+1.149
+(continuation lines \(although the semantics are not well de\214ned in man)102
+550.2 R 3.648(yp)-.15 G 3.648(laces\). Blank)407.516 550.2 R 1.148(lines and)
+3.648 F(lines be)102 562.2 Q(ginning with a sharp symbol \(`#'\) are comments.)
+-.15 E F0 2.5(5.1.1. R)102 586.2 R(and S \212 r)2.5 E(ewriting rules)-.18 E F1
+.406(The core of address parsing are the re)142 602.4 R .406(writing rules.)
+-.25 F .407(These are an ordered production sys-)5.407 F(tem.)117 614.4 Q F2
+(Sendmail)5.283 E F1 .283(scans through the set of re)2.783 F .282
+(writing rules looking for a match on the left hand side)-.25 F .131
+(\(LHS\) of the rule.)117 626.4 R .131(When a rule matches, the address is rep\
+laced by the right hand side \(RHS\) of)5.131 F(the rule.)117 638.4 Q 1.126
+(There are se)142 654.6 R -.15(ve)-.25 G 1.126(ral sets of re).15 F 1.126
+(writing rules.)-.25 F 1.126(Some of the re)6.126 F 1.125
+(writing sets are used internally)-.25 F .21(and must ha)117 666.6 R .51 -.15
+(ve s)-.2 H .21(peci\214c semantics.).15 F .21(Other re)5.21 F .21
+(writing sets do not ha)-.25 F .51 -.15(ve s)-.2 H .21
+(peci\214cally assigned seman-).15 F
+(tics, and may be referenced by the mailer de\214nitions or by other re)117
+678.6 Q(writing sets.)-.25 E(The syntax of these tw)142 694.8 Q 2.5(oc)-.1 G
+(ommands are:)244.38 694.8 Q F0(S)157 711 Q F2(n)A EP
+%%Page: 25 20
+%%BeginPageSetup
+BP
+%%EndPageSetup
+/F0 10/Times-Bold@0 SF(Sendmail Installation and Operation Guide)72 60 Q
+(SMM:08-25)452.9 60 Q/F1 10/Times-Roman@0 SF .278
+(Sets the current ruleset being collected to)117 96 R/F2 10/Times-Italic@0 SF
+(n)2.778 E F1 5.278(.I)C 2.778(fy)302.524 96 S .278(ou be)313.632 96 R .278
+(gin a ruleset more than once it deletes the)-.15 F(old de\214nition.)117 108 Q
+F0(R)157 124.2 Q F2(lhs rhs comments)A F1 .303(The \214elds must be separated \
+by at least one tab character; there may be embedded spaces in the)117 140.4 R
+2.739(\214elds. The)117 152.4 R F2(lhs)2.739 E F1 .239
+(is a pattern that is applied to the input.)2.739 F .238
+(If it matches, the input is re)5.238 F .238(written to the)-.25 F F2(rhs)117
+164.4 Q F1 5(.T)C(he)143.39 164.4 Q F2(comments)2.5 E F1(are ignored.)2.5 E
+2.265(Macro e)142 180.6 R 2.265(xpansions of the form)-.15 F F0($)4.765 E F2(x)
+A F1 2.266(are performed when the con\214guration \214le is read.)4.765 F .081
+(Expansions of the form)117 192.6 R F0($&)2.581 E F2(x)A F1 .081
+(are performed at run time using a some)2.581 F .08
+(what less general algorithm.)-.25 F .639
+(This for is intended only for referencing internally de\214ned macros such as)
+117 204.6 R F0($h)3.139 E F1 .639(that are changed)3.139 F(at runtime.)117
+216.6 Q F0 2.5(5.1.1.1. The)117 240.6 R(left hand side)2.5 E F1 1.617
+(The left hand side of re)157 256.8 R 1.617(writing rules contains a pattern.)
+-.25 F 1.617(Normal w)6.617 F 1.617(ords are simply)-.1 F(matched directly)132
+268.8 Q 5(.M)-.65 G(etasyntax is introduced using a dollar sign.)214.67 268.8 Q
+(The metasymbols are:)5 E F0($*)172 285 Q F1(Match zero or more tok)192.14 285
+Q(ens)-.1 E F0($+)172 297 Q F1(Match one or more tok)9.44 E(ens)-.1 E F0<24ad>
+172 309 Q F1(Match e)9.44 E(xactly one tok)-.15 E(en)-.1 E F0($=)172 321 Q F2
+(x)A F1(Match an)5 E 2.5(yp)-.15 G(hrase in class)241.98 321 Q F2(x)2.5 E F0
+($~)172 333 Q F2(x)A F1(Match an)7.37 E 2.5(yw)-.15 G(ord not in class)244.1
+333 Q F2(x)2.5 E F1 .498(If an)132 349.2 R 2.998(yo)-.15 G 2.998(ft)163.946
+349.2 S .499(hese match, the)173.054 349.2 R 2.999(ya)-.15 G .499
+(re assigned to the symbol)248.271 349.2 R F0($)2.999 E F2(n)A F1 .499
+(for replacement on the right hand)2.999 F(side, where)132 361.2 Q F2(n)2.5 E
+F1(is the inde)2.5 E 2.5(xi)-.15 G 2.5(nt)238.78 361.2 S(he LHS.)249.06 361.2 Q
+-.15(Fo)5 G 2.5(re).15 G(xample, if the LHS:)307.92 361.2 Q($\255:$+)172 377.4
+Q(is applied to the input:)132 393.6 Q(UCB)172 409.8 Q(ARP)-.35 E(A:eric)-.92 E
+(the rule will match, and the v)132 426 Q(alues passed to the RHS will be:)-.25
+E 7.5($1 UCB)172 442.2 R(ARP)-.35 E(A)-.92 E 7.5($2 eric)172 454.2 R
+(Additionally)157 474.6 Q 3.398(,t)-.65 G .898(he LHS can include)215.588 474.6
+R F0($@)3.398 E F1 .898(to match zero tok)3.398 F 3.398(ens. This)-.1 F(is)
+3.398 E F2(not)3.398 E F1 .898(bound to a)3.398 F F0($)132 486.6 Q F2(N)A F1
+.837(on the RHS, and is normally only used when it stands alone in order to ma\
+tch the null)3.337 F(input.)132 498.6 Q F0 2.5(5.1.1.2. The)117 522.6 R
+(right hand side)2.5 E F1 .526(When the left hand side of a re)157 538.8 R .525
+(writing rule matches, the input is deleted and replaced)-.25 F .931
+(by the right hand side.)132 550.8 R -.8(To)5.932 G -.1(ke).8 G .932
+(ns are copied directly from the RHS unless the).1 F 3.432(yb)-.15 G -.15(eg)
+457.846 550.8 S .932(in with a).15 F(dollar sign.)132 562.8 Q(Metasymbols are:)
+5 E F0($)172 579 Q F2(n)A F1(Substitute inde\214nite tok)222.55 579 Q(en)-.1 E
+F2(n)2.5 E F1(from LHS)2.5 E F0($[)172 591 Q F2(name)A F0($])A F1(Canonicalize)
+222.55 591 Q F2(name)2.5 E F0($\()172 603 Q F2(map k)A -.3(ey)-.1 G F0($@)2.8 E
+F2(ar)A(guments)-.37 E F0($:)2.5 E F2(default)A F0($\))2.5 E F1(Generalized k)
+222.55 615 Q -.15(ey)-.1 G(ed mapping function).15 E F0($>)172 627 Q F2(n)A F1
+(\231Call\232 ruleset)222.55 627 Q F2(n)2.5 E F0($#)172 639 Q F2(mailer)A F1
+(Resolv)222.55 639 Q 2.5(et)-.15 G(o)259.9 639 Q F2(mailer)2.5 E F0($@)172 651
+Q F2(host)A F1(Specify)222.55 651 Q F2(host)2.5 E F0($:)172 663 Q F2(user)A F1
+(Specify)222.55 663 Q F2(user)2.5 E F1(The)157 683.4 Q F0($)3.013 E F2(n)A F1
+.513(syntax substitutes the corresponding v)3.013 F .513(alue from a)-.25 F F0
+($+)3.013 E F1(,)A F0<24ad>3.013 E F1(,)A F0($*)3.012 E F1(,)A F0($=)3.012 E F1
+3.012(,o)C(r)461.876 683.4 Q F0($~)3.012 E F1(match)3.012 E(on the LHS.)132
+695.4 Q(It may be used an)5 E(ywhere.)-.15 E 2.7(Ah)157 711.6 S .2
+(ost name enclosed between)171.92 711.6 R F0($[)2.7 E F1(and)2.7 E F0($])2.7 E
+F1 .2(is look)2.7 F .201(ed up using the)-.1 F F2 -.1(ge)2.701 G(thostent).1 E
+F1 .201(\(3\) routines)1.666 F EP
+%%Page: 26 21
+%%BeginPageSetup
+BP
+%%EndPageSetup
+/F0 10/Times-Bold@0 SF 193.36(SMM:08-26 Sendmail)72 60 R
+(Installation and Operation Guide)2.5 E/F1 10/Times-Roman@0 SF 3.333
+(and replaced by the canonical name)132 98 R/F2 7/Times-Roman@0 SF(8)291.675 94
+Q F1 8.333(.F)295.175 98 S 3.333(or e)311.418 98 R 3.332
+(xample, \231$[csam$]\232 might become \231lbl-)-.15 F 1.923
+(csam.arpa\232 and \231$[[128.32.130.2]$]\232 w)132 110 R 1.923
+(ould become \231v)-.1 F(angogh.CS.Berk)-.25 E(ele)-.1 E -.65(y.)-.15 G(EDU.)
+.65 E<9a>-.7 E/F3 10/Times-Italic@0 SF(Send-)6.924 E(mail)132 122 Q F1 .436
+(recognizes it')2.936 F 2.936(sn)-.55 G .436
+(umeric IP address without calling the name serv)218.578 122 R .435
+(er and replaces it with)-.15 F(it')132 134 Q 2.5(sc)-.55 G(anonical name.)
+151.17 134 Q(The)157 150.2 Q F0($\()2.861 E F1(...)2.861 E F0($\))5.361 E F1
+.361(syntax is a more general form of lookup; it uses a named map instead of)
+2.861 F .028(an implicit map.)132 162.2 R .027
+(If no lookup is found, the indicated)5.027 F F3(default)2.527 E F1 .027
+(is inserted; if no def)2.527 F .027(ault is spec-)-.1 F
+(i\214ed and no lookup matches, the v)132 174.2 Q(alue is left unchanged.)-.25
+E(The)157 190.4 Q F0($>)3.571 E F3(n)A F1 1.071
+(syntax causes the remainder of the line to be substituted as usual and then)
+3.571 F .572(passed as the ar)132 202.4 R .572(gument to ruleset)-.18 F F3(n)
+3.072 E F1 5.572(.T)C .572(he \214nal v)288.854 202.4 R .572(alue of ruleset)
+-.25 F F3(n)3.072 E F1 .571(then becomes the substitu-)3.072 F
+(tion for this rule.)132 214.4 Q(The)157 230.6 Q F0($#)3.358 E F1 .858
+(syntax should)3.358 F F3(only)3.358 E F1 .858
+(be used in ruleset zero or a subroutine of ruleset zero.)3.358 F(It)5.859 E
+1.1(causes e)132 242.6 R -.25(va)-.25 G 1.1
+(luation of the ruleset to terminate immediately).25 F 3.6(,a)-.65 G 1.1
+(nd signals to)377.11 242.6 R F3(sendmail)3.6 E F1 1.1(that the)3.6 F
+(address has completely resolv)132 254.6 Q 2.5(ed. The)-.15 F
+(complete syntax is:)2.5 E F0($#)172 270.8 Q F3(mailer)A F0($@)2.5 E F3(host)A
+F0($:)2.5 E F3(user)A F1 .394(This speci\214es the {mailer)132 287 R 2.894(,h)
+-.4 G .394(ost, user} 3-tuple necessary to direct the mailer)245.466 287 R
+5.394(.I)-.55 G 2.894(ft)447.548 287 S .394(he mailer is)456.552 287 R .135
+(local the host part may be omitted)132 301 R F2(9)268.91 297 Q F1 5.135(.T)
+272.41 301 S(he)286.155 301 Q F3(mailer)2.635 E F1 .136(must be a single w)
+2.636 F .136(ord, b)-.1 F .136(ut the)-.2 F F3(host)2.636 E F1(and)2.636 E F3
+(user)2.636 E F1 .252(may be multi-part.)132 313 R .252(If the)5.252 F F3
+(mailer)2.752 E F1 .252(is the b)2.752 F .252(uiltin IPC mailer)-.2 F 2.752(,t)
+-.4 G(he)369.722 313 Q F3(host)2.752 E F1 .251(may be a colon-separated)2.752 F
+2.439(list of hosts that are searched in order for the \214rst w)132 325 R
+2.439(orking address \(e)-.1 F 2.439(xactly lik)-.15 F 4.939(eM)-.1 G(X)496.78
+325 Q 5.185(records\). The)132 337 R F3(user)5.185 E F1 2.685(is later re)5.185
+F 2.685(written by the mailer)-.25 F 2.685(-speci\214c en)-.2 F -.15(ve)-.4 G
+2.685(lope re).15 F 2.685(writing set and)-.25 F .122(assigned to the)132 349 R
+F0($u)2.622 E F1 2.622(macro. As)2.622 F 2.622(as)2.622 G .123
+(pecial case, if the v)264.784 349 R .123(alue to)-.25 F F0($#)2.623 E F1 .123
+(is \231local\232 and the \214rst charac-)2.623 F .458(ter of the)132 361 R F0
+($:)2.958 E F1 -.25(va)2.958 G .458
+(lue is \231@\232, the \231@\232 is stripped of).25 F .457
+(f, and a \215ag is set in the address descriptor)-.25 F
+(that causes sendmail to not do ruleset 5 processing.)132 373 Q(Normally)157
+389.2 Q 3.593(,ar)-.65 G 1.093
+(ule that matches is retried, that is, the rule loops until it f)212.136 389.2
+R 3.594(ails. A)-.1 F(RHS)3.594 E .209(may also be preceded by a)132 401.2 R F0
+($@)2.709 E F1 .209(or a)2.709 F F0($:)2.708 E F1 .208(to change this beha)
+2.708 F(vior)-.2 E 5.208(.A)-.55 G F0($@)398.338 401.2 Q F1 .208
+(pre\214x causes the rule-)2.708 F .527
+(set to return with the remainder of the RHS as the v)132 413.2 R 3.027
+(alue. A)-.25 F F0($:)3.028 E F1 .528(pre\214x causes the rule to ter)3.028 F
+(-)-.2 E .295(minate immediately)132 425.2 R 2.795(,b)-.65 G .294
+(ut the ruleset to continue; this can be used to a)221.46 425.2 R -.2(vo)-.2 G
+.294(id continued applica-).2 F(tion of a rule.)132 437.2 Q
+(The pre\214x is stripped before continuing.)5 E(The)157 453.4 Q F0($@)2.5 E F1
+(and)2.5 E F0($:)2.5 E F1(pre\214x)2.5 E(es may precede a)-.15 E F0($>)2.5 E F1
+(spec; for e)2.5 E(xample:)-.15 E 20.19(R$+ $:)172 469.6 R($>7 $1)2.5 E .256
+(matches an)132 485.8 R .256(ything, passes that to ruleset se)-.15 F -.15(ve)
+-.25 G .256(n, and continues; the).15 F F0($:)2.756 E F1 .256
+(is necessary to a)2.756 F -.2(vo)-.2 G .256(id an).2 F(in\214nite loop.)132
+497.8 Q .051(Substitution occurs in the order described, that is, parameters f\
+rom the LHS are substi-)157 514 R .556(tuted, hostnames are canonicalized, \
+\231subroutines\232 are called, and \214nally)132 526 R F0($#)3.056 E F1(,)A F0
+($@)3.056 E F1 3.056(,a)C(nd)467.346 526 Q F0($:)3.057 E F1(are)3.057 E
+(processed.)132 538 Q F0 2.5(5.1.1.3. Semantics)117 562 R(of r)2.5 E
+(ewriting rule sets)-.18 E F1 2.922(There are \214v)157 578.2 R 5.422(er)-.15 G
+-.25(ew)226.976 578.2 S 2.922(riting sets that ha).25 F 3.222 -.15(ve s)-.2 H
+2.922(peci\214c semantics.).15 F 2.921(These are related as)7.921 F
+(depicted by \214gure 2.)132 590.2 Q 1.091
+(Ruleset three should turn the address into \231canonical form.)157 606.4 R
+6.092<9a54>-.7 G 1.092(his form should ha)416.914 606.4 R -.15(ve)-.2 G
+(the basic syntax:)132 618.4 Q(local-part@host-domain-spec)172 634.6 Q 1.296
+(If no \231@\232 sign is speci\214ed, then the host-domain-spec)132 650.8 R F3
+(may)3.796 E F1 1.295(be appended from the sender)3.796 F 1.284
+(address \(if the)132 662.8 R F0(C)3.784 E F1 1.284
+(\215ag is set in the mailer de\214nition corresponding to the)3.784 F F3
+(sending)3.784 E F1(mailer\).)3.784 E .32 LW 76 672.4 72 672.4 DL 80 672.4 76
+672.4 DL 84 672.4 80 672.4 DL 88 672.4 84 672.4 DL 92 672.4 88 672.4 DL 96
+672.4 92 672.4 DL 100 672.4 96 672.4 DL 104 672.4 100 672.4 DL 108 672.4 104
+672.4 DL 112 672.4 108 672.4 DL 116 672.4 112 672.4 DL 120 672.4 116 672.4 DL
+124 672.4 120 672.4 DL 128 672.4 124 672.4 DL 132 672.4 128 672.4 DL 136 672.4
+132 672.4 DL 140 672.4 136 672.4 DL 144 672.4 140 672.4 DL 148 672.4 144 672.4
+DL 152 672.4 148 672.4 DL 156 672.4 152 672.4 DL 160 672.4 156 672.4 DL 164
+672.4 160 672.4 DL 168 672.4 164 672.4 DL 172 672.4 168 672.4 DL 176 672.4 172
+672.4 DL 180 672.4 176 672.4 DL 184 672.4 180 672.4 DL 188 672.4 184 672.4 DL
+192 672.4 188 672.4 DL 196 672.4 192 672.4 DL 200 672.4 196 672.4 DL 204 672.4
+200 672.4 DL 208 672.4 204 672.4 DL 212 672.4 208 672.4 DL 216 672.4 212 672.4
+DL/F4 5/Times-Roman@0 SF(8)93.6 682.8 Q/F5 8/Times-Roman@0 SF
+(This is actually completely equi)3.2 I -.2(va)-.2 G(lent to $\(host).2 E/F6 8
+/Times-Italic@0 SF(hostname)2 E F5 2($\). In)B(particular)2 E 2(,a)-.32 G/F7 8
+/Times-Bold@0 SF($:)A F5(def)2 E(ault can be used.)-.08 E F4(9)93.6 696.4 Q F5
+-.88(Yo)3.2 K 2.208(um).88 G .208(ay w)117.428 699.6 R .208
+(ant to use it for special \231per user\232 e)-.08 F 2.208(xtensions. F)-.12 F
+.208(or e)-.12 F .208
+(xample, at CMU you can send email to \231jgm+foo\232; the part af-)-.12 F(ter\
+ the plus sign is not part of the user name, and is passed to the local mailer\
+ for local use.)72 709.2 Q EP
+%%Page: 27 22
+%%BeginPageSetup
+BP
+%%EndPageSetup
+/F0 10/Times-Bold@0 SF(Sendmail Installation and Operation Guide)72 60 Q
+(SMM:08-27)452.9 60 Q .4 LW 77 108 72 108 DL 79 108 74 108 DL 84 108 79 108 DL
+89 108 84 108 DL 94 108 89 108 DL 99 108 94 108 DL 104 108 99 108 DL 109 108
+104 108 DL 114 108 109 108 DL 119 108 114 108 DL 124 108 119 108 DL 129 108 124
+108 DL 134 108 129 108 DL 139 108 134 108 DL 144 108 139 108 DL 149 108 144 108
+DL 154 108 149 108 DL 159 108 154 108 DL 164 108 159 108 DL 169 108 164 108 DL
+174 108 169 108 DL 179 108 174 108 DL 184 108 179 108 DL 189 108 184 108 DL 194
+108 189 108 DL 199 108 194 108 DL 204 108 199 108 DL 209 108 204 108 DL 214 108
+209 108 DL 219 108 214 108 DL 224 108 219 108 DL 229 108 224 108 DL 234 108 229
+108 DL 239 108 234 108 DL 244 108 239 108 DL 249 108 244 108 DL 254 108 249 108
+DL 259 108 254 108 DL 264 108 259 108 DL 269 108 264 108 DL 274 108 269 108 DL
+279 108 274 108 DL 284 108 279 108 DL 289 108 284 108 DL 294 108 289 108 DL 299
+108 294 108 DL 304 108 299 108 DL 309 108 304 108 DL 314 108 309 108 DL 319 108
+314 108 DL 324 108 319 108 DL 329 108 324 108 DL 334 108 329 108 DL 339 108 334
+108 DL 344 108 339 108 DL 349 108 344 108 DL 354 108 349 108 DL 359 108 354 108
+DL 364 108 359 108 DL 369 108 364 108 DL 374 108 369 108 DL 379 108 374 108 DL
+384 108 379 108 DL 389 108 384 108 DL 394 108 389 108 DL 399 108 394 108 DL 404
+108 399 108 DL 409 108 404 108 DL 414 108 409 108 DL 419 108 414 108 DL 424 108
+419 108 DL 429 108 424 108 DL 434 108 429 108 DL 439 108 434 108 DL 444 108 439
+108 DL 449 108 444 108 DL 454 108 449 108 DL 459 108 454 108 DL 464 108 459 108
+DL 469 108 464 108 DL 474 108 469 108 DL 479 108 474 108 DL 484 108 479 108 DL
+489 108 484 108 DL 494 108 489 108 DL 499 108 494 108 DL 504 108 499 108 DL/F1
+10/Times-Roman@0 SF(addr)91.915 202.4 Q 133.2 200.4 111.6 200.4 DL 133.2 200.4
+126 202.2 DL 133.2 200.4 126 198.6 DL(3)141.5 202.4 Q 133.2 189.6 133.2 211.2
+DL 154.8 189.6 133.2 189.6 DL 154.8 211.2 154.8 189.6 DL 133.2 211.2 154.8
+211.2 DL 176.4 200.4 154.8 200.4 DL 176.4 200.4 169.2 202.2 DL 176.4 200.4
+169.2 198.6 DL(D)183.59 202.4 Q 176.4 189.6 176.4 211.2 DL 198 189.6 176.4
+189.6 DL 198 211.2 198 189.6 DL 176.4 211.2 198 211.2 DL 219.6 200.4 198 200.4
+DL 277.2 182.4 255.6 182.4 DL 277.2 182.4 270 184.2 DL 277.2 182.4 270 180.6 DL
+(1)285.5 184.4 Q 277.2 171.6 277.2 193.2 DL 298.8 171.6 277.2 171.6 DL 298.8
+193.2 298.8 171.6 DL 277.2 193.2 298.8 193.2 DL 320.4 182.4 298.8 182.4 DL
+320.4 182.4 313.2 184.2 DL 320.4 182.4 313.2 180.6 DL(S)328.42 184.4 Q 320.4
+171.6 320.4 193.2 DL 342 171.6 320.4 171.6 DL 342 193.2 342 171.6 DL 320.4
+193.2 342 193.2 DL 363.6 182.4 342 182.4 DL 277.2 218.4 255.6 218.4 DL 277.2
+218.4 270 220.2 DL 277.2 218.4 270 216.6 DL(2)285.5 220.4 Q 277.2 207.6 277.2
+229.2 DL 298.8 207.6 277.2 207.6 DL 298.8 229.2 298.8 207.6 DL 277.2 229.2
+298.8 229.2 DL 320.4 218.4 298.8 218.4 DL 320.4 218.4 313.2 220.2 DL 320.4
+218.4 313.2 216.6 DL(R)327.865 220.4 Q 320.4 207.6 320.4 229.2 DL 342 207.6
+320.4 207.6 DL 342 229.2 342 207.6 DL 320.4 229.2 342 229.2 DL 363.6 218.4 342
+218.4 DL 421.2 200.4 399.6 200.4 DL 421.2 200.4 414 202.2 DL 421.2 200.4 414
+198.6 DL(4)429.5 202.4 Q 421.2 189.6 421.2 211.2 DL 442.8 189.6 421.2 189.6 DL
+442.8 211.2 442.8 189.6 DL 421.2 211.2 442.8 211.2 DL 464.4 200.4 442.8 200.4
+DL 464.4 200.4 457.2 202.2 DL 464.4 200.4 457.2 198.6 DL(msg)466.865 202.4 Q
+255.6 182.4 219.6 200.4 DL 255.6 218.4 219.6 200.4 DL 399.6 200.4 363.6 182.4
+DL 399.6 200.4 363.6 218.4 DL 208.8 146.4 187.2 146.4 DL 208.8 146.4 201.6
+148.2 DL 208.8 146.4 201.6 144.6 DL(0)217.1 148.4 Q 208.8 135.6 208.8 157.2 DL
+230.4 135.6 208.8 135.6 DL 230.4 157.2 230.4 135.6 DL 208.8 157.2 230.4 157.2
+DL 252 146.4 230.4 146.4 DL 252 146.4 244.8 148.2 DL 252 146.4 244.8 144.6 DL
+(resolv)265.69 148.4 Q(ed address)-.15 E 187.2 146.4 162 200.4 DL
+(Figure 2 \212 Re)216.045 248.4 Q(writing set semantics)-.25 E 2.5(D\212s)
+209.35 260.4 S(ender domain addition)235.46 260.4 Q 2.5(S\212m)209.35 272.4 S
+(ailer)237.69 272.4 Q(-speci\214c sender re)-.2 E(writing)-.25 E 2.5(R\212m)
+209.35 284.4 S(ailer)238.8 284.4 Q(-speci\214c recipient re)-.2 E(writing)-.25
+E 77 296.4 72 296.4 DL 79 296.4 74 296.4 DL 84 296.4 79 296.4 DL 89 296.4 84
+296.4 DL 94 296.4 89 296.4 DL 99 296.4 94 296.4 DL 104 296.4 99 296.4 DL 109
+296.4 104 296.4 DL 114 296.4 109 296.4 DL 119 296.4 114 296.4 DL 124 296.4 119
+296.4 DL 129 296.4 124 296.4 DL 134 296.4 129 296.4 DL 139 296.4 134 296.4 DL
+144 296.4 139 296.4 DL 149 296.4 144 296.4 DL 154 296.4 149 296.4 DL 159 296.4
+154 296.4 DL 164 296.4 159 296.4 DL 169 296.4 164 296.4 DL 174 296.4 169 296.4
+DL 179 296.4 174 296.4 DL 184 296.4 179 296.4 DL 189 296.4 184 296.4 DL 194
+296.4 189 296.4 DL 199 296.4 194 296.4 DL 204 296.4 199 296.4 DL 209 296.4 204
+296.4 DL 214 296.4 209 296.4 DL 219 296.4 214 296.4 DL 224 296.4 219 296.4 DL
+229 296.4 224 296.4 DL 234 296.4 229 296.4 DL 239 296.4 234 296.4 DL 244 296.4
+239 296.4 DL 249 296.4 244 296.4 DL 254 296.4 249 296.4 DL 259 296.4 254 296.4
+DL 264 296.4 259 296.4 DL 269 296.4 264 296.4 DL 274 296.4 269 296.4 DL 279
+296.4 274 296.4 DL 284 296.4 279 296.4 DL 289 296.4 284 296.4 DL 294 296.4 289
+296.4 DL 299 296.4 294 296.4 DL 304 296.4 299 296.4 DL 309 296.4 304 296.4 DL
+314 296.4 309 296.4 DL 319 296.4 314 296.4 DL 324 296.4 319 296.4 DL 329 296.4
+324 296.4 DL 334 296.4 329 296.4 DL 339 296.4 334 296.4 DL 344 296.4 339 296.4
+DL 349 296.4 344 296.4 DL 354 296.4 349 296.4 DL 359 296.4 354 296.4 DL 364
+296.4 359 296.4 DL 369 296.4 364 296.4 DL 374 296.4 369 296.4 DL 379 296.4 374
+296.4 DL 384 296.4 379 296.4 DL 389 296.4 384 296.4 DL 394 296.4 389 296.4 DL
+399 296.4 394 296.4 DL 404 296.4 399 296.4 DL 409 296.4 404 296.4 DL 414 296.4
+409 296.4 DL 419 296.4 414 296.4 DL 424 296.4 419 296.4 DL 429 296.4 424 296.4
+DL 434 296.4 429 296.4 DL 439 296.4 434 296.4 DL 444 296.4 439 296.4 DL 449
+296.4 444 296.4 DL 454 296.4 449 296.4 DL 459 296.4 454 296.4 DL 464 296.4 459
+296.4 DL 469 296.4 464 296.4 DL 474 296.4 469 296.4 DL 479 296.4 474 296.4 DL
+484 296.4 479 296.4 DL 489 296.4 484 296.4 DL 494 296.4 489 296.4 DL 499 296.4
+494 296.4 DL 504 296.4 499 296.4 DL(Ruleset three is applied by)132 332.4 Q/F2
+10/Times-Italic@0 SF(sendmail)2.5 E F1(before doing an)2.5 E(ything with an)
+-.15 E 2.5(ya)-.15 G(ddress.)411.39 332.4 Q .506(Ruleset zero is applied after\
+ ruleset three to addresses that are going to actually spec-)157 348.6 R .295
+(ify recipients.)132 360.6 R .295(It must resolv)5.295 F 2.795(et)-.15 G 2.795
+(oa)258.035 360.6 S F2({mailer).001 E 2.796(,h)-1.11 G .296(ost, user})312.362
+360.6 R F1 2.796(triple. The)2.796 F F2(mailer)2.796 E F1 .296
+(must be de\214ned in)2.796 F .561
+(the mailer de\214nitions from the con\214guration \214le.)132 372.6 R(The)
+5.561 E F2(host)3.061 E F1 .56(is de\214ned into the)3.061 F F0($h)3.06 E F1
+.56(macro for)3.06 F(use in the ar)132 384.6 Q(gv e)-.18 E
+(xpansion of the speci\214ed mailer)-.15 E(.)-.55 E 1.356(Rulesets one and tw)
+157 400.8 R 3.856(oa)-.1 G 1.357
+(re applied to all sender and recipient addresses respecti)254.534 400.8 R -.15
+(ve)-.25 G(ly).15 E(.)-.65 E(The)132 412.8 Q 2.5(ya)-.15 G
+(re applied before an)159.34 412.8 Q 2.5(ys)-.15 G
+(peci\214cation in the mailer de\214nition.)250.27 412.8 Q(The)5 E 2.5(ym)-.15
+G(ust ne)429 412.8 Q -.15(ve)-.25 G 2.5(rr).15 G(esolv)470.81 412.8 Q(e.)-.15 E
+.266(Ruleset four is applied to all addresses in the message.)157 429 R .265
+(It is typically used to translate)5.265 F(internal to e)132 441 Q
+(xternal form.)-.15 E F0 2.5(5.1.1.4. IPC)117 465 R(mailers)2.5 E F1 .332
+(Some special processing occurs if the ruleset zero resolv)157 481.2 R .333
+(es to an IPC mailer \(that is, a)-.15 F .242
+(mailer that has \231[IPC]\232 listed as the P)132 493.2 R .241(ath in the)-.15
+F F0(M)2.741 E F1 .241(con\214guration line.)2.741 F .241(The host name passed)
+5.241 F .884(after \231$@\232 has MX e)132 505.2 R .885
+(xpansion performed; this looks the name up in DNS to \214nd alternate)-.15 F
+(deli)132 517.2 Q -.15(ve)-.25 G(ry sites.).15 E(The host name can also be pro)
+157 533.4 Q(vided as a dotted quad in square brack)-.15 E(ets; for e)-.1 E
+(xample:)-.15 E([128.32.149.78])172 549.6 Q(This causes direct con)132 565.8 Q
+-.15(ve)-.4 G(rsion of the numeric v).15 E(alue to a TCP/IP host address.)-.25
+E .894(The host name passed in after the \231$@\232 may also be a colon-separa\
+ted list of hosts.)157 582 R .629(Each is separately MX e)132 594 R .629
+(xpanded and the results are concatenated to mak)-.15 F 3.13(e\()-.1 G .63
+(essentially\) one)440.88 594 R .379(long MX list.)132 606 R .378
+(The intent here is to create \231f)5.379 F(ak)-.1 E .378
+(e\232 MX records that are not published in DNS)-.1 F(for pri)132 618 Q -.25
+(va)-.25 G(te internal netw).25 E(orks.)-.1 E .17
+(As a \214nal special case, the host name can be passed in as a te)157 634.2 R
+.17(xt string in square brack-)-.15 F(ets:)132 646.2 Q([ucb)172 662.4 Q -.25
+(va)-.15 G(x.berk).25 E(ele)-.1 E -.65(y.)-.15 G(edu]).65 E 1.245(This form a)
+132 678.6 R -.2(vo)-.2 G 1.245(ids the MX mapping.).2 F F0(N.B.:)6.244 E F1
+1.244(This is intended only for situations where you)3.744 F(ha)132 690.6 Q
+.814 -.15(ve a n)-.2 H(etw).15 E .514(ork \214re)-.1 F -.1(wa)-.25 G .514
+(ll, so that your MX record points to a g).1 F(ate)-.05 E -.1(wa)-.25 G 3.014
+(ym).1 G .514(achine; this machine)420.762 690.6 R 1.604
+(could then do direct deli)132 702.6 R -.15(ve)-.25 G 1.604
+(ry to machines within your local domain.).15 F 1.603(Use of this feature)6.603
+F(directly violates RFC 1123 section 5.3.5: it should not be used lightly)132
+714.6 Q(.)-.65 E EP
+%%Page: 28 23
+%%BeginPageSetup
+BP
+%%EndPageSetup
+/F0 10/Times-Bold@0 SF 193.36(SMM:08-28 Sendmail)72 60 R
+(Installation and Operation Guide)2.5 E 2.5(5.1.2. D)102 96 R 2.5<8a64>2.5 G
+(e\214ne macr)157.28 96 Q(o)-.18 E/F1 10/Times-Roman@0 SF .546
+(Macros are named with a single character)142 112.2 R 5.546(.T)-.55 G .547
+(hese may be selected from the entire ASCII)325.492 112.2 R .892(set, b)117
+124.2 R .892(ut user)-.2 F .892
+(-de\214ned macros should be selected from the set of upper case letters only)
+-.2 F 5.892(.L)-.65 G -.25(ow)484.26 124.2 S(er).25 E
+(case letters and special symbols are used internally)117 136.2 Q(.)-.65 E
+(The syntax for macro de\214nitions is:)142 152.4 Q F0(D)157 168.6 Q/F2 10
+/Times-Italic@0 SF 1.666(xv)C(al)-1.666 E F1(where)117 184.8 Q F2(x)2.5 E F1
+(is the name of the macro and)2.5 E F2(val)2.5 E F1(is the v)2.5 E
+(alue it should ha)-.25 E -.15(ve)-.2 G(.).15 E 1.085
+(Macros are interpolated using the construct)142 201 R F0($)3.585 E F2(x)A F1
+3.585(,w)C(here)346.775 201 Q F2(x)3.585 E F1 1.085
+(is the name of the macro to be)3.585 F 3.45(interpolated. This)117 213 R .95
+(interpolation is done when the con\214guration \214le is read, e)3.45 F .95
+(xcept in)-.15 F F0(M)3.45 E F1(lines.)3.45 E(The special construct)117 225 Q
+F0($&)2.5 E F2(x)A F1(can be used in)2.5 E F0(R)2.5 E F1
+(lines to get deferred interpolation.)2.5 E
+(Conditionals can be speci\214ed using the syntax:)142 241.2 Q($?x te)157 257.4
+Q(xt1 $| te)-.15 E(xt2 $.)-.15 E .245(This interpolates)117 273.6 R F2(te)2.745
+E(xt1)-.2 E F1 .245(if the macro)2.745 F F0($x)2.745 E F1 .245(is set, and)
+2.745 F F2(te)2.745 E(xt2)-.2 E F1 2.745(otherwise. The)2.745 F .246
+(\231else\232 \()2.746 F F0($|)A F1 2.746(\)c)C .246(lause may be)451.298 273.6
+R(omitted.)117 285.6 Q(Lo)142 301.8 Q .262(wer case macro names are reserv)-.25
+F .262(ed to ha)-.15 F .561 -.15(ve s)-.2 H .261
+(pecial semantics, used to pass information).15 F 1.162(in or out of)117 313.8
+R F2(sendmail)3.663 E F1 3.663(,a)C 1.163(nd special characters are reserv)
+215.583 313.8 R 1.163(ed to pro)-.15 F 1.163(vide conditionals, etc.)-.15 F
+(Upper)6.163 E(case names \(that is,)117 325.8 Q F0($A)2.5 E F1(through)2.5 E
+F0($Z)2.5 E F1 2.5(\)a)C(re speci\214cally reserv)267.53 325.8 Q
+(ed for con\214guration \214le authors.)-.15 E .053(The follo)142 342 R .053
+(wing macros are de\214ned and/or used internally by)-.25 F F2(sendmail)2.552 E
+F1 .052(for interpolation into)2.552 F(ar)117 354 Q(gv')-.18 E 5.178(sf)-.55 G
+2.678(or mailers or for other conte)149.768 354 R 5.179(xts. The)-.15 F 2.679
+(ones mark)5.179 F 2.679(ed \207 are information passed into)-.1 F(sendmail)117
+368 Q/F3 7/Times-Roman@0 SF(10)153.11 364 Q F1 4.232(,t)160.11 368 S 1.732
+(he ones mark)169.622 368 R 1.732
+(ed \210 are information passed both in and out of sendmail, and the)-.1 F
+(unmark)117 380 Q 2.177(ed macros are passed out of sendmail b)-.1 F 2.177
+(ut are not otherwise used internally)-.2 F 7.177(.T)-.65 G(hese)486.23 380 Q
+(macros are:)117 392 Q($a)117 408.2 Q F0(The origination date in RFC 822 f)142
+408.2 Q(ormat.)-.25 E F1($b)117 424.4 Q F0(The curr)142 424.4 Q
+(ent date in RFC 822 f)-.18 E(ormat.)-.25 E F1($c)117 440.6 Q F0
+(The hop count.)142 440.6 Q F1($d)117 456.8 Q F0(The curr)142 456.8 Q
+(ent date in UNIX \(ctime\) f)-.18 E(ormat.)-.25 E F1($e\207)117 473 Q F0 1.342
+(The SMTP entry message.)142 473 R F1 1.341
+(This is printed out when SMTP starts up.)6.342 F 1.341(The \214rst w)6.341 F
+(ord)-.1 E .428(must be the)142 485 R F0($j)2.928 E F1 .429
+(macro as speci\214ed by RFC821.)2.928 F(Def)5.429 E .429
+(aults to \231$j Sendmail $v ready at $b\232.)-.1 F 2.313
+(Commonly rede\214ned to include the con\214guration v)142 497 R 2.313
+(ersion number)-.15 F 4.813(,e)-.4 G 2.313(.g., \231$j Sendmail)431.874 497 R
+($v/$Z ready at $b\232)142 509 Q($f)117 525.2 Q F0(The sender \(fr)142 525.2 Q
+(om\) addr)-.18 E(ess.)-.18 E F1($g)117 541.4 Q F0(The sender addr)142 541.4 Q
+(ess r)-.18 E(elati)-.18 E .2 -.1(ve t)-.1 H 2.5(ot).1 G(he r)275.59 541.4 Q
+(ecipient.)-.18 E F1($h)117 557.6 Q F0(The r)142 557.6 Q(ecipient host.)-.18 E
+F1($i)117 573.8 Q F0(The queue id.)142 573.8 Q F1($j\210)117 590 Q F0 .557
+(The \231of\214cial\232 domain name f)142 590 R .557(or this site.)-.25 F F1
+.557(This is fully quali\214ed if the full quali\214cation)5.557 F .137
+(can be found.)142 602 R(It)5.137 E F2(must)2.637 E F1 .136
+(be rede\214ned to be the fully quali\214ed domain name if your system is)2.637
+F(not con\214gured so that information can \214nd it automatically)142 614 Q(.)
+-.65 E($k)117 630.2 Q F0(The UUCP node name \(fr)142 630.2 Q
+(om the uname system call\).)-.18 E F1($l\207)117 646.4 Q F0 .972(The f)142
+646.4 R .972(ormat of the UNIX fr)-.25 F .972(om line.)-.18 F F1 .972
+(Unless you ha)5.972 F 1.272 -.15(ve c)-.2 H .972(hanged the UNIX mailbox for)
+.15 F(-)-.2 E(mat, you should not change the def)142 658.4 Q
+(ault, which is \231From $g)-.1 E($d\232.)5 E .32 LW 76 678.8 72 678.8 DL 80
+678.8 76 678.8 DL 84 678.8 80 678.8 DL 88 678.8 84 678.8 DL 92 678.8 88 678.8
+DL 96 678.8 92 678.8 DL 100 678.8 96 678.8 DL 104 678.8 100 678.8 DL 108 678.8
+104 678.8 DL 112 678.8 108 678.8 DL 116 678.8 112 678.8 DL 120 678.8 116 678.8
+DL 124 678.8 120 678.8 DL 128 678.8 124 678.8 DL 132 678.8 128 678.8 DL 136
+678.8 132 678.8 DL 140 678.8 136 678.8 DL 144 678.8 140 678.8 DL 148 678.8 144
+678.8 DL 152 678.8 148 678.8 DL 156 678.8 152 678.8 DL 160 678.8 156 678.8 DL
+164 678.8 160 678.8 DL 168 678.8 164 678.8 DL 172 678.8 168 678.8 DL 176 678.8
+172 678.8 DL 180 678.8 176 678.8 DL 184 678.8 180 678.8 DL 188 678.8 184 678.8
+DL 192 678.8 188 678.8 DL 196 678.8 192 678.8 DL 200 678.8 196 678.8 DL 204
+678.8 200 678.8 DL 208 678.8 204 678.8 DL 212 678.8 208 678.8 DL 216 678.8 212
+678.8 DL/F4 5/Times-Roman@0 SF(10)93.6 689.2 Q/F5 8/Times-Roman@0 SF(As of v)
+3.2 I(ersion 8.6, all of these macros ha)-.12 E .24 -.12(ve r)-.16 H
+(easonable def).12 E 2(aults. Pre)-.08 F(vious v)-.2 E
+(ersions required that the)-.12 E 2(yb)-.12 G 2(ed)424.728 692.4 S(e\214ned.)
+434.28 692.4 Q EP
+%%Page: 29 24
+%%BeginPageSetup
+BP
+%%EndPageSetup
+/F0 10/Times-Bold@0 SF(Sendmail Installation and Operation Guide)72 60 Q
+(SMM:08-29)452.9 60 Q/F1 10/Times-Roman@0 SF($m)117 96 Q F0 .84
+(The domain part of the)142 96 R/F2 10/Times-Italic@0 SF -.1(ge)3.339 G
+(thostname).1 E F0 -.18(re)3.339 G(tur).18 E 3.339(nv)-.15 G(alue.)337.055 96 Q
+F1 .839(Under normal circumstances,)5.839 F F0($j)3.339 E F1(is)3.339 E(equi)
+142 108 Q -.25(va)-.25 G(lent to).25 E F0($w)2.5 E(.$m)-.7 E F1(.)A($n\207)117
+124.2 Q F0(The name of the daemon \(f)142 124.2 Q(or err)-.25 E(or messages\).)
+-.18 E F1(Def)5 E(aults to \231MAILER-D)-.1 E(AEMON\232.)-.4 E($o\207)117 140.4
+Q F0 2.03(The set of \231operators\232 in addr)142 140.4 R(esses.)-.18 E F1
+4.531(Al)7.031 G 2.031(ist of characters which will be considered)325.744 140.4
+R(tok)142 152.4 Q .537(ens and which will separate tok)-.1 F .537
+(ens when doing parsing.)-.1 F -.15(Fo)5.537 G 3.037(re).15 G .537
+(xample, if \231@\232 were in)408.502 152.4 R(the)142 164.4 Q F0($o)2.898 E F1
+.398(macro, then the input \231a@b\232 w)2.898 F .398
+(ould be scanned as three tok)-.1 F .398(ens: \231a,)-.1 F 2.898<9a99>-.7 G(@,)
+453.032 164.4 Q 2.899<9a61>-.7 G .399(nd \231b)475.821 164.4 R -.7<2e9a>-.4 G
+(Def)142 176.4 Q .436(aults to \231.:@[]\232, which is the minimum set necessa\
+ry to do RFC 822 parsing; a richer)-.1 F 1.715
+(set of operators is \231.:%@!/[]\232, which adds support for UUCP)142 188.4 R
+4.216(,t)-1.11 G 1.716(he %-hack, and X.400)409.712 188.4 R(addresses.)142
+200.4 Q($p)117 216.6 Q F0(Sendmail')142 216.6 Q 2.5(sp)-.37 G -.18(ro)196.92
+216.6 S(cess id.).18 E F1($q\207)117 232.8 Q F0 2.358(Default f)142 232.8 R
+2.358(ormat of sender addr)-.25 F(ess.)-.18 E F1(The)7.358 E F0($q)4.858 E F1
+2.357(macro speci\214es ho)4.857 F 4.857(wa)-.25 G 4.857(na)432.626 232.8 S
+2.357(ddress should)446.923 232.8 R .625(appear in a message when it is def)142
+244.8 R 3.126(aulted. Def)-.1 F .626(aults to \231<$g>\232.)-.1 F .626
+(It is commonly rede\214ned)5.626 F .183(to be \231$?x$x <$g>$|$g$.)142 256.8 R
+5.183<9a6f>-.7 G 2.683<7299>255.852 256.8 S .183($g$?x \($x\)$.)266.305 256.8 R
+.182(\232, corresponding to the follo)-.7 F .182(wing tw)-.25 F 2.682(of)-.1 G
+(ormats:)474 256.8 Q(Eric Allman <eric@CS.Berk)182 273 Q(ele)-.1 E -.65(y.)-.15
+G(EDU>).65 E(eric@CS.Berk)182 285 Q(ele)-.1 E -.65(y.)-.15 G
+(EDU \(Eric Allman\)).65 E F2(Sendmail)142 301.2 Q F1
+(properly quotes names that ha)2.5 E .3 -.15(ve s)-.2 H
+(pecial characters if the \214rst form is used.).15 E($r)117 317.4 Q F0(Pr)142
+317.4 Q(otocol used to r)-.18 E(ecei)-.18 E .2 -.1(ve t)-.1 H(he message.).1 E
+F1($s)117 333.6 Q F0(Sender')142 333.6 Q 2.5(sh)-.37 G(ost name.)186.91 333.6 Q
+F1($t)117 349.8 Q F0 2.5(An)142 349.8 S(umeric r)157.28 349.8 Q(epr)-.18 E
+(esentation of the curr)-.18 E(ent time.)-.18 E F1($u)117 366 Q F0(The r)142
+366 Q(ecipient user)-.18 E(.)-1 E F1($v)117 382.2 Q F0(The v)142 382.2 Q
+(ersion number of)-.1 E F2(sendmail)2.5 E F0(.)A F1($w\210)117 398.4 Q F0
+(The hostname of this site.)7.78 E F1(The)142 414.6 Q F0($w)2.5 E F1
+(macro is set to the root name of this host \(b)2.5 E(ut see belo)-.2 E 2.5(wf)
+-.25 G(or ca)403.46 414.6 Q -.15(ve)-.2 G(ats\).).15 E($x)117 430.8 Q F0
+(The full name of the sender)142 430.8 Q(.)-1 E F1($z)117 447 Q F0
+(The home dir)142 447 Q(ectory of the r)-.18 E(ecipient.)-.18 E F1($_)117 463.2
+Q F0(The v)142 463.2 Q(alidated sender addr)-.1 E(ess.)-.18 E F1 .918
+(There are three types of dates that can be used.)142 479.4 R(The)5.918 E F0
+($a)3.418 E F1(and)3.418 E F0($b)3.418 E F1 .918(macros are in RFC 822)3.418 F
+(format;)117 491.4 Q F0($a)3.047 E F1 .547(is the time as e)3.047 F .547
+(xtracted from the \231Date:\232 line of the message \(if there w)-.15 F .546
+(as one\), and)-.1 F F0($b)117 503.4 Q F1 .145
+(is the current date and time \(used for postmarks\).)2.645 F .145
+(If no \231Date:\232 line is found in the incoming)5.145 F(message,)117 515.4 Q
+F0($a)2.547 E F1 .047(is set to the current time also.)2.547 F(The)5.046 E F0
+($d)2.546 E F1 .046(macro is equi)2.546 F -.25(va)-.25 G .046(lent to the).25 F
+F0($b)2.546 E F1 .046(macro in UNIX)2.546 F(\(ctime\) format.)117 527.4 Q .606
+(The macros)142 543.6 R F0($w)3.106 E F1(,)A F0($j)3.106 E F1 3.106(,a)C(nd)
+228.844 543.6 Q F0($m)3.106 E F1 .607(are set to the identity of this host.)
+3.106 F F2(Sendmail)5.607 E F1 .607(tries to \214nd the)3.107 F .025(fully qua\
+li\214ed name of the host if at all possible; it does this by calling)117 555.6
+R F2 -.1(ge)2.525 G(thostname).1 E F1 .025(\(2\) to get the)B 1.511
+(current hostname and then passing that to)117 567.6 R F2 -.1(ge)4.012 G
+(thostbyname).1 E F1 1.512(\(3\) which is supposed to return the)B .185
+(canonical v)117 581.6 R .185(ersion of that host name.)-.15 F/F3 7
+/Times-Roman@0 SF(11)262.195 577.6 Q F1 .184(Assuming this is successful,)
+271.88 581.6 R F0($j)2.684 E F1 .184(is set to the fully quali\214ed)2.684 F
+1.463(name and)117 593.6 R F0($m)3.963 E F1 1.464
+(is set to the domain part of the name \(e)3.964 F -.15(ve)-.25 G 1.464
+(rything after the \214rst dot\).).15 F(The)6.464 E F0($w)3.964 E F1 .166
+(macro is set to the \214rst w)117 605.6 R .166(ord \(e)-.1 F -.15(ve)-.25 G
+.166(rything before the \214rst dot\) if you ha).15 F .466 -.15(ve a l)-.2 H
+-2.15 -.25(ev e).15 H 2.666(l5o).25 G 2.666(rh)452.018 605.6 S .166(igher con-)
+463.014 605.6 R .183(\214guration \214le; otherwise, it is set to the same v)
+117 617.6 R .184(alue as)-.25 F F0($j)2.684 E F1 5.184(.I)C 2.684(ft)355.32
+617.6 S .184(he canoni\214cation is not successful,)364.114 617.6 R
+(it is imperati)117 631.6 Q .3 -.15(ve t)-.25 H(hat the con\214g \214le set).15
+E F0($j)2.5 E F1(to the fully quali\214ed domain name)2.5 E F3(12)416.59 627.6
+Q F1(.)423.59 631.6 Q(The)142 647.8 Q F0($f)3.115 E F1 .614(macro is the id of\
+ the sender as originally determined; when mailing to a speci\214c)3.115 F .601
+(host the)117 659.8 R F0($g)3.101 E F1 .601
+(macro is set to the address of the sender)3.101 F F2 -.37(re)3.102 G .602
+(lative to the r).37 F(ecipient.)-.37 E F1 -.15(Fo)5.602 G 3.102(re).15 G .602
+(xample, if I)456.416 659.8 R .32 LW 76 669.4 72 669.4 DL 80 669.4 76 669.4 DL
+84 669.4 80 669.4 DL 88 669.4 84 669.4 DL 92 669.4 88 669.4 DL 96 669.4 92
+669.4 DL 100 669.4 96 669.4 DL 104 669.4 100 669.4 DL 108 669.4 104 669.4 DL
+112 669.4 108 669.4 DL 116 669.4 112 669.4 DL 120 669.4 116 669.4 DL 124 669.4
+120 669.4 DL 128 669.4 124 669.4 DL 132 669.4 128 669.4 DL 136 669.4 132 669.4
+DL 140 669.4 136 669.4 DL 144 669.4 140 669.4 DL 148 669.4 144 669.4 DL 152
+669.4 148 669.4 DL 156 669.4 152 669.4 DL 160 669.4 156 669.4 DL 164 669.4 160
+669.4 DL 168 669.4 164 669.4 DL 172 669.4 168 669.4 DL 176 669.4 172 669.4 DL
+180 669.4 176 669.4 DL 184 669.4 180 669.4 DL 188 669.4 184 669.4 DL 192 669.4
+188 669.4 DL 196 669.4 192 669.4 DL 200 669.4 196 669.4 DL 204 669.4 200 669.4
+DL 208 669.4 204 669.4 DL 212 669.4 208 669.4 DL 216 669.4 212 669.4 DL/F4 5
+/Times-Roman@0 SF(11)93.6 679.8 Q/F5 8/Times-Roman@0 SF -.12(Fo)3.2 K 2(re).12
+G(xample, on some systems)115.024 683 Q/F6 8/Times-Italic@0 SF -.08(ge)2 G
+(thostname).08 E F5(might return \231foo\232 which w)2 E
+(ould be mapped to \231foo.bar)-.08 E(.com\232 by)-.44 E F6 -.08(ge)2 G
+(thostbyname).08 E F5(.)A F4(12)93.6 693.4 Q F5(Older v)3.2 I
+(ersions of sendmail didn')-.12 E 2(tp)-.144 G(re-de\214ne)211.88 696.6 Q/F7 8
+/Times-Bold@0 SF($j)2 E F5(at all, so up until 8.6, con\214g \214les)2 E F6
+(always)2 E F5(had to de\214ne)2 E F7($j)2 E F5(.)A EP
+%%Page: 30 25
+%%BeginPageSetup
+BP
+%%EndPageSetup
+/F0 10/Times-Bold@0 SF 193.36(SMM:08-30 Sendmail)72 60 R
+(Installation and Operation Guide)2.5 E/F1 10/Times-Roman@0 SF 1.65
+(send to \231bollard@matisse.CS.Berk)117 96 R(ele)-.1 E -.65(y.)-.15 G 1.65
+(EDU\232 from the machine \231v).65 F(angogh.CS.Berk)-.25 E(ele)-.1 E -.65(y.)
+-.15 G(EDU\232).65 E(the)117 108 Q F0($f)2.5 E F1
+(macro will be \231eric\232 and the)2.5 E F0($g)2.5 E F1
+(macro will be \231eric@v)2.5 E(angogh.CS.Berk)-.25 E(ele)-.1 E -.65(y.)-.15 G
+(EDU.).65 E<9a>-.7 E(The)142 124.2 Q F0($x)3.837 E F1 1.338
+(macro is set to the full name of the sender)3.837 F 6.338(.T)-.55 G 1.338
+(his can be determined in se)369.13 124.2 R -.15(ve)-.25 G(ral).15 E -.1(wa)117
+136.2 S 2.953(ys. It).1 F .453(can be passed as \215ag to)2.953 F/F2 10
+/Times-Italic@0 SF(sendmail)2.953 E F1 5.453(.T)C .453
+(he second choice is the v)303.447 136.2 R .453(alue of the \231Full-name:\232)
+-.25 F .512(line in the header if it e)117 148.2 R .513
+(xists, and the third choice is the comment \214eld of a \231From:\232 line.)
+-.15 F .513(If all)5.513 F 1.149(of these f)117 160.2 R 1.149
+(ail, and if the message is being originated locally)-.1 F 3.648(,t)-.65 G
+1.148(he full name is look)369.684 160.2 R 1.148(ed up in the)-.1 F F2
+(/etc/passwd)117 172.2 Q F1(\214le.)2.5 E .438(When sending, the)142 188.4 R F0
+($h)2.938 E F1(,)A F0($u)2.938 E F1 2.938(,a)C(nd)256.96 188.4 Q F0($z)2.938 E
+F1 .438(macros get set to the host, user)2.938 F 2.939(,a)-.4 G .439
+(nd home directory \(if)417.423 188.4 R 1.455(local\) of the recipient.)117
+200.4 R 1.455(The \214rst tw)6.455 F 3.955(oa)-.1 G 1.454(re set from the)
+278.445 200.4 R F0($@)3.954 E F1(and)3.954 E F0($:)3.954 E F1 1.454
+(part of the re)3.954 F 1.454(writing rules,)-.25 F(respecti)117 212.4 Q -.15
+(ve)-.25 G(ly).15 E(.)-.65 E(The)142 228.6 Q F0($p)2.806 E F1(and)2.806 E F0
+($t)2.806 E F1 .306(macros are used to create unique strings \(e.g., for the \
+\231Message-Id:\232 \214eld\).)2.806 F(The)117 240.6 Q F0($i)2.538 E F1 .037(m\
+acro is set to the queue id on this host; if put into the timestamp line it ca\
+n be e)2.538 F(xtremely)-.15 E .407(useful for tracking messages.)117 252.6 R
+(The)5.407 E F0($v)2.907 E F1 .407(macro is set to be the v)2.907 F .407
+(ersion number of)-.15 F F2(sendmail)2.907 E F1 2.907(;t)C .408(his is)482.752
+252.6 R(normally put in timestamps and has been pro)117 264.6 Q -.15(ve)-.15 G
+2.5(ne).15 G(xtremely useful for deb)317.64 264.6 Q(ugging.)-.2 E(The)142 280.8
+Q F0($c)2.715 E F1 .215(\214eld is set to the \231hop count,)2.715 F 2.714
+<9a69>-.7 G .214(.e., the number of times this message has been pro-)297.664
+280.8 R 3.183(cessed. This)117 292.8 R .683(can be determined by the)3.183 F F0
+<ad68>3.183 E F1 .684(\215ag on the command line or by counting the times-)
+3.183 F(tamps in the message.)117 304.8 Q(The)142 321 Q F0($r)3.427 E F1(and)
+3.427 E F0($s)3.427 E F1 .926
+(\214elds are set to the protocol used to communicate with)3.427 F F2(sendmail)
+3.426 E F1 .926(and the)3.426 F(sending hostname.)117 333 Q(The)142 349.2 Q F0
+($_)2.72 E F1 .22(is set to a v)2.72 F .22(alidated sender host name.)-.25 F
+.22(If the sender is running an RFC 1413 com-)5.22 F(pliant IDENT serv)117
+361.2 Q(er)-.15 E 2.5(,i)-.4 G 2.5(tw)206.43 361.2 S
+(ill include the user name on that host.)218.93 361.2 Q F0 2.5(5.1.3. C)102
+385.2 R(and F \212 de\214ne classes)2.5 E F1 .197
+(Classes of phrases may be de\214ned to match on the left hand side of re)142
+401.4 R .196(writing rules, where)-.25 F 2.79<6199>117 413.4 S .291
+(phrase\232 is a sequence of characters that do not contain space characters.)
+128.67 413.4 R -.15(Fo)5.291 G 2.791(re).15 G .291(xample a class)445.098 413.4
+R .356(of all local names for this site might be created so that attempts to s\
+end to oneself can be elimi-)117 425.4 R 2.89(nated. These)117 437.4 R .39(can\
+ either be de\214ned directly in the con\214guration \214le or read in from an\
+other \214le.)2.89 F .797(Classes may be gi)117 449.4 R -.15(ve)-.25 G 3.297
+(nn).15 G .796(ames from the set of upper case letters.)213.668 449.4 R(Lo)
+5.796 E .796(wer case letters and special)-.25 F(characters are reserv)117
+461.4 Q(ed for system use.)-.15 E(The syntax is:)142 477.6 Q F0(C)157 493.8 Q
+F2 1.666(cp)C(hr)-1.666 E(ase1 phr)-.15 E(ase2...)-.15 E F0(F)157 505.8 Q F2
+1.666<638c>C(le)-1.666 E F1 1.114(The \214rst form de\214nes the class)117 522
+R F2(c)3.614 E F1 1.114(to match an)3.614 F 3.614(yo)-.15 G 3.615(ft)319.63 522
+S 1.115(he named w)329.355 522 R 3.615(ords. It)-.1 F 1.115
+(is permissible to split)3.615 F(them among multiple lines; for e)117 534 Q
+(xample, the tw)-.15 E 2.5(of)-.1 G(orms:)317.57 534 Q(CHmonet ucbmonet)157
+550.2 Q(and)117 566.4 Q(CHmonet)157 582.6 Q(CHucbmonet)157 594.6 Q(are equi)117
+610.8 Q -.25(va)-.25 G 2.5(lent. The).25 F
+(second form reads the elements of the class)2.5 E F2(c)2.5 E F1
+(from the named)2.5 E F2(\214le)2.5 E F1(.)A(The)142 627 Q F0($~)3.113 E F1
+.613(\(match entries not in class\) only matches a single w)3.113 F .612
+(ord; multi-w)-.1 F .612(ord entries in the)-.1 F
+(class are ignored in this conte)117 639 Q(xt.)-.15 E .383(The class)142 655.2
+R F0($=w)2.883 E F1 .384(is set to be the set of all names this host is kno)
+2.883 F .384(wn by)-.25 F 5.384(.T)-.65 G .384(his can be used to)431.364 655.2
+R(match local hostnames.)117 667.2 Q(The class)142 683.4 Q F0($=k)2.5 E F1
+(is set to be the same as)2.5 E F0($k)2.5 E F1 2.5(,t)C
+(hat is, the UUCP node name.)312.69 683.4 Q(The class)142 699.6 Q F0($=m)2.5 E
+F1(is set to the set of domains by which this host is kno)2.5 E
+(wn, initially just)-.25 E F0($m)2.5 E F1(.)A EP
+%%Page: 31 26
+%%BeginPageSetup
+BP
+%%EndPageSetup
+/F0 10/Times-Bold@0 SF(Sendmail Installation and Operation Guide)72 60 Q
+(SMM:08-31)452.9 60 Q/F1 10/Times-Italic@0 SF(Sendmail)142 96 Q/F2 10
+/Times-Roman@0 SF .543(can be compiled to allo)3.043 F 3.043(wa)-.25 G F1
+(scanf)-.001 E F2 .542(\(3\) string on the)B F0(F)3.042 E F2 3.042(line. This)
+3.042 F .542(lets you do sim-)3.042 F .519(plistic parsing of te)117 108 R .519
+(xt \214les.)-.15 F -.15(Fo)5.519 G 3.019(re).15 G .52
+(xample, to read all the user names in your system)251.884 108 R F1
+(/etc/passwd)3.02 E F2(\214le into a class, use)117 120 Q(FL/etc/passwd %[^:])
+157 136.2 Q(which reads e)117 152.4 Q -.15(ve)-.25 G
+(ry line up to the \214rst colon.).15 E F0 2.5(5.1.4. M)102 176.4 R 2.5<8a64>
+2.5 G(e\214ne mailer)159.5 176.4 Q F2(Programs and interf)142 192.6 Q
+(aces to mailers are de\214ned in this line.)-.1 E(The format is:)5 E F0(M)157
+208.8 Q F1(name)A F2 2.5(,{)C F1(\214eld)197.9 208.8 Q F2(=)A F1(value)A F2(}*)
+1.666 E(where)117 225 Q F1(name)3.244 E F2 .744(is the name of the mailer \(us\
+ed internally only\) and the \231\214eld=name\232 pairs de\214ne)3.244 F
+(attrib)117 237 Q(utes of the mailer)-.2 E 5(.F)-.55 G(ields are:)220.13 237 Q
+-.15(Pa)157 253.2 S 51.87(th The).15 F(pathname of the mailer)2.5 E 47.83
+(Flags Special)157 265.2 R(\215ags for this mailer)2.5 E 41.73(Sender A)157
+277.2 R(re)2.5 E(writing set for sender addresses)-.25 E 31.17(Recipient A)157
+289.2 R(re)2.5 E(writing set for recipient addresses)-.25 E(Ar)157 301.2 Q
+49.13(gv An)-.18 F(ar)2.5 E(gument v)-.18 E(ector to pass to this mailer)-.15 E
+55.61(Eol The)157 313.2 R(end-of-line string for this mailer)2.5 E 35.62
+(Maxsize The)157 325.2 R(maximum message length to this mailer)2.5 E 32.27
+(Linelimit The)157 337.2 R(maximum line length in the message body)2.5 E 31.18
+(Directory The)157 349.2 R -.1(wo)2.5 G(rking directory for the mailer).1 E
+(Only the \214rst character of the \214eld name is check)117 365.4 Q(ed.)-.1 E
+1.144(The follo)142 381.6 R 1.144
+(wing \215ags may be set in the mailer description.)-.25 F(An)6.144 E 3.644(yo)
+-.15 G 1.144(ther \215ags may be used)409.994 381.6 R(freely to conditionally \
+assign headers to messages destined for particular mailers.)117 393.6 Q 15.56
+(aR)117 409.8 S(un Extended SMTP \(ESMTP\) protocol \(de\214ned in RFCs 1425, \
+1426, and 1427\).)143.67 409.8 Q 15(bF)117 426 S .674
+(orce a blank line on the end of a message.)142.41 426 R .674
+(This is intended to w)5.674 F .674(ork around some stupid)-.1 F -.15(ve)137
+438 S .851(rsions of /bin/mail that require a blank line, b).15 F .851
+(ut do not pro)-.2 F .852(vide it themselv)-.15 F 3.352(es. It)-.15 F -.1(wo)
+3.352 G(uld).1 E(not normally be used on netw)137 450 Q(ork mail.)-.1 E 15.56
+(cD)117 466.2 S 4.166(on)144.22 466.2 S 1.666
+(ot include comments in addresses.)158.386 466.2 R 1.665
+(This should only be used if you ha)6.665 F 1.965 -.15(ve t)-.2 H 4.165(ow).15
+G(ork)490.67 466.2 Q(around a remote mailer that gets confused by comments.)137
+478.2 Q 13.33(CI)117 494.4 S 3.06(fm)140.33 494.4 S .56(ail is)154.5 494.4 R F1
+-.37(re)3.06 G(ceived).37 E F2 .56(from a mailer with this \215ag set, an)3.06
+F 3.06(ya)-.15 G .56(ddresses in the header that do not)367.33 494.4 R(ha)137
+506.4 Q .331 -.15(ve a)-.2 H 2.531(na).15 G 2.531(ts)174.472 506.4 S .031
+(ign \(\231@\232\) after being re)183.673 506.4 R .031
+(written by ruleset three will ha)-.25 F .33 -.15(ve t)-.2 H .03
+(he \231@domain\232 clause).15 F(from the sender tack)137 518.4 Q(ed on.)-.1 E
+(This allo)5 E(ws mail with headers of the form:)-.25 E(From: usera@hosta)177
+534.6 Q -.8(To)177 546.6 S 2.5(:u).8 G(serb@hostb, userc)197.59 546.6 Q
+(to be re)137 562.8 Q(written as:)-.25 E(From: usera@hosta)177 579 Q -.8(To)177
+591 S 2.5(:u).8 G(serb@hostb, userc@hosta)197.59 591 Q(automatically)137 607.2
+Q(.)-.65 E 12.78(DT)117 623.4 S(his mailer w)143.11 623.4 Q
+(ants a \231Date:\232 header line.)-.1 E 15.56(eT)117 639.6 S .562
+(his mailer is e)143.11 639.6 R(xpensi)-.15 E .862 -.15(ve t)-.25 H 3.062(oc)
+.15 G .562(onnect to, so try to a)253.97 639.6 R -.2(vo)-.2 G .562
+(id connecting normally; an).2 F 3.063(yn)-.15 G(ecessary)470.13 639.6 Q
+(connection will occur during a queue run.)137 651.6 Q 13.89(EE)117 667.8 S
+(scape lines be)143.11 667.8 Q
+(ginning with \231From\232 in the message with a `>' sign.)-.15 E 16.67(fT)117
+684 S .969(he mailer w)143.11 684 R .969(ants a)-.1 F F0<ad66>3.469 E F1(fr)
+3.469 E(om)-.45 E F2 .969(\215ag, b)3.469 F .969(ut only if this is a netw)-.2
+F .969(ork forw)-.1 F .968(ard operation \(i.e., the)-.1 F(mailer will gi)137
+696 Q .3 -.15(ve a)-.25 H 2.5(ne).15 G(rror if the e)218.81 696 Q -.15(xe)-.15
+G(cuting user does not ha).15 E .3 -.15(ve s)-.2 H(pecial permissions\).).15 E
+14.44(FT)117 712.2 S(his mailer w)143.11 712.2 Q
+(ants a \231From:\232 header line.)-.1 E EP
+%%Page: 32 27
+%%BeginPageSetup
+BP
+%%EndPageSetup
+/F0 10/Times-Bold@0 SF 193.36(SMM:08-32 Sendmail)72 60 R
+(Installation and Operation Guide)2.5 E/F1 10/Times-Roman@0 SF 15(gN)117 96 S
+(ormally)144.22 96 Q(,)-.65 E/F2 10/Times-Italic@0 SF(sendmail)3.529 E F1 1.029
+(sends internally generated email \(e.g., error messages\) using the null)3.529
+F 1.767(return address)137 110 R/F3 7/Times-Roman@0 SF(13)195.137 106 Q F1
+1.766(as required by RFC 1123.)206.404 110 R(Ho)6.766 E(we)-.25 E -.15(ve)-.25
+G 2.566 -.4(r, s).15 H 1.766(ome mailers don').4 F 4.266(ta)-.18 G 1.766
+(ccept a null)454.368 110 R .922(return address.)137 122 R .922(If necessary)
+5.922 F 3.422(,y)-.65 G .922(ou can set the)261.938 122 R F0(g)3.422 E F1 .922
+(\215ag to pre)3.422 F -.15(ve)-.25 G(nt).15 E F2(sendmail)3.422 E F1 .922
+(from obe)3.422 F .922(ying the)-.15 F .212
+(standards; error messages will be sent as from the MAILER-D)137 134 R .211
+(AEMON \(actually)-.4 F 2.711(,t)-.65 G .211(he v)470.439 134 R(alue)-.25 E
+(of the)137 146 Q F0($n)2.5 E F1(macro\).)2.5 E 15(hU)117 162.2 S
+(pper case should be preserv)144.22 162.2 Q(ed in host names for this mailer)
+-.15 E(.)-.55 E 16.67(IT)117 178.4 S .092
+(his mailer will be speaking SMTP to another)143.11 178.4 R F2(sendmail)2.592 E
+F1 2.593<8a61>2.593 G 2.593(ss)381.242 178.4 S .093
+(uch it can use special proto-)391.615 178.4 R .319(col features.)137 190.4 R
+.319(This option is not required \(i.e., if this option is omitted the transmi\
+ssion will)5.319 F(still operate successfully)137 202.4 Q 2.5(,a)-.65 G
+(lthough perhaps not as ef)244.11 202.4 Q(\214ciently as possible\).)-.25 E
+17.22(lT)117 218.6 S(his mailer is local \(i.e., \214nal deli)143.11 218.6 Q
+-.15(ve)-.25 G(ry will be performed\).).15 E 13.89(LL)117 234.8 S .69
+(imit the line lengths as speci\214ed in RFC821.)143.11 234.8 R .69
+(This deprecated option should be replaced)5.69 F(by the)137 246.8 Q F0(L=)2.5
+E F1(mail declaration.)2.5 E -.15(Fo)5 G 2.5(rh).15 G(istoric reasons, the)
+272.54 246.8 Q F0(L)2.5 E F1(\215ag also sets the)2.5 E F0(7)2.5 E F1(\215ag.)
+2.5 E 12.22(mT)117 263 S 1.273
+(his mailer can send to multiple users on the same host in one transaction.)
+143.11 263 R 1.273(When a)6.273 F F0($u)3.773 E F1 .621(macro occurs in the)137
+275 R F2(ar)3.121 E(gv)-.37 E F1 .621
+(part of the mailer de\214nition, that \214eld will be repeated as neces-)3.121
+F(sary for all qualifying users.)137 287 Q 11.11(MT)117 303.2 S(his mailer w)
+143.11 303.2 Q(ants a \231Message-Id:\232 header line.)-.1 E 15(nD)117 319.4 S
+2.5(on)144.22 319.4 S
+(ot insert a UNIX-style \231From\232 line on the front of the message.)156.72
+319.4 Q 15(pU)117 335.6 S .702(se the route-addr style re)144.22 335.6 R -.15
+(ve)-.25 G .702(rse-path in the SMTP \231MAIL FR).15 F .701
+(OM:\232 command rather than)-.4 F .421
+(just the return address; although this is required in RFC821 section 3.1, man)
+137 347.6 R 2.922(yh)-.15 G .422(osts do not)459.816 347.6 R(process re)137
+359.6 Q -.15(ve)-.25 G(rse-paths properly).15 E 5(.R)-.65 G -2.15 -.25(ev e)
+272.3 359.6 T(rse-paths are of).25 E(\214cially discouraged by RFC 1123.)-.25 E
+14.44(PT)117 375.8 S(his mailer w)143.11 375.8 Q(ants a \231Return-P)-.1 E
+(ath:\232 line.)-.15 E 16.67(rS)117 392 S(ame as)142.56 392 Q F0(f)2.5 E F1 2.5
+(,b)C(ut sends a)185.68 392 Q F0<ad72>2.5 E F1(\215ag.)2.5 E 16.11(sS)117 408.2
+S(trip quote characters of)142.56 408.2 Q 2.5(fo)-.25 G 2.5(ft)245.61 408.2 S
+(he address before calling the mailer)254.22 408.2 Q(.)-.55 E 14.44(SD)117
+424.4 S(on')144.22 424.4 Q 3.443(tr)-.18 G .943
+(eset the userid before calling the mailer)166.923 424.4 R 5.943(.T)-.55 G .943
+(his w)344.324 424.4 R .942(ould be used in a secure en)-.1 F(viron-)-.4 E .49
+(ment where)137 436.4 R F2(sendmail)2.99 E F1 .49(ran as root.)2.99 F .491
+(This could be used to a)5.491 F -.2(vo)-.2 G .491(id for).2 F .491
+(ged addresses.)-.18 F .491(This \215ag)5.491 F(is suppressed if gi)137 448.4 Q
+-.15(ve)-.25 G 2.5(nf).15 G(rom an \231unsafe\232 en)228.81 448.4 Q
+(vironment \(e.g, a user')-.4 E 2.5(sm)-.55 G(ail.cf \214le\).)410.31 448.4 Q
+15(uU)117 464.6 S(pper case should be preserv)144.22 464.6 Q
+(ed in user names for this mailer)-.15 E(.)-.55 E 12.78(UT)117 480.8 S 2.997
+(his mailer w)143.11 480.8 R 2.996
+(ants Unix-style \231From\232 lines with the ugly UUCP-style \231remote from)
+-.1 F(<host>\232 on the end.)137 492.8 Q 15(xT)117 509 S(his mailer w)143.11
+509 Q(ants a \231Full-Name:\232 header line.)-.1 E 12.78(XT)117 525.2 S 1.22
+(his mailer w)143.11 525.2 R 1.22
+(ant to use the hidden dot algorithm as speci\214ed in RFC821; basically)-.1 F
+3.72(,a)-.65 G -.15(ny)494.15 525.2 S .225(line be)137 537.2 R .225
+(ginning with a dot will ha)-.15 F .525 -.15(ve a)-.2 H 2.725(ne).15 G .224
+(xtra dot prepended \(to be stripped at the other end\).)296.47 537.2 R .525(T\
+his insures that lines in the message containing a dot will not terminate the \
+message pre-)137 549.2 R(maturely)137 561.2 Q(.)-.65 E 15(7S)117 577.4 S .351
+(trip all output to se)142.56 577.4 R -.15(ve)-.25 G 2.851(nb).15 G 2.851
+(its. This)241.416 577.4 R .351(is the def)2.851 F .351(ault if the)-.1 F F0(L)
+2.851 E F1 .351(\215ag is set.)2.851 F .351(Note that clearing this)5.351 F
+.377(option is not suf)137 589.4 R .378
+(\214cient to get full eight bit data passed through)-.25 F F2(sendmail)2.878 E
+F1 5.378(.I)C 2.878(ft)439.708 589.4 S(he)448.696 589.4 Q F0(7)2.878 E F1 .378
+(option is)2.878 F(set, this is essentially al)137 601.4 Q -.1(wa)-.1 G
+(ys set, since the eighth bit w).1 E(as stripped on input.)-.1 E 2.122(The mai\
+ler with the special name \231error\232 can be used to generate a user error)
+142 617.6 R 7.122(.T)-.55 G(he)494.56 617.6 Q .246
+(\(optional\) host \214eld is an e)117 629.6 R .247
+(xit status to be returned, and the user \214eld is a message to be printed.)
+-.15 F .337(The e)117 641.6 R .337(xit status may be numeric or one of the v)
+-.15 F .336(alues USA)-.25 F .336(GE, NOUSER, NOHOST)-.4 F 2.836(,U)-.74 G -.35
+(NA)465.4 641.6 S -1.35(VA)-1 G(IL-)1.35 E .828(ABLE, SOFTW)117 653.6 R .828
+(ARE, TEMPF)-1.2 F .828(AIL, PR)-.74 F -1.88 -.4(OT O)-.4 H .828
+(COL, or CONFIG to return the corresponding EX_).4 F -.15(ex)117 665.6 S
+(it code.).15 E -.15(Fo)5 G 2.5(re).15 G(xample, the entry:)181.26 665.6 Q .32
+LW 76 678.8 72 678.8 DL 80 678.8 76 678.8 DL 84 678.8 80 678.8 DL 88 678.8 84
+678.8 DL 92 678.8 88 678.8 DL 96 678.8 92 678.8 DL 100 678.8 96 678.8 DL 104
+678.8 100 678.8 DL 108 678.8 104 678.8 DL 112 678.8 108 678.8 DL 116 678.8 112
+678.8 DL 120 678.8 116 678.8 DL 124 678.8 120 678.8 DL 128 678.8 124 678.8 DL
+132 678.8 128 678.8 DL 136 678.8 132 678.8 DL 140 678.8 136 678.8 DL 144 678.8
+140 678.8 DL 148 678.8 144 678.8 DL 152 678.8 148 678.8 DL 156 678.8 152 678.8
+DL 160 678.8 156 678.8 DL 164 678.8 160 678.8 DL 168 678.8 164 678.8 DL 172
+678.8 168 678.8 DL 176 678.8 172 678.8 DL 180 678.8 176 678.8 DL 184 678.8 180
+678.8 DL 188 678.8 184 678.8 DL 192 678.8 188 678.8 DL 196 678.8 192 678.8 DL
+200 678.8 196 678.8 DL 204 678.8 200 678.8 DL 208 678.8 204 678.8 DL 212 678.8
+208 678.8 DL 216 678.8 212 678.8 DL/F4 5/Times-Roman@0 SF(13)93.6 689.2 Q/F5 8
+/Times-Roman@0 SF(Actually)3.2 I 2(,t)-.52 G(his only applies to SMTP)131.856
+692.4 Q 2(,w)-.888 G(hich uses the `)222.088 692.4 Q(`MAIL FR)-.592 E(OM:<>')
+-.32 E 2('c)-.592 G(ommand.)336.48 692.4 Q EP
+%%Page: 33 28
+%%BeginPageSetup
+BP
+%%EndPageSetup
+/F0 10/Times-Bold@0 SF(Sendmail Installation and Operation Guide)72 60 Q
+(SMM:08-33)452.9 60 Q/F1 10/Times-Roman@0 SF($#error $@ NOHOST $: Host unkno)
+157 96 Q(wn in this domain)-.25 E .261(on the RHS of a rule will cause the spe\
+ci\214ed error to be generated and the \231Host unkno)117 112.2 R .261
+(wn\232 e)-.25 F(xit)-.15 E(status to be returned if the LHS matches.)117 124.2
+Q(This mailer is only functional in ruleset zero.)5 E 1.563
+(The mailer named \231local\232)142 140.4 R/F2 10/Times-Italic@0 SF(must)4.063
+E F1 1.564(be de\214ned in e)4.063 F -.15(ve)-.25 G 1.564
+(ry con\214guration \214le.).15 F 1.564(This is used to)6.564 F(deli)117 152.4
+Q -.15(ve)-.25 G 4.039(rl).15 G 1.539
+(ocal mail, and is treated specially in se)151.189 152.4 R -.15(ve)-.25 G 1.538
+(ral w).15 F 4.038(ays. Additionally)-.1 F 4.038(,t)-.65 G 1.538
+(hree other mailers)428.724 152.4 R 1.367(named \231prog\232, \231*\214le*\232\
+, and \231*include*\232 may be de\214ned to tune the deli)117 164.4 R -.15(ve)
+-.25 G 1.368(ry of messages to).15 F
+(programs, \214les, and :include: lists respecti)117 176.4 Q -.15(ve)-.25 G(ly)
+.15 E 5(.T)-.65 G(he)315.38 176.4 Q 2.5(yd)-.15 G(ef)337.17 176.4 Q(ault to:)
+-.1 E(Mprog, P=/bin/sh, F=lsD, A=sh \255c $u)157 192.6 Q(M*\214le*, P=/de)157
+204.6 Q(v/null, F=lsDFMPEu, A=FILE)-.25 E(M*include*, P=/de)157 216.6 Q
+(v/null, F=su, A=INCLUDE)-.25 E 1.264(The Sender and Recipient re)142 237 R
+1.263(writing sets may either be a simple inte)-.25 F 1.263(ger or may be tw)
+-.15 F(o)-.1 E(inte)117 249 Q .046
+(gers separated by a slash; if so, the \214rst re)-.15 F .047
+(writing set is applied to en)-.25 F -.15(ve)-.4 G .047(lope addresses and the)
+.15 F(second is applied to headers.)117 261 Q 1.259
+(The Directory is actually a colon-separated path of directories to try)142
+277.2 R 6.258(.F)-.65 G 1.258(or e)439.704 277.2 R 1.258(xample, the)-.15 F
+.143(de\214nition \231D=$z:/\232 \214rst tries to e)117 289.2 R -.15(xe)-.15 G
+.143(cute in the recipient').15 F 2.643(sh)-.55 G .144
+(ome directory; if that is not a)353.327 289.2 R -.25(va)-.2 G(ilable,).25 E
+.781(it tries to e)117 301.2 R -.15(xe)-.15 G .781
+(cute in the root of the \214lesystem.).15 F .78
+(This is intended to be used only on the \231prog\232)5.781 F(mailer)117 313.2
+Q 2.898(,s)-.4 G .398(ince some shells \(such as)151.438 313.2 R F2(csh)2.898 E
+F1 2.898(\)r)C .398(efuse to e)279.356 313.2 R -.15(xe)-.15 G .398(cute if the)
+.15 F 2.898(yc)-.15 G .398(annot read the home directory)380.586 313.2 R(.)-.65
+E .416(Since the queue directory is not normally readable by normal users)117
+325.2 R F2(csh)2.916 E F1 .416(scripts as recipients can)2.916 F -.1(fa)117
+337.2 S(il.).1 E F0 2.5(5.1.5. H)102 361.2 R 2.5<8a64>2.5 G(e\214ne header)
+157.84 361.2 Q F1 .198(The format of the header lines that)142 377.4 R F2
+(sendmail)2.698 E F1 .198(inserts into the message are de\214ned by the)2.698 F
+F0(H)2.699 E F1 2.5(line. The)117 389.4 R(syntax of this line is:)2.5 E F0(H)
+157 405.6 Q F1([)A F0(?)A F2(m\215a)A(gs)-.1 E F0(?)A F1(])A F2(hname)A F0(:)A
+F2(htemplate)2.5 E F1 .691(Continuation lines in this spec are re\215ected dir\
+ectly into the outgoing message.)117 421.8 R(The)5.69 E F2(htemplate)3.19 E F1
+1.566(is macro e)117 433.8 R 1.567(xpanded before insertion into the message.)
+-.15 F 1.567(If the)6.567 F F2(m\215a)4.067 E(gs)-.1 E F1 1.567
+(\(surrounded by question)4.067 F .219(marks\) are speci\214ed, at least one o\
+f the speci\214ed \215ags must be stated in the mailer de\214nition for)117
+445.8 R .093(this header to be automatically output.)117 457.8 R .093
+(If one of these headers is in the input it is re\215ected to the)5.093 F
+(output re)117 469.8 Q -.05(ga)-.15 G(rdless of these \215ags.).05 E
+(Some headers ha)142 486 Q .3 -.15(ve s)-.2 H
+(pecial semantics that will be described belo).15 E -.65(w.)-.25 G F0 2.5
+(5.1.6. O)102 510 R 2.5<8a73>2.5 G(et option)156.17 510 Q F1 .045(There are a \
+number of \231random\232 options that can be set from a con\214guration \214le\
+.)142 526.2 R(Options)5.045 E(are represented by single characters.)117 538.2 Q
+(The syntax of this line is:)5 E F0(O)157 554.4 Q F2 1.666(ov)C(alue)-1.666 E
+F1 1.054(This sets option)117 570.6 R F2(o)3.554 E F1 1.054(to be)3.554 F F2
+(value)3.554 E F1 6.054(.D)C 1.054(epending on the option,)256.318 570.6 R F2
+(value)3.555 E F1 1.055(may be a string, an inte)3.555 F(ger)-.15 E 3.555(,a)
+-.4 G(boolean \(with le)117 582.6 Q -.05(ga)-.15 G 2.5(lv).05 G
+(alues \231t\232, \231T\232, \231f\232, or \231F\232; the def)201.26 582.6 Q
+(ault is TR)-.1 E(UE\), or a time interv)-.4 E(al.)-.25 E
+(The options supported are:)142 598.8 Q(a)117 615 Q F2(N)A F1 .655(If set, w)
+189 615 R .655(ait up to)-.1 F F2(N)3.155 E F1 .655
+(minutes for an \231@:@\232 entry to e)3.155 F .655(xist in the alias database)
+-.15 F .474(before starting up.)189 627 R .474(If it does not appear in)5.474 F
+F2(N)2.974 E F1 .475(minutes, reb)2.974 F .475(uild the database \(if)-.2 F
+(the)189 639 Q F0(D)2.5 E F1(option is also set\) or issue a w)2.5 E(arning.)
+-.1 E(A)117 655.2 Q F2 .507(spec, spec, ...)B F1 .507
+(Specify possible alias \214le\(s\).)190.014 655.2 R(Each)5.507 E F2(spec)3.006
+E F1 .506(should be in the format `)3.006 F(`)-.74 E F2(class)A F0(:)A F2
+(\214le)3.006 E F1 -.74('')C(where)189 667.2 Q F2(class)3.049 E F0(:)A F1 .549
+(is optional and def)3.049 F .549(aults to `)-.1 F(`implicit')-.74 E 3.049
+('. Depending)-.74 F .549(on ho)3.049 F(w)-.25 E F2(send-)3.05 E(mail)189 679.2
+Q F1 1.335(is compiled, v)3.835 F 1.335
+(alid classes are \231implicit\232 \(search through a compiled-in)-.25 F .193
+(list of alias \214le types, for back compatibility\), \231hash\232 \(if)189
+691.2 R/F3 9/Times-Roman@0 SF(NEWDB)2.693 E F1 .193(is speci\214ed\),)2.693 F
+.882(\231dbm\232 \(if)189 703.2 R F3(NDBM)3.382 E F1 .882
+(is speci\214ed\), \231stab\232 \(internal symbol table \212 not normally)3.382
+F .475(used unless you ha)189 715.2 R .775 -.15(ve n)-.2 H 2.975(oo).15 G .476
+(ther database lookup\), or \231nis\232 \(if)295.735 715.2 R F3(NIS)2.976 E F1
+.476(is speci\214ed\).)2.976 F EP
+%%Page: 34 29
+%%BeginPageSetup
+BP
+%%EndPageSetup
+/F0 10/Times-Bold@0 SF 193.36(SMM:08-34 Sendmail)72 60 R
+(Installation and Operation Guide)2.5 E/F1 10/Times-Roman@0 SF(If a list of)189
+96 Q/F2 10/Times-Italic@0 SF(spec)2.5 E F1 2.5(sa)C(re pro)259.26 96 Q(vided,)
+-.15 E F2(sendmail)2.5 E F1(searches them in order)2.5 E(.)-.55 E(b)117 112.2 Q
+F2(N)A F1(/)A F2(M)A F1 1.589(Insist on at least)189 112.2 R F2(N)4.089 E F1
+1.588(blocks free on the \214lesystem that holds the queue \214les)4.089 F .19
+(before accepting email via SMTP)189 124.2 R 5.19(.I)-1.11 G 2.69(ft)334.09
+124.2 S .19(here is insuf)342.89 124.2 R .19(\214cient space)-.25 F F2
+(sendmail)2.69 E F1(gi)2.69 E -.15(ve)-.25 G(s).15 E 3.67(a4)189 136.2 S 1.17
+(52 response to the MAIL command.)202.11 136.2 R 1.17(This in)6.17 F 1.17
+(vites the sender to try ag)-.4 F(ain)-.05 E(later)189 148.2 Q 5.986(.T)-.55 G
+.986(he optional)220.816 148.2 R F2(M)3.486 E F1 .987
+(is a maximum message size adv)3.486 F .987(ertised in the ESMTP)-.15 F
+(EHLO response.)189 160.2 Q(It is currently otherwise unused.)5 E(B)117 176.4 Q
+F2(c)A F1 1.445(Set the blank substitution character to)189 176.4 R F2(c)3.945
+E F1 6.444(.U)C 1.444(nquoted spaces in addresses are)371.594 176.4 R
+(replaced by this character)189 188.4 Q 5(.D)-.55 G(ef)305.63 188.4 Q
+(aults to space \(i.e., no change is made\).)-.1 E 67.56(cI)117 204.6 S 3.892
+(fa)192.33 204.6 S 3.892(no)203.992 204.6 S 1.393(utgoing mailer is mark)
+217.884 204.6 R 1.393(ed as being e)-.1 F(xpensi)-.15 E -.15(ve)-.25 G 3.893
+(,d).15 G(on')415.294 204.6 Q 3.893(tc)-.18 G 1.393(onnect immedi-)439.557
+204.6 R(ately)189 216.6 Q 6.164(.T)-.65 G 1.164
+(his requires that queueing be compiled in, since it will depend on a)222.564
+216.6 R(queue run process to actually send the mail.)189 228.6 Q(C)117 244.8 Q
+F2(N)A F1 1.49(Checkpoints the queue e)189 244.8 R -.15(ve)-.25 G(ry).15 E F2
+(N)3.99 E F1(\(def)3.99 E 1.49(ault 10\) addresses sent.)-.1 F 1.49
+(If your system)6.49 F .785(crashes during deli)189 256.8 R -.15(ve)-.25 G .785
+(ry to a lar).15 F .785(ge list, this pre)-.18 F -.15(ve)-.25 G .785
+(nts retransmission to an).15 F 3.285(yb)-.15 G(ut)496.22 256.8 Q
+(the last recipients.)189 268.8 Q(d)117 285 Q F2(x)A F1(Deli)189 285 Q -.15(ve)
+-.25 G 2.5(ri).15 G 2.5(nm)223.87 285 S(ode)239.15 285 Q F2(x)2.5 E F1 5(.L)C
+-2.25 -.15(eg a)274.14 285 T 2.5(lm).15 G(odes are:)300.88 285 Q 17.22(iD)229
+301.2 S(eli)256.22 301.2 Q -.15(ve)-.25 G 2.5(ri).15 G(nteracti)283.87 301.2 Q
+-.15(ve)-.25 G(ly \(synchronously\)).15 E 15(bD)229 313.2 S(eli)256.22 313.2 Q
+-.15(ve)-.25 G 2.5(ri).15 G 2.5(nb)283.87 313.2 S(ackground \(asynchronously\))
+296.37 313.2 Q 15(qJ)229 325.2 S(ust queue the message \(deli)252.89 325.2 Q
+-.15(ve)-.25 G 2.5(rd).15 G(uring queue run\))382.74 325.2 Q(Def)189 341.4 Q
+1.32(aults to `)-.1 F(`b')-.74 E 3.82('i)-.74 G 3.82(fn)261.64 341.4 S 3.82(oo)
+273.79 341.4 S 1.32(ption is speci\214ed, `)287.61 341.4 R(`i')-.74 E 3.82('i)
+-.74 G 3.82(fi)385.57 341.4 S 3.82(ti)395.5 341.4 S 3.82(ss)404.88 341.4 S 1.32
+(peci\214ed b)416.48 341.4 R 1.32(ut gi)-.2 F -.15(ve)-.25 G 3.82(nn).15 G(o)
+499 341.4 Q(ar)189 353.4 Q(gument \(i.e., `)-.18 E(`Od')-.74 E 2.5('i)-.74 G
+2.5(se)278.98 353.4 S(qui)289.81 353.4 Q -.25(va)-.25 G(lent to `).25 E(`Odi')
+-.74 E('\).)-.74 E 64.78(DI)117 369.6 S 2.736(fs)192.33 369.6 S .236(et, reb)
+202.286 369.6 R .236(uild the alias database if necessary and possible.)-.2 F
+.235(If this option is not)5.236 F(set,)189 381.6 Q F2(sendmail)3.385 E F1 .885
+(will ne)3.385 F -.15(ve)-.25 G 3.385(rr).15 G(eb)292.96 381.6 Q .885
+(uild the alias database unless e)-.2 F .885(xplicitly requested)-.15 F(using)
+189 393.6 Q F0(\255bi)2.5 E F1(.)A(e)117 409.8 Q F2(x)A F1
+(Dispose of errors using mode)189 409.8 Q F2(x)2.5 E F1 5(.T)C(he v)327.31
+409.8 Q(alues for)-.25 E F2(x)2.5 E F1(are:)2.5 E 15(pP)229 426 S
+(rint error messages \(def)254.56 426 Q(ault\))-.1 E 15(qN)229 438 S 2.5(om)
+256.22 438 S(essages, just gi)271.5 438 Q .3 -.15(ve ex)-.25 H(it status).15 E
+12.22(mM)229 450 S(ail back errors)257.89 450 Q 12.78(wW)229 462 S
+(rite back errors \(mail if user not logged in\))258.44 462 Q 15.56(eM)229 474
+S(ail back errors and gi)257.89 474 Q .3 -.15(ve z)-.25 H(ero e).15 E
+(xit stat al)-.15 E -.1(wa)-.1 G(ys).1 E(E)117 494.4 Q F2(\214le/messa)A -.1
+(ge)-.1 G F1 .549(Prepend error messages with the indicated message.)189 494.4
+R .549(If it be)5.549 F .549(gins with a slash,)-.15 F .107(it is assumed to b\
+e the pathname of a \214le containing a message \(this is the rec-)189 506.4 R
+1.317(ommended setting\).)189 518.4 R 1.316
+(Otherwise, it is a literal message.)6.317 F 1.316(The error \214le might)6.316
+F .99
+(contain the name, email address, and/or phone number of a local postmaster)189
+530.4 R .429(who could pro)189 542.4 R .429(vide assistance in to end users.)
+-.15 F .428(If the option is missing or null,)5.429 F .342
+(or if it names a \214le which does not e)189 554.4 R .342
+(xist or which is not readable, no message)-.15 F(is printed.)189 566.4 Q 68.67
+(fS)117 582.6 S -2.25 -.2(av e)194.56 582.6 T 2.399
+(Unix-style \231From\232 lines at the front of headers.)5.1 F 2.399
+(Normally the)7.399 F 4.899(ya)-.15 G(re)496.23 582.6 Q
+(assumed redundant and discarded.)189 594.6 Q(F)117 610.8 Q F2(mode)A F1
+(The \214le mode for queue \214les.)189 610.8 Q(g)117 627 Q F2(n)A F1 .933
+(Set the def)189 627 R .933(ault group id for mailers to run in to)-.1 F F2(n)
+3.433 E F1 5.933(.D)C(ef)408.966 627 Q .933(aults to 1.)-.1 F .934(The v)5.934
+F(alue)-.25 E(can also be gi)189 639 Q -.15(ve)-.25 G 2.5(na).15 G 2.5(sas)
+264.69 639 S(ymbolic group name.)281.91 639 Q 64.78(GA)117 655.2 S(llo)196.22
+655.2 Q 3.492(wf)-.25 G .992(uzzy matching on the GECOS \214eld.)220.572 655.2
+R .991(If this \215ag is set, and the usual)5.991 F .793(user name lookups f)
+189 667.2 R .793(ail \(that is, there is no alias with this name and a)-.1 F F2
+-.1(ge)3.294 G(tpw-).1 E(nam)189 679.2 Q F1 -.1(fa)3.702 G 1.202
+(ils\), sequentially search the passw).1 F 1.201
+(ord \214le for a matching entry in the)-.1 F 1.446(GECOS \214eld.)189 691.2 R
+1.446(This also requires that MA)6.446 F 1.446(TCHGECOS be turned on during)
+-1.11 F 2.5(compilation. This)189 703.2 R(option is not recommended.)2.5 E EP
+%%Page: 35 30
+%%BeginPageSetup
+BP
+%%EndPageSetup
+/F0 10/Times-Bold@0 SF(Sendmail Installation and Operation Guide)72 60 Q
+(SMM:08-35)452.9 60 Q/F1 10/Times-Roman@0 SF(h)117 96 Q/F2 10/Times-Italic@0 SF
+(N)A F1 1.274(The maximum hop count.)189 96 R 1.274(Messages that ha)6.274 F
+1.574 -.15(ve b)-.2 H 1.273(een processed more than).15 F F2(N)3.773 E F1
+(times are assumed to be in a loop and are rejected.)189 108 Q(Def)5 E
+(aults to 25.)-.1 E(H)117 124.2 Q F2(\214le)A F1
+(Specify the help \214le for SMTP)189 124.2 Q(.)-1.11 E 69.22(iI)117 140.4 S
+1.014(gnore dots in incoming messages.)192.33 140.4 R 1.014(This is al)6.014 F
+-.1(wa)-.1 G 1.014(ys disabled \(that is, dots are).1 F(al)189 152.4 Q -.1(wa)
+-.1 G(ys accepted\) when reading SMTP mail.).1 E 68.67(II)117 168.6 S .62
+(nsist that the BIND name serv)192.33 168.6 R .619(er be running to resolv)-.15
+F 3.119(eh)-.15 G .619(ost names.)421.524 168.6 R .619(If this is)5.619 F .945
+(not set and the name serv)189 180.6 R .945(er is not running, the)-.15 F F2
+(/etc/hosts)3.445 E F1 .945(\214le will be consid-)3.445 F .188(ered complete.)
+189 192.6 R .188(In general, you do w)5.188 F .188
+(ant to set this option if your)-.1 F F2(/etc/hosts)2.687 E F1(\214le)2.687 E
+.412(does not include all hosts kno)189 204.6 R .412
+(wn to you or if you are using the MX \(mail for)-.25 F(-)-.2 E -.1(wa)189
+216.6 S .315(rding\) feature of the BIND name serv).1 F(er)-.15 E 5.315(.T)-.55
+G .315(he name serv)373.955 216.6 R .314(er will still be con-)-.15 F 1.522
+(sulted e)189 228.6 R -.15(ve)-.25 G 4.022(ni).15 G 4.022(ft)242.194 228.6 S
+1.523(his option is not set, b)252.326 228.6 R(ut)-.2 E F2(sendmail)4.023 E F1
+1.523(will feel free to resort to)4.023 F(reading)189 240.6 Q F2(/etc/hosts)
+3.053 E F1 .553(if the name serv)3.053 F .552(er is not a)-.15 F -.25(va)-.2 G
+3.052(ilable. Thus,).25 F .552(you should)3.052 F F2(ne)3.052 E(ver)-.15 E F1
+(set this option if you do not run the name serv)189 252.6 Q(er)-.15 E(.)-.55 E
+69.22(jI)117 268.8 S 3.128(fs)192.33 268.8 S .628
+(et, send error messages in MIME format \(see RFC1341 and RFC1344 for)202.678
+268.8 R(details\).)189 280.8 Q(J)117 297 Q F2(path)A F1 4.923
+(Set the path for searching for users' .forw)189 297 R 4.923(ard \214les.)-.1 F
+4.922(The def)9.922 F 4.922(ault is)-.1 F(\231$z/.forw)189 309 Q 2.868
+(ard\232. Some)-.1 F .368
+(sites that use the automounter may prefer to change this)2.868 F .676
+(to \231/v)189 321 R(ar/forw)-.25 E .676
+(ard/$u\232 to search a \214le with the same name as the user in a sys-)-.1 F
+.924(tem directory)189 333 R 5.924(.I)-.65 G 3.424(tc)254.628 333 S .924
+(an also be set to a sequence of paths separated by colons;)265.272 333 R F2
+(sendmail)189 345 Q F1 .645
+(stops at the \214rst \214le it can successfully and safely open.)3.146 F -.15
+(Fo)5.645 G 3.145(re).15 G(xam-)483.45 345 Q 1.535(ple, \231/v)189 357 R
+(ar/forw)-.25 E(ard/$u:$z/.forw)-.1 E 1.535(ard\232 will search \214rst in /v)
+-.1 F(ar/forw)-.25 E(ard/)-.1 E F2(username)A F1(and then in)189 369 Q F2
+(~username)2.5 E F1(/.forw)A(ard \(b)-.1 E
+(ut only if the \214rst \214le does not e)-.2 E(xist\).)-.15 E(k)117 385.2 Q F2
+(N)A F1 .196
+(The maximum number of open connections that will be cached at a time.)189
+385.2 R(The)5.196 E(def)189 397.2 Q 1.956(ault is one.)-.1 F 1.956
+(This delays closing the current connection until either this)6.956 F(in)189
+409.2 Q -.2(vo)-.4 G .516(cation of).2 F F2(sendmail)3.016 E F1 .516
+(needs to connect to another host or it terminates.)3.016 F(Set-)5.515 E 1.958
+(ting it to zero def)189 421.2 R 1.958(aults to the old beha)-.1 F(vior)-.2 E
+4.459(,t)-.4 G 1.959(hat is, connections are closed)379.244 421.2 R
+(immediately)189 433.2 Q(.)-.65 E(K)117 449.4 Q F2(timeout)A F1 .883
+(The maximum amount of time a cached connection will be permitted to idle)189
+449.4 R 2.746(without acti)189 461.4 R(vity)-.25 E 7.746(.I)-.65 G 5.246(ft)
+267.482 461.4 S 2.746(his time is e)278.838 461.4 R 2.746
+(xceeded, the connection is immediately)-.15 F 4.423(closed. This)189 473.4 R
+-.25(va)4.423 G 1.922(lue should be small \(on the order of ten minutes\).).25
+F(Before)6.922 E F2(sendmail)189 485.4 Q F1 1.286
+(uses a cached connection, it al)3.786 F -.1(wa)-.1 G 1.287
+(ys sends a NOOP \(no operation\)).1 F 2.058
+(command to check the connection; if this f)189 497.4 R 2.058
+(ails, it reopens the connection.)-.1 F .478(This k)189 509.4 R .478
+(eeps your end from f)-.1 F .478(ailing if the other end times out.)-.1 F .478
+(The point of this)5.478 F 3.099(option is to be a good netw)189 521.4 R 3.099
+(ork neighbor and a)-.1 F -.2(vo)-.2 G 3.099(id using up e).2 F(xcessi)-.15 E
+-.15(ve)-.25 G(resources on the other end.)189 533.4 Q(The def)5 E
+(ault is \214v)-.1 E 2.5(em)-.15 G(inutes.)383.99 533.4 Q 69.22(lI)117 549.6 S
+3.14(ft)192.33 549.6 S .64(here is an \231Errors-T)201.58 549.6 R .64
+(o:\232 header)-.8 F 3.14(,s)-.4 G .64
+(end error messages to the addresses listed)333.53 549.6 R 3.951(there. The)189
+561.6 R 3.951(yn)-.15 G 1.451(ormally go to the en)247.292 561.6 R -.15(ve)-.4
+G 1.451(lope sender).15 F 6.451(.U)-.55 G 1.451(se of this option causes)
+405.428 561.6 R F2(sendmail)189 573.6 Q F1(to violate RFC 1123.)2.5 E(L)117
+589.8 Q F2(n)A F1(Set the def)189 589.8 Q(ault log le)-.1 E -.15(ve)-.25 G 2.5
+(lt).15 G(o)288.77 589.8 Q F2(n)2.5 E F1 5(.D)C(ef)315.99 589.8 Q(aults to 9.)
+-.1 E 64.22(mS)117 606 S(end to me too, e)194.56 606 Q -.15(ve)-.25 G 2.5(ni)
+.15 G 2.5(fIa)278.04 606 S 2.5(mi)294.14 606 S 2.5(na)307.2 606 S 2.5(na)319.14
+606 S(lias e)331.08 606 Q(xpansion.)-.15 E(M)117 622.2 Q F2 1.666(xv)C(alue)
+-1.666 E F1 1.312(Set the macro)189 622.2 R F2(x)3.812 E F1(to)3.812 E F2
+(value)3.812 E F1 6.312(.T)C 1.312
+(his is intended only for use from the command)306.852 622.2 R(line.)189 634.2
+Q 67(nV)117 650.4 S(alidate the RHS of aliases when reb)195.11 650.4 Q
+(uilding the alias database.)-.2 E 67(oA)117 666.6 S 1.786
+(ssume that the headers may be in old format, i.e., spaces delimit names.)
+196.22 666.6 R .432(This actually turns on an adapti)189 678.6 R .733 -.15
+(ve a)-.25 H .433(lgorithm: if an).15 F 2.933(yr)-.15 G .433
+(ecipient address contains)403.154 678.6 R 5.09(ac)189 690.6 S 2.589
+(omma, parenthesis, or angle brack)202.97 690.6 R 2.589
+(et, it will be assumed that commas)-.1 F .484(already e)189 702.6 R 2.984
+(xist. If)-.15 F .485(this \215ag is not on, only commas delimit names.)2.984 F
+.485(Headers are)5.485 F(al)189 714.6 Q -.1(wa)-.1 G
+(ys output with commas between the names.).1 E EP
+%%Page: 36 31
+%%BeginPageSetup
+BP
+%%EndPageSetup
+/F0 10/Times-Bold@0 SF 193.36(SMM:08-36 Sendmail)72 60 R
+(Installation and Operation Guide)2.5 E/F1 10/Times-Roman@0 SF(O)117 96 Q/F2 10
+/Times-Italic@0 SF(options)A F1(Set serv)189 96 Q(er SMTP options.)-.15 E
+(The options are)5 E F2 -.1(ke)2.5 G(y=value)-.2 E F1 2.5(pairs. Kno)2.5 F
+(wn k)-.25 E -.15(ey)-.1 G 2.5(sa).15 G(re:)488.82 96 Q 52.83(Port Name/number)
+229 112.2 R(of listening port \(def)2.5 E(aults to "smtp"\))-.1 E 48.95
+(Addr Address)229 124.2 R(mask \(def)2.5 E(aults IN)-.1 E(ADDR_ANY\))-.35 E
+-.15(Fa)229 136.2 S 41.31(mily Address).15 F -.1(fa)2.5 G(mily \(def).1 E
+(aults to INET\))-.1 E 44.5(Listen Size)229 148.2 R(of listen queue \(def)2.5 E
+(aults to 10\))-.1 E(The)189 164.4 Q F2(Addr)4.114 E F1 1.614
+(ess mask may be a numeric address in dot notation or a netw)B(ork)-.1 E(name.)
+189 176.4 Q(p)117 192.6 Q F2(opt,opt,...)1.666 E F1 1.22(Set the pri)189 192.6
+R -.25(va)-.25 G -.15(cy).25 G F2(opt)3.871 E F1 3.721(ions. `)B(`Pri)-.74 E
+-.25(va)-.25 G -.15(cy).25 G 2.701 -.74('' i).15 H 3.721(sr).74 G 1.221
+(eally a misnomer; man)351.854 192.6 R 3.721(yo)-.15 G 3.721(ft)460.468 192.6 S
+1.221(hese are)470.299 192.6 R 2.419(just a w)189 204.6 R 2.418
+(ay of insisting on stricter adherence to the SMTP protocol.)-.1 F(The)7.418 E
+F2(opt)189 216.6 Q F1(ions can be selected from:)A 40.26(public Allo)229 232.8
+R 2.5(wo)-.25 G(pen access)329.01 232.8 Q 11.38(needmailhelo Insist)229 244.8 R
+(on HELO or EHLO command before MAIL)2.5 E(neede)229 256.8 Q 9.87
+(xpnhelo Insist)-.15 F(on HELO or EHLO command before EXPN)2.5 E(noe)229 268.8
+Q 35.97(xpn Disallo)-.15 F 2.5(wE)-.25 G(XPN entirely)341.23 268.8 Q 12.5
+(needvrfyhelo Insist)229 280.8 R(on HELO or EHLO command before VRFY)2.5 E(no)
+229 292.8 Q 38.75(vrfy Disallo)-.15 F 2.5(wV)-.25 G(RFY entirely)342.34 292.8 Q
+14.71(restrictmailq Restrict)229 304.8 R(mailq command)2.5 E 19.16
+(restrictqrun Restrict)229 316.8 R(\255q command line \215ag)2.5 E 24.16
+(noreceipts Ignore)229 328.8 R(Return-Receipt-T)2.5 E(o: header)-.8 E(goa)229
+340.8 Q -.1(wa)-.15 G 36.91(yD).1 G(isallo)303.98 340.8 Q 2.5(we)-.25 G
+(ssentially all SMTP status queries)339.56 340.8 Q(authw)229 352.8 Q 11.48
+(arnings Put)-.1 F(X-Authentication-W)2.5 E(arning: headers in messages)-.8 E
+1.565(The \231goa)189 369 R -.1(wa)-.15 G 1.565
+(y\232 pseudo-\215ag sets all \215ags e).1 F 1.566
+(xcept \231restrictmailq\232 and \231restric-)-.15 F 4.299(tqrun\232. If)189
+381 R 1.798(mailq is restricted, only people in the same group as the queue)
+4.299 F .946(directory can print the queue.)189 393 R .946
+(If queue runs are restricted, only root and the)5.946 F -.25(ow)189 405 S .178
+(ner of the queue directory can run the queue.).25 F .178(Authentication W)
+5.178 F .178(arnings add)-.8 F -.1(wa)189 417 S .008(rnings about v).1 F .008
+(arious conditions that may indicate attempts to spoof the mail)-.25 F
+(system, such as using an non-standard queue directory)189 429 Q(.)-.65 E(P)117
+445.2 Q F2(postmaster)A F1 1.115
+(If set, copies of error messages will be sent to the named)189 445.2 R F2
+(postmaster)3.614 E F1 6.114(.O)C(nly)491.22 445.2 Q .397(the header of the f)
+189 457.2 R .398(ailed message is sent.)-.1 F .398
+(Since most errors are user problems,)5.398 F .564
+(this is probably not a good idea on lar)189 469.2 R .563(ge sites, and ar)-.18
+F .563(guably contains all sorts)-.18 F .05(of pri)189 481.2 R -.25(va)-.25 G
+.35 -.15(cy v).25 H .05(iolations, b).15 F .05
+(ut it seems to be popular with certain operating systems)-.2 F -.15(ve)189
+493.2 S(ndors.).15 E(q)117 509.4 Q F2(factor)A F1(Use)189 509.4 Q F2(factor)
+3.098 E F1 .597
+(as the multiplier in the map function to decide when to just queue)3.098 F
+.425(up jobs rather than run them.)189 521.4 R .425(This v)5.425 F .425
+(alue is di)-.25 F .426(vided by the dif)-.25 F .426(ference between)-.25 F
+1.064(the current load a)189 533.4 R -.15(ve)-.2 G 1.064(rage and the load a)
+.15 F -.15(ve)-.2 G 1.064(rage limit \().15 F F0(x)A F1 1.063
+(\215ag\) to determine the)3.564 F(maximum message priority that will be sent.)
+189 545.4 Q(Def)5 E(aults to 600000.)-.1 E(Q)117 561.6 Q F2(dir)A F1
+(Use the named)189 561.6 Q F2(dir)2.5 E F1(as the queue directory)2.5 E(.)-.65
+E(r)117 577.8 Q F2(timeouts)1.666 E F1 -.35(Ti)189 577.8 S 3.938
+(meout reads after).35 F F2(time)6.438 E F1(interv)6.438 E 6.438(al. The)-.25 F
+F2(timeouts)6.438 E F1(ar)6.438 E 3.938(gument is a list of)-.18 F F2 -.1(ke)
+189 589.8 S(ywor)-.2 E(d=value)-.37 E F1 3.61(pairs. The)3.61 F 1.11
+(recognized timeouts and their def)3.61 F 1.11(ault v)-.1 F 1.11(alues, and)
+-.25 F(their minimum v)189 601.8 Q
+(alues speci\214ed in RFC 1123 section 5.3.2 are:)-.25 E EP
+%%Page: 37 32
+%%BeginPageSetup
+BP
+%%EndPageSetup
+/F0 10/Times-Bold@0 SF(Sendmail Installation and Operation Guide)72 60 Q
+(SMM:08-37)452.9 60 Q/F1 10/Times-Roman@0 SF 23.6(initial w)229 96 R
+(ait for initial greeting message [5m, 5m])-.1 E 29.72(helo reply)229 108 R
+(to HELO or EHLO command [5m, none])2.5 E 29.16(mail reply)229 120 R
+(to MAIL command [10m, 5m])2.5 E 31.39(rcpt reply)229 132 R
+(to RCPT command [1h, 5m])2.5 E 16.94(datainit reply)229 144 R(to D)2.5 E -1.21
+-1.11(AT A)-.4 H(command [5m, 2m])3.61 E 8.06(datablock data)229 156 R
+(block read [1h, 3m])2.5 E 12.5(data\214nal reply)229 168 R(to \214nal `)2.5 E
+(`.)-.74 E 1.48 -.74('' i)-.7 H 2.5(nd).74 G(ata [1h, 10m])363.47 168 Q 32.5
+(rset reply)229 180 R(to RSET command [5m, none])2.5 E 31.38(quit reply)229 192
+R(to Q)2.5 E(UIT command [2m, none])-.1 E 28.05(misc reply)229 204 R
+(to NOOP and VERB commands [2m, none])2.5 E 7.5(command command)229 216 R
+(read [1h, 5m])2.5 E 26.94(ident IDENT)229 228 R(protocol timeout [30s, none])
+2.5 E .798(All b)189 244.2 R .798(ut \231command\232 apply to client SMTP)-.2 F
+5.798(.F)-1.11 G .798(or back compatibility)373.406 244.2 R 3.299(,at)-.65 G
+(imeout)476.22 244.2 Q(with no `)189 256.2 Q(`k)-.74 E -.15(ey)-.1 G -.1(wo).15
+G(rd=').1 E 2.5('p)-.74 G(art will set all of the longer v)281.4 256.2 Q
+(alues.)-.25 E 65.33(RN)117 272.4 S(ormally)196.22 272.4 Q(,)-.65 E/F2 10
+/Times-Italic@0 SF(sendmail)4.154 E F1 1.653(tries to eliminate an)4.154 F
+4.153(yu)-.15 G 1.653(nnecessary e)371.721 272.4 R 1.653(xplicit routes when)
+-.15 F .931(sending an error message \(as discussed in RFC 1123 \247 5.2.6\).)
+189 284.4 R -.15(Fo)5.931 G 3.431(re).15 G(xample,)472.06 284.4 Q
+(when sending an error message to)189 296.4 Q(<@kno)229 312.6 Q(wn1,@kno)-.25 E
+(wn2,@unkno)-.25 E(wn:user@kno)-.25 E(wn3>)-.25 E F2(sendmail)189 328.8 Q F1
+.46(will strip of)2.96 F 2.96(ft)-.25 G .46(he \231@kno)284.48 328.8 R .46
+(wn1\232 in order to mak)-.25 F 2.96(et)-.1 G .46(he route as direct as)422.74
+328.8 R 3.429(possible. Ho)189 340.8 R(we)-.25 E -.15(ve)-.25 G 1.729 -.4(r, i)
+.15 H 3.429(ft).4 G(he)284.057 340.8 Q F0(R)3.429 E F1 .929
+(option is set, this will be disabled, and the mail)3.429 F .362
+(will be sent to the \214rst address in the route, e)189 352.8 R -.15(ve)-.25 G
+2.862(ni).15 G 2.862(fl)391.452 352.8 S .362(ater addresses are kno)400.424
+352.8 R(wn.)-.25 E(This may be useful if you are caught behind a \214re)189
+364.8 Q -.1(wa)-.25 G(ll.).1 E 68.11(sB)117 381 S 2.729(es)195.67 381 S(uper)
+206.729 381 Q .229(-safe when running things, i.e., al)-.2 F -.1(wa)-.1 G .229
+(ys instantiate the queue \214le, e).1 F -.15(ve)-.25 G(n).15 E .739
+(if you are going to attempt immediate deli)189 393 R -.15(ve)-.25 G(ry).15 E
+(.)-.65 E F2(Sendmail)5.739 E F1(al)3.239 E -.1(wa)-.1 G .739(ys instantiates)
+.1 F(the queue \214le before returning control the client under an)189 405 Q
+2.5(yc)-.15 G(ircumstances.)429.35 405 Q(S)117 421.2 Q F2(\214le)A F1
+(Log statistics in the named)189 421.2 Q F2(\214le)2.5 E F1(.)A(t)117 437.4 Q
+F2(tzinfo)A F1 .716(Set the local time zone info to)189 437.4 R F2(tzinfo)3.217
+E F1 3.217<8a66>3.217 G .717(or e)358.499 437.4 R .717
+(xample, \231PST8PDT\232.)-.15 F(Actually)5.717 E(,)-.65 E .315
+(if this is not set, the TZ en)189 449.4 R .314(vironment v)-.4 F .314
+(ariable is cleared \(so the system def)-.25 F(ault)-.1 E .55
+(is used\); if set b)189 461.4 R .55(ut null, the user')-.2 F 3.051(sT)-.55 G
+3.051(Zv)334.032 461.4 S .551(ariable is used, and if set and non-null)347.943
+461.4 R(the TZ v)189 473.4 Q(ariable is set to this v)-.25 E(alue.)-.25 E(T)117
+489.6 Q F2(rtime/wtime)A F1 1.604(Set the queue timeout to)189 489.6 R F2
+(rtime)4.103 E F1 6.603(.A)C 1.603(fter this interv)334.172 489.6 R 1.603
+(al, messages that ha)-.25 F 1.903 -.15(ve n)-.2 H(ot).15 E 1.251
+(been successfully sent will be returned to the sender)189 501.6 R 6.252(.D)
+-.55 G(ef)422.724 501.6 Q 1.252(aults to \214v)-.1 F 3.752(ed)-.15 G(ays.)
+488.17 501.6 Q .546(The optional)189 513.6 R F2(wtime)3.046 E F1 .546
+(is the time after which a w)3.046 F .546(arning message is sent.)-.1 F .546
+(If it is)5.546 F(missing or zero then no w)189 525.6 Q
+(arning messages are sent.)-.1 E(u)117 541.8 Q F2(n)A F1 .175(Set the def)189
+541.8 R .175(ault userid for mailers to)-.1 F F2(n)2.675 E F1 5.175(.M)C .175
+(ailers without the)355.28 541.8 R F2(S)2.676 E F1 .176(\215ag in the mailer)
+2.676 F .084(de\214nition will run as this user)189 553.8 R 5.084(.D)-.55 G(ef)
+322.844 553.8 Q .084(aults to 1.)-.1 F .084(The v)5.084 F .084
+(alue can also be gi)-.25 F -.15(ve)-.25 G 2.583(na).15 G 2.583(sa)493.087
+553.8 S(symbolic user name.)189 565.8 Q(U)117 582 Q F2(udbspec)A F1
+(The user database speci\214cation.)189 582 Q 67(vR)117 598.2 S .411(un in v)
+195.67 598.2 R .411(erbose mode.)-.15 F .411(If this is set,)5.411 F F2
+(sendmail)2.912 E F1 .412(adjusts options)2.912 F F0(c)2.912 E F1(\(don')2.912
+E 2.912(tc)-.18 G(onnect)477.34 598.2 Q .428(to e)189 610.2 R(xpensi)-.15 E
+.728 -.15(ve m)-.25 H .428(ailers\) and).15 F F0(d)2.928 E F1(\(deli)2.928 E
+-.15(ve)-.25 G .428(ry mode\) so that all mail is deli).15 F -.15(ve)-.25 G
+.427(red com-).15 F .048
+(pletely in a single job so that you can see the entire deli)189 622.2 R -.15
+(ve)-.25 G .048(ry process.).15 F(Option)5.048 E F0(v)2.548 E F1(should)189
+634.2 Q F2(ne)3.39 E(ver)-.15 E F1 .889
+(be set in the con\214guration \214le; it is intended for command line)3.39 F
+(use only)189 646.2 Q(.)-.65 E(V)117 662.4 Q F2(fallbac)A(khost)-.2 E F1 .963
+(If speci\214ed, the)189 662.4 R F2(fallbac)3.464 E(khost)-.2 E F1 .964
+(acts lik)3.464 F 3.464(eav)-.1 G .964(ery lo)358.606 662.4 R 3.464(wp)-.25 G
+.964(riority MX on e)398.054 662.4 R -.15(ve)-.25 G .964(ry host.).15 F
+(This is intended to be used by sites with poor netw)189 674.4 Q(ork connecti)
+-.1 E(vity)-.25 E(.)-.65 E 64.78(wI)117 690.6 S 4.06(fy)192.33 690.6 S 1.56
+(ou are the \231best\232 \(that is, lo)204.72 690.6 R 1.56
+(west preference\) MX for a gi)-.25 F -.15(ve)-.25 G 4.06(nh).15 G 1.56
+(ost, you)470.77 690.6 R .433
+(should normally detect this situation and treat that condition specially)189
+702.6 R 2.933(,b)-.65 G 2.933(yf)481.277 702.6 S(or)492.54 702.6 Q(-)-.2 E -.1
+(wa)189 714.6 S .594
+(rding the mail to a UUCP feed, treating it as local, or whate).1 F -.15(ve)
+-.25 G 4.193 -.55(r. H).15 H -.25(ow).55 G -2.15 -.25(ev e).25 H -.4(r,).25 G
+EP
+%%Page: 38 33
+%%BeginPageSetup
+BP
+%%EndPageSetup
+/F0 10/Times-Bold@0 SF 193.36(SMM:08-38 Sendmail)72 60 R
+(Installation and Operation Guide)2.5 E/F1 10/Times-Roman@0 SF 1.897
+(in some cases \(such as Internet \214re)189 96 R -.1(wa)-.25 G 1.898
+(lls\) you may w).1 F 1.898(ant to try to connect)-.1 F .352
+(directly to that host as though it had no MX records at all.)189 108 R .352
+(Setting this option)5.352 F(causes)189 120 Q/F2 10/Times-Italic@0 SF(sendmail)
+3.032 E F1 .532(to try this.)3.032 F .532(The do)5.532 F .533
+(wnside is that errors in your con\214guration)-.25 F .543(are lik)189 132 R
+.543(ely to be diagnosed as \231host unkno)-.1 F .542
+(wn\232 or \231message timed out\232 instead)-.25 F
+(of something more meaningful.)189 144 Q(This option is disrecommended.)5 E(x)
+117 160.2 Q F2(LA)A F1 .108(When the system load a)189 160.2 R -.15(ve)-.2 G
+.108(rage e).15 F(xceeds)-.15 E F2(LA)2.608 E F1 2.608(,j)C .109
+(ust queue messages \(i.e., don')367.546 160.2 R 2.609(tt)-.18 G(ry)495.67
+160.2 Q(to send them\).)189 172.2 Q(Def)5 E(aults to 8.)-.1 E(X)117 188.4 Q F2
+(LA)A F1 1.251(When the system load a)189 188.4 R -.15(ve)-.2 G 1.251(rage e)
+.15 F(xceeds)-.15 E F2(LA)3.751 E F1 3.751(,r)C 1.251
+(efuse incoming SMTP connec-)376.097 188.4 R 2.5(tions. Def)189 200.4 R
+(aults to 12.)-.1 E(y)117 216.6 Q F2(fact)A F1 .621(The indicated)189 216.6 R
+F2(fact)3.121 E F1 .621(or is added to the priority \(thus)B F2(lowering)3.122
+E F1 .622(the priority of the)3.122 F 1.384
+(job\) for each recipient, i.e., this v)189 228.6 R 1.383
+(alue penalizes jobs with lar)-.25 F 1.383(ge numbers of)-.18 F 2.5
+(recipients. Def)189 240.6 R(aults to 30000.)-.1 E 64.78(YI)117 256.8 S 3.346
+(fs)192.33 256.8 S .846(et, deli)202.896 256.8 R -.15(ve)-.25 G 3.346(re).15 G
+.847(ach job that is run from the queue in a separate process.)251.118 256.8 R
+(Use)5.847 E .037(this option if you are short of memory)189 268.8 R 2.536(,s)
+-.65 G .036(ince the def)350.024 268.8 R .036(ault tends to consume con-)-.1 F
+(siderable amounts of memory while the queue is being processed.)189 280.8 Q(z)
+117 297 Q F2(fact)A F1 1.644(The indicated)189 297 R F2(fact)4.144 E F1 1.645
+(or is multiplied by the message class \(determined by the)B .923
+(Precedence: \214eld in the user header and the)189 309 R F0(P)3.423 E F1 .923
+(lines in the con\214guration \214le\))3.423 F .819
+(and subtracted from the priority)189 321 R 5.819(.T)-.65 G .819
+(hus, messages with a higher Priority: will)333.255 321 R(be f)189 333 Q -.2
+(avo)-.1 G 2.5(red. Def).2 F(aults to 1800.)-.1 E(Z)117 349.2 Q F2(fact)A F1
+(The)189 349.2 Q F2(fact)3.346 E F1 .846(or is added to the priority e)B -.15
+(ve)-.25 G .846(ry time a job is processed.).15 F .845(Thus, each)5.845 F .942
+(time a job is processed, its priority will be decreased by the indicated v)189
+361.2 R(alue.)-.25 E .297(In most en)189 373.2 R .296
+(vironments this should be positi)-.4 F -.15(ve)-.25 G 2.796(,s).15 G .296
+(ince hosts that are do)378.614 373.2 R .296(wn are all)-.25 F(too often do)189
+385.2 Q(wn for a long time.)-.25 E(Def)5 E(aults to 90000.)-.1 E 67(7S)117
+401.4 S .278(trip input to se)194.56 401.4 R -.15(ve)-.25 G 2.778(nb).15 G .278
+(its for compatibility with old systems.)275.272 401.4 R .279(This shouldn')
+5.279 F 2.779(tb)-.18 G(e)499.56 401.4 Q(necessary)189 413.4 Q(.)-.65 E .78
+(All options can be speci\214ed on the command line using the \255o \215ag, b)
+117 429.6 R .779(ut most will cause)-.2 F F2(send-)3.279 E(mail)117 441.6 Q F1
+.236(to relinquish its setuid permissions.)2.736 F .237
+(The options that will not cause this are b, d, e, i, L, m,)5.237 F .175
+(o, p, r)117 453.6 R 2.675(,s)-.4 G 2.675(,v)149.345 453.6 S 2.675(,C)158.87
+453.6 S 2.675(,a)170.715 453.6 S .174(nd 7.)180.33 453.6 R .174(Also, M \(de\
+\214ne macro\) when de\214ning the r or s macros is also considered)5.174 F
+(\231safe\232.)117 465.6 Q F0 2.5(5.1.7. P)102 489.6 R 2.5<8a70>2.5 G -.18(re)
+156.17 489.6 S(cedence de\214nitions).18 E F1 -1.11(Va)142 505.8 S .304
+(lues for the \231Precedence:\232 \214eld may be de\214ned using the)1.11 F F0
+(P)2.805 E F1 .305(control line.)2.805 F .305(The syntax of)5.305 F
+(this \214eld is:)117 517.8 Q F0(P)157 534 Q F2(name)A F0(=)A F2(num)A F1 .286
+(When the)117 550.2 R F2(name)2.786 E F1 .285
+(is found in a \231Precedence:\232 \214eld, the message class is set to)2.786 F
+F2(num)2.785 E F1 5.285(.H)C .285(igher num-)459.555 550.2 R .479
+(bers mean higher precedence.)117 562.2 R .479(Numbers less than zero ha)5.479
+F .779 -.15(ve t)-.2 H .48(he special property that if an error).15 F 1.11(occ\
+urs during processing the body of the message will not be returned; this is e)
+117 574.2 R 1.11(xpected to be)-.15 F .678(used for \231b)117 586.2 R .678
+(ulk\232 mail such as through mailing lists.)-.2 F .678(The def)5.678 F .678
+(ault precedence is zero.)-.1 F -.15(Fo)5.678 G 3.178(re).15 G(xam-)483.45
+586.2 Q(ple, our list of precedences is:)117 598.2 Q(P\214rst-class=0)157 614.4
+Q(Pspecial-deli)157 626.4 Q -.15(ve)-.25 G(ry=100).15 E(Plist=\25530)157 638.4
+Q(Pb)157 650.4 Q(ulk=\25560)-.2 E(Pjunk=\255100)157 662.4 Q .8
+(People writing mailing list e)117 678.6 R .799
+(xploders are encouraged to use \231Precedence: list\232.)-.15 F .799(Older v)
+5.799 F(ersions)-.15 E(of)117 690.6 Q F2(sendmail)3.759 E F1 1.259
+(\(which discarded all error returns for ne)3.759 F -.05(ga)-.15 G(ti).05 E
+1.559 -.15(ve p)-.25 H 1.259(recedences\) didn').15 F 3.76(tr)-.18 G 1.26
+(ecognize this)450.25 690.6 R .255(name, gi)117 702.6 R .255(ving it a def)-.25
+F .255(ault precedence of zero.)-.1 F .254(This allo)5.254 F .254
+(ws list maintainers to see error returns on)-.25 F(both old and ne)117 714.6 Q
+2.5(wv)-.25 G(ersions of)193.26 714.6 Q F2(sendmail)2.5 E F1(.)A EP
+%%Page: 39 34
+%%BeginPageSetup
+BP
+%%EndPageSetup
+/F0 10/Times-Bold@0 SF(Sendmail Installation and Operation Guide)72 60 Q
+(SMM:08-39)452.9 60 Q 2.5(5.1.8. V)102 96 R 2.5<8a63>2.5 G(on\214guration v)
+156.16 96 Q(ersion le)-.1 E -.1(ve)-.15 G(l).1 E/F1 10/Times-Roman@0 SF 2.11
+-.8(To p)142 112.2 T(ro).8 E .51
+(vide compatibility with old con\214guration \214les, the)-.15 F F0(V)3.01 E F1
+.51(line has been added to de\214ne)3.01 F .173(some v)117 124.2 R .173
+(ery basic semantics of the con\214guration \214le.)-.15 F .172
+(These are not intended to be long term sup-)5.173 F 1.84(ports; rather)117
+136.2 R 4.34(,t)-.4 G(he)176.66 136.2 Q 4.34(yd)-.15 G 1.84
+(escribe compatibility features which will probably be remo)200.29 136.2 R -.15
+(ve)-.15 G 4.34(di).15 G 4.34(nf)470.78 136.2 S(uture)483.45 136.2 Q(releases.)
+117 148.2 Q F0(N.B.:)142 164.4 Q F1 1.032(these v)3.532 F(ersion)-.15 E/F2 10
+/Times-Italic@0 SF(le)3.532 E(vels)-.15 E F1(ha)3.532 E 1.332 -.15(ve n)-.2 H
+1.032(othing to do with the v).15 F(ersion)-.15 E F2(number)3.532 E F1 1.032
+(on the \214les.)3.532 F -.15(Fo)6.032 G(r).15 E -.15(ex)117 176.4 S .384
+(ample, as of this writing v).15 F .384
+(ersion 8 con\214g \214les \(speci\214cally)-.15 F 2.884(,8)-.65 G .384
+(.6\) used v)373.76 176.4 R .384(ersion le)-.15 F -.15(ve)-.25 G 2.884(l5c).15
+G(on\214gu-)475.11 176.4 Q(rations.)117 188.4 Q .031
+(\231Old\232 con\214guration \214les are de\214ned as v)142 204.6 R .031
+(ersion le)-.15 F -.15(ve)-.25 G 2.531(lo).15 G 2.531(ne. V)359.438 204.6 R
+.031(ersion le)-1.11 F -.15(ve)-.25 G 2.53(lt).15 G .23 -.1(wo \214)433.84
+204.6 T .03(les mak).1 F 2.53(et)-.1 G(he)494.56 204.6 Q(follo)117 216.6 Q
+(wing changes:)-.25 E 12.5(\(1\) Host)122 232.8 R .757(name canoni\214cation \
+\($[ ... $]\) appends a dot if the name is recognized; this gi)3.256 F -.15(ve)
+-.25 G(s).15 E .903(the con\214g \214le a w)148.66 244.8 R .903
+(ay of \214nding out if an)-.1 F .903(ything matched.)-.15 F(\(Actually)5.903 E
+3.403(,t)-.65 G .902(his just initializes)432.186 244.8 R .424
+(the \231host\232 map with the \231\255a.)148.66 256.8 R 5.424<9a8d>-.7 G .424
+(ag \212 you can reset it to an)280.014 256.8 R .424
+(ything you prefer by declar)-.15 F(-)-.2 E(ing the map e)148.66 268.8 Q
+(xplicitly)-.15 E(.\))-.65 E 12.5(\(2\) Def)122 285 R .436(ault host name e)-.1
+F .435(xtension is consistent throughout processing; v)-.15 F .435(ersion le)
+-.15 F -.15(ve)-.25 G 2.935(lo).15 G .435(ne con-)473.855 285 R .828
+(\214gurations turned of)148.66 297 R 3.328(fd)-.25 G .828(omain e)243.384 297
+R .828(xtension \(that is, adding the local domain name\) during)-.15 F .597
+(certain points in processing.)148.66 309 R -1.11(Ve)5.597 G .597(rsion le)1.11
+F -.15(ve)-.25 G 3.097(lt).15 G .797 -.1(wo c)326.822 309 T .597
+(on\214gurations are e).1 F .596(xpected to include a)-.15 F
+(trailing dot to indicate that the name is already canonical.)148.66 321 Q 12.5
+(\(3\) Local)122 337.2 R .176
+(names that are not aliases are passed through a ne)2.675 F 2.676(wd)-.25 G
+.176(istinguished ruleset \214v)388.892 337.2 R .176(e; this)-.15 F .797
+(can be used to append a local relay)148.66 349.2 R 5.797(.T)-.65 G .797
+(his beha)307.676 349.2 R .796(viour can be pre)-.2 F -.15(ve)-.25 G .796
+(nted by resolving the).15 F .62(local name with an initial `@'.)148.66 361.2 R
+.621(That is, something that resolv)5.62 F .621(es to a local mailer and a)-.15
+F .844(user name of \231vikki\232 will be passed through ruleset \214v)148.66
+373.2 R .843(e, b)-.15 F .843(ut a user name of \231@vikki\232)-.2 F .328
+(will ha)148.66 385.2 R .628 -.15(ve t)-.2 H .328
+(he `@' stripped, will not be passed through ruleset \214v).15 F .328(e, b)-.15
+F .328(ut will otherwise be)-.2 F 1.509(treated the same as the prior e)148.66
+397.2 R 4.009(xample. The)-.15 F -.15(ex)4.009 G 1.508
+(pectation is that this might be used to).15 F .907(implement a polic)148.66
+409.2 R 3.407(yw)-.15 G .907(here mail sent to \231vikki\232 w)238.171 409.2 R
+.908(as handled by a central hub, b)-.1 F .908(ut mail)-.2 F
+(sent to \231vikki@localhost\232 w)148.66 421.2 Q(as deli)-.1 E -.15(ve)-.25 G
+(red directly).15 E(.)-.65 E -1.11(Ve)142 437.4 S .229(rsion le)1.11 F -.15(ve)
+-.25 G 2.729(lt).15 G .229(hree \214les allo)199.828 437.4 R 2.729(w#i)-.25 G
+.228(nitiated comments on all lines.)274.374 437.4 R .228
+(Exceptions are backslash)5.228 F(escaped # marks and the $# syntax.)117 449.4
+Q -1.11(Ve)142 465.6 S 1.593(rsion le)1.11 F -.15(ve)-.25 G 4.093(lf).15 G
+1.593(our con\214gurations are completely equi)203.106 465.6 R -.25(va)-.25 G
+1.594(lent to le).25 F -.15(ve)-.25 G 4.094(lt).15 G 1.594(hree for historical)
+429.722 465.6 R(reasons.)117 477.6 Q -1.11(Ve)142 493.8 S .234(rsion le)1.11 F
+-.15(ve)-.25 G 2.734<6c8c>.15 G .534 -.15(ve c)202.618 493.8 T .234
+(on\214guration \214les change the def).15 F .234(ault de\214nition of)-.1 F F0
+($w)2.734 E F1 .234(to be just the \214rst)2.734 F(component of the hostname.)
+117 505.8 Q(The)142 522 Q F0(V)2.64 E F1 .14(line may ha)2.64 F .44 -.15(ve a)
+-.2 H 2.64(no).15 G(ptional)245.8 522 Q F0(/)2.64 E F2(vendor)A F1 .14
+(to indicate that this con\214guration \214le uses modi-)2.64 F
+(\214cations speci\214c to a particular v)117 536 Q(endor)-.15 E/F3 7
+/Times-Roman@0 SF(14)272.1 532 Q F1(.)279.1 536 Q F0 2.5(5.1.9. K)102 560 R 2.5
+<8a6b>2.5 G(ey \214le declaration)157.74 560 Q F1
+(Special maps can be de\214ned using the line:)142 576.2 Q
+(Kmapname mapclass ar)157 592.4 Q(guments)-.18 E(The)117 608.6 Q F2(mapname)
+3.443 E F1 .944(is the handle by which this map is referenced in the re)3.443 F
+.944(writing rules.)-.25 F(The)5.944 E F2(map-)3.444 E(class)117 620.6 Q F1
+.301(is the name of a type of map; these are compiled in to)2.801 F F2
+(sendmail)2.8 E F1 5.3(.T)C(he)410.64 620.6 Q F2(ar)2.8 E(guments)-.37 E F1 .3
+(are inter)2.8 F(-)-.2 E .569(preted depending on the class; typically)117
+632.6 R 3.069(,t)-.65 G .569(here w)286.134 632.6 R .569(ould be a single ar)
+-.1 F .57(gument naming the \214le con-)-.18 F(taining the map.)117 644.6 Q .32
+LW 76 669.2 72 669.2 DL 80 669.2 76 669.2 DL 84 669.2 80 669.2 DL 88 669.2 84
+669.2 DL 92 669.2 88 669.2 DL 96 669.2 92 669.2 DL 100 669.2 96 669.2 DL 104
+669.2 100 669.2 DL 108 669.2 104 669.2 DL 112 669.2 108 669.2 DL 116 669.2 112
+669.2 DL 120 669.2 116 669.2 DL 124 669.2 120 669.2 DL 128 669.2 124 669.2 DL
+132 669.2 128 669.2 DL 136 669.2 132 669.2 DL 140 669.2 136 669.2 DL 144 669.2
+140 669.2 DL 148 669.2 144 669.2 DL 152 669.2 148 669.2 DL 156 669.2 152 669.2
+DL 160 669.2 156 669.2 DL 164 669.2 160 669.2 DL 168 669.2 164 669.2 DL 172
+669.2 168 669.2 DL 176 669.2 172 669.2 DL 180 669.2 176 669.2 DL 184 669.2 180
+669.2 DL 188 669.2 184 669.2 DL 192 669.2 188 669.2 DL 196 669.2 192 669.2 DL
+200 669.2 196 669.2 DL 204 669.2 200 669.2 DL 208 669.2 204 669.2 DL 212 669.2
+208 669.2 DL 216 669.2 212 669.2 DL/F4 5/Times-Roman@0 SF(14)93.6 679.6 Q/F5 8
+/Times-Roman@0 SF .214(And of course, v)3.2 J .214
+(endors are encouraged to add themselv)-.12 F .214
+(es to the list of recognized v)-.12 F .214(endors by editing the routine)-.12
+F/F6 8/Times-Italic@0 SF(setvendor)2.214 E F5(in)2.214 E F6(conf)72 692.4 Q(.c)
+-.12 E F5(.)A EP
+%%Page: 40 35
+%%BeginPageSetup
+BP
+%%EndPageSetup
+/F0 10/Times-Bold@0 SF 193.36(SMM:08-40 Sendmail)72 60 R
+(Installation and Operation Guide)2.5 E/F1 10/Times-Roman@0 SF
+(Maps are referenced using the syntax:)142 96 Q($\()157 112.2 Q/F2 10
+/Times-Italic@0 SF(map k)2.5 E -.3(ey)-.1 G F1($@)2.8 E F2(ar)2.5 E(guments)
+-.37 E F1($:)2.5 E F2(default)2.5 E F1($\))2.5 E .797
+(where either or both of the)117 128.4 R F2(ar)3.297 E(guments)-.37 E F1(or)
+3.297 E F2(default)3.297 E F1 .796(portion may be omitted.)3.297 F(The)5.796 E
+F2(ar)3.296 E(guments)-.37 E F1(may)3.296 E .205(appear more than once.)117
+140.4 R .205(The indicated)5.205 F F2 -.1(ke)2.705 G(y)-.2 E F1(and)2.705 E F2
+(ar)2.705 E(guments)-.37 E F1 .205(are passed to the appropriate mapping)2.705
+F 2.503(function. If)117 152.4 R .003(it returns a v)2.503 F .003
+(alue, it replaces the input.)-.25 F .003(If it does not return a v)5.003 F
+.003(alue and the)-.25 F F2(default)2.503 E F1(is)2.503 E(speci\214ed, the)117
+164.4 Q F2(default)2.5 E F1(replaces the input.)2.5 E
+(Otherwise, the input is unchanged.)5 E .159
+(During replacement of either a map v)142 180.6 R .159(alue or def)-.25 F .159
+(ault the string \231%)-.1 F F2(n)A F1 2.66<9a28>C(where)421.82 180.6 Q F2(n)
+2.66 E F1 .16(is a digit\) is)2.66 F .204(replaced by the corresponding)117
+192.6 R F2(ar)2.704 E(gument)-.37 E F1 5.204(.A)C -.18(rg)294 192.6 S .204
+(ument zero is al).18 F -.1(wa)-.1 G .204(ys the database k).1 F -.15(ey)-.1 G
+5.203(.F)-.5 G .203(or e)468.127 192.6 R(xam-)-.15 E(ple, the rule)117 204.6 Q
+(R$- ! $+)157 220.8 Q($: $\(uucp $1 $@ $2 $: %1 @ %0 . UUCP $\))265 220.8 Q
+.436(Looks up the UUCP name in a \(user de\214ned\) UUCP map; if not found it \
+turns it into \231.UUCP\232)117 237 R 2.5(form. The)117 249 R
+(database might contain records lik)2.5 E(e:)-.1 E(decv)157 265.2 Q 77.43
+(ax %1@%0.DEC.COM)-.25 F 72.19(research %1@%0.A)157 277.2 R(TT)-1.11 E(.COM)
+-.74 E 2.065(The b)142 297.6 R 2.064(uilt in map with both name and class \231\
+host\232 is the host name canonicalization)-.2 F 2.5(lookup. Thus,)117 309.6 R
+(the syntax:)2.5 E($\(host)157 325.8 Q F2(hostname)2.5 E F1($\))A(is equi)117
+342 Q -.25(va)-.25 G(lent to:).25 E($[)157 358.2 Q F2(hostname)A F1($])A 1.783
+(There are four prede\214ned database lookup classes: \231dbm\232, \231btree\
+\232, \231hash\232, and \231nis\232.)142 378.6 R .569
+(The \214rst requires that)117 390.6 R F2(sendmail)3.069 E F1 .569
+(be compiled with the)3.069 F F0(ndbm)3.069 E F1 .568(library; the second tw)
+3.069 F 3.068(or)-.1 G .568(equire the)463.722 390.6 R F0(db)117 402.6 Q F1
+(library)3.198 E 3.198(,a)-.65 G .698(nd the third requires that)167.466 402.6
+R F2(sendmail)3.198 E F1 .698(be compiled with NIS support.)3.198 F .698
+(All four accept)5.698 F .345(as ar)117 414.6 R .344(guments the same optional\
+ \215ags and a \214lename \(or a mapname for NIS; the \214lename is the)-.18 F
+.105(root of the database path, so that \231.db\232 or some other e)117 426.6 R
+.105(xtension appropriate for the database type)-.15 F
+(will be added to get the actual database name\).)117 438.6 Q(Kno)5 E
+(wn \215ags are:)-.25 E 58.86(\255o Indicates)117 454.8 R .21
+(that this map is optional \212 that is, if it cannot be opened, no error is)
+2.71 F(produced, and)189 466.8 Q F2(sendmail)2.5 E F1(will beha)2.5 E .3 -.15
+(ve a)-.2 H 2.5(si).15 G 2.5(ft)348.9 466.8 S(he map e)357.51 466.8 Q(xisted b)
+-.15 E(ut w)-.2 E(as empty)-.1 E(.)-.65 E 56.64(\255N Normally)117 483 R .515
+(when maps are written, the trailing null byte is not included as part)3.015 F
+.8(of the k)189 495 R -.15(ey)-.1 G 5.8(.I)-.5 G 3.3(ft)241.32 495 S .799
+(his \215ag is indicated it will be included.)250.73 495 R .799
+(During lookups, only)5.799 F(the null-byte-included form will be searched.)189
+507 Q(See also)5 E F0(\255O.)2.5 E F1 56.64(\255O If)117 523.2 R(neither)4.388
+E F0<ad4e>4.388 E F1(or)4.388 E F0<ad4f>4.388 E F1 1.888(are speci\214ed,)4.388
+F F2(sendmail)4.388 E F1 1.889(uses an adapti)4.388 F 2.189 -.15(ve a)-.25 H
+1.889(lgorithm to).15 F 1.025
+(decide whether or not to look for null bytes on the end of k)189 535.2 R -.15
+(ey)-.1 G 3.525(s. It).15 F 1.025(starts by)3.525 F .922
+(trying both; if it \214nds an)189 547.2 R 3.422(yk)-.15 G 1.222 -.15(ey w)
+304.29 547.2 T .922(ith a null byte it ne).15 F -.15(ve)-.25 G 3.422(rt).15 G
+.922(ries ag)422.684 547.2 R .922(ain without a)-.05 F .124
+(null byte and vice v)189 559.2 R 2.623(ersa. If)-.15 F .123
+(this \215ag is speci\214ed, it ne)2.623 F -.15(ve)-.25 G 2.623(rt).15 G .123
+(ries with a null byte;)421.288 559.2 R .748(this can speed matches b)189 571.2
+R .748(ut is ne)-.2 F -.15(ve)-.25 G 3.249(rn).15 G(ecessary)341.667 571.2 Q
+5.749(.I)-.65 G 3.249(fb)386.466 571.2 S(oth)398.045 571.2 Q F0<ad4e>3.249 E F1
+(and)3.249 E F0<ad4f>3.249 E F1 .749(are speci-)3.249 F(\214ed,)189 583.2 Q F2
+(sendmail)4.349 E F1 1.849(will ne)4.349 F -.15(ve)-.25 G 4.349(rt).15 G 1.849
+(ry an)300.156 583.2 R 4.349(ym)-.15 G 1.848(atches at all \212 that is, e)
+339.254 583.2 R -.15(ve)-.25 G 1.848(rything will).15 F(appear to f)189 595.2 Q
+(ail.)-.1 E<ad61>117 611.4 Q F2(x)A F1 .106(Append the string)189 611.4 R F2(x)
+2.606 E F1 .107(on successful matches.)2.606 F -.15(Fo)5.107 G 2.607(re).15 G
+.107(xample, the def)387.852 611.4 R(ault)-.1 E F2(host)2.607 E F1(map)2.607 E
+(appends a dot on successful matches.)189 623.4 Q 60.53(\255f Do)117 639.6 R
+(not fold upper to lo)2.5 E(wer case before looking up the k)-.25 E -.15(ey)-.1
+G(.)-.5 E 56.08(\255m Match)117 655.8 R .085(only \(without replacing the v)
+2.585 F 2.585(alue\). If)-.25 F .085(you only care about the e)2.585 F
+(xistence)-.15 E 2.618(of a k)189 667.8 R 2.918 -.15(ey a)-.1 H 2.618
+(nd not the v).15 F 2.619(alue \(as you might when searching the NIS map)-.25 F
+.447(\231hosts.byname\232 for e)189 679.8 R .447(xample\), this \215ag pre)-.15
+F -.15(ve)-.25 G .447(nts the map from substituting the).15 F -.25(va)189 691.8
+S 4.935(lue. Ho).25 F(we)-.25 E -.15(ve)-.25 G 3.235 -.4(r, T).15 H 2.436
+(he \255a ar).4 F 2.436(gument is still appended on a match, and the)-.18 F
+(def)189 703.8 Q(ault is still tak)-.1 E(en if the match f)-.1 E(ails.)-.1 E EP
+%%Page: 41 36
+%%BeginPageSetup
+BP
+%%EndPageSetup
+/F0 10/Times-Bold@0 SF(Sendmail Installation and Operation Guide)72 60 Q
+(SMM:08-41)452.9 60 Q/F1 10/Times-Roman@0 SF(The)142 96 Q/F2 10/Times-Italic@0
+SF(dbm)3.874 E F1 1.374
+(map appends the strings \231.pag\232 and \231.dir\232 to the gi)3.874 F -.15
+(ve)-.25 G 3.874<6e8c>.15 G 1.374(lename; the tw)420.268 96 R(o)-.1 E F2(db)
+3.874 E F1(-)A(based maps append \231.db\232.)117 108 Q -.15(Fo)5 G 2.5(re).15
+G(xample, the map speci\214cation)246.67 108 Q -.15(Ku)157 124.2 S
+(ucp dbm \255o \255N /usr/lib/uucpmap).15 E .77
+(speci\214es an optional map named \231uucp\232 of class \231dbm\232; it al)117
+140.4 R -.1(wa)-.1 G .77(ys has null bytes at the end of).1 F -2.15 -.25(ev e)
+117 152.4 T(ry string, and the data is located in /usr/lib/uucpmap.{dir).25 E
+(,pag}.)-.4 E .023(The program)142 168.6 R F2(mak)2.523 E(emap)-.1 E F1 .023
+(\(8\) can be used to b)B .023(uild an)-.2 F 2.523(yo)-.15 G 2.523(ft)353.097
+168.6 S .023(he three database-oriented maps.)361.73 168.6 R(It)5.022 E(tak)117
+180.6 Q(es the follo)-.1 E(wing \215ags:)-.25 E 60.53(\255f F)117 196.8 R
+(old upper to lo)-.15 E(wer case in the map.)-.25 E 56.64(\255N Include)117 213
+R(null bytes in k)2.5 E -.15(ey)-.1 G(s.).15 E 58.86(\255o Append)117 229.2 R
+(to an e)2.5 E(xisting \(old\) \214le.)-.15 E 60.53(\255r Allo)117 245.4 R
+3.479(wr)-.25 G .979(eplacement of e)220.559 245.4 R .979(xisting k)-.15 F -.15
+(ey)-.1 G .979(s; normally).15 F 3.479(,r)-.65 G .979(e-inserting an e)385.494
+245.4 R .979(xisting k)-.15 F 1.279 -.15(ey i)-.1 H(s).15 E(an error)189 257.4
+Q(.)-.55 E 58.86(\255v Print)117 273.6 R(what is happening.)2.5 E(The)117 289.8
+Q F2(sendmail)2.773 E F1 .273(daemon does not ha)2.773 F .572 -.15(ve t)-.2 H
+2.772(ob).15 G 2.772(er)282.148 289.8 S .272(estarted to read the ne)292.69
+289.8 R 2.772(wm)-.25 G .272(aps as long as you change)399.05 289.8 R .042
+(them in place; \214le locking is used so that the maps w)117 303.8 R(on')-.1 E
+2.542(tb)-.18 G 2.542(er)352.214 303.8 S .042(ead while the)362.526 303.8 R
+2.543(ya)-.15 G .043(re being updated.)427.764 303.8 R/F3 7/Times-Roman@0 SF
+(15)497 299.8 Q F1(There are also tw)142 320 Q 2.5(ob)-.1 G
+(uiltin maps that are, strictly speaking, not database lookups.)223.34 320 Q
+1.563(The \231host\232 map does host domain canoni\214cation; gi)142 336.2 R
+-.15(ve)-.25 G 4.063(nah).15 G 1.563(ost name it calls the name)392.585 336.2 R
+(serv)117 348.2 Q(er to \214nd the canonical name for that host.)-.15 E .106
+(The \231dequote\232 map strips double quotes \("\) from a name.)142 364.4 R
+.106(It does not strip backslashes.)5.106 F(It)5.106 E 1.838
+(will not strip quotes if the resulting string w)117 376.4 R 1.838
+(ould contain unscannable syntax \(that is, basic)-.1 F .601(errors lik)117
+388.4 R 3.101(eu)-.1 G .601(nbalanced angle brack)166.422 388.4 R .601
+(ets; more sophisticated errors such as unkno)-.1 F .6(wn hosts are not)-.25 F
+(check)117 400.4 Q 3.398(ed\). The)-.1 F .899
+(intent is for use when trying to accept mail from systems such as DECnet that)
+3.398 F(routinely quote odd syntax such as)117 412.4 Q("49ers::ubell")157 428.6
+Q 2.5(At)117 444.8 S(ypical usage is probably something lik)129.5 444.8 Q(e:)
+-.1 E(Kdequote dequote)157 461 Q(...)157 485 Q 88.19(R$\255 $:)157 509 R
+($\(dequote $1 $\))2.5 E(R$\255 $+)157 521 Q($: $>3 $1 $2)265 521 Q
+(Care must be tak)117 537.2 Q(en to pre)-.1 E -.15(ve)-.25 G(nt une).15 E
+(xpected results; for e)-.15 E(xample,)-.15 E("|someprogram < input > output")
+157 553.4 Q .084(will ha)117 569.6 R .384 -.15(ve q)-.2 H .083
+(uotes stripped, b).15 F .083
+(ut the result is probably not what you had in mind.)-.2 F -.15(Fo)5.083 G .083
+(rtunately these).15 F(cases are rare.)117 581.6 Q(Ne)142 597.8 Q 2.5(wc)-.25 G
+(lasses can be added in the routine)167.57 597.8 Q F0(setupmaps)2.5 E F1
+(in \214le)2.5 E F0(conf)2.5 E(.c)-.15 E F1(.)A F0 2.5(5.2. Building)87 621.8 R
+2.5(aC)2.5 G(on\214guration File Fr)160.91 621.8 Q(om Scratch)-.18 E F1 1.517
+(Building a con\214guration table from scratch is an e)127 638 R 1.518
+(xtremely dif)-.15 F 1.518(\214cult job)-.25 F 6.518(.F)-.4 G(ortunately)
+441.334 638 Q 4.018(,i)-.65 G 4.018(ti)490.532 638 S(s)500.11 638 Q 1.855
+(almost ne)102 650 R -.15(ve)-.25 G 4.355(rn).15 G 1.855
+(ecessary to do so; nearly e)164.19 650 R -.15(ve)-.25 G 1.855
+(ry situation that may come up may be resolv).15 F 1.855(ed by)-.15 F 1.38
+(changing an e)102 662 R 1.38(xisting table.)-.15 F 1.38(In an)6.38 F 3.88(yc)
+-.15 G 1.381(ase, it is critical that you understand what it is that you are)
+254.4 662 R .32 LW 76 671.6 72 671.6 DL 80 671.6 76 671.6 DL 84 671.6 80 671.6
+DL 88 671.6 84 671.6 DL 92 671.6 88 671.6 DL 96 671.6 92 671.6 DL 100 671.6 96
+671.6 DL 104 671.6 100 671.6 DL 108 671.6 104 671.6 DL 112 671.6 108 671.6 DL
+116 671.6 112 671.6 DL 120 671.6 116 671.6 DL 124 671.6 120 671.6 DL 128 671.6
+124 671.6 DL 132 671.6 128 671.6 DL 136 671.6 132 671.6 DL 140 671.6 136 671.6
+DL 144 671.6 140 671.6 DL 148 671.6 144 671.6 DL 152 671.6 148 671.6 DL 156
+671.6 152 671.6 DL 160 671.6 156 671.6 DL 164 671.6 160 671.6 DL 168 671.6 164
+671.6 DL 172 671.6 168 671.6 DL 176 671.6 172 671.6 DL 180 671.6 176 671.6 DL
+184 671.6 180 671.6 DL 188 671.6 184 671.6 DL 192 671.6 188 671.6 DL 196 671.6
+192 671.6 DL 200 671.6 196 671.6 DL 204 671.6 200 671.6 DL 208 671.6 204 671.6
+DL 212 671.6 208 671.6 DL 216 671.6 212 671.6 DL/F4 5/Times-Roman@0 SF(15)93.6
+682 Q/F5 8/Times-Roman@0 SF .129(That is, don')3.2 J 2.129(tc)-.144 G .129
+(reate ne)147.283 685.2 R 2.129(wm)-.2 G .129(aps and then use)186.437 685.2 R
+/F6 8/Times-Italic@0 SF(mv)2.129 E F5 .129(\(1\) to mo)B .369 -.12(ve t)-.12 H
+.129(hem into place.).12 F 2.129(Ic)4.129 G .128(onsider this a shortf)354.472
+685.2 R .128(all \(a.k.a. b)-.08 F .128(ug\) in)-.16 F F6(sendmail)2.128 E F5
+(which should be \214x)72 694.8 Q(ed in a future release.)-.12 E EP
+%%Page: 42 37
+%%BeginPageSetup
+BP
+%%EndPageSetup
+/F0 10/Times-Bold@0 SF 193.36(SMM:08-42 Sendmail)72 60 R
+(Installation and Operation Guide)2.5 E/F1 10/Times-Roman@0 SF .498
+(trying to do and come up with a philosoph)102 96 R 2.998(yf)-.05 G .498
+(or the con\214guration table.)286.702 96 R .497(This section is intended to)
+5.497 F -.15(ex)102 108 S .67
+(plain what the real purpose of a con\214guration table is and to gi).15 F .97
+-.15(ve y)-.25 H .67(ou some ideas for what your).15 F(philosoph)102 120 Q 2.5
+(ym)-.05 G(ight be.)156.68 120 Q F0 1.32(Do not e)127 136.2 R -.1(ve)-.15 G
+3.82(nc).1 G(onsider)188.2 136.2 Q F1 1.32(writing your o)3.82 F 1.32
+(wn con\214guration \214le without carefully studying RFC)-.25 F
+(821, 822, and 1123.)102 148.2 Q -1.1(Yo)5 G 2.5(us)1.1 G
+(hould also read RFC 976 if you are doing UUCP e)208.95 148.2 Q(xchange.)-.15 E
+F0 2.5(5.2.1. What)102 172.2 R -.25(yo)2.5 G 2.5(ua).25 G .36 -.18(re t)178.7
+172.2 T(rying to do).18 E F1 .82
+(The con\214guration table has three major purposes.)142 188.4 R .821
+(The \214rst and simplest is to set up the)5.821 F(en)117 200.4 Q .35
+(vironment for)-.4 F/F2 10/Times-Italic@0 SF(sendmail)2.85 E F1 5.35(.T)C .35
+(his in)234.58 200.4 R -.2(vo)-.4 G(lv).2 E .35
+(es setting the options, de\214ning a fe)-.15 F 2.85(wc)-.25 G .35
+(ritical macros, etc.)429.43 200.4 R(Since these are described in other places\
+, we will not go into more detail here.)117 212.4 Q .283
+(The second purpose is to re)142 228.6 R .284(write addresses in the message.)
+-.25 F .284(This should typically be done)5.284 F .214(in tw)117 240.6 R 2.714
+(op)-.1 G 2.713(hases. The)150.108 240.6 R .213
+(\214rst phase maps addresses in an)2.713 F 2.713(yf)-.15 G .213
+(ormat into a canonical form.)337.182 240.6 R .213(This should)5.213 F .156
+(be done in ruleset three.)117 252.6 R .157
+(The second phase maps this canonical form into the syntax appropriate)5.156 F
+1.998(for the recei)117 264.6 R 1.997(ving mailer)-.25 F(.)-.55 E F2(Sendmail)
+6.997 E F1 1.997(does this in three subphases.)4.497 F 1.997
+(Rulesets one and tw)6.997 F 4.497(oa)-.1 G(re)496.23 264.6 Q .043
+(applied to all sender and recipient addresses respecti)117 276.6 R -.15(ve)
+-.25 G(ly).15 E 5.043(.A)-.65 G .043(fter this, you may specify per)357.904
+276.6 R(-mailer)-.2 E 2.723
+(rulesets for both sender and recipient addresses; this allo)117 288.6 R 2.723
+(ws mailer)-.25 F 2.723(-speci\214c customization.)-.2 F(Finally)117 300.6 Q
+2.5(,r)-.65 G(uleset four is applied to do an)153.02 300.6 Q 2.5(yd)-.15 G(ef)
+283.69 300.6 Q(ault con)-.1 E -.15(ve)-.4 G(rsion to e).15 E(xternal form.)-.15
+E .785(The third purpose is to map addresses into the actual set of instructio\
+ns necessary to get)142 316.8 R .154(the message deli)117 328.8 R -.15(ve)-.25
+G 2.654(red. Ruleset).15 F .154(zero must resolv)2.654 F 2.654(et)-.15 G 2.654
+(ot)321.658 328.8 S .153(he internal form, which is in turn used as a)332.092
+328.8 R .446(pointer to a mailer descriptor)117 340.8 R 5.446(.T)-.55 G .446
+(he mailer descriptor describes the interf)248.38 340.8 R .447
+(ace requirements of the)-.1 F(mailer)117 352.8 Q(.)-.55 E F0 2.5
+(5.2.2. Philosoph)102 376.8 R(y)-.15 E F1 1.481(The particular philosoph)142
+393 R 3.981(yy)-.05 G 1.481(ou choose will depend hea)257.213 393 R 1.481
+(vily on the size and structure of)-.2 F .55(your or)117 405 R -.05(ga)-.18 G
+3.05(nization. I).05 F .55(will present a fe)3.05 F 3.05(wp)-.25 G .55
+(ossible philosophies here.)283.39 405 R .55(There are as man)5.55 F 3.05(yp)
+-.15 G(hiloso-)476.22 405 Q
+(phies as there are con\214g designers; feel free to de)117 417 Q -.15(ve)-.25
+G(lop your o).15 E(wn.)-.25 E .388
+(One general point applies to all of these philosophies: it is almost al)142
+433.2 R -.1(wa)-.1 G .388(ys a mistak).1 F 2.888(et)-.1 G 2.888(ot)485.002
+433.2 S(ry)495.67 433.2 Q .176(to do full host route resolution.)117 445.2 R
+-.15(Fo)5.176 G 2.676(re).15 G .176
+(xample, if you are on a UUCP-only site and you are trying)267.652 445.2 R
+1.223(to get names of the form \231user@host\232 to the Internet, it does not \
+pay to route them to \231xyz-)117 457.2 R -.25(va)117 469.2 S(x!decv).25 E
+(ax!ucb)-.25 E -.25(va)-.15 G .304
+(x!c70!user@host\232 since you then depend on se).25 F -.15(ve)-.25 G .305
+(ral links not under your con-).15 F .996(trol, some of which are lik)117 481.2
+R .996(ely to misparse it an)-.1 F(yw)-.15 E(ay)-.1 E 5.996(.T)-.65 G .996
+(he best approach to this problem is to)347.32 481.2 R 1.048(simply forw)117
+493.2 R 1.048(ard the message for \231user@host\232 to \231xyzv)-.1 F 1.049
+(ax\232 and let xyzv)-.25 F 1.049(ax w)-.25 F 1.049(orry about it from)-.1 F
+3.606(there. In)117 505.2 R(summary)3.606 E 3.606(,j)-.65 G 1.106
+(ust get the message closer to the destination, rather than determining the)
+202.988 505.2 R(full path.)117 517.2 Q F0 2.5(5.2.2.1. Lar)117 541.2 R
+(ge site, many hosts \212 minimum inf)-.1 E(ormation)-.25 E F1(Berk)157 557.4 Q
+(ele)-.1 E 3.018(yi)-.15 G 3.018(sa)198.648 557.4 S 3.018(ne)209.996 557.4 S
+.518(xample of a lar)222.304 557.4 R .518(ge site, i.e., more than tw)-.18 F
+3.018(oo)-.1 G 3.018(rt)400.266 557.4 S .519(hree hosts and multiple)409.394
+557.4 R .444(mail connections.)132 569.4 R 2.044 -.8(We h)5.444 H -2.25 -.2
+(av e).8 H .443(decided that the only reasonable philosoph)3.144 F 2.943(yi)
+-.05 G 2.943(no)429.634 569.4 S .443(ur en)442.577 569.4 R(vironment)-.4 E .312
+(is to designate one host as the guru for our site.)132 581.4 R .312
+(It must be able to resolv)5.312 F 2.812(ea)-.15 G .612 -.15(ny p)438.504 581.4
+T .312(iece of mail).15 F 1.083(it recei)132 593.4 R -.15(ve)-.25 G 3.583
+(s. The).15 F 1.083(other sites should ha)3.583 F 1.383 -.15(ve t)-.2 H 1.083
+(he minimum amount of information the).15 F 3.582(yc)-.15 G 1.082(an get)
+478.758 593.4 R -2.3 -.15(aw a)132 605.4 T 2.635(yw).15 G 2.635(ith. In)162.705
+605.4 R .135(addition, an)2.635 F 2.635(yi)-.15 G .135(nformation the)249.485
+605.4 R 2.635(yd)-.15 G 2.635(oh)321.265 605.4 S -2.25 -.2(av e)333.9 605.4 T
+.136(should be hints rather than solid infor)2.835 F(-)-.2 E(mation.)132 617.4
+Q -.15(Fo)157 633.6 S 6.71(re).15 G 4.209
+(xample, a typical site on our local ether netw)181.74 633.6 R 4.209
+(ork is \231monet\232 \(actually)-.1 F(\231monet.CS.Berk)132 645.6 Q(ele)-.1 E
+-.65(y.)-.15 G 3.887(EDU\232\). When).65 F 1.387(monet recei)3.887 F -.15(ve)
+-.25 G 3.887(sm).15 G 1.387(ail for deli)354.258 645.6 R -.15(ve)-.25 G(ry).15
+E 3.887(,i)-.65 G 3.887(tc)424.579 645.6 S 1.387(hecks whether it)435.686 645.6
+R(kno)132 657.6 Q 1.342(ws that the destination host is directly reachable; if\
+ so, mail is sent to that host.)-.25 F 1.342(If it)6.342 F(recei)132 669.6 Q
+-.15(ve)-.25 G 2.915(sm).15 G .415(ail for an)175.055 669.6 R 2.915(yu)-.15 G
+(nkno)224.75 669.6 Q .415(wn host, it just passes it directly to \231ucb)-.25 F
+-.25(va)-.15 G(x.CS.Berk).25 E(ele)-.1 E -.65(y.)-.15 G(EDU\232,).65 E .178
+(our master host.)132 681.6 R(Ucb)5.178 E -.25(va)-.15 G 2.678(xm).25 G .177
+(ay determine that the host name is ille)242.852 681.6 R -.05(ga)-.15 G 2.677
+(la).05 G .177(nd reject the message,)415.159 681.6 R .754
+(or may be able to do deli)132 693.6 R -.15(ve)-.25 G(ry).15 E 5.754(.H)-.65 G
+-.25(ow)268.146 693.6 S -2.15 -.25(ev e).25 H 1.554 -.4(r, i).25 H 3.254(ti).4
+G 3.254(si)313.874 693.6 S .754(mportant to note that when a ne)323.798 693.6 R
+3.254(wm)-.25 G .754(ail con-)472.976 693.6 R .164
+(nection is added, the only host that)132 705.6 R F2(must)2.664 E F1(ha)2.664 E
+.464 -.15(ve i)-.2 H .164(ts tables updated is ucb).15 F -.25(va)-.15 G .164
+(x; the others).25 F F2(may)2.664 E F1(be)2.664 E(updated if con)132 717.6 Q
+-.15(ve)-.4 G(nient, b).15 E(ut this is not critical.)-.2 E EP
+%%Page: 43 38
+%%BeginPageSetup
+BP
+%%EndPageSetup
+/F0 10/Times-Bold@0 SF(Sendmail Installation and Operation Guide)72 60 Q
+(SMM:08-43)452.9 60 Q/F1 10/Times-Roman@0 SF 2.121
+(This picture is slightly muddied due to netw)157 96 R 2.122
+(ork connections that are not actually)-.1 F 2.362(located on ucb)132 108 R
+-.25(va)-.15 G 4.862(x. F).25 F 2.362(or e)-.15 F 2.362
+(xample, some UUCP connections are currently on \231ucbarpa.)-.15 F<9a>-.7 E
+(Ho)132 120 Q(we)-.25 E -.15(ve)-.25 G 1.044 -.4(r, m).15 H(onet).4 E/F2 10
+/Times-Italic@0 SF .244(does not)2.744 F F1(kno)2.744 E 2.744(wa)-.25 G .245
+(bout this; the information is hidden totally between ucb)266.34 120 R -.25(va)
+-.15 G(x).25 E 1.045(and ucbarpa.)132 132 R 1.045
+(Mail going from monet to a UUCP host is transferred via the ethernet from)
+6.045 F 1.43(monet to ucb)132 144 R -.25(va)-.15 G 1.43
+(x, then via the ethernet from ucb).25 F -.25(va)-.15 G 3.931(xt).25 G 3.931
+(ou)355.704 144 S 1.431(cbarpa, and then is submitted to)369.635 144 R(UUCP)132
+156 Q 5(.A)-1.11 G(lthough this in)172.28 156 Q -.2(vo)-.4 G(lv).2 E(es some e)
+-.15 E(xtra hops, we feel this is an acceptable tradeof)-.15 E(f.)-.25 E .826
+(An interesting point is that it w)157 172.2 R .826
+(ould be possible to update monet to send appropriate)-.1 F .127
+(UUCP mail directly to ucbarpa if the load got too high; if monet f)132 184.2 R
+.127(ailed to note a host as con-)-.1 F .353(nected to ucbarpa it w)132 196.2 R
+.353(ould go via ucb)-.1 F -.25(va)-.15 G 2.853(xa).25 G 2.852(sb)305.954 196.2
+S .352(efore, and if monet incorrectly sent a message)317.696 196.2 R .395
+(to ucbarpa it w)132 208.2 R .396(ould still be sent by ucbarpa to ucb)-.1 F
+-.25(va)-.15 G 2.896(xa).25 G 2.896(sb)356.654 208.2 S 2.896(efore. The)368.44
+208.2 R .396(only problem that can)2.896 F .901(occur is loops, for e)132 220.2
+R .901(xample, if ucbarpa thought that ucb)-.15 F -.25(va)-.15 G 3.401(xh).25 G
+.9(ad the UUCP connection and)383.75 220.2 R(vice v)132 232.2 Q 2.5(ersa. F)
+-.15 F(or this reason, updates should)-.15 E F2(always)2.5 E F1
+(happen to the master host \214rst.)2.5 E .144(This philosoph)157 248.4 R 2.644
+(yr)-.05 G .145(esults as much from the need to ha)227.798 248.4 R .445 -.15
+(ve a s)-.2 H .145(ingle source for the con\214gu-).15 F .289
+(ration \214les \(typically b)132 260.4 R .289(uilt using)-.2 F F2(m4)2.789 E
+F1 .289(\(1\) or some similar tool\) as an)1.666 F 2.789(yl)-.15 G .288
+(ogical need.)410.664 260.4 R(Maintain-)5.288 E
+(ing more than three separate tables by hand is essentially an impossible job)
+132 272.4 Q(.)-.4 E F0 2.5(5.2.2.2. Small)117 296.4 R(site \212 complete inf)
+2.5 E(ormation)-.25 E F1 3.356(As)157 312.6 S .856(mall site \(tw)171.466 312.6
+R 3.356(oo)-.1 G 3.356(rt)236.434 312.6 S .856(hree hosts and fe)245.9 312.6 R
+3.356(we)-.25 G .856(xternal connections\) may \214nd it more rea-)330.564
+312.6 R .435(sonable to ha)132 324.6 R .735 -.15(ve c)-.2 H .435
+(omplete information at each host.).15 F .435(This w)5.435 F .435
+(ould require that each host kno)-.1 F(w)-.25 E -.15(ex)132 336.6 S .185
+(actly where each netw).15 F .185
+(ork connection is, possibly including the names of each host on that)-.1 F
+(netw)132 348.6 Q 3.465(ork. As)-.1 F .965
+(long as the site remains small and the con\214guration remains relati)3.465 F
+-.15(ve)-.25 G .964(ly static,).15 F
+(the update problem will probably not be too great.)132 360.6 Q F0 2.5
+(5.2.2.3. Single)117 384.6 R(host)2.5 E F1 .117(This is in some sense the tri)
+157 400.8 R .117(vial case.)-.25 F .117
+(The only major issue is trying to insure that you)5.117 F(don')132 412.8 Q
+3.425(th)-.18 G -2.25 -.2(av e)161.355 412.8 T .925(to kno)3.625 F 3.425(wt)
+-.25 G .925(oo much about your en)217.69 412.8 R 3.425(vironment. F)-.4 F .925
+(or e)-.15 F .924(xample, if you ha)-.15 F 1.224 -.15(ve a U)-.2 H(UCP).15 E
+.614(connection you might \214nd it useful to kno)132 424.8 R 3.115(wa)-.25 G
+.615(bout the names of hosts connected directly to)318.885 424.8 R(you, b)132
+436.8 Q
+(ut this is really not necessary since this may be determined from the syntax.)
+-.2 E F0 2.5(5.2.2.4. A)117 460.8 R(completely differ)2.5 E(ent philosoph)-.18
+E(y)-.15 E F1(This is adapted from Bruce Lilly)157 477 Q 5(.A)-.65 G .3 -.15
+(ny e)301.89 477 T(rrors in interpretation are mine.).15 E .065
+(Do minimal changes in ruleset 3: \214x some common b)157 493.2 R .064
+(ut unambiguous errors \(e.g. trail-)-.2 F 2.758
+(ing dot on domains\) and hide bang paths foo!bar into bar@foo.UUCP)132 505.2 R
+7.759(.T)-1.11 G 2.759(he resulting)454.301 505.2 R("canonical" form is an)132
+517.2 Q 2.5(yv)-.15 G(alid RFC822/RFC1123/RFC976 address.)233.63 517.2 Q 1.388
+(Ruleset 0 does the b)157 533.4 R 1.387(ulk of the w)-.2 F 3.887(ork. It)-.1 F
+(remo)3.887 E -.15(ve)-.15 G 3.887(st).15 G 1.387
+(he trailing "@.UUCP" that hides)367.472 533.4 R .66(bang paths, strips an)132
+545.4 R .661(ything not needed to resolv)-.15 F .661
+(e, e.g. the phrase from phrase <route-addr>)-.15 F .497
+(and from named groups, rejects unparseable addresses using $#error)132 557.4 R
+2.996(,a)-.4 G .496(nd \214nally resolv)419.052 557.4 R .496(es to)-.15 F 4.324
+(am)132 569.4 S 1.824(ailer/host/user triple.)148.544 569.4 R 1.824
+(Ruleset 0 is rather length)6.824 F 4.325(ya)-.05 G 4.325(si)360.965 569.4 S
+4.325(th)371.96 569.4 S 1.825(as to handle 3 basic address)384.065 569.4 R
+5.373(forms: RFC976 bang paths, RFC1123 %-hacks \(including v)132 581.4 R 5.373
+(anilla RFC822 local-)-.25 F .136(part@domain\), and RFC822 source routes.)132
+593.4 R(It')5.137 E 2.637(sa)-.55 G .137(lso complicated by ha)329.508 593.4 R
+.137(ving to handle named)-.2 F(lists.)132 605.4 Q .617(The header re)157 621.6
+R .616(writing rulesets 1 and 2 remo)-.25 F .916 -.15(ve t)-.15 H .616
+(he trailing "@.UUCP" that hides bang).15 F 2.5(paths. Ruleset)132 633.6 R 2.5
+(2a)2.5 G(lso strips the $# mailer $@ host \(for test mode\).)205.05 633.6 Q
+(Ruleset 4 does absolutely nothing.)157 649.8 Q 1.316(The per)157 666 R 1.316
+(-mailer re)-.2 F 1.316(writing rulesets conform the en)-.25 F -.15(ve)-.4 G
+1.317(lope and header addresses to the).15 F
+(requirements of the speci\214c mailer)132 678 Q(.)-.55 E
+(Lots of rulesets-as-subroutines are used.)157 694.2 Q .35(As a result, header\
+ addresses are subject to minimal munging \(per RFC1123\), and the)157 710.4 R
+(general plan is per RFC822 sect. 3.4.10.)132 722.4 Q EP
+%%Page: 44 39
+%%BeginPageSetup
+BP
+%%EndPageSetup
+/F0 10/Times-Bold@0 SF 193.36(SMM:08-44 Sendmail)72 60 R
+(Installation and Operation Guide)2.5 E 2.5(5.2.3. Rele)102 96 R -.1(va)-.15 G
+(nt issues).1 E/F1 10/Times-Roman@0 SF .584(The canonical form you use should \
+almost certainly be as speci\214ed in the Internet proto-)142 112.2 R 2.604
+(cols RFC819 and RFC822.)117 124.2 R 2.604(Copies of these RFC')7.604 F 5.104
+(sa)-.55 G 2.603(re included on the)347.852 124.2 R/F2 10/Times-Italic@0 SF
+(sendmail)5.103 E F1 2.603(tape as)5.103 F F2(doc/rfc819.lpr)117 136.2 Q F1
+(and)2.5 E F2(doc/rfc822.lpr)2.5 E F1(.)A 2.04
+(RFC822 describes the format of the mail message itself.)142 152.4 R F2
+(Sendmail)7.04 E F1(follo)4.54 E 2.04(ws this RFC)-.25 F(closely)117 164.4 Q
+2.984(,t)-.65 G 2.984(ot)152.944 164.4 S .483(he e)163.708 164.4 R .483
+(xtent that man)-.15 F 2.983(yo)-.15 G 2.983(ft)251.44 164.4 S .483
+(he standards described in this document can not be changed)260.533 164.4 R
+(without changing the code.)117 176.4 Q(In particular)5 E 2.5(,t)-.4 G
+(he follo)286.85 176.4 Q(wing characters ha)-.25 E .3 -.15(ve s)-.2 H
+(pecial interpretations:).15 E 2.5(<>\(\)"\\)157 192.6 S(An)117 208.8 Q 3.036
+(ya)-.15 G .537(ttempt to use these characters for other than their RFC822 pur\
+pose in addresses is proba-)141.546 208.8 R(bly doomed to disaster)117 220.8 Q
+(.)-.55 E 1.327
+(RFC819 describes the speci\214cs of the domain-based addressing.)142 237 R
+1.326(This is touched on in)6.327 F 1.439(RFC822 as well.)117 249 R 1.439
+(Essentially each host is gi)6.439 F -.15(ve)-.25 G 3.939(nan).15 G 1.44
+(ame which is a right-to-left dot quali\214ed)333.711 249 R .232
+(pseudo-path from a distinguished root.)117 261 R .232
+(The elements of the path need not be ph)5.232 F .232(ysical hosts; the)-.05 F
+2.365(domain is logical rather than ph)117 273 R 4.866(ysical. F)-.05 F 2.366
+(or e)-.15 F 2.366(xample, at Berk)-.15 F(ele)-.1 E 4.866(yo)-.15 G 2.366
+(ne le)406.406 273 R -.05(ga)-.15 G 4.866(lh).05 G 2.366(ost might be)449.818
+273 R(\231a.CC.Berk)117 285 Q(ele)-.1 E -.65(y.)-.15 G .366
+(EDU\232; reading from right to left, \231EDU\232 is a top le).65 F -.15(ve)
+-.25 G 2.865(ld).15 G .365(omain comprising edu-)410.5 285 R .561
+(cational institutions, \231Berk)117 297 R(ele)-.1 E .562
+(y\232 is a logical domain name, \231CC\232 represents the Computer Cen-)-.15 F
+(ter)117 309 Q 2.5(,\()-.4 G(in this case a strictly logical entity\), and \
+\231a\232 is a host in the Computer Center)135.48 309 Q(.)-.55 E(Be)142 325.2 Q
+-.1(wa)-.25 G(re when reading RFC819 that there are a number of errors in it.)
+.1 E F0 2.5(5.2.4. Ho)102 349.2 R 2.5(wt)-.1 G 2.5(op)155.23 349.2 S -.18(ro)
+168.29 349.2 S(ceed).18 E F1 .335(Once you ha)142 365.4 R .635 -.15(ve d)-.2 H
+.335(ecided on a philosoph).15 F 1.635 -.65(y, i)-.05 H 2.835(ti).65 G 2.834
+(sw)319.44 365.4 S .334(orth e)333.284 365.4 R .334(xamining the a)-.15 F -.25
+(va)-.2 G .334(ilable con\214guration).25 F .174(tables to decide if an)117
+377.4 R 2.674(yo)-.15 G 2.674(ft)212.98 377.4 S .174
+(hem are close enough to steal major parts of.)221.764 377.4 R(Ev)5.174 E .175
+(en under the w)-.15 F .175(orst of)-.1 F(conditions, there is a f)117 389.4 Q
+(air amount of boiler plate that can be collected safely)-.1 E(.)-.65 E .33
+(The ne)142 405.6 R .33(xt step is to b)-.15 F .33(uild ruleset three.)-.2 F
+.329(This will be the hardest part of the job)5.33 F 5.329(.B)-.4 G -2.1 -.25
+(ew a)469.321 405.6 T .329(re of).25 F .781
+(doing too much to the address in this ruleset, since an)117 417.6 R .781
+(ything you do will re\215ect through to the)-.15 F 2.744(message. In)117 429.6
+R(particular)2.744 E 2.744(,s)-.4 G .243
+(tripping of local domains is best deferred, since this can lea)216.752 429.6 R
+.543 -.15(ve y)-.2 H .243(ou with).15 F 1.234
+(addresses with no domain spec at all.)117 441.6 R(Since)6.235 E F2(sendmail)
+3.735 E F1(lik)3.735 E 1.235(es to append the sending domain to)-.1 F .83
+(addresses with no domain, this can change the semantics of addresses.)117
+453.6 R .83(Also try to a)5.83 F -.2(vo)-.2 G .83(id fully).2 F .342
+(qualifying domains in this ruleset.)117 465.6 R .342(Although technically le)
+5.342 F -.05(ga)-.15 G .343(l, this can lead to unpleasantly and).05 F 1.287
+(unnecessarily long addresses re\215ected into messages.)117 477.6 R 1.287
+(The Berk)6.287 F(ele)-.1 E 3.787(yc)-.15 G 1.287
+(on\214guration \214les de\214ne)406.426 477.6 R .093
+(ruleset nine to qualify domain names and strip local domains.)117 489.6 R .093
+(This is called from ruleset zero to)5.093 F
+(get all addresses into a cleaner form.)117 501.6 Q .318(Once you ha)142 517.8
+R .618 -.15(ve r)-.2 H .318
+(uleset three \214nished, the other rulesets should be relati).15 F -.15(ve)
+-.25 G .318(ly tri).15 F 2.817(vial. If)-.25 F(you)2.817 E(need hints, e)117
+529.8 Q(xamine the supplied con\214guration tables.)-.15 E F0 2.5(5.2.5. T)102
+553.8 R(esting the r)-.92 E(ewriting rules \212 the \255bt \215ag)-.18 E F1
+1.075(When you b)142 570 R 1.075(uild a con\214guration table, you can do a ce\
+rtain amount of testing using the)-.2 F(\231test mode\232 of)117 582 Q F2
+(sendmail)2.5 E F1 5(.F)C(or e)226.84 582 Q(xample, you could in)-.15 E -.2(vo)
+-.4 G -.1(ke).2 G F2(sendmail)2.6 E F1(as:)2.5 E(sendmail \255bt \255Ctest.cf)
+157 598.2 Q .904(which w)117 614.4 R .903
+(ould read the con\214guration \214le \231test.cf\232 and enter test mode.)-.1
+F .903(In this mode, you enter)5.903 F(lines of the form:)117 626.4 Q
+(rwset address)157 642.6 Q(where)117 658.8 Q F2(rwset)3.376 E F1 .876
+(is the re)3.376 F .876(writing set you w)-.25 F .876(ant to use and)-.1 F F2
+(addr)3.376 E(ess)-.37 E F1 .877(is an address to apply the set to.)3.376 F -.7
+(Te)117 670.8 S .17(st mode sho).7 F .17(ws you the steps it tak)-.25 F .169
+(es as it proceeds, \214nally sho)-.1 F .169(wing you the address it ends up)
+-.25 F 3.635(with. Y)117 682.8 R 1.135(ou may use a comma separated list of rw\
+sets for sequential application of rules to an)-1.1 F 2.5(input. F)117 694.8 R
+(or e)-.15 E(xample:)-.15 E(3,1,21,4 monet:bollard)157 711 Q EP
+%%Page: 45 40
+%%BeginPageSetup
+BP
+%%EndPageSetup
+/F0 10/Times-Bold@0 SF(Sendmail Installation and Operation Guide)72 60 Q
+(SMM:08-45)452.9 60 Q/F1 10/Times-Roman@0 SF .386
+(\214rst applies ruleset three to the input \231monet:bollard.)117 96 R 5.385
+<9a52>-.7 G .385(uleset one is then applied to the output)347.145 96 R
+(of ruleset three, follo)117 108 Q
+(wed similarly by rulesets twenty-one and four)-.25 E(.)-.55 E .202(If you nee\
+d more detail, you can also use the \231\255d21\232 \215ag to turn on more deb)
+142 124.2 R 2.702(ugging. F)-.2 F(or)-.15 E -.15(ex)117 136.2 S(ample,).15 E
+(sendmail \255bt \255d21.99)157 152.4 Q .754
+(turns on an incredible amount of information; a single w)117 168.6 R .753
+(ord address is probably going to print)-.1 F(out se)117 180.6 Q -.15(ve)-.25 G
+(ral pages w).15 E(orth of information.)-.1 E -1.1(Yo)142 196.8 S 3.234(us)1.1
+G .734(hould be w)165.244 196.8 R .734(arned that internally)-.1 F(,)-.65 E/F2
+10/Times-Italic@0 SF(sendmail)3.234 E F1 .734
+(applies ruleset 3 to all addresses.)3.234 F .735(In this)5.735 F -.15(ve)117
+208.8 S 1.23(rsion of).15 F F2(sendmail)3.73 E F1 3.73(,y)C 1.23(ou will ha)
+209.42 208.8 R 1.53 -.15(ve t)-.2 H 3.73(od).15 G 3.73(ot)281.21 208.8 S 1.23
+(hat manually)292.72 208.8 R 6.23(.F)-.65 G 1.23(or e)359.38 208.8 R 1.23
+(xample, older v)-.15 F 1.23(ersions allo)-.15 F(wed)-.25 E(you to use)117
+220.8 Q 2.5(0b)157 237 S(ruce@broadcast.son)169.5 237 Q -.65(y.)-.15 G(com).65
+E(This v)117 253.2 Q(ersion requires that you use:)-.15 E
+(3,0 bruce@broadcast.son)157 269.4 Q -.65(y.)-.15 G(com).65 E F0 2.5
+(5.2.6. Building)102 297.6 R(mailer descriptions)2.5 E F1 1.886 -.8(To a)142
+313.8 T .287(dd an outgoing mailer to your mail system, you will ha).8 F .587
+-.15(ve t)-.2 H 2.787(od).15 G .287(e\214ne the characteristics)409.566 313.8 R
+(of the mailer)117 325.8 Q(.)-.55 E 1.481(Each mailer must ha)142 342 R 1.781
+-.15(ve a)-.2 H 3.981(ni).15 G 1.481(nternal name.)257.645 342 R 1.481
+(This can be arbitrary)6.481 F 3.98(,e)-.65 G 1.48(xcept that the names)417.63
+342 R(\231local\232 and \231prog\232 must be de\214ned.)117 354 Q .127
+(The pathname of the mailer must be gi)142 370.2 R -.15(ve)-.25 G 2.628(ni).15
+G 2.628(nt)317.038 370.2 S .128(he P \214eld.)327.446 370.2 R .128
+(If this mailer should be accessed)5.128 F
+(via an IPC connection, use the string \231[IPC]\232 instead.)117 382.2 Q .021
+(The F \214eld de\214nes the mailer \215ags.)142 398.4 R -1.1(Yo)5.021 G 2.521
+(us)1.1 G .021(hould specify an \231f\232 or \231r\232 \215ag to pass the name)
+311.06 398.4 R .465(of the sender as a)117 410.4 R F0<ad66>2.965 E F1(or)2.965
+E F0<ad72>2.965 E F1 .465(\215ag respecti)2.965 F -.15(ve)-.25 G(ly).15 E 5.465
+(.T)-.65 G .465(hese \215ags are only passed if the)306.95 410.4 R 2.966(yw)
+-.15 G .466(ere passed to)451.418 410.4 R F2(sendmail)117 422.4 Q F1 4.205(,s)C
+4.205(ot)163.705 422.4 S 1.705(hat mailers that gi)175.69 422.4 R 2.005 -.15
+(ve e)-.25 H 1.705(rrors under some circumstances can be placated.).15 F 1.705
+(If the)6.705 F 1.362(mailer is not pick)117 434.4 R 3.862(yy)-.15 G 1.362
+(ou can just specify \231\255f $g\232 in the ar)204.518 434.4 R 1.362
+(gv template.)-.18 F 1.363(If the mailer must be)6.362 F 1.708(called as)117
+446.4 R F0 -.18(ro)4.207 G(ot).18 E F1 1.707(the \231S\232 \215ag should be gi)
+4.207 F -.15(ve)-.25 G 1.707
+(n; this will not reset the userid before calling the).15 F(mailer)117 460.4 Q
+/F3 7/Times-Roman@0 SF(16)142.55 456.4 Q F1 5.112(.I)149.55 460.4 S 2.612(ft)
+160.492 460.4 S .112(his mailer is local \(i.e., will perform \214nal deli)
+169.214 460.4 R -.15(ve)-.25 G .112(ry rather than another netw).15 F .112
+(ork hop\))-.1 F .728(the \231l\232 \215ag should be gi)117 472.4 R -.15(ve)
+-.25 G 3.227(n. Quote).15 F .727
+(characters \(backslashes and " marks\) can be stripped from)3.227 F .268
+(addresses if the \231s\232 \215ag is speci\214ed; if this is not gi)117 484.4
+R -.15(ve)-.25 G 2.769(nt).15 G(he)344.247 484.4 Q 2.769(ya)-.15 G .269
+(re passed through.)365.746 484.4 R .269(If the mailer is)5.269 F .67(capable \
+of sending to more than one user on the same host in a single transaction the \
+\231m\232 \215ag)117 496.4 R 1.176(should be stated.)117 508.4 R 1.176
+(If this \215ag is on, then the ar)6.176 F 1.177(gv template containing)-.18 F
+F0($u)3.677 E F1 1.177(will be repeated for)3.677 F .089
+(each unique user on a gi)117 520.4 R -.15(ve)-.25 G 2.589(nh).15 G 2.589
+(ost. The)235.994 520.4 R .089
+(\231e\232 \215ag will mark the mailer as being \231e)2.589 F(xpensi)-.15 E
+-.15(ve)-.25 G 1.488 -.7(,\232 w).15 H(hich).7 E(will cause)117 534.4 Q F2
+(sendmail)2.5 E F1(to defer connection until a queue run)2.5 E F3(17)345.57
+530.4 Q F1(.)352.57 534.4 Q 2.037(An unusual case is the \231C\232 \215ag.)142
+550.6 R 2.037(This \215ag applies to the mailer that the message is)7.037 F
+(recei)117 562.6 Q -.15(ve)-.25 G 2.654(df).15 G .153(rom, rather than the mai\
+ler being sent to; if set, the domain spec of the sender \(i.e., the)156.454
+562.6 R 1.519(\231@host.domain\232 part\) is sa)117 574.6 R -.15(ve)-.2 G 4.019
+(da).15 G 1.519(nd is appended to an)252.746 574.6 R 4.019(ya)-.15 G 1.52
+(ddresses in the message that do not)354.341 574.6 R
+(already contain a domain spec.)117 586.6 Q -.15(Fo)5 G 2.5(re).15 G
+(xample, a message of the form:)266.11 586.6 Q(From: eric@v)157 602.8 Q
+(angogh.CS.Berk)-.25 E(ele)-.1 E -.65(y.)-.15 G(EDU).65 E -.8(To)157 614.8 S
+2.5(:w).8 G(nj@monet.CS.Berk)179.81 614.8 Q(ele)-.1 E -.65(y.)-.15 G
+(EDU, mckusick).65 E(will be modi\214ed to:)117 631 Q .32 LW 76 665.2 72 665.2
+DL 80 665.2 76 665.2 DL 84 665.2 80 665.2 DL 88 665.2 84 665.2 DL 92 665.2 88
+665.2 DL 96 665.2 92 665.2 DL 100 665.2 96 665.2 DL 104 665.2 100 665.2 DL 108
+665.2 104 665.2 DL 112 665.2 108 665.2 DL 116 665.2 112 665.2 DL 120 665.2 116
+665.2 DL 124 665.2 120 665.2 DL 128 665.2 124 665.2 DL 132 665.2 128 665.2 DL
+136 665.2 132 665.2 DL 140 665.2 136 665.2 DL 144 665.2 140 665.2 DL 148 665.2
+144 665.2 DL 152 665.2 148 665.2 DL 156 665.2 152 665.2 DL 160 665.2 156 665.2
+DL 164 665.2 160 665.2 DL 168 665.2 164 665.2 DL 172 665.2 168 665.2 DL 176
+665.2 172 665.2 DL 180 665.2 176 665.2 DL 184 665.2 180 665.2 DL 188 665.2 184
+665.2 DL 192 665.2 188 665.2 DL 196 665.2 192 665.2 DL 200 665.2 196 665.2 DL
+204 665.2 200 665.2 DL 208 665.2 204 665.2 DL 212 665.2 208 665.2 DL 216 665.2
+212 665.2 DL/F4 5/Times-Roman@0 SF(16)93.6 675.6 Q/F5 8/Times-Italic@0 SF
+(Sendmail)3.2 I/F6 8/Times-Roman@0 SF
+(must be running setuid to root for this to w)2 E(ork.)-.08 E F4(17)93.6 689.2
+Q F6(The \231c\232 con\214guration option must be gi)3.2 I -.12(ve)-.2 G 2(nf)
+.12 G(or this to be ef)242.04 692.4 Q(fecti)-.2 E -.12(ve)-.2 G(.).12 E EP
+%%Page: 46 41
+%%BeginPageSetup
+BP
+%%EndPageSetup
+/F0 10/Times-Bold@0 SF 193.36(SMM:08-46 Sendmail)72 60 R
+(Installation and Operation Guide)2.5 E/F1 10/Times-Roman@0 SF(From: eric@v)157
+96 Q(angogh.CS.Berk)-.25 E(ele)-.1 E -.65(y.)-.15 G(EDU).65 E -.8(To)157 108 S
+2.5(:w).8 G(nj@monet.CS.Berk)179.81 108 Q(ele)-.1 E -.65(y.)-.15 G
+(EDU, mckusick@v).65 E(angogh.CS.Berk)-.25 E(ele)-.1 E -.65(y.)-.15 G(EDU).65 E
+/F2 10/Times-Italic@0 SF 6.608(if and only if)117 124.2 R F1 6.607
+(the \231C\232 \215ag is de\214ned in the mailer resolv)9.108 F 6.607
+(ed to by running)-.15 F(\231eric@v)117 136.2 Q(angogh.CS.Berk)-.25 E(ele)-.1 E
+-.65(y.)-.15 G(EDU\232 through rulesets 3 and 0.).65 E
+(Other \215ags are described in Appendix C.)142 152.4 Q .538
+(The S and R \214elds in the mailer description are per)142 168.6 R .538
+(-mailer re)-.2 F .538(writing sets to be applied to)-.25 F 2.253
+(sender and recipient addresses respecti)117 180.6 R -.15(ve)-.25 G(ly).15 E
+7.253(.T)-.65 G 2.252(hese are applied after the sending domain is)312.995
+180.6 R .546(appended and the general re)117 192.6 R .547
+(writing sets \(numbers one and tw)-.25 F .547(o\) are applied, b)-.1 F .547
+(ut before the out-)-.2 F .458(put re)117 204.6 R .458
+(write \(ruleset four\) is applied.)-.25 F 2.958(At)5.458 G .457
+(ypical use is to append the current domain to addresses)279.646 204.6 R
+(that do not already ha)117 216.6 Q .3 -.15(ve a d)-.2 H 2.5(omain. F).15 F
+(or e)-.15 E(xample, a header of the form:)-.15 E(From: eric)157 232.8 Q
+(might be changed to be:)117 249 Q(From: eric@v)157 265.2 Q(angogh.CS.Berk)-.25
+E(ele)-.1 E -.65(y.)-.15 G(EDU).65 E(or)117 281.4 Q(From: ucb)157 297.6 Q -.25
+(va)-.15 G(x!eric).25 E .186(depending on the domain it is being shipped into.)
+117 313.8 R .186(These sets can also be used to do special pur)5.186 F(-)-.2 E
+(pose output re)117 325.8 Q(writing in cooperation with ruleset four)-.25 E(.)
+-.55 E .026(The S and R \214elds can be speci\214ed as tw)142 342 R 2.526(on)
+-.1 G .025(umbers separated by a slash \(e.g., \231S=10/11\232\),)318.25 342 R
+2.915(meaning that all en)117 354 R -.15(ve)-.4 G 2.915
+(lope addresses will be processed through ruleset 10 and all header).15 F .403
+(addresses will be processed through ruleset 11.)117 366 R -.4(Wi)5.402 G .402
+(th only one number speci\214ed, both en).4 F -.15(ve)-.4 G(lope).15 E
+(and header re)117 378 Q(writing sets are set to the indicated ruleset.)-.25 E
+.228(The E \214eld de\214nes the string to use as an end-of-line indication.)
+142 394.2 R 2.728(As)5.228 G .228(tring containing only)419.654 394.2 R(ne)117
+406.2 Q(wline is the def)-.25 E 2.5(ault. The)-.1 F
+(usual backslash escapes \(\\r)2.5 E 2.5(,\\)-.4 G(n, \\f, \\b\) may be used.)
+342.87 406.2 Q(Finally)142 422.4 Q 2.584(,a)-.65 G 2.584(na)179.214 422.4 S
+-.18(rg)191.238 422.4 S 2.584(vt).18 G .084(emplate is gi)209.752 422.4 R -.15
+(ve)-.25 G 2.584(na).15 G 2.584(st)282.094 422.4 S .084(he A \214eld.)291.348
+422.4 R .083(It may ha)5.083 F .383 -.15(ve e)-.2 H .083(mbedded spaces.).15 F
+.083(If there is)5.083 F .203(no ar)117 434.4 R .203(gv with a)-.18 F F0($u)
+2.703 E F1 .203(macro in it,)2.703 F F2(sendmail)2.704 E F1 .204
+(will speak SMTP to the mailer)2.704 F 5.204(.I)-.55 G 2.704(ft)412.644 434.4 S
+.204(he pathname for this)421.458 434.4 R(mailer is \231[IPC],)117 446.4 Q 2.5
+<9a74>-.7 G(he ar)192.4 446.4 Q(gv should be)-.18 E(IPC $h [)157 462.6 Q F2
+(port)2.5 E F1(])2.5 E(where)117 478.8 Q F2(port)2.5 E F1
+(is the optional port number to connect to.)2.5 E -.15(Fo)142 495 S 2.5(re).15
+G(xample, the speci\214cations:)162.53 495 Q(Mlocal, P=/bin/mail, F=rlsm)157
+511.2 Q(S=10, R=20, A=mail \255d $u)5 E(Mether)157 523.2 Q 2.35(,P)-.4 G 13.9
+(=[IPC], F=meC,)195.89 523.2 R(S=11, R=21, A=IPC $h, M=100000)1.39 E 1.644
+(speci\214es a mailer to do local deli)117 539.4 R -.15(ve)-.25 G 1.644
+(ry and a mailer for ethernet deli).15 F -.15(ve)-.25 G(ry).15 E 6.643(.T)-.65
+G 1.643(he \214rst is called)436.021 539.4 R(\231local,)117 551.4 Q 2.648<9a69>
+-.7 G 2.648(sl)152.548 551.4 S .148(ocated in the \214le \231/bin/mail,)161.866
+551.4 R 2.649<9a74>-.7 G(ak)283.569 551.4 Q .149(es a pick)-.1 F(y)-.15 E F0
+<ad72>2.649 E F1 .149(\215ag, does local deli)2.649 F -.15(ve)-.25 G(ry).15 E
+2.649(,q)-.65 G .149(uotes should)453.571 551.4 R 1.017
+(be stripped from addresses, and multiple users can be deli)117 563.4 R -.15
+(ve)-.25 G 1.016(red at once; ruleset ten should be).15 F 1.417(applied to sen\
+der addresses in the message and ruleset twenty should be applied to recipient)
+117 575.4 R .123(addresses; the ar)117 587.4 R .123
+(gv to send to a message will be the w)-.18 F .123(ord \231mail,)-.1 F 2.623
+<9a74>-.7 G .123(he w)383.129 587.4 R .122(ord \231\255d,)-.1 F 2.622<9a61>-.7
+G .122(nd w)446.646 587.4 R .122(ords con-)-.1 F 1.484
+(taining the name of the recei)117 599.4 R 1.484(ving user)-.25 F 6.484(.I)-.55
+G 3.984(fa)288.496 599.4 S F0<ad72>A F1 1.484
+(\215ag is inserted it will be between the w)3.984 F(ords)-.1 E .289
+(\231mail\232 and \231\255d.)117 611.4 R 5.289<9a54>-.7 G .289
+(he second mailer is called \231ether)196.397 611.4 R 1.689 -.7(,\232 i)-.4 H
+2.789(ts).7 G .289(hould be connected to via an IPC con-)348.95 611.4 R .932(n\
+ection, it can handle multiple users at once, connections should be deferred, \
+and an)117 623.4 R 3.433(yd)-.15 G(omain)479 623.4 Q 1.458
+(from the sender address should be appended to an)117 635.4 R 3.958(yr)-.15 G
+(ecei)340.202 635.4 Q -.15(ve)-.25 G 3.958(rn).15 G 1.458
+(ame without a domain; sender)377.63 635.4 R .74
+(addresses should be processed by ruleset ele)117 647.4 R -.15(ve)-.25 G 3.24
+(na).15 G .74(nd recipient addresses by ruleset twenty-one.)320.34 647.4 R
+(There is a 100,000 byte limit on messages passed through this mailer)117 659.4
+Q(.)-.55 E F0 2.5(5.3. The)87 683.4 R(User Database)2.5 E F1 .109(If you ha)127
+699.6 R .409 -.15(ve a ve)-.2 H .109(rsion of).15 F F2(sendmail)2.609 E F1 .109
+(with the user database package compiled in, the handling of)2.609 F
+(sender and recipient addresses is modi\214ed.)102 711.6 Q EP
+%%Page: 47 42
+%%BeginPageSetup
+BP
+%%EndPageSetup
+/F0 10/Times-Bold@0 SF(Sendmail Installation and Operation Guide)72 60 Q
+(SMM:08-47)452.9 60 Q/F1 10/Times-Roman@0 SF
+(The location of this database is controlled with the)127 96 Q F0(U)2.5 E F1
+(option.)2.5 E F0 2.5(5.3.1. Structur)102 120 R 2.5(eo)-.18 G 2.5(ft)177.92 120
+S(he user database)187.08 120 Q F1(The database is a sorted \(BT)142 136.2 Q
+(ree-based\) structure.)-.35 E(User records are stored with the k)5 E -.15(ey)
+-.1 G(:).15 E/F2 10/Times-Italic@0 SF(user)157 152.4 Q(-name)-.2 E F0(:)A F2
+(\214eld-name)A F1 .128
+(The sorted database format ensures that user records are clustered together)
+117 168.6 R 5.129(.M)-.55 G .129(eta-information is)432.491 168.6 R(al)117
+180.6 Q -.1(wa)-.1 G(ys stored with a leading colon.).1 E
+(Field names de\214ne both the syntax and semantics of the v)142 196.8 Q 2.5
+(alue. De\214ned)-.25 F(\214elds include:)2.5 E 33.39(maildrop The)117 213 R
+(deli)4.873 E -.15(ve)-.25 G 2.373(ry address for this user).15 F 7.373(.T)-.55
+G 2.372(here may be multiple v)349.478 213 R 2.372(alues of this)-.25 F 2.675
+(record. In)189 225 R(particular)2.675 E 2.675(,m)-.4 G .175
+(ailing lists will ha)284.095 225 R .475 -.15(ve o)-.2 H(ne).15 E F2(maildr)
+2.675 E(op)-.45 E F1 .175(record for each user)2.675 F(on the list.)189 237 Q
+30.06(mailname The)117 253.2 R 1.027(outgoing mailname for this user)3.527 F
+6.026(.F)-.55 G 1.026(or each outgoing name, there should)353.34 253.2 R .08
+(be an appropriate)189 265.2 R F2(maildr)2.58 E(op)-.45 E F1 .08
+(record for that name to allo)2.58 F 2.58(wr)-.25 G .08(eturn mail.)422.38
+265.2 R .08(See also)5.08 F F2(:default:mailname)189 277.2 Q F1(.)A 25.62
+(mailsender Changes)117 293.4 R(an)3.448 E 3.448(ym)-.15 G .948
+(ail sent to this address to ha)252.406 293.4 R 1.247 -.15(ve t)-.2 H .947
+(he indicated en).15 F -.15(ve)-.4 G .947(lope sender).15 F(.)-.55 E .498(This\
+ is intended for mailing lists, and will normally be the name of an appro-)189
+305.4 R .755(priate -request address.)189 317.4 R .755(It is v)5.755 F .755
+(ery similar to the o)-.15 F(wner)-.25 E(-)-.2 E F2(list)A F1 .754
+(syntax in the alias)3.254 F(\214le.)189 329.4 Q 33.95(fullname The)117 345.6 R
+(full name of the user)2.5 E(.)-.55 E(of)117 361.8 Q 13.66(\214ce-address The)
+-.25 F(of)2.5 E(\214ce address for this user)-.25 E(.)-.55 E(of)117 378 Q 19.21
+(\214ce-phone The)-.25 F(of)2.5 E(\214ce phone number for this user)-.25 E(.)
+-.55 E(of)117 394.2 Q(\214ce-f)-.25 E 30.98(ax The)-.1 F(of)2.5 E(\214ce F)-.25
+E(AX number for this user)-.74 E(.)-.55 E 13.96(home-address The)117 410.4 R
+(home address for this user)2.5 E(.)-.55 E 19.51(home-phone The)117 426.6 R
+(home phone number for this user)2.5 E(.)-.55 E(home-f)117 442.8 Q 31.28
+(ax The)-.1 F(home F)2.5 E(AX number for this user)-.74 E(.)-.55 E 41.73
+(project A)117 459 R .855
+(\(short\) description of the project this person is af)3.355 F .856
+(\214liated with.)-.25 F .856(In the Uni-)5.856 F -.15(ve)189 471 S
+(rsity this is often just the name of their graduate advisor).15 E(.)-.55 E
+52.28(plan A)117 487.2 R
+(pointer to a \214le from which plan information can be g)2.5 E(athered.)-.05 E
+.925(As of this writing, only a fe)142 503.4 R 3.424(wo)-.25 G 3.424(ft)273.214
+503.4 S .924(hese \214elds are actually being used by)282.748 503.4 R F2
+(sendmail)3.424 E F1(:)A F2(mail-)3.424 E(dr)117 515.4 Q(op)-.45 E F1(and)2.5 E
+F2(mailname)2.5 E F1 5(.A)C F2(\214ng)211.54 515.4 Q(er)-.1 E F1
+(program that uses the other \214elds is planned.)2.5 E F0 2.5(5.3.2. User)102
+539.4 R(database semantics)2.5 E F1 .995(When the re)142 555.6 R .995
+(writing rules submit an address to the local mailer)-.25 F 3.496(,t)-.4 G .996
+(he user name is passed)408.926 555.6 R .781(through the alias \214le.)117
+567.6 R .78
+(If no alias is found \(or if the alias points back to the same address\), the)
+5.781 F 1.777(name \(with \231:maildrop\232 appended\) is then used as a k)117
+579.6 R 2.078 -.15(ey i)-.1 H 4.278(nt).15 G 1.778(he user database.)375.98
+579.6 R 1.778(If no match)6.778 F
+(occurs \(or if the maildrop points at the same address\), forw)117 591.6 Q
+(arding is tried.)-.1 E .551(If the \214rst tok)142 607.8 R .55(en of the user\
+ name returned by ruleset 0 is an \231@\232 sign, the user database)-.1 F .625
+(lookup is skipped.)117 619.8 R .625
+(The intent is that the user database will act as a set of def)5.625 F .626
+(aults for a cluster)-.1 F 1.533(\(in our case, the Computer Science Di)117
+631.8 R 1.533(vision\); mail sent to a speci\214c machine should ignore)-.25 F
+(these def)117 643.8 Q(aults.)-.1 E .351
+(When mail is sent, the name of the sending user is look)142 660 R .351
+(ed up in the database.)-.1 F .352(If that user)5.351 F .041
+(has a \231mailname\232 record, the v)117 672 R .041
+(alue of that record is used as their outgoing name.)-.25 F -.15(Fo)5.04 G 2.54
+(re).15 G .04(xample, I)466.19 672 R(might ha)117 684 Q .3 -.15(ve a r)-.2 H
+(ecord:).15 E 25.94(eric:mailname Eric.Allman@CS.Berk)157 700.2 R(ele)-.1 E
+-.65(y.)-.15 G(EDU).65 E(This w)117 716.4 Q
+(ould cause my outgoing mail to be sent as Eric.Allman.)-.1 E EP
+%%Page: 48 43
+%%BeginPageSetup
+BP
+%%EndPageSetup
+/F0 10/Times-Bold@0 SF 193.36(SMM:08-48 Sendmail)72 60 R
+(Installation and Operation Guide)2.5 E/F1 10/Times-Roman@0 SF .519
+(If a \231maildrop\232 is found for the user)142 96 R 3.019(,b)-.4 G .52
+(ut no corresponding \231mailname\232 record e)299.682 96 R .52(xists, the)-.15
+F 1.128(record \231:def)117 108 R 1.128(ault:mailname\232 is consulted.)-.1 F
+1.127(If present, this is the name of a host to o)6.128 F -.15(ve)-.15 G 1.127
+(rride the).15 F .625(local host.)117 120 R -.15(Fo)5.625 G 3.125(re).15 G .625
+(xample, in our case we w)185.515 120 R .625(ould set it to \231CS.Berk)-.1 F
+(ele)-.1 E -.65(y.)-.15 G 3.125(EDU\232. The).65 F(ef)3.125 E .625
+(fect is that)-.25 F(an)117 132 Q .882(yone kno)-.15 F .882
+(wn in the database gets their outgoing mail stamped as \231user@CS.Berk)-.25 F
+(ele)-.1 E -.65(y.)-.15 G(EDU\232,).65 E -.2(bu)117 144 S 2.5(tp).2 G
+(eople not listed in the database use the local hostname.)137.08 144 Q F0 2.5
+(5.3.3. Cr)102 170 R(eating the database)-.18 E/F2 7/Times-Bold@0 SF(18)223.2
+166 Q F1 .375(The user database is b)142 186.2 R .375(uilt from a te)-.2 F .375
+(xt \214le using the)-.15 F/F3 10/Times-Italic@0 SF(mak)2.875 E(emap)-.1 E F1
+.375(utility \(in the distrib)2.875 F .375(ution in)-.2 F 1.038(the mak)117
+198.2 R 1.038(emap subdirectory\).)-.1 F 1.038(The te)6.038 F 1.039
+(xt \214le is a series of lines corresponding to userdb records;)-.15 F 1.589
+(each line has a k)117 210.2 R 1.889 -.15(ey a)-.1 H 1.589(nd a v).15 F 1.589
+(alue separated by white space.)-.25 F 1.589(The k)6.589 F 1.889 -.15(ey i)-.1
+H 4.089(sa).15 G -.1(lwa)421.945 210.2 S 1.588(ys in the format).1 F
+(described abo)117 222.2 Q .3 -.15(ve \212 f)-.15 H(or e).15 E(xample:)-.15 E
+(eric:maildrop)157 238.4 Q .447
+(This \214le is normally installed in a system directory; for e)117 254.6 R
+.448(xample, it might be called)-.15 F F3(/etc/user)2.948 E(db)-.37 E F1(.)A
+1.6 -.8(To m)117 266.6 T(ak).8 E 2.5(et)-.1 G(he database v)156.65 266.6 Q
+(ersion of the map, run the program:)-.15 E(mak)157 282.8 Q
+(emap btree /etc/userdb)-.1 E(.db < /etc/userdb)-.4 E .077
+(Then create a con\214g \214le that uses this.)117 299 R -.15(Fo)5.077 G 2.577
+(re).15 G .077(xample, using the V8 M4 con\214guration, include the)296.533 299
+R(follo)117 311 Q(wing line in your .mc \214le:)-.25 E
+(de\214ne\(\222confUSERDB_SPEC\264, /etc/userdb)157 327.2 Q(.db\))-.4 E F0 2.5
+(6. O)72 355.4 R(THER CONFIGURA)-.4 E(TION)-.95 E F1 .907
+(There are some con\214guration changes that can be made by recompiling)112
+371.6 R F3(sendmail)3.407 E F1 5.907(.T)C .907(his section)460.593 371.6 R
+(describes what changes can be made and what has to be modi\214ed to mak)87
+383.6 Q 2.5(et)-.1 G(hem.)387.95 383.6 Q F0 2.5(6.1. P)87 407.6 R
+(arameters in sr)-.1 E(c/Mak)-.18 E(e\214le)-.1 E F1 .92
+(These parameters are intended to describe the compilation en)127 423.8 R .92
+(vironment, not site polic)-.4 F 2.22 -.65(y, a)-.15 H(nd).65 E
+(should normally be de\214ned in src/Mak)102 435.8 Q(e\214le.)-.1 E 39.5
+(NDBM If)102 452 R .664(set, the ne)3.164 F 3.164(wv)-.25 G .664
+(ersion of the DBM library that allo)240.406 452 R .665
+(ws multiple databases will be)-.25 F 2.543(used. If)174 464 R .042
+(neither NDBM nor NEWDB are set, a much less ef)2.543 F .042
+(\214cient method of alias)-.25 F(lookup is used.)174 476 Q 32.84(NEWDB If)102
+492.2 R .141(set, use the ne)2.641 F 2.642(wd)-.25 G .142
+(atabase package from Berk)254.436 492.2 R(ele)-.1 E 2.642(y\()-.15 G .142
+(from 4.4BSD\).)385.814 492.2 R .142(This package)5.142 F .267
+(is substantially f)174 504.2 R .267(aster than DBM or NDBM.)-.1 F .267
+(If NEWDB and NDBM are both set,)5.267 F F3(sendmail)174 516.2 Q F1
+(will read DBM \214les, b)2.5 E(ut will create and use NEWDB \214les.)-.2 E
+53.39(NIS Include)102 532.4 R .119(support for NIS.)2.619 F .119
+(If set together with)5.119 F F3(both)2.619 E F1 .119(NEWDB and NDBM,)2.619 F
+F3(sendmail)2.62 E F1 1.076
+(will create both DBM and NEWDB \214les if and only if the \214le /v)174 544.4
+R(ar/yp/Mak)-.25 E(e\214le)-.1 E -.15(ex)174 556.4 S .292
+(ists and is readable.).15 F .293
+(This is intended for compatibility with Sun Microsystems')5.293 F F3(mkalias)
+174 568.4 Q F1(program used on YP masters.)2.5 E 25.05(SYSTEM5 Set)102 584.6 R
+(all of the compilation parameters appropriate for System V)2.5 E(.)-1.29 E
+36.72(LOCKF Use)102 600.8 R .3(System V)2.8 F F0(lockf)2.8 E F1 .299
+(instead of Berk)2.799 F(ele)-.1 E(y)-.15 E F0(\215ock)2.799 E F1 5.299(.D)C
+.299(ue to the highly unusual seman-)375.015 600.8 R .051
+(tics of locks across forks in)174 612.8 R F0(lockf)2.551 E F1 2.551(,t)C .051
+(his should ne)314.897 612.8 R -.15(ve)-.25 G 2.552(rb).15 G 2.552(eu)387.702
+612.8 S .052(sed unless absolutely nec-)399.694 612.8 R(essary)174 624.8 Q 5
+(.S)-.65 G(et by def)211.4 624.8 Q(ault if SYSTEM5 is set.)-.1 E 33.94
+(SYS5TZ Use)102 641 R(System V time zone semantics.)2.5 E(HASINITGR)102 657.2 Q
+(OUPS)-.4 E 2.392(Set this if your system has the)174 669.2 R F3(initgr)4.892 E
+(oups\(\))-.45 E F1 2.391(call \(if you ha)4.891 F 2.691 -.15(ve m)-.2 H 2.391
+(ultiple group).15 F .32 LW 76 678.8 72 678.8 DL 80 678.8 76 678.8 DL 84 678.8
+80 678.8 DL 88 678.8 84 678.8 DL 92 678.8 88 678.8 DL 96 678.8 92 678.8 DL 100
+678.8 96 678.8 DL 104 678.8 100 678.8 DL 108 678.8 104 678.8 DL 112 678.8 108
+678.8 DL 116 678.8 112 678.8 DL 120 678.8 116 678.8 DL 124 678.8 120 678.8 DL
+128 678.8 124 678.8 DL 132 678.8 128 678.8 DL 136 678.8 132 678.8 DL 140 678.8
+136 678.8 DL 144 678.8 140 678.8 DL 148 678.8 144 678.8 DL 152 678.8 148 678.8
+DL 156 678.8 152 678.8 DL 160 678.8 156 678.8 DL 164 678.8 160 678.8 DL 168
+678.8 164 678.8 DL 172 678.8 168 678.8 DL 176 678.8 172 678.8 DL 180 678.8 176
+678.8 DL 184 678.8 180 678.8 DL 188 678.8 184 678.8 DL 192 678.8 188 678.8 DL
+196 678.8 192 678.8 DL 200 678.8 196 678.8 DL 204 678.8 200 678.8 DL 208 678.8
+204 678.8 DL 212 678.8 208 678.8 DL 216 678.8 212 678.8 DL/F4 5/Times-Roman@0
+SF(18)93.6 689.2 Q/F5 8/Times-Roman@0 SF .288(These instructions are kno)3.2 J
+.289(wn to be incomplete.)-.2 F 2.289(Af)4.289 G .289(uture v)266.46 692.4 R
+.289(ersion of the user database is planned including things such as \214n-)
+-.12 F(ger service \212 and good documentation.)72 702 Q EP
+%%Page: 49 44
+%%BeginPageSetup
+BP
+%%EndPageSetup
+/F0 10/Times-Bold@0 SF(Sendmail Installation and Operation Guide)72 60 Q
+(SMM:08-49)452.9 60 Q/F1 10/Times-Roman@0 SF 2.5(support\). This)174 96 R
+(is the def)2.5 E(ault if SYSTEM5 is)-.1 E/F2 10/Times-Italic@0 SF(not)2.5 E F1
+(de\214ned or if you are on HPUX.)2.5 E(HASUN)102 112.2 Q 13.19(AME Set)-.35 F
+.89(this if you ha)3.39 F 1.19 -.15(ve t)-.2 H(he).15 E F2(uname)3.39 E F1 .89
+(\(2\) system call \(or corresponding library routine\).)B(Set by def)174 124.2
+Q(ault if SYSTEM5 is set.)-.1 E(HASST)102 140.4 Q -1.11(AT)-.93 G 15.42(FS Set)
+1.11 F .202(this if you ha)2.702 F .502 -.15(ve t)-.2 H(he).15 E F2(statfs)
+2.702 E F1 .202(\(2\) system call.)B .202(This will allo)5.202 F 2.702(wy)-.25
+G .202(ou to gi)425.824 140.4 R .501 -.15(ve a t)-.25 H(empo-).15 E .107
+(rary f)174 152.4 R .108(ailure message to incoming SMTP email when you are lo)
+-.1 F 2.608(wo)-.25 G 2.608(nd)441.186 152.4 S .108(isk space.)453.794 152.4 R
+(It)5.108 E(is set by def)174 164.4 Q(ault on 4.4BSD and OSF/1 systems.)-.1 E
+(HASUST)102 180.6 Q 21.54 -1.11(AT S)-.93 H .594(et if you ha)1.11 F .894 -.15
+(ve t)-.2 H(he).15 E F2(ustat)3.094 E F1 .594(\(2\) system call.)B .594
+(This is an alternati)5.594 F .893 -.15(ve i)-.25 H .593(mplementation of).15 F
+.525(disk space control.)174 192.6 R -1.1(Yo)5.525 G 3.025(us)1.1 G .525
+(hould only set one of HASST)278.32 192.6 R -1.11(AT)-.93 G .525(FS or HASUST)
+1.11 F -.83 -1.11(AT ;)-.93 H(the)4.135 E(\214rst is preferred.)174 204.6 Q(_P)
+102 220.8 Q -1.11(AT)-.92 G(H_SENDMAILCF)1.11 E
+(The pathname of the sendmail.cf \214le.)174 232.8 Q(_P)102 249 Q -1.11(AT)-.92
+G(H_SENDMAILPID)1.11 E(The pathname of the sendmail.pid \214le.)174 261 Q 26.17
+(LA_TYPE The)102 277.2 R(load a)2.5 E -.15(ve)-.2 G(rage type.).15 E
+(Details are described belo)5 E -.65(w.)-.25 G .343(The are se)102 293.4 R -.15
+(ve)-.25 G .342(ral b).15 F .342(uilt-in w)-.2 F .342
+(ays of computing the load a)-.1 F -.15(ve)-.2 G(rage.).15 E F2(Sendmail)5.342
+E F1 .342(tries to auto-con\214gure them)2.842 F .266
+(based on imperfect guesses; you can select one using the)102 305.4 R F2(cc)
+2.767 E F1(option)2.767 E F0(\255DLA_TYPE=)2.767 E F2(type)A F1 2.767(,w)C
+(here)467.363 305.4 Q F2(type)2.767 E F1(is:)102 317.4 Q 34.51(LA_INT The)102
+333.6 R -.1(ke)2.979 G .479(rnel stores the load a).1 F -.15(ve)-.2 G .479
+(rage in the k).15 F .478(ernel as an array of long inte)-.1 F 2.978(gers. The)
+-.15 F(actual v)174 345.6 Q(alues are scaled by a f)-.25 E(actor FSCALE \(def)
+-.1 E(ault 256\).)-.1 E(LA_SHOR)102 361.8 Q 21.49(TT)-.6 G .33(he k)180.11
+361.8 R .33(ernel stores the load a)-.1 F -.15(ve)-.2 G .331(rage in the k).15
+F .331(ernel as an array of short inte)-.1 F 2.831(gers. The)-.15 F(actual v)
+174 373.8 Q(alues are scaled by a f)-.25 E(actor FSCALE \(def)-.1 E
+(ault 256\).)-.1 E(LA_FLO)102 390 Q 22.63 -1.11(AT T)-.35 H 1.118(he k)1.11 F
+1.117(ernel stores the load a)-.1 F -.15(ve)-.2 G 1.117(rage in the k).15 F
+1.117(ernel as an array of double precision)-.1 F(\215oats.)174 402 Q(LA_MA)102
+418.2 Q 21.57(CH Use)-.4 F(MA)2.5 E(CH-style load a)-.4 E -.15(ve)-.2 G(rages.)
+.15 E 25.05(LA_SUBR Call)102 434.4 R(the)2.5 E F2 -.1(ge)2.5 G(tloadavg).1 E F1
+(routine to get the load a)2.5 E -.15(ve)-.2 G(rage as an array of doubles.).15
+E(LA_ZER)102 450.6 Q 27.96(OA)-.4 G -.1(lwa)181.22 450.6 S
+(ys return zero as the load a).1 E -.15(ve)-.2 G 2.5(rage. This).15 F(is the f)
+2.5 E(allback case.)-.1 E .493(If type)102 466.8 R/F3 9/Times-Roman@0 SF
+(LA_INT)2.993 E F1(,)A F3(LA_SHOR)2.993 E(T)-.54 E F1 2.993(,o)C(r)224.802
+466.8 Q F3(LA_FLO)2.993 E -.999(AT)-.315 G F1 .493
+(is speci\214ed, you may also need to specify)3.992 F F3(_P)2.994 E -.999(AT)
+-.828 G(H_UNIX).999 E F1 .949(\(the path to your system binary\) and)102 478.8
+R F3(LA_A)3.448 E(VENR)-1.215 E(UN)-.36 E F1 .948(\(the name of the v)3.448 F
+.948(ariable containing the load)-.25 F -2.25 -.2(av e)102 490.8 T
+(rage in the k).2 E(ernel; usually \231_a)-.1 E -.15(ve)-.2 G
+(nrun\232 or \231a).15 E -.15(ve)-.2 G(nrun\232\).).15 E 1.439
+(There are also se)127 507 R -.15(ve)-.25 G 1.439
+(ral compilation \215ags to indicate the en).15 F 1.44
+(vironment such as \231_AIX3\232 and)-.4 F 2.5(\231_SCO_unix_\232. See)102 519
+R(the READ_ME \214le for the latest scoop on these \215ags.)2.5 E F0 2.5
+(6.2. P)87 543 R(arameters in sr)-.1 E(c/conf)-.18 E(.h)-.15 E F1 -.15(Pa)127
+559.2 S .896(rameters and compilation options are de\214ned in conf.h.).15 F
+.895(Most of these need not normally)5.895 F .192(be tweak)102 571.2 R .192
+(ed; common parameters are all in sendmail.cf.)-.1 F(Ho)5.192 E(we)-.25 E -.15
+(ve)-.25 G .992 -.4(r, t).15 H .192(he sizes of certain primiti).4 F .493 -.15
+(ve ve)-.25 H(c-).15 E(tors, etc., are included in this \214le.)102 583.2 Q
+(The numbers follo)5 E(wing the parameters are their def)-.25 E(ault v)-.1 E
+(alue.)-.25 E 1.91(MAXLINE [1024])102 599.4 R 1.909
+(The maximum line length of an)190.31 599.4 R 4.409(yi)-.15 G 1.909(nput line.)
+338.276 599.4 R 1.909(If message lines e)6.909 F 1.909(xceed this)-.15 F .575
+(length the)188.4 611.4 R 3.075(yw)-.15 G .575
+(ill still be processed correctly; ho)243.84 611.4 R(we)-.25 E -.15(ve)-.25 G
+1.375 -.4(r, h).15 H .575(eader lines, con\214gura-).4 F
+(tion \214le lines, alias lines, etc., must \214t within this limit.)188.4
+623.4 Q(MAXN)102 639.6 Q(AME [256])-.35 E(The maximum length of an)9.82 E 2.5
+(yn)-.15 G(ame, such as a host or a user name.)309.63 639.6 Q .231(MAXPV [40])
+102 655.8 R .231(The maximum number of parameters to an)188.631 655.8 R 2.731
+(ym)-.15 G(ailer)376.458 655.8 Q 5.231(.T)-.55 G .23(his limits the number of)
+407.519 655.8 R .375(recipients that may be passed in one transaction.)188.4
+667.8 R .376(It can be set to an)5.376 F 2.876(ya)-.15 G(rbitrary)474.01 667.8
+Q .876(number abo)188.4 679.8 R 1.176 -.15(ve a)-.15 H .876(bout 10, since).15
+F F2(sendmail)3.376 E F1 .876(will break up a deli)3.376 F -.15(ve)-.25 G .875
+(ry into smaller).15 F .886(batches as needed.)188.4 691.8 R 3.386(Ah)5.886 G
+.887(igher number may reduce load on your system, ho)285.804 691.8 R(w-)-.25 E
+-2.15 -.25(ev e)188.4 703.8 T -.55(r.).25 G EP
+%%Page: 50 45
+%%BeginPageSetup
+BP
+%%EndPageSetup
+/F0 10/Times-Bold@0 SF 193.36(SMM:08-50 Sendmail)72 60 R
+(Installation and Operation Guide)2.5 E/F1 10/Times-Roman@0 SF(MAXA)102 96 Q
+-.18(TO)-1.11 G 2.559(M[).18 G 8.26(100] The)159.369 96 R .059
+(maximum number of atoms \(tok)2.559 F .058(ens\) in a single address.)-.1 F
+-.15(Fo)5.058 G 2.558(re).15 G .058(xample, the)457.282 96 R
+(address \231eric@CS.Berk)188.4 108 Q(ele)-.1 E -.65(y.)-.15 G(EDU\232 is se)
+.65 E -.15(ve)-.25 G 2.5(na).15 G(toms.)367.93 108 Q .112(MAXMAILERS [25])102
+124.2 R .112(The maximum number of mailers that may be de\214ned in the con\
+\214guration \214le.).02 F(MAXR)102 140.4 Q(WSETS [100])-.55 E
+(The maximum number of re).01 E(writing sets that may be de\214ned.)-.25 E
+(MAXPRIORITIES [25])102 156.6 Q 2.482(The maximum number of v)188.4 168.6 R
+2.482(alues for the \231Precedence:\232 \214eld that may be)-.25 F
+(de\214ned \(using the)188.4 180.6 Q F0(P)2.5 E F1(line in sendmail.cf\).)2.5 E
+(MAXUSERENVIR)102 196.8 Q(ON [40])-.4 E .399
+(The maximum number of items in the user en)188.4 208.8 R .4
+(vironment that will be passed to)-.4 F(subordinate mailers.)188.4 220.8 Q -.1
+(QU)102 237 S(EUESIZE [1000]).1 E
+(The maximum number of entries that will be processed in a single queue run.)
+2.35 E(MAXMXHOSTS [20])102 253.2 Q
+(The maximum number of MX records we will accept for an)188.4 265.2 Q 2.5(ys)
+-.15 G(ingle host.)439.03 265.2 Q 2.851(An)102 281.4 S .351
+(umber of other compilation options e)117.071 281.4 R 2.851(xist. These)-.15 F
+.35(specify whether or not speci\214c code should be)2.851 F(compiled in.)102
+293.4 Q(DEB)102 309.6 Q 49.56(UG If)-.1 F 1.226(set, deb)3.726 F 1.226
+(ugging information is compiled in.)-.2 F 2.827 -.8(To a)6.226 H 1.227
+(ctually get the deb).8 F(ugging)-.2 E .4(output, the)188.4 321.6 R F0<ad64>2.9
+E F1 .4(\215ag must be used.)2.9 F F0 .4(WE STR)5.4 F(ONGL)-.3 E 2.9(YR)-.92 G
+.4(ECOMMEND THA)412.05 321.6 R(T)-.95 E .97(THIS BE LEFT ON.)188.4 333.6 R F1
+.97(Some people, belie)5.97 F .97(ving that it w)-.25 F .97
+(as a security hole \(it)-.1 F -.1(wa)188.4 345.6 S(s, once\) ha).1 E .3 -.15
+(ve t)-.2 H(urned it of).15 E 2.5(fa)-.25 G(nd thus crippled deb)309.05 345.6 Q
+(uggers.)-.2 E 41.69(NETINET If)102 361.8 R .829
+(set, support for Internet protocol netw)3.33 F .829(orking is compiled in.)-.1
+F(Pre)5.829 E .829(vious v)-.25 F(er)-.15 E(-)-.2 E .177(sions of)188.4 373.8 R
+/F2 10/Times-Italic@0 SF(sendmail)2.677 E F1 .177(referred to this as)2.677 F
+/F3 9/Times-Roman@0 SF -.36(DA)2.678 G(EMON).36 E F1 2.678(;t)C .178
+(his old usage is no)381.71 373.8 R 2.678(wi)-.25 G(ncorrect.)468.74 373.8 Q
+48.35(NETISO If)102 390 R .143(set, support for ISO protocol netw)2.643 F .142
+(orking is compiled in \(it may be appropri-)-.1 F
+(ate to #de\214ne this in the Mak)188.4 402 Q(e\214le instead of conf.h\).)-.1
+E 63.35(LOG If)102 418.2 R .5(set, the)3 F F2(syslo)3 E(g)-.1 E F1 .5
+(routine in use at some sites is used.)3 F .5(This mak)5.5 F .5(es an informa-)
+-.1 F .504(tional log record for each message processed, and mak)188.4 430.2 R
+.504(es a higher priority log)-.1 F(record for internal system errors.)188.4
+442.2 Q(MA)102 458.4 Q 16.12(TCHGECOS Compile)-1.11 F 3.555
+(in the code to do `)6.055 F 3.555(`fuzzy matching')-.74 F 6.055('o)-.74 G
+6.055(nt)404.22 458.4 S 3.555(he GECOS \214eld in)418.055 458.4 R 2.5
+(/etc/passwd. This)188.4 470.4 R(also requires that option G be turned on.)2.5
+E -.35(NA)102 486.6 S 18.15(MED_BIND Compile).35 F .413
+(in code to use the Berk)2.913 F(ele)-.1 E 2.912(yI)-.15 G .412
+(nternet Name Domain \(BIND\) serv)342.41 486.6 R .412(er to)-.15 F(resolv)
+188.4 498.6 Q 2.5(eT)-.15 G(CP/IP host names.)225.74 498.6 Q(NO)102 514.8 Q
+38.76(TUNIX If)-.4 F .247
+(you are using a non-UNIX mail format, you can set this \215ag to turn of)2.747
+F 2.748(fs)-.25 G(pe-)491.23 514.8 Q
+(cial processing of UNIX-style \231From \232 lines.)188.4 526.8 Q -.1(QU)102
+543 S 50.12(EUE This).1 F 1.559
+(\215ag should be set to compile in the queueing code.)4.06 F 1.559
+(If this is not set,)6.559 F
+(mailers must accept the mail immediately or it will be returned to the sender)
+188.4 555 Q(.)-.55 E(SETPR)102 571.2 Q 12.63(OCTITLE If)-.4 F(de\214ned,)3.88 E
+F2(sendmail)3.88 E F1 1.381(will change its)3.881 F F2(ar)3.881 E(gv)-.37 E F1
+1.381(array to indicate its current status.)3.881 F .207
+(This can be used in conjunction with the)188.4 583.2 R F2(ps)2.707 E F1 .206
+(command to \214nd out just what it')2.707 F(s)-.55 E(up to.)188.4 595.2 Q
+57.78(SMTP If)102 611.4 R .756(set, the code to handle user and serv)3.256 F
+.756(er SMTP will be compiled in.)-.15 F .756(This is)5.756 F 2.507
+(only necessary if your machine has some mailer that speaks SMTP \(this)188.4
+623.4 R(means most machines e)188.4 635.4 Q -.15(ve)-.25 G(rywhere\).).15 E
+(UGL)102 651.6 Q 30.46(YUUCP If)-1 F 1.023(you ha)3.523 F 1.323 -.15(ve a U)-.2
+H 1.024(UCP host adjacent to you which is not running a reasonable).15 F -.15
+(ve)188.4 663.6 S .112(rsion of).15 F F2(rmail)2.612 E F1 2.612(,y)C .112
+(ou will ha)263.026 663.6 R .412 -.15(ve t)-.2 H 2.612(os).15 G .112
+(et this \215ag to include the \231remote from sys-)329.234 663.6 R .031
+(name\232 info on the from line.)188.4 675.6 R .032
+(Otherwise, UUCP gets confused about where the)5.032 F(mail came from.)188.4
+687.6 Q 44.45(USERDB Include)102 703.8 R(the)3.449 E F0(experimental)3.449 E F1
+(Berk)3.449 E(ele)-.1 E 3.449(yu)-.15 G .949(ser information database package.)
+341.356 703.8 R(This)5.948 E .27(adds a ne)188.4 715.8 R 2.77(wl)-.25 G -2.15
+-.25(ev e)238.67 715.8 T 2.77(lo).25 G 2.77(fl)262.7 715.8 S .27(ocal name e)
+271.58 715.8 R .27(xpansion between aliasing and forw)-.15 F 2.77(arding. It)
+-.1 F EP
+%%Page: 51 46
+%%BeginPageSetup
+BP
+%%EndPageSetup
+/F0 10/Times-Bold@0 SF(Sendmail Installation and Operation Guide)72 60 Q
+(SMM:08-51)452.9 60 Q/F1 10/Times-Roman@0 SF(also uses the NEWDB package.)188.4
+96 Q(This may change in future releases.)5 E(IDENTPR)102 112.2 Q -1.88 -.4
+(OT O)-.4 H .376(Compile in the IDENT protocol as de\214ned in RFC 1413.)188.4
+112.2 R .375(This def)5.375 F .375(aults on for)-.1 F 1.053(all systems e)188.4
+124.2 R 1.053
+(xcept Ultrix, which apparently has the interesting \231feature\232 that)-.15 F
+.83(when it recei)188.4 136.2 R -.15(ve)-.25 G 3.33(sa\231).15 G .83
+(host unreachable\232 message it closes all open connections)270.18 136.2 R
+1.921(to that host.)188.4 148.2 R 1.921(Since some \214re)6.921 F -.1(wa)-.25 G
+1.922(ll g).1 F(ate)-.05 E -.1(wa)-.25 G 1.922
+(ys send this error code when you).1 F 2.055
+(access an unauthorized port \(such as 113, used by IDENT\), Ultrix cannot)
+188.4 160.2 R(recei)188.4 172.2 Q .3 -.15(ve e)-.25 H(mail from such hosts.).15
+E F0 2.5(6.3. Con\214guration)87 196.2 R(in sr)2.5 E(c/conf)-.18 E(.c)-.15 E F1
+(The follo)127 212.4 Q(wing changes can be made in conf.c.)-.25 E F0 2.5
+(6.3.1. Built-in)102 236.4 R(Header Semantics)2.5 E F1 1.248
+(Not all header semantics are de\214ned in the con\214guration \214le.)142
+252.6 R 1.248(Header lines that should)6.248 F .305(only be included by certai\
+n mailers \(as well as other more obscure semantics\) must be speci\214ed)117
+264.6 R .046(in the)117 276.6 R/F2 10/Times-Italic@0 SF(HdrInfo)2.546 E F1 .046
+(table in)2.546 F F2(conf)2.546 E(.c)-.15 E F1 5.046(.T)C .047
+(his table contains the header name \(which should be in all lo)246.836 276.6 R
+(wer)-.25 E(case\) and a set of header control \215ags \(described belo)117
+288.6 Q(w\), The \215ags are:)-.25 E(H_A)117 304.8 Q 30.97(CHECK Normally)-.4 F
+.007(when the check is made to see if a header line is compatible with)2.508 F
+2.94(am)203.4 316.8 S(ailer)218.56 316.8 Q(,)-.4 E F2(sendmail)2.94 E F1 .441
+(will not delete an e)2.94 F .441(xisting line.)-.15 F .441
+(If this \215ag is set,)5.441 F F2(send-)2.941 E(mail)203.4 328.8 Q F1 .152
+(will delete e)2.652 F -.15(ve)-.25 G 2.652(ne).15 G .152
+(xisting header lines.)293.998 328.8 R .152
+(That is, if this bit is set and the)5.152 F 1.425(mailer does not ha)203.4
+340.8 R 1.725 -.15(ve \215)-.2 H 1.425
+(ag bits set that intersect with the required mailer).15 F 2.204
+(\215ags in the header de\214nition in sendmail.cf, the header line is)203.4
+352.8 R F2(always)4.703 E F1(deleted.)203.4 364.8 Q 51.13(H_EOH If)117 381 R
+.206(this header \214eld is set, treat it lik)2.705 F 2.706(eab)-.1 G .206
+(lank line, i.e., it will signal the end)363.948 381 R
+(of the header and the be)203.4 393 Q(ginning of the message te)-.15 E(xt.)-.15
+E 39.45(H_FORCE Add)117 409.2 R 2.039(this header entry e)4.539 F -.15(ve)-.25
+G 4.539(ni).15 G 4.539(fo)326.225 409.2 S 2.038(ne e)339.094 409.2 R 2.038
+(xisted in the message before.)-.15 F 2.038(If a)7.038 F 2.188
+(header entry does not ha)203.4 421.2 R 2.488 -.15(ve t)-.2 H 2.188
+(his bit set,).15 F F2(sendmail)4.688 E F1 2.189(will not add another)4.689 F
+.62(header line if a header line of this name already e)203.4 433.2 R 3.12
+(xisted. This)-.15 F -.1(wo)3.12 G .62(uld nor).1 F(-)-.2 E
+(mally be used to stamp the message by e)203.4 445.2 Q -.15(ve)-.25 G
+(ryone who handled it.).15 E(H_TRA)117 461.4 Q 39.3(CE If)-.4 F 1.043
+(set, this is a timestamp \(trace\) \214eld.)3.543 F 1.044
+(If the number of trace \214elds in a)6.043 F .706(message e)203.4 473.4 R .705
+(xceeds a preset amount the message is returned on the assump-)-.15 F
+(tion that it has an aliasing loop.)203.4 485.4 Q 46.67(H_RCPT If)117 501.6 R
+.332(set, this \214eld contains recipient addresses.)2.832 F .332
+(This is used by the)5.332 F F0<ad74>2.832 E F1 .333(\215ag to)2.833 F 1.349
+(determine who to send to when it is collecting recipients from the mes-)203.4
+513.6 R(sage.)203.4 525.6 Q(H_FR)117 541.8 Q 43.74(OM This)-.4 F 1.673
+(\215ag indicates that this \214eld speci\214es a sender)4.173 F 6.674(.T)-.55
+G 1.674(he order of these)432.058 541.8 R .898(\214elds in the)203.4 553.8 R F2
+(HdrInfo)3.398 E F1 .898(table speci\214es)3.398 F F2(sendmail)3.398 E F1 1.998
+-.55('s p)D .898(reference for which \214eld).55 F
+(to return error messages to.)203.4 565.8 Q(Let')117 582 Q 2.5(sl)-.55 G
+(ook at a sample)142.28 582 Q F2(HdrInfo)2.5 E F1(speci\214cation:)2.5 E EP
+%%Page: 52 47
+%%BeginPageSetup
+BP
+%%EndPageSetup
+/F0 10/Times-Bold@0 SF 193.36(SMM:08-52 Sendmail)72 60 R
+(Installation and Operation Guide)2.5 E/F1 10/Times-Roman@0 SF(struct hdrinfo)
+157 96 Q(HdrInfo[] =)258.19 96 Q({)157 108 Q
+(/* originator \214elds, most to least signi\214cant)189.5 120 Q(*/)5 E 14.72
+("resent-sender", H_FR)177 132 R(OM,)-.4 E 21.38("resent-from", H_FR)177 144 R
+(OM,)-.4 E 41.93("sender", H_FR)177 156 R(OM,)-.4 E 48.59("from", H_FR)177 168
+R(OM,)-.4 E 29.15("full-name", H_A)177 180 R(CHECK,)-.4 E
+(/* destination \214elds */)189.5 192 Q 60.25("to", H_RCPT)177 204 R(,)-.74 E
+33.04("resent-to", H_RCPT)177 216 R(,)-.74 E 59.15("cc", H_RCPT)177 228 R(,)
+-.74 E(/* message identi\214cation and control */)189.5 240 Q 34.15
+("message", H_EOH,)177 252 R("te)177 264 Q 53.18(xt", H_EOH,)-.15 F
+(/* trace \214elds */)189.5 276 Q("recei)177 288 Q -.15(ve)-.25 G 34.56
+(d", H_TRA).15 F(CE|H_FORCE,)-.4 E 49.53(NULL, 0,)177 312 R(};)157 324 Q 2.435
+(This structure indicates that the \231T)117 340.2 R 2.435
+(o:\232, \231Resent-T)-.8 F 2.435
+(o:\232, and \231Cc:\232 \214elds all specify recipient)-.8 F 3.162
+(addresses. An)117 352.2 R 3.162<7999>-.15 G .661(Full-Name:\232 \214eld will \
+be deleted unless the required mailer \215ag \(indicated in)188.154 352.2 R
+.245(the con\214guration \214le\) is speci\214ed.)117 364.2 R .245
+(The \231Message:\232 and \231T)5.245 F -.15(ex)-.7 G .246
+(t:\232 \214elds will terminate the header;).15 F 1.936
+(these are used by random dissenters around the netw)117 376.2 R 1.936(ork w)
+-.1 F 4.436(orld. The)-.1 F(\231Recei)4.436 E -.15(ve)-.25 G 1.936
+(d:\232 \214eld will).15 F(al)117 388.2 Q -.1(wa)-.1 G
+(ys be added, and can be used to trace messages.).1 E .445
+(There are a number of important points here.)142 404.4 R .446
+(First, header \214elds are not added automati-)5.446 F .657
+(cally just because the)117 416.4 R 3.157(ya)-.15 G .657(re in the)216.678
+416.4 R/F2 10/Times-Italic@0 SF(HdrInfo)3.157 E F1 .657(structure; the)3.157 F
+3.157(ym)-.15 G .656(ust be speci\214ed in the con\214guration)358.23 416.4 R
+.727(\214le in order to be added to the message.)117 428.4 R(An)5.728 E 3.228
+(yh)-.15 G .728(eader \214elds mentioned in the con\214guration \214le)312.982
+428.4 R -.2(bu)117 440.4 S 3.24(tn).2 G .74(ot mentioned in the)137.82 440.4 R
+F2(HdrInfo)3.24 E F1 .74(structure ha)3.24 F 1.04 -.15(ve d)-.2 H(ef).15 E .74
+(ault processing performed; that is, the)-.1 F 3.24(ya)-.15 G(re)496.23 440.4 Q
+1.374(added unless the)117 452.4 R 3.874(yw)-.15 G 1.374
+(ere in the message already)201.792 452.4 R 6.375(.S)-.65 G 1.375(econd, the)
+326.595 452.4 R F2(HdrInfo)3.875 E F1 1.375(structure only speci\214es)3.875 F
+.324
+(cliched processing; certain headers are processed specially by ad hoc code re)
+117 464.4 R -.05(ga)-.15 G .324(rdless of the sta-).05 F .48
+(tus speci\214ed in)117 476.4 R F2(HdrInfo)2.98 E F1 5.48(.F)C .481(or e)226.55
+476.4 R .481(xample, the \231Sender:\232 and \231From:\232 \214elds are al)-.15
+F -.1(wa)-.1 G .481(ys scanned on).1 F(ARP)117 490.4 Q .75
+(ANET mail to determine the sender)-.92 F/F3 7/Times-Roman@0 SF(19)282.31 486.4
+Q F1 3.251(;t)289.31 490.4 S .751
+(his is used to perform the \231return to sender\232 func-)298.121 490.4 R
+2.977(tion. The)117 502.4 R .476(\231From:\232 and \231Full-Name:\232 \214elds\
+ are used to determine the full name of the sender if)2.977 F
+(possible; this is stored in the macro)117 514.4 Q F0($x)2.5 E F1
+(and used in a number of w)2.5 E(ays.)-.1 E F0 2.5(6.3.2. Restricting)102 538.4
+R(Use of Email)2.5 E F1 .149
+(If it is necessary to restrict mail through a relay)142 554.6 R 2.649(,t)-.65
+G(he)339.75 554.6 Q F2 -.15(ch)2.65 G(ec).15 E(kcompat)-.2 E F1 .15
+(routine can be modi\214ed.)2.65 F .163(This routine is called for e)117 566.6
+R -.15(ve)-.25 G .163(ry recipient address.).15 F .163(It returns an e)5.163 F
+.163(xit status indicating the status of)-.15 F .895(the message.)117 578.6 R
+.895(The status)5.895 F/F4 9/Times-Roman@0 SF(EX_OK)3.395 E F1 .895
+(accepts the address,)3.395 F F4(EX_TEMPF)3.395 E(AIL)-.666 E F1 .895
+(queues the message for a)3.395 F .264(later try)117 590.6 R 2.764(,a)-.65 G
+.264(nd other v)157.698 590.6 R .264(alues \(commonly)-.25 F F4(EX_UN)2.764 E
+-1.215(AVA)-.315 G(ILABLE)1.215 E F1 2.764(\)r)C .264(eject the message.)
+358.375 590.6 R .263(It is up to)5.264 F F2 -.15(ch)2.763 G(ec).15 E(k-)-.2 E
+(compat)117 602.6 Q F1 .429(to print an error message \(using)2.929 F F2(usr)
+2.929 E(err)-.37 E F1 2.929(\)i)C 2.929(ft)315.032 602.6 S .43
+(he message is rejected.)324.071 602.6 R -.15(Fo)5.43 G 2.93(re).15 G(xample,)
+443.39 602.6 Q F2 -.15(ch)2.93 G(ec).15 E(k-)-.2 E(compat)117 614.6 Q F1
+(could read:)2.5 E .32 LW 76 669.2 72 669.2 DL 80 669.2 76 669.2 DL 84 669.2 80
+669.2 DL 88 669.2 84 669.2 DL 92 669.2 88 669.2 DL 96 669.2 92 669.2 DL 100
+669.2 96 669.2 DL 104 669.2 100 669.2 DL 108 669.2 104 669.2 DL 112 669.2 108
+669.2 DL 116 669.2 112 669.2 DL 120 669.2 116 669.2 DL 124 669.2 120 669.2 DL
+128 669.2 124 669.2 DL 132 669.2 128 669.2 DL 136 669.2 132 669.2 DL 140 669.2
+136 669.2 DL 144 669.2 140 669.2 DL 148 669.2 144 669.2 DL 152 669.2 148 669.2
+DL 156 669.2 152 669.2 DL 160 669.2 156 669.2 DL 164 669.2 160 669.2 DL 168
+669.2 164 669.2 DL 172 669.2 168 669.2 DL 176 669.2 172 669.2 DL 180 669.2 176
+669.2 DL 184 669.2 180 669.2 DL 188 669.2 184 669.2 DL 192 669.2 188 669.2 DL
+196 669.2 192 669.2 DL 200 669.2 196 669.2 DL 204 669.2 200 669.2 DL 208 669.2
+204 669.2 DL 212 669.2 208 669.2 DL 216 669.2 212 669.2 DL/F5 5/Times-Roman@0
+SF(19)93.6 679.6 Q/F6 8/Times-Roman@0 SF(Actually)3.2 I 2.632(,t)-.52 G .632
+(his is no longer true in SMTP; this information is contained in the en)132.488
+682.8 R -.12(ve)-.32 G 2.631(lope. The).12 F .631(older ARP)2.631 F .631
+(ANET protocols did)-.736 F(not completely distinguish en)72 692.4 Q -.12(ve)
+-.32 G(lope from header).12 E(.)-.44 E EP
+%%Page: 53 48
+%%BeginPageSetup
+BP
+%%EndPageSetup
+/F0 10/Times-Bold@0 SF(Sendmail Installation and Operation Guide)72 60 Q
+(SMM:08-53)452.9 60 Q/F1 9/Times-Roman@0 SF(int)157 94.8 Q
+(checkcompat\(to, e\))157 105.6 Q(re)175 116.4 Q(gister ADDRESS *to;)-.135 E
+(re)175 127.2 Q(gister ENVELOPE *e;)-.135 E({)157 138 Q(re)175 148.8 Q
+(gister ST)-.135 E(AB *s;)-.837 E 2.25(s=s)175 170.4 S(tab\("pri)191.578 170.4
+Q -.225(va)-.225 G(te", ST_MAILER, ST_FIND\);).225 E
+(if \(s != NULL && e\255>e_from.q_mailer != LocalMailer &&)175 181.2 Q
+(to->q_mailer == s->s_mailer\))184 192 Q({)175 202.8 Q(usrerr\("No pri)193
+213.6 Q -.225(va)-.225 G(te net mail allo).225 E(wed through this machine"\);)
+-.225 E(return \(EX_UN)193 224.4 Q -1.215(AVA)-.315 G(ILABLE\);)1.215 E(})175
+235.2 Q(if \(MsgSize > 50000 && to\255>q_mailer != LocalMailer\))175 246 Q({)
+175 256.8 Q(usrerr\("Message too lar)193 267.6 Q(ge for non-local deli)-.162 E
+-.135(ve)-.225 G(ry"\);).135 E(NoReturn = TR)193 278.4 Q(UE;)-.36 E
+(return \(EX_UN)193 289.2 Q -1.215(AVA)-.315 G(ILABLE\);)1.215 E(})175 300 Q
+(return \(EX_OK\);)175 310.8 Q(})157 321.6 Q/F2 10/Times-Roman@0 SF .205
+(This w)117 337.8 R .205
+(ould reject messages greater than 50000 bytes unless the)-.1 F 2.705(yw)-.15 G
+.205(ere local.)387.09 337.8 R(The)5.205 E/F3 10/Times-Italic@0 SF(NoReturn)
+2.705 E F2(\215ag)2.705 E 1.196(can be sent to suppress the return of the actu\
+al body of the message in the error return.)117 349.8 R(The)6.197 E(actual use\
+ of this routine is highly dependent on the implementation, and use should be \
+limited.)117 361.8 Q F0 2.5(6.3.3. Load)102 385.8 R -.6 -1(Av e)2.5 H
+(rage Computation)1 E F2 .18(The routine)142 402 R F3 -.1(ge)2.68 G(tla).1 E F2
+.18(should return an approximation of the current system load a)2.68 F -.15(ve)
+-.2 G .18(rage as an).15 F(inte)117 414 Q(ger)-.15 E 5(.T)-.55 G
+(here are four v)157.68 414 Q
+(ersions included on compilation \215ags as described abo)-.15 E -.15(ve)-.15 G
+(.).15 E F0 2.5(6.3.4. New)102 438 R(Database Map Classes)2.5 E F2(Ne)142 454.2
+Q 2.875(wk)-.25 G .675 -.15(ey m)168.405 454.2 T .375(aps can be added by crea\
+ting a class initialization function and a lookup func-).15 F 2.5(tion. These)
+117 466.2 R(are then added to the routine)2.5 E F3(setupmaps.)2.5 E F2
+(The initialization function is called as)142 482.4 Q F3(xxx)157 498.6 Q F2
+(_map_init\(MAP *map, char *mapname, char *ar)A(gs\))-.18 E(The)117 514.8 Q F3
+(map)2.555 E F2 .055(is an internal data structure.)2.555 F(The)5.055 E F3
+(mapname)2.555 E F2 .054(is the name of the map \(used for error mes-)2.554 F
+2.819(sages\). The)117 526.8 R F3(ar)2.819 E(gs)-.37 E F2 .32(is a pointer to \
+the rest of the con\214guration \214le line; \215ags and \214lenames can be)
+2.819 F -.15(ex)117 538.8 S .675(tracted from this line.).15 F .675
+(The initialization function must return)5.675 F F1(TR)3.175 E(UE)-.36 E F2
+.674(if it successfully opened)3.174 F(the map,)117 550.8 Q F1 -.666(FA)2.5 G
+(LSE).666 E F2(otherwise.)2.5 E(The lookup function is called as)142 567 Q F3
+(xxx)157 583.2 Q F2(_map_lookup\(MAP *map, char b)A(uf[], int b)-.2 E
+(ufsize, char **a)-.2 E 1.3 -.65(v, i)-.2 H(nt *statp\)).65 E(The)117 599.4 Q
+F3(map)3.475 E F2 .975(de\214nes the map internally)3.475 F 5.975(.T)-.65 G
+.975(he parameters)277.18 599.4 R F3 -.2(bu)3.475 G(f).2 E F2(and)3.475 E F3
+-.2(bu)3.475 G(fsize).2 E F2(ha)3.476 E 1.276 -.15(ve t)-.2 H .976(he input k)
+.15 F -.15(ey)-.1 G 5.976(.T)-.5 G(his)492.33 599.4 Q .043
+(may be \(and often is\) used destructi)117 611.4 R -.15(ve)-.25 G(ly).15 E
+5.043(.T)-.65 G(he)289.831 611.4 Q F3(av)2.543 E F2 .043(is a list of ar)2.543
+F .042(guments passed in from the re)-.18 F(write)-.25 E 3.654(line. The)117
+623.4 R 1.154(lookup function should return a pointer to the ne)3.654 F 3.655
+(wv)-.25 G 3.655(alue. IF)378.335 623.4 R 1.155(the map lookup f)3.655 F(ails,)
+-.1 E F3(*statp)117 635.4 Q F2 1.272(should be set to an e)3.772 F 1.272
+(xit status code; in particular)-.15 F 3.772(,i)-.4 G 3.771(ts)357.652 635.4 S
+1.271(hould be set to)368.093 635.4 R F1(EX_TEMPF)3.771 E(AIL)-.666 E F2(if)
+3.771 E(reco)117 647.4 Q -.15(ve)-.15 G(ry is to be attempted by the higher le)
+.15 E -.15(ve)-.25 G 2.5(lc).15 G(ode.)308.76 647.4 Q F0 2.5(6.3.5. Queueing)
+102 671.4 R(Function)2.5 E F2 .782(The routine)142 687.6 R F3(shouldqueue)3.282
+E F2 .783(is called to decide if a message should be queued or processed)3.283
+F(immediately)117 699.6 Q 6.619(.T)-.65 G 1.618
+(ypically this compares the message priority to the current load a)180.779
+699.6 R -.15(ve)-.2 G 4.118(rage. The).15 F(def)117 711.6 Q
+(ault de\214nition is:)-.1 E EP
+%%Page: 54 49
+%%BeginPageSetup
+BP
+%%EndPageSetup
+/F0 10/Times-Bold@0 SF 193.36(SMM:08-54 Sendmail)72 60 R
+(Installation and Operation Guide)2.5 E/F1 10/Times-Roman@0 SF(bool)157 96 Q
+(shouldqueue\(pri, ctime\))157 108 Q(long pri;)175 120 Q(time_t ctime;)175 132
+Q({)157 144 Q(if \(CurrentLA < QueueLA\))175 156 Q(return \(F)193 168 Q
+(ALSE\);)-.74 E(if \(CurrentLA >= RefuseLA\))175 180 Q(return \(TR)193 192 Q
+(UE\);)-.4 E(return \(pri > \(QueueF)175 204 Q
+(actor / \(CurrentLA \255 QueueLA + 1\)\)\);)-.15 E(})157 216 Q 2.062
+(If the current load a)117 232.2 R -.15(ve)-.2 G 2.062(rage \(global v).15 F
+(ariable)-.25 E/F2 10/Times-Italic@0 SF(Curr)4.562 E(entLA)-.37 E F1 4.562(,w)C
+2.062(hich is set before this function is)361.636 232.2 R 1.058
+(called\) is less than the lo)117 244.2 R 3.558(wt)-.25 G 1.058
+(hreshold load a)234.198 244.2 R -.15(ve)-.2 G 1.058(rage \(option).15 F F0(x)
+3.557 E F1 3.557(,v)C(ariable)375.526 244.2 Q F2(QueueLA)3.557 E F1(\),)A F2
+(shouldqueue)3.557 E F1(returns)117 256.2 Q/F3 9/Times-Roman@0 SF -.666(FA)
+2.586 G(LSE).666 E F1 .086(immediately \(that is, it should)2.586 F F2(not)
+2.586 E F1 2.586(queue\). If)2.586 F .086(the current load a)2.586 F -.15(ve)
+-.2 G .087(rage e).15 F .087(xceeds the)-.15 F .588(high threshold load a)117
+268.2 R -.15(ve)-.2 G .588(rage \(option).15 F F0(X)3.087 E F1 3.087(,v)C
+(ariable)281.846 268.2 Q F2(RefuseLA)3.087 E F1(\),)A F2(shouldqueue)3.087 E F1
+(returns)3.087 E F3(TR)3.087 E(UE)-.36 E F1(immedi-)3.087 E(ately)117 280.2 Q
+7.125(.O)-.65 G 2.125
+(therwise, it computes the function based on the message priority)152.635 280.2
+R 4.626(,t)-.65 G 2.126(he queue f)438.208 280.2 R(actor)-.1 E(\(option)117
+292.2 Q F0(q)2.5 E F1 2.5(,g)C(lobal v)163.95 292.2 Q(ariable)-.25 E F2(QueueF)
+2.5 E(actor)-.75 E F1(\), and the current and threshold load a)A -.15(ve)-.2 G
+(rages.).15 E 1.067(An implementation wishing to tak)142 308.4 R 3.567(et)-.1 G
+1.066(he actual age of the message into account can also)293.625 308.4 R 1.41
+(use the)117 320.4 R F2(ctime)3.91 E F1(parameter)3.91 E 3.91(,w)-.4 G 1.41
+(hich is the time that the message w)229.15 320.4 R 1.41
+(as \214rst submitted to)-.1 F F2(sendmail)3.91 E F1(.)A .929(Note that the)117
+332.4 R F2(pri)3.428 E F1 .928
+(parameter is already weighted by the number of times the message has been)
+3.428 F .395(tried \(although this tends to lo)117 344.4 R .395
+(wer the priority of the message with time\); the e)-.25 F .395
+(xpectation is that)-.15 F(the)117 356.4 Q F2(ctime)2.674 E F1 -.1(wo)2.674 G
+.174(uld be used as an \231escape clause\232 to ensure that messages are e).1 F
+-.15(ve)-.25 G .174(ntually processed.).15 F F0 2.5(6.3.6. Refusing)102 380.4 R
+(Incoming SMTP Connections)2.5 E F1 1.148(The function)142 396.6 R F2 -.37(re)
+3.648 G(fuseconnections).37 E F1(returns)3.648 E F3(TR)3.648 E(UE)-.36 E F1
+1.148(if incoming SMTP connections should be)3.648 F 3.564(refused. The)117
+408.6 R 1.063(current implementation is based e)3.563 F(xclusi)-.15 E -.15(ve)
+-.25 G 1.063(ly on the current load a).15 F -.15(ve)-.2 G 1.063(rage and the)
+.15 F(refuse load a)117 420.6 Q -.15(ve)-.2 G(rage option \(option).15 E F0(X)
+2.5 E F1 2.5(,g)C(lobal v)273.56 420.6 Q(ariable)-.25 E F2(RefuseLA)2.5 E F1
+(\):)A(bool)157 436.8 Q(refuseconnections\(\))157 448.8 Q({)157 460.8 Q
+(return \(CurrentLA >= RefuseLA\);)175 472.8 Q(})157 484.8 Q 2.5(Am)117 501 S
+(ore cle)134.5 501 Q -.15(ve)-.25 G 2.5(ri).15 G
+(mplementation could look at more system resources.)179.08 501 Q F0 2.5
+(6.3.7. Load)102 525 R -.6 -1(Av e)2.5 H(rage Computation)1 E F1 .243
+(The routine)142 541.2 R F2 -.1(ge)2.743 G(tla).1 E F1 .243
+(returns the current load a)2.743 F -.15(ve)-.2 G .243
+(rage \(as a rounded inte).15 F 2.743(ger\). The)-.15 F(distrib)2.744 E(ution)
+-.2 E(includes se)117 553.2 Q -.15(ve)-.25 G(ral possible implementations.).15
+E F0 2.5(6.4. Con\214guration)87 577.2 R(in sr)2.5 E(c/daemon.c)-.18 E F1 .4
+(The \214le)127 593.4 R F2(sr)2.9 E(c/daemon.c)-.37 E F1 .4
+(contains a number of routines that are dependent on the local netw)2.9 F(ork-)
+-.1 E(ing en)102 605.4 Q 2.5(vironment. The)-.4 F -.15(ve)2.5 G
+(rsion supplied assumes you ha).15 E .3 -.15(ve B)-.2 H(SD style sock).15 E
+(ets.)-.1 E 2.16(In pre)127 621.6 R 2.16
+(vious releases, we recommended that you modify the routine)-.25 F F2
+(maphostname)4.66 E F1 2.16(if you)4.66 F -.1(wa)102 633.6 S 1.919
+(nted to generalize).1 F F0($[)4.418 E F1(...)4.418 E F0($])4.418 E F1 4.418
+(lookups. W)4.418 F 4.418(en)-.8 G 2.418 -.25(ow r)293.906 633.6 T 1.918
+(ecommend that you create a ne).25 F 4.418(wk)-.25 G -.15(ey)463.632 633.6 S
+1.918(ed map).15 F(instead.)102 645.6 Q F0 2.5(7. CHANGES)72 669.6 R
+(IN VERSION 8)2.5 E F1 .172(The follo)112 685.8 R .172
+(wing summarizes changes since the last commonly a)-.25 F -.25(va)-.2 G .173
+(ilable v).25 F .173(ersion of)-.15 F F2(sendmail)2.673 E F1(\(5.67\):)2.673 E
+EP
+%%Page: 55 50
+%%BeginPageSetup
+BP
+%%EndPageSetup
+/F0 10/Times-Bold@0 SF(Sendmail Installation and Operation Guide)72 60 Q
+(SMM:08-55)452.9 60 Q 2.5(7.1. Connection)87 96 R(Caching)2.5 E/F1 10
+/Times-Roman@0 SF .398(Instead of closing SMTP connections immediately)127
+112.2 R 2.897(,t)-.65 G .397(hose connections are cached for possible)339.005
+112.2 R .597(future use.)102 124.2 R .597(The adv)5.597 F .597
+(ent of MX records made this ef)-.15 F(fecti)-.25 E .897 -.15(ve f)-.25 H .598
+(or mailing lists; in addition, substantial).15 F(performance impro)102 136.2 Q
+-.15(ve)-.15 G(ments can be e).15 E(xpected for queue processing.)-.15 E F0 2.5
+(7.2. MX)87 160.2 R(Piggybacking)2.5 E F1 1.258(If tw)127 176.4 R 3.757(oh)-.1
+G 1.257(osts with dif)161.075 176.4 R 1.257
+(ferent names in a single message happen to ha)-.25 F 1.557 -.15(ve t)-.2 H
+1.257(he same set of MX).15 F .94(hosts, the)102 188.4 R 3.44(yc)-.15 G .94
+(an be sent in the same transaction.)153.45 188.4 R -1.11(Ve)5.94 G .94
+(rsion 8 notices this and tries to batch the mes-)1.11 F(sages.)102 200.4 Q F0
+2.5(7.3. RFC)87 224.4 R(1123 Compliance)2.5 E F1 3.463(An)127 240.6 S .963
+(umber of changes ha)142.683 240.6 R 1.262 -.15(ve b)-.2 H .962
+(een made to mak).15 F(e)-.1 E/F2 10/Times-Italic@0 SF(sendmail)3.462 E F1 .962
+(\231conditionally compliant\232 \(that is,)3.462 F F2(sendmail)102 252.6 Q F1
+.049(satis\214es all of the \231MUST\232 clauses and most b)2.549 F .05
+(ut not all of the \231SHOULD\232 clauses in RFC)-.2 F(1123\).)102 264.6 Q
+(The major areas of change are \(numbers are RFC 1123 section numbers\):)127
+280.8 Q 15(5.2.7 Response)102 297 R(to RCPT command is f)2.5 E(ast.)-.1 E 15
+(5.2.8 Numeric)102 313.2 R(IP addresses are logged in Recei)2.5 E -.15(ve)-.25
+G(d: lines.).15 E 10(5.2.17 Self)102 329.4 R
+(domain literal is properly handled.)2.5 E 15(5.3.2 Better)102 345.6 R
+(control o)2.5 E -.15(ve)-.15 G 2.5(ri).15 G(ndi)220.02 345.6 Q
+(vidual timeouts.)-.25 E 15(5.3.3 Error)102 361.8 R
+(messages are sent as \231From:<>\232.)2.5 E 15(5.3.3 Error)102 378 R
+(messages are ne)2.5 E -.15(ve)-.25 G 2.5(rs).15 G(ent to \231<>\232.)246.28
+378 Q 15(5.3.3 Route-addrs)102 394.2 R(are pruned.)2.5 E(The areas in which)102
+410.4 Q F2(sendmail)2.5 E F1(is not \231unconditionally compliant\232 are:)2.5
+E(5.2.6)102 426.6 Q F2(Sendmail)139.5 426.6 Q F1(does do header munging.)2.5 E
+(5.2.10)102 442.8 Q F2(Sendmail)139.5 442.8 Q F1(doesn')2.5 E 2.5(ta)-.18 G -.1
+(lwa)215.42 442.8 S(ys use the e).1 E(xact SMTP message te)-.15 E
+(xt as listed in RFC 821.)-.15 E(5.3.1.1)102 459 Q F2(Sendmail)139.5 459 Q F1
+(doesn')2.5 E 2.5(tg)-.18 G
+(uarantee only one connect for each host in queue runs.)215.98 459 Q(5.3.1.1)
+102 475.2 Q F2(Sendmail)139.5 475.2 Q F1(doesn')2.5 E 2.5(ta)-.18 G -.1(lwa)
+215.42 475.2 S(ys pro).1 E(vide adequate concurrenc)-.15 E 2.5(yl)-.15 G
+(imits.)366.54 475.2 Q F0 2.5(7.4. Extended)87 499.2 R(SMTP Support)2.5 E F1
+-1.11(Ve)127 515.4 S .155(rsion 8 includes both sending and recei)1.11 F .154
+(ving support for Extended SMTP support as de\214ned)-.25 F(by RFC 1425 \(basi\
+c\) and RFC 1427 \(SIZE\); and limited support for RFC 1426 \(BOD)102 527.4 Q
+(Y\).)-.55 E F0 2.5(7.5. Eight-Bit)87 551.4 R(Clean)2.5 E F1(Pre)127 567.6 Q
+1.263(vious v)-.25 F 1.263(ersions of)-.15 F F2(sendmail)3.763 E F1 1.264
+(used the 0200 bit for quoting.)3.763 F 1.264(This v)6.264 F 1.264(ersion a)
+-.15 F -.2(vo)-.2 G 1.264(ids that use.).2 F(Ho)102 579.6 Q(we)-.25 E -.15(ve)
+-.25 G .8 -.4(r, f).15 H
+(or compatibility with RFC 822, you can set option `7' to get se).4 E -.15(ve)
+-.25 G 2.5(nb).15 G(it stripping.)418.86 579.6 Q(Indi)127 595.8 Q
+(vidual mailers can still produce se)-.25 E -.15(ve)-.25 G 2.5(nb).15 G
+(it output using the `7' mailer \215ag.)300.77 595.8 Q F0 2.5(7.6. User)87
+619.8 R(Database)2.5 E F1 1.073(The user database is an as-yet e)127 636 R
+1.072(xperimental attempt to pro)-.15 F 1.072(vide uni\214ed lar)-.15 F 1.072
+(ge-site name sup-)-.18 F 2.5(port. W)102 648 R 2.5(ea)-.8 G
+(re installing it at Berk)145.63 648 Q(ele)-.1 E(y; future v)-.15 E
+(ersions may sho)-.15 E 2.5(ws)-.25 G(igni\214cant modi\214cations.)363.57 648
+Q F0 2.5(7.7. Impr)87 672 R -.1(ove)-.18 G 2.5(dB).1 G(IND Support)158.01 672 Q
+F1 .489(The BIND support, particularly for MX records, had a number of anno)127
+688.2 R .49(ying \231features\232 which)-.1 F(ha)102 700.2 Q 1.212 -.15(ve b)
+-.2 H .912(een remo).15 F -.15(ve)-.15 G 3.412(di).15 G 3.412(nt)187.116 700.2
+S .912(his release.)198.308 700.2 R .912(In particular)5.912 F 3.412(,t)-.4 G
+.912(hese more tightly bind \(pun intended\) the name)307.916 700.2 R(serv)102
+712.2 Q(er to)-.15 E F2(sendmail)2.5 E F1 2.5(,s)C 2.5(ot)184.06 712.2 S
+(hat the name serv)194.34 712.2 Q
+(er resolution rules are incorporated directly into)-.15 E F0(sendmail)2.5 E F1
+(.)A EP
+%%Page: 56 51
+%%BeginPageSetup
+BP
+%%EndPageSetup
+/F0 10/Times-Bold@0 SF 193.36(SMM:08-56 Sendmail)72 60 R
+(Installation and Operation Guide)2.5 E 2.5(7.8. K)87 96 R(ey)-.25 E(ed Files)
+-.1 E/F1 10/Times-Roman@0 SF .365(Generalized k)127 112.2 R -.15(ey)-.1 G .365
+(ed \214les is an idea tak).15 F .365(en directly from)-.1 F/F2 9/Times-Roman@0
+SF(ID)2.866 E(A)-.36 E/F3 10/Times-Italic@0 SF(sendmail)2.866 E F1 .366
+(\(albeit with a completely)2.866 F(dif)102 124.2 Q(ferent implementation\).)
+-.25 E(The)5 E 2.5(yc)-.15 G(an be useful on lar)239.63 124.2 Q(ge sites.)-.18
+E -1.11(Ve)127 140.4 S(rsion 8 also understands YP)1.11 E(.)-1.11 E F0 2.5
+(7.9. Multi-W)87 164.4 R(ord Classes)-.75 E F1(Classes can no)127 180.6 Q 2.5
+(wb)-.25 G 2.5(em)200.35 180.6 S(ultiple w)215.07 180.6 Q 2.5(ords. F)-.1 F
+(or e)-.15 E(xample,)-.15 E(CShofmann.CS.Berk)142 196.8 Q(ele)-.1 E -.65(y.)
+-.15 G(EDU).65 E(allo)102 213 Q 2.664
+(ws you to match the entire string \231hofmann.CS.Berk)-.25 F(ele)-.1 E -.65
+(y.)-.15 G 2.663(EDU\232 using the single construct).65 F(\231$=S\232.)102 225
+Q F0 2.5(7.10. Deferr)87 249 R(ed Macr)-.18 E 2.5(oE)-.18 G(xpansion)189.94 249
+Q F1(The)127 265.2 Q F0($&)2.5 E F3(x)A F1(construct has been adopted from)2.5
+E F2(ID)2.5 E(A)-.36 E F1(.)A F0 2.5(7.11. IDENT)87 289.2 R(Pr)2.5 E
+(otocol Support)-.18 E F1
+(The IDENT protocol as de\214ned in RFC 1413 is supported.)127 305.4 Q F0 2.5
+(7.12. P)87 329.4 R(arsing Bug Fixes)-.1 E F1 4.03(An)127 345.6 S 1.53
+(umber of small b)143.25 345.6 R 1.53(ugs ha)-.2 F 1.53
+(ving to do with things lik)-.2 F 4.03(eb)-.1 G 1.53
+(ackslash-escaped quotes inside of)364.72 345.6 R(comments ha)102 357.6 Q .3
+-.15(ve b)-.2 H(een \214x).15 E(ed.)-.15 E F0 2.5(7.13. Separate)87 381.6 R(En)
+2.5 E -.1(ve)-.4 G(lope/Header Pr).1 E(ocessing)-.18 E F1 .854
+(Since the From: line is passed in separately from the en)127 397.8 R -.15(ve)
+-.4 G .854(lope sender).15 F 3.354(,t)-.4 G .854(hese ha)420.978 397.8 R 1.154
+-.15(ve b)-.2 H .854(oth been).15 F .427(made visible; the)102 409.8 R F0($g)
+2.927 E F1 .427(macro is set to the en)2.927 F -.15(ve)-.4 G .428
+(lope sender during processing of mailer ar).15 F .428(gument v)-.18 F(ec-)-.15
+E(tors and the header sender during processing of headers.)102 421.8 Q .085
+(It is also possible to specify separate per)127 438 R .085(-mailer en)-.2 F
+-.15(ve)-.4 G .084(lope and header processing.).15 F(The)5.084 E F0(S)2.584 E
+F1(ender)A(-)-.2 E -.55(RW)102 450 S .512(Set and).55 F F0(R)3.012 E F1
+(ecipientR)A .512(Wset ar)-.55 F .512
+(guments for mailers can be speci\214ed as)-.18 F F3(en)3.013 E(velope/header)
+-.4 E F1 .513(to gi)3.013 F .813 -.15(ve d)-.25 H(if-).15 E(ferent re)102 462 Q
+(writings for en)-.25 E -.15(ve)-.4 G(lope v).15 E(ersus header addresses.)-.15
+E F0 2.5(7.14. Owner)87 486 R(-List Pr)-.37 E(opagates to En)-.18 E -.1(ve)-.4
+G(lope).1 E F1 1.001(When an alias has an associated o)127 502.2 R 1
+(wner\255list name, that alias is used to change the en)-.25 F -.15(ve)-.4 G
+(lope).15 E(sender address.)102 514.2 Q(This will cause do)5 E
+(wnstream errors to be returned to that o)-.25 E(wner)-.25 E(.)-.55 E F0 2.5
+(7.15. Dynamic)87 538.2 R(Header Allocation)2.5 E F1(The \214x)127 554.4 Q
+(ed size limit on header lines has been eliminated.)-.15 E F0 2.5(7.16. New)87
+578.4 R(Command Line Flags)2.5 E F1(The)127 594.6 Q F0<ad42>2.5 E F1
+(\215ag has been added to pass in body type information.)2.5 E(The)127 610.8 Q
+F0<ad70>2.5 E F1(\215ag has been added to pass in protocol information.)2.5 E
+(The)127 627 Q F0<ad58>2.6 E F1 .1(\215ag has been added to allo)2.6 F 2.6(wl)
+-.25 G .1(ogging of all protocol in and out of)279.89 627 R F3(sendmail)2.6 E
+F1 .1(for deb)2.6 F(ug-)-.2 E(ging.)102 639 Q F0 2.5(7.17. Enhanced)87 663 R
+(Command Line Flags)2.5 E F1(The)127 679.2 Q F0<ad71>4.007 E F1 1.507(\215ag c\
+an limit limit a queue run to speci\214c recipients, senders, or queue ids usi\
+ng)4.007 F F0(\255qR)102 691.2 Q F3(substring)A F0 2.5<2cad>C(qS)168.41 691.2 Q
+F3(substring)A F0 2.5(,o)C 2.5<72ad>226.76 691.2 S(qI)239.4 691.2 Q F3
+(substring)A F0 -.18(re)2.5 G(specti).18 E -.1(ve)-.1 G(ly).1 E(.)-.7 E EP
+%%Page: 57 52
+%%BeginPageSetup
+BP
+%%EndPageSetup
+/F0 10/Times-Bold@0 SF(Sendmail Installation and Operation Guide)72 60 Q
+(SMM:08-57)452.9 60 Q 2.5(7.18. New)87 96 R(and Old Con\214guration Line T)2.5
+E(ypes)-.74 E/F1 10/Times-Roman@0 SF(The)127 112.2 Q F0(T)2.766 E F1(\(T)2.766
+E .267(rusted users\) con\214guration line has been deleted.)-.35 F .267
+(It will still be accepted b)5.267 F .267(ut will be)-.2 F(ignored.)102 124.2 Q
+(The)127 140.4 Q F0(K)2.5 E F1(line has been added to declare database maps.)
+2.5 E(The)127 156.6 Q F0(V)2.5 E F1
+(line has been added to declare the con\214guration v)2.5 E(ersion le)-.15 E
+-.15(ve)-.25 G(l.).15 E(The)127 172.8 Q F0(M)2.797 E F1 .296(line has a \231D=\
+\232 \214eld that lets you change into a temporary directory while that mailer)
+2.797 F(is running.)102 184.8 Q F0 2.5(7.19. New)87 208.8 R(Options)2.5 E F1
+(Se)127 225 Q -.15(ve)-.25 G .9(ral ne).15 F 3.4(wo)-.25 G .9(ptions ha)184.8
+225 R 1.2 -.15(ve b)-.2 H .9(een added, man).15 F 3.4(yt)-.15 G 3.4(os)314.89
+225 S .9(upport ne)327.18 225 R 3.4(wf)-.25 G .9(eatures, others to allo)379.83
+225 R 3.4(wt)-.25 G(uning)481.22 225 Q 1.187(that w)102 237 R 1.187(as pre)-.1
+F 1.187(viously a)-.25 F -.25(va)-.2 G 1.187(ilable only by recompiling.).25 F
+(The)6.186 E 3.686(ya)-.15 G 1.186(re described in detail in Section 5.1.5.)
+345.514 237 R(Brie\215y)102 249 Q(,)-.65 E 31(bI)102 265.2 S
+(nsist on a minimum number of disk blocks.)141.33 265.2 Q 29.33(CS)102 281.4 S
+(et checkpoint interv)143.56 281.4 Q(al.)-.25 E 29.89(ED)102 297.6 S(ef)145.22
+297.6 Q(ault error message.)-.1 E 28.78(GE)102 313.8 S(nable GECOS matching.)
+144.11 313.8 Q 31(hM)102 330 S(aximum hop count.)146.89 330 Q 33.22(jS)102
+346.2 S(end errors in MIME-encapsulated format.)143.56 346.2 Q 32.11(JF)102
+362.4 S(orw)143.41 362.4 Q(ard \214le path.)-.1 E 31(kC)102 378.6 S
+(onnection cache size)144.67 378.6 Q 28.78(KC)102 394.8 S
+(onnection cache lifetime.)144.67 394.8 Q 33.22(lE)102 411 S .333
+(nable Errors-T)144.11 411 R .333(o: header)-.8 F 5.334(.T)-.55 G .334
+(hese headers violate RFC 1123; this option is included to pro-)252.89 411 R
+(vide back compatibility with old v)138 423 Q(ersions of)-.15 E/F2 10
+/Times-Italic@0 SF(sendmail)2.5 E F1(.)A 28.78(OS)102 439.2 S
+(et incoming SMTP daemon options, such as an alternate SMTP port.)143.56 439.2
+Q 31(pP)102 455.4 S(ri)143.56 455.4 Q -.25(va)-.25 G .3 -.15(cy o).25 H
+(ptions.).15 E 29.33(RD)102 471.6 S(on')145.22 471.6 Q 2.5(tp)-.18 G
+(rune route-addrs.)168.65 471.6 Q 28.78(UU)102 487.8 S(ser database spec.)
+145.22 487.8 Q 28.78(VF)102 504 S(allback \231MX\232 host.)143.41 504 Q 28.78
+<7799>102 520.2 S(Best MX\232 handling technique.)142.44 520.2 Q 31(7D)102
+536.4 S 2.5(on)145.22 536.4 S(ot run eight bit clean.)157.72 536.4 Q F0 2.5
+(7.20. Extended)87 560.4 R(Options)2.5 E F1(The)127 576.6 Q F0(r)3.764 E F1
+1.264(\(read timeout\),)3.764 F F0(I)3.764 E F1 1.264(\(use BIND\), and)3.764 F
+F0(T)3.764 E F1 1.264(\(queue timeout\) options ha)3.764 F 1.564 -.15(ve b)-.2
+H 1.264(een e).15 F 1.264(xtended to)-.15 F(pass in more information.)102 588.6
+Q F0 2.5(7.21. New)87 612.6 R(Mailer Flags)2.5 E F1(Se)127 628.8 Q -.15(ve)-.25
+G(ral ne).15 E 2.5(wm)-.25 G(ailer \215ags ha)185.78 628.8 Q .3 -.15(ve b)-.2 H
+(een added.).15 E 31.56(aT)102 645 S .636
+(ry to use ESMTP when creating a connection.)143.76 645 R .636
+(If this is not set,)5.636 F F2(sendmail)3.136 E F1 .636(will still try if)
+3.136 F .221(the other end hints that it kno)138 657 R .22
+(ws about ESMTP in its greeting message; this \215ag says to try)-.25 F -2.15
+-.25(ev e)138 669 T 2.595(ni).25 G 2.595(fi)161.855 669 S 2.595(td)170.56 669 S
+(oesn')180.935 669 Q 2.595(th)-.18 G 2.595(int. If)212.79 669 R .095
+(the EHLO \(e)2.595 F .095(xtended hello\) command f)-.15 F(ails,)-.1 E F2
+(sendmail)2.596 E F1 -.1(fa)2.596 G .096(lls back to).1 F(old SMTP)138 681 Q(.)
+-1.11 E 31(bE)102 697.2 S
+(nsure that there is a blank line at the end of all messages.)144.11 697.2 Q
+31.56(cS)102 713.4 S .68(trip all comments from addresses; this should only be\
+ used as a last resort when dealing)143.56 713.4 R(with crank)138 725.4 Q 2.5
+(ym)-.15 G(ailers.)195.62 725.4 Q EP
+%%Page: 58 53
+%%BeginPageSetup
+BP
+%%EndPageSetup
+/F0 10/Times-Bold@0 SF 193.36(SMM:08-58 Sendmail)72 60 R
+(Installation and Operation Guide)2.5 E/F1 10/Times-Roman@0 SF 31(gN)102 96 S
+-2.15 -.25(ev e)145.22 96 T 2.64(ru).25 G .14(se the null sender as the en)
+169.67 96 R -.15(ve)-.4 G .141(lope sender).15 F 2.641(,e)-.4 G -.15(ve)341.495
+96 S 2.641(nw).15 G .141(hen running SMTP)365.646 96 R 5.141(.A)-1.11 G .141
+(lthough this)456.349 96 R 1.521(violates RFC 1123, it may be necessary when y\
+ou must deal with some obnoxious old)138 108 R(hosts.)138 120 Q 31(7S)102 136.2
+S(trip all output to 7 bits.)143.56 136.2 Q F0 2.5(7.22. New)87 160.2 R(Pr)2.5
+E(e-De\214ned Macr)-.18 E(os)-.18 E F1(The follo)127 176.4 Q
+(wing macros are pre-de\214ned:)-.25 E 23.5($k The)102 192.6 R
+(UUCP node name, nominally from)2.5 E/F2 10/Times-Italic@0 SF(uname)2.5 E F1
+(\(2\) call.)A 20.72($m The)102 208.8 R(domain part of our full hostname.)2.5 E
+23.5($_ The)102 225 R(RFC 1413-pro)2.5 E(vided sender address.)-.15 E F0 2.5
+(7.23. New)87 249 R(LHS T)2.5 E(ok)-.92 E(en)-.1 E F1 -1.11(Ve)127 265.2 S
+1.375(rsion 8 allo)1.11 F(ws)-.25 E F0($@)3.875 E F1 1.376
+(on the Left Hand Side of an \231R\232 line to match zero tok)3.875 F 3.876
+(ens. This)-.1 F(is)3.876 E(intended to be used to match the null input.)102
+277.2 Q F0 2.5(7.24. Bigger)87 301.2 R(Defaults)2.5 E F1 -1.11(Ve)127 317.4 S
+1.284(rsion 8 allo)1.11 F 1.284(ws up to 100 rulesets instead of 30.)-.25 F
+1.283(It is recommended that rulesets 0\2559 be)6.284 F(reserv)102 329.4 Q
+(ed for)-.15 E F2(sendmail)2.5 E F1 1.1 -.55('s d)D
+(edicated use in future releases.).55 E
+(The total number of MX records that can be used has been raised to 20.)127
+345.6 Q .335(The number of queued messages that can be handled at one time has\
+ been raised from 600 to)127 361.8 R(1000.)102 373.8 Q F0 2.5(7.25. Differ)87
+397.8 R(ent Default T)-.18 E(uning P)-.92 E(arameters)-.1 E F1 -1.11(Ve)127 414
+S .8(rsion 8 has changed the def)1.11 F .8
+(ault parameters for tuning queue costs to mak)-.1 F 3.3(et)-.1 G .8
+(he number of)449.08 414 R .712(recipients more important than the size of the\
+ message \(for small messages\).)102 426 R .712(This is reasonable if)5.712 F
+(you are connected with reasonably f)102 438 Q(ast links.)-.1 E F0 2.5(7.26. A)
+87 462 R(uto-Quoting in Addr)-.5 E(esses)-.18 E F1(Pre)127 478.2 Q(viously)-.25
+E 2.611(,t)-.65 G .111(he \231Full Name <email address>\232 syntax w)176.771
+478.2 R .111(ould generate incorrect protocol output)-.1 F
+(if \231Full Name\232 had special characters such as dot.)102 490.2 Q(This v)5
+E(ersion puts quotes around such names.)-.15 E F0 2.5(7.27. Symbolic)87 514.2 R
+(Names On Err)2.5 E(or Mailer)-.18 E F1(Se)127 530.4 Q -.15(ve)-.25 G
+(ral names ha).15 E .3 -.15(ve b)-.2 H(een b).15 E
+(uilt in to the $@ portion of the $#error mailer)-.2 E(.)-.55 E F0 2.5
+(7.28. SMTP)87 554.4 R(VRFY Doesn't Expand)2.5 E F1(Pre)127 570.6 Q 1.437
+(vious v)-.25 F 1.437(ersions of)-.15 F F2(sendmail)3.937 E F1 1.438
+(treated VRFY and EXPN the same.)3.937 F 1.438(In this v)6.438 F 1.438
+(ersion, VRFY)-.15 F(doesn')102 582.6 Q 2.5(te)-.18 G(xpand aliases or follo)
+138.05 582.6 Q 2.5(w.)-.25 G(forw)235.84 582.6 Q(ard \214les.)-.1 E
+(EXPN still does.)5 E .682(As an optimization, if you run with your def)127
+598.8 R .681(ault deli)-.1 F -.15(ve)-.25 G .681
+(ry mode being queue-only or deli).15 F -.15(ve)-.25 G -.2(r-).15 G 1.582
+(in-background, the RCPT command will also not chase aliases and .forw)102
+610.8 R 1.582(ard \214les.)-.1 F 1.583(It will chase)6.582 F
+(them when it processes the queue.)102 622.8 Q F0 2.5(7.29. [IPC])87 646.8 R
+(Mailers Allo)2.5 E 2.5(wM)-.1 G(ultiple Hosts)210.49 646.8 Q F1 .448
+(When an address resolv)127 663 R .448
+(es to a mailer that has \231[IPC]\232 as its \231P)-.15 F .447
+(ath\232, the $@ part \(host name\))-.15 F .137
+(can be a colon-separated list of hosts instead of a single hostname.)102 675 R
+.138(This asks)5.138 F F2(sendmail)2.638 E F1 .138(to search the)2.638 F .161
+(list for the \214rst entry that is a)102 687 R -.25(va)-.2 G .161(ilable e).25
+F .16(xactly as though it were an MX record.)-.15 F .16(The intent is to route)
+5.16 F .737(internal traf)102 699 R .738(\214c through internal netw)-.25 F
+.738(orks without publishing an MX record to the net.)-.1 F .738(MX e)5.738 F
+(xpan-)-.15 E(sion is still done on the indi)102 711 Q(vidual items.)-.25 E EP
+%%Page: 59 54
+%%BeginPageSetup
+BP
+%%EndPageSetup
+/F0 10/Times-Bold@0 SF(Sendmail Installation and Operation Guide)72 60 Q
+(SMM:08-59)452.9 60 Q 2.5(7.30. Aliases)87 96 R(Extended)2.5 E/F1 10
+/Times-Roman@0 SF 1.457(The implementation has been mer)127 112.2 R 1.457
+(ged with maps.)-.18 F 1.456(Among other things, this supports NIS-)6.457 F
+(based aliases.)102 124.2 Q F0 2.5(7.31. P)87 148.2 R
+(ortability and Security Enhancements)-.2 E F1 2.5(An)127 164.4 S
+(umber of internal changes ha)141.72 164.4 Q .3 -.15(ve b)-.2 H
+(een made to enhance portability).15 E(.)-.65 E(Se)127 180.6 Q -.15(ve)-.25 G
+(ral \214x).15 E(es ha)-.15 E .3 -.15(ve b)-.2 H
+(een made to increase the paranoia f).15 E(actor)-.1 E(.)-.55 E F0 2.5
+(7.32. Miscellaneous)87 204.6 R(Changes)2.5 E/F2 10/Times-Italic@0 SF(Sendmail)
+127 220.8 Q F1(writes a)2.5 E F2(/etc/sendmail.pid)2.5 E F1
+(\214le with the current process id of the SMTP daemon.)2.5 E -1 -.8(Tw o)127
+237 T 1.646(people using the same program in their .forw)4.946 F 1.647
+(ard \214le are considered dif)-.1 F 1.647(ferent so that)-.25 F
+(duplicate elimination doesn')102 249 Q 2.5(td)-.18 G(elete one of them.)225.98
+249 Q(The)127 265.2 Q F2(mailstats)3.181 E F1 .681
+(program prints mailer names and gets the location of the)3.181 F F2
+(sendmail.st)3.18 E F1 .68(\214le from)3.18 F F2(/etc/sendmail.cf)102 277.2 Q
+F1(.)A(Man)127 293.4 Q 2.5(ym)-.15 G(inor b)160.46 293.4 Q(ugs ha)-.2 E .3 -.15
+(ve b)-.2 H(een \214x).15 E
+(ed, such as handling of backslashes inside of quotes.)-.15 E 2.5(Ah)127 309.6
+S(ook \(ruleset 5\) has been added to allo)141.72 309.6 Q 2.5(wr)-.25 G -.25
+(ew)304.21 309.6 S(riting of local addresses after aliasing.).25 E F0 2.5(8. A)
+72 333.6 R(CKNO)-.55 E(WLEDGEMENTS)-.5 E F1(I')112 349.8 Q 2.036 -.15(ve w)-.5
+H(ork).05 E 1.737(ed on)-.1 F F2(sendmail)4.237 E F1 1.737(for man)4.237 F
+4.237(yy)-.15 G 1.737(ears, and man)267.501 349.8 R 4.237(ye)-.15 G(mplo)
+339.762 349.8 Q 1.737(yers ha)-.1 F 2.037 -.15(ve b)-.2 H 1.737
+(een remarkably patient).15 F .404(about letting me w)87 361.8 R .404
+(ork on a lar)-.1 F .404(ge project that w)-.18 F .403(as not part of my of)-.1
+F .403(\214cial job)-.25 F 5.403(.T)-.4 G .403(his includes time on the)407.388
+361.8 R(INGRES Project at Berk)87 373.8 Q(ele)-.1 E 1.3 -.65(y, a)-.15 H 2.5
+(tB).65 G(ritton Lee, and ag)222.75 373.8 Q(ain on the Mammoth Project at Berk)
+-.05 E(ele)-.1 E -.65(y.)-.15 G .453(Much of the second w)112 390 R -2.25 -.2
+(av e)-.1 H .453(of impro)3.153 F -.15(ve)-.15 G .453
+(ments should be credited to Bryan Costales of ICSI.).15 F .454(As he)5.454 F
+.781(passed me drafts of his book on)87 402 R F2(sendmail)3.281 E F1 3.281(Iw)
+3.281 G .781(as inspired to start w)274.741 402 R .781(orking on things ag)-.1
+F 3.281(ain. Bryan)-.05 F -.1(wa)3.281 G(s).1 E(also a)87 414 Q -.25(va)-.2 G
+(ilable to bounce ideas of).25 E 2.5(fo)-.25 G(f.)227.38 414 Q(Man)112 430.2 Q
+2.856 -.65(y, m)-.15 H(an).65 E 4.056(yp)-.15 G 1.556(eople contrib)172.212
+430.2 R 1.556(uted chunks of code and ideas to)-.2 F F2(sendmail)4.056 E F1
+6.556(.I)C 4.056(th)418.476 430.2 S 1.557(as pro)430.312 430.2 R -.15(ve)-.15 G
+4.057(nt).15 G 4.057(ob)477.006 430.2 S 4.057(ea)491.063 430.2 S .464
+(group netw)87 442.2 R .464(ork ef)-.1 F 2.964(fort. V)-.25 F .464
+(ersion 8 in particular w)-1.11 F .463(as a group project.)-.1 F .463
+(The follo)5.463 F .463(wing people made notable)-.25 F(contrib)87 454.2 Q
+(utions:)-.2 E -.25(Ke)127 470.4 S(ith Bostic, CSRG, Uni).25 E -.15(ve)-.25 G
+(rsity of California, Berk).15 E(ele)-.1 E(y)-.15 E(Michael J. Corrig)127 482.4
+Q(an, Uni)-.05 E -.15(ve)-.25 G(rsity of California, San Die).15 E(go)-.15 E
+(Bryan Costales, International Computer Science Institute)127 494.4 Q -.15(Pa)
+127 506.4 S -.5(..)132.298 500.4 S 2.5(r\()136.85 506.4 S(Pell\) Emanuelsson)
+146.01 506.4 Q(Craig Ev)127 518.4 Q(erhart, T)-.15 E(ransarc Corporation)-.35 E
+-.8(To)127 530.4 S 2.5(mI).8 G -.25(va)150.92 530.4 S 2.5(rH).25 G
+(elbekkmo, Norwe)173.16 530.4 Q(gian School of Economics)-.15 E
+(Allan E. Johannesen, WPI)127 542.4 Q(Jonathan Kamens, OpenV)127 554.4 Q
+(ision T)-.6 E(echnologies, Inc.)-.7 E -.8(Ta)127 566.4 S
+(kahiro Kanbe, Fuji Xerox Information Systems Co., Ltd.).8 E(Brian Kantor)127
+578.4 Q 2.5(,U)-.4 G(ni)191.31 578.4 Q -.15(ve)-.25 G
+(rsity of California, San Die).15 E(go)-.15 E(Murray S. K)127 590.4 Q(uchera)
+-.15 E(wy)-.15 E 2.5(,H)-.65 G(ookUp Communication Corp.)227.41 590.4 Q
+(Bruce Lilly)127 602.4 Q 2.5(,S)-.65 G(on)182.74 602.4 Q 2.5(yU)-.15 G(.S.)
+207.31 602.4 Q(Karl London)127 614.4 Q(Nakamura Motonori, K)127 626.4 Q
+(yoto Uni)-.25 E -.15(ve)-.25 G(rsity).15 E(John Gardiner Myers, Carne)127
+638.4 Q(gie Mellon Uni)-.15 E -.15(ve)-.25 G(rsity).15 E(Neil Rick)127 650.4 Q
+(ert, Northern Illinois Uni)-.1 E -.15(ve)-.25 G(rsity).15 E
+(Eric Schnoebelen, Con)127 662.4 Q .3 -.15(vex C)-.4 H(omputer Corp.).15 E
+(Eric W)127 674.4 Q(assenaar)-.8 E 2.5(,N)-.4 G
+(ational Institute for Nuclear and High Ener)200.49 674.4 Q(gy Ph)-.18 E
+(ysics, Amsterdam)-.05 E(Christophe W)127 686.4 Q(olfhugel, Herv)-.8 E 2.5(eS)
+-.15 G(chauer Consultants \(P)252.7 686.4 Q(aris\))-.15 E 2.687(Ia)87 702.6 S
+.187(pologize for an)97.457 702.6 R .188(yone I ha)-.15 F .488 -.15(ve o)-.2 H
+.188(mitted, misspelled, misattrib).15 F .188(uted, or otherwise missed.)-.2 F
+(Man)5.188 E 2.688(yo)-.15 G .188(ther peo-)467.992 702.6 R(ple ha)87 714.6 Q
+.3 -.15(ve c)-.2 H(ontrib).15 E(uted ideas, comments, and encouragement.)-.2 E
+2.5(Ia)5 G(ppreciate their contrib)338.06 714.6 Q(ution as well.)-.2 E EP
+%%Page: 60 55
+%%BeginPageSetup
+BP
+%%EndPageSetup
+/F0 12/Times-Bold@0 SF 3(APPENDIX A)257.172 98.4 R(COMMAND LINE FLA)224.832
+141.6 Q(GS)-.66 E/F1 10/Times-Roman@0 SF(Ar)97 201 Q
+(guments must be presented with \215ags before addresses.)-.18 E
+(The \215ags are:)5 E<ad62>72 217.2 Q/F2 10/Times-Italic@0 SF(x)A F1
+(Set operation mode to)144 217.2 Q F2(x)2.5 E F1 5(.O)C(peration modes are:)
+253.71 217.2 Q 12.22(mD)184 233.4 S(eli)211.22 233.4 Q -.15(ve)-.25 G 2.5(rm)
+.15 G(ail \(def)243.87 233.4 Q(ault\))-.1 E 16.11(sS)184 245.4 S
+(peak SMTP on input side)209.56 245.4 Q 15(dR)184 257.4 S(un as a daemon)210.67
+257.4 Q 17.22(tR)184 269.4 S(un in test mode)210.67 269.4 Q 15(vJ)184 281.4 S
+(ust v)207.89 281.4 Q(erify addresses, don')-.15 E 2.5(tc)-.18 G
+(ollect or deli)319.48 281.4 Q -.15(ve)-.25 G(r).15 E 17.22(iI)184 293.4 S
+(nitialize the alias database)207.33 293.4 Q 15(pP)184 305.4 S
+(rint the mail queue)209.56 305.4 Q<ad42>72 325.8 Q F2(type)A F1
+(Indicate body type.)144 325.8 Q<ad43>72 342 Q F2(\214le)A F1 .947(Use a dif)
+144 342 R .946(ferent con\214guration \214le.)-.25 F F2(Sendmail)5.946 E F1
+.946(runs as the in)3.446 F -.2(vo)-.4 G .946(king user \(rather than root\)).2
+F(when this \215ag is speci\214ed.)144 354 Q<ad64>72 370.2 Q F2(le)A(vel)-.15 E
+F1(Set deb)144 370.2 Q(ugging le)-.2 E -.15(ve)-.25 G(l.).15 E<ad66>72 386.4 Q
+F2(addr)2.5 E F1(The sender')144 386.4 Q 2.5(sm)-.55 G(achine address is)205.1
+386.4 Q F2(addr)2.5 E F1(.)A<ad46>72 402.6 Q F2(name)A F1
+(Sets the full name of this user to)144 402.6 Q F2(name)2.5 E F1(.)A<ad68>72
+418.8 Q F2(cnt)2.5 E F1 .725(Sets the \231hop count\232 to)144 418.8 R F2(cnt)
+3.225 E F1 5.725(.T)C .726
+(his represents the number of times this message has been)269.45 418.8 R .02
+(processed by)144 430.8 R F2(sendmail)2.52 E F1 .02(\(to the e)2.52 F .02
+(xtent that it is supported by the underlying netw)-.15 F(orks\).)-.1 E F2(Cnt)
+5.02 E F1 1.521
+(is incremented during processing, and if it reaches MAXHOP \(currently 30\))
+144 442.8 R F2(sendmail)4.021 E F1(thro)144 454.8 Q(ws a)-.25 E -.1(wa)-.15 G
+2.5(yt).1 G(he message with an error)199.6 454.8 Q(.)-.55 E 58.86(\255n Don')72
+471 R 2.5(td)-.18 G 2.5(oa)174.65 471 S(liasing or forw)186.59 471 Q(arding.)
+-.1 E<ad72>72 487.2 Q F2(addr)2.5 E F1(An obsolete form of)144 487.2 Q/F3 10
+/Times-Bold@0 SF<ad66>2.5 E F1(.)A<ad6f>72 503.4 Q F2 1.666(xv)C(alue)-1.666 E
+F1(Set option)144 503.4 Q F2(x)2.5 E F1(to the speci\214ed)2.5 E F2(value)2.5 E
+F1 5(.T)C(hese options are described in Appendix B.)292.6 503.4 Q<ad70>72 519.6
+Q F2(pr)A(otocol)-.45 E F1 .401(Set the sending protocol.)144 519.6 R .401
+(Programs are encouraged to set this.)5.401 F .4(The protocol \214eld can be)
+5.401 F .114(in the form)144 531.6 R F2(pr)2.614 E(otocol)-.45 E F3(:)A F2
+(host)A F1 .114(to set both the sending protocol and sending host.)2.614 F -.15
+(Fo)5.115 G 2.615(re).15 G(xample,)472.06 531.6 Q 2.147(\231\255pUUCP:uunet\
+\232 sets the sending protocol to UUCP and the sending host to uunet.)144 543.6
+R .973(\(Some e)144 555.6 R .974
+(xisting programs use \255oM to set the r and s macros; this is equi)-.15 F
+-.25(va)-.25 G .974(lent to using).25 F(\255p.\))144 567.6 Q<ad71>72 583.8 Q F2
+(time)A F1 -.35(Tr)144 583.8 S 3.168(yt).35 G 3.167(op)164.038 583.8 S .667
+(rocess the queued up mail.)177.205 583.8 R .667(If the time is gi)5.667 F -.15
+(ve)-.25 G .667(n, a).15 F F2(sendmail)3.167 E F1 .667(will run through the)
+3.167 F(queue at the speci\214ed interv)144 595.8 Q(al to deli)-.25 E -.15(ve)
+-.25 G 2.5(rq).15 G(ueued mail; otherwise, it only runs once.)310.82 595.8 Q
+<ad71>72 612 Q F2(Xstring)A F1 .312
+(Run the queue once, limiting the jobs to those matching)144 612 R F2(Xstring)
+2.813 E F1 5.313(.T)C .313(he k)416.325 612 R .613 -.15(ey l)-.1 H(etter).15 E
+F2(X)2.813 E F1 .313(can be)2.813 F F3(I)144 624 Q F1 .671
+(to limit based on queue identi\214er)3.171 F(,)-.4 E F3(R)3.171 E F1 .67
+(to limit based on recipient, or)3.171 F F3(S)3.17 E F1 .67(to limit based on)
+3.17 F(sender)144 636 Q 6.053(.A)-.55 G 1.054
+(particular queued job is accepted if one of the corresponding addresses con-)
+188.876 636 R(tains the indicated)144 648 Q F2(string)2.5 E F1(.)A 61.08
+(\255t Read)72 664.2 R .752(the header for \231T)3.252 F .752
+(o:\232, \231Cc:\232, and \231Bcc:\232 lines, and send to e)-.8 F -.15(ve)-.25
+G .752(ryone listed in those).15 F 2.539(lists. The)144 676.2 R .039
+(\231Bcc:\232 line will be deleted before sending.)2.539 F(An)5.039 E 2.539(ya)
+-.15 G .04(ddresses in the ar)385.31 676.2 R .04(gument v)-.18 F(ec-)-.15 E
+(tor will be deleted from the send list.)144 688.2 Q<ad58>72 704.4 Q F2(lo)3.18
+E(g\214le)-.1 E F1 .68(Log all traf)144.68 704.4 R .68(\214c in and out of)-.25
+F F2(sendmail)3.179 E F1 .679(in the indicated)3.179 F F2(lo)3.179 E(g\214le)
+-.1 E F1 .679(for deb)3.179 F .679(ugging mailer prob-)-.2 F 2.5(lems. This)144
+716.4 R(produces a lot of data v)2.5 E
+(ery quickly and should be used sparingly)-.15 E(.)-.65 E F3 193.36
+(SMM:08-60 Sendmail)72 756 R(Installation and Operation Guide)2.5 E EP
+%%Page: 61 56
+%%BeginPageSetup
+BP
+%%EndPageSetup
+/F0 10/Times-Bold@0 SF(Sendmail Installation and Operation Guide)72 60 Q
+(SMM:08-61)452.9 60 Q/F1 10/Times-Roman@0 SF .637
+(There are a number of options that may be speci\214ed as primiti)97 96 R .938
+-.15(ve \215)-.25 H 3.138(ags. These).15 F .638(are the e, i, m, and v)3.138 F
+2.5(options. Also,)72 108 R(the f option may be speci\214ed as the)2.5 E F0
+<ad73>2.5 E F1(\215ag.)2.5 E EP
+%%Page: 62 57
+%%BeginPageSetup
+BP
+%%EndPageSetup
+/F0 12/Times-Bold@0 SF 3(APPENDIX B)250.002 98.4 R -.12(QU)220.29 141.6 S
+(EUE FILE FORMA).12 E(TS)-1.14 E/F1 10/Times-Roman@0 SF .292
+(This appendix describes the format of the queue \214les.)97 201 R .292
+(These \214les li)5.292 F .592 -.15(ve i)-.25 H 2.792(nt).15 G .291
+(he directory de\214ned by the)395.636 201 R/F2 10/Times-Bold@0 SF(Q)72 213 Q
+F1(option in the)2.5 E/F3 10/Times-Italic@0 SF(sendmail.cf)2.5 E F1
+(\214le, usually)2.5 E F3(/var/spool/mqueue)2.5 E F1(or)2.5 E F3
+(/usr/spool/mqueue)2.5 E F1(.)A .229(All queue \214les ha)97 229.2 R .529 -.15
+(ve t)-.2 H .229(he name).15 F F3(x)2.729 E F2(f)1.666 E F3(AAA99999)A F1
+(where)2.73 E F3(AAA99999)2.73 E F1 .23(is the)2.73 F F3(id)2.73 E F1 .23
+(for this message and the)2.73 F F3(x)2.73 E F1 .23(is a)2.73 F 3.601
+(type. The)72 241.2 R 1.101
+(\214rst letter of the id encodes the hour of the day that the message w)3.601
+F 1.101(as recei)-.1 F -.15(ve)-.25 G 3.601(db).15 G 3.601(yt)451.798 241.2 S
+1.101(he system)463.179 241.2 R .551
+(\(with A being the hour between midnight and 1:00AM\).)72 253.2 R .552
+(All \214les with the same id collecti)5.552 F -.15(ve)-.25 G .552
+(ly de\214ne one).15 F(message.)72 265.2 Q(The types are:)97 281.4 Q 31(dT)72
+297.6 S(he data \214le.)114.11 297.6 Q(The message body \(e)5 E
+(xcluding the header\) is k)-.15 E(ept in this \214le.)-.1 E 33.22(lT)72 313.8
+S .312(he lock \214le.)114.11 313.8 R .312(If this \214le e)5.312 F .311
+(xists, the job is currently being processed, and a queue run will not pro-)
+-.15 F .523(cess the \214le.)108 325.8 R -.15(Fo)5.524 G 3.024(rt).15 G .524
+(hat reason, an e)183.274 325.8 R(xtraneous)-.15 E F2(lf)3.024 E F1 .524
+(\214le can cause a job to apparently disappear \(it will)3.024 F .285(not e)
+108 337.8 R -.15(ve)-.25 G 2.785(nt).15 G .284(ime out!\).)147.61 337.8 R
+([Actually)5.284 E 2.784(,t)-.65 G .284
+(his \214le is obsolete on most systems that support the)237.802 337.8 R F2
+(\215ock)2.784 E F1(or)2.784 E F2(lockf)2.784 E F1(system calls.])108 349.8 Q
+31(nT)72 366 S .348(his \214le is created when an id is being created.)114.11
+366 R .348(It is a separate \214le to insure that no mail can e)5.348 F -.15
+(ve)-.25 G(r).15 E .805(be destro)108 378 R .805(yed due to a race condition.)
+-.1 F .805(It should e)5.805 F .805(xist for no more than a fe)-.15 F 3.305(wm)
+-.25 G .805(illiseconds at an)433.1 378 R(y)-.15 E(gi)108 390 Q -.15(ve)-.25 G
+2.5(nt).15 G 2.5(ime. [This)135.1 390 R(is only used on old v)2.5 E(ersions of)
+-.15 E F3(sendmail)2.5 E F1 2.5(;i)C 2.5(ti)349.95 390 S 2.5(sn)358.01 390 S
+(ot used on ne)369.4 390 Q(wer v)-.25 E(ersions.])-.15 E 31(qT)72 406.2 S
+(he queue control \214le.)114.11 406.2 Q
+(This \214le contains the information necessary to process the job)5 E(.)-.4 E
+33.22(tA)72 422.4 S .344(temporary \214le.)118.064 422.4 R .344
+(These are an image of the)5.344 F F2(qf)2.844 E F1 .344
+(\214le when it is being reb)2.844 F 2.845(uilt. It)-.2 F .345
+(should be renamed)2.845 F(to a)108 434.4 Q F2(qf)2.5 E F1(\214le v)2.5 E
+(ery quickly)-.15 E(.)-.65 E 31(xA)72 450.6 S .567(transcript \214le, e)118.287
+450.6 R .567(xisting during the life of a session sho)-.15 F .566(wing e)-.25 F
+-.15(ve)-.25 G .566(rything that happens during that).15 F(session.)108 462.6 Q
+(The)97 478.8 Q F2(qf)3.333 E F1 .833
+(\214le is structured as a series of lines each be)3.333 F .834
+(ginning with a code letter)-.15 F 5.834(.T)-.55 G .834(he lines are as fol-)
+427.354 478.8 R(lo)72 490.8 Q(ws:)-.25 E 28.78(DT)72 507 S
+(he name of the data \214le.)114.11 507 Q
+(There may only be one of these lines.)5 E 28.78(HA)72 523.2 S .33
+(header de\214nition.)118.05 523.2 R .33(There may be an)5.33 F 2.829(yn)-.15 G
+.329(umber of these lines.)274.289 523.2 R .329(The order is important: the)
+5.329 F 2.829(yr)-.15 G(epre-)483.46 523.2 Q .046
+(sent the order in the \214nal message.)108 535.2 R .046
+(These use the same syntax as header de\214nitions in the con\214gu-)5.046 F
+(ration \214le.)108 547.2 Q 29.33(CT)72 563.4 S .575(he controlling address.)
+114.11 563.4 R .575(The syntax is \231localuser:aliasname\232.)5.575 F .575
+(Recipient addresses follo)5.575 F .575(wing this)-.25 F 2.814
+(line will be \215agged so that deli)108 575.4 R -.15(ve)-.25 G 2.814
+(ries will be run as the).15 F F3(localuser)5.314 E F1 2.814
+(\(a user name from the)5.314 F .562(/etc/passwd \214le\);)108 587.4 R F3
+(aliasname)3.062 E F1 .561(is the name of the alias that e)3.062 F .561
+(xpanded to this address \(used for print-)-.15 F(ing messages\).)108 599.4 Q
+29.33(RA)72 615.6 S .705(recipient address.)118.425 615.6 R .705
+(This will normally be completely aliased, b)5.705 F .705
+(ut is actually realiased when the)-.2 F(job is processed.)108 627.6 Q
+(There will be one line for each recipient.)5 E 30.44(ST)72 643.8 S
+(he sender address.)114.11 643.8 Q(There may only be one of these lines.)5 E
+29.89(EA)72 660 S 3.742(ne)115.22 660 S 1.242(rror address.)128.402 660 R 1.242
+(If an)6.242 F 3.742(ys)-.15 G 1.241(uch lines e)218.19 660 R 1.241(xist, the)
+-.15 F 3.741(yr)-.15 G 1.241(epresent the addresses that should recei)308.124
+660 R 1.541 -.15(ve e)-.25 H(rror).15 E(messages.)108 672 Q 29.89(TT)72 688.2 S
+(he job creation time.)114.11 688.2 Q
+(This is used to compute when to time out the job)5 E(.)-.4 E 30.44(PT)72 704.4
+S .113(he current message priority)114.11 704.4 R 5.113(.T)-.65 G .113
+(his is used to order the queue.)236.662 704.4 R .114(Higher numbers mean lo)
+5.114 F .114(wer priori-)-.25 F 3.677(ties. The)108 716.4 R 1.176
+(priority changes as the message sits in the queue.)3.677 F 1.176
+(The initial priority depends on the)6.176 F F2 193.36(SMM:08-62 Sendmail)72
+756 R(Installation and Operation Guide)2.5 E EP
+%%Page: 63 58
+%%BeginPageSetup
+BP
+%%EndPageSetup
+/F0 10/Times-Bold@0 SF(Sendmail Installation and Operation Guide)72 60 Q
+(SMM:08-63)452.9 60 Q/F1 10/Times-Roman@0 SF
+(message class and the size of the message.)108 96 Q 27.11(MA)72 112.2 S 2.703
+(message. This)117.923 112.2 R .203(line is printed by the)2.703 F/F2 10
+/Times-Italic@0 SF(mailq)2.703 E F1 .204
+(command, and is generally used to store status infor)2.704 F(-)-.2 E 2.5
+(mation. It)108 124.2 R(can contain an)2.5 E 2.5(yt)-.15 G -.15(ex)219.78 124.2
+S(t.).15 E 30.44(FF)72 140.4 S .044
+(lag bits, represented as one letter per \215ag.)113.56 140.4 R .043
+(De\214ned \215ag bits are)5.043 F F0(r)2.543 E F1 .043
+(indicating that this is a response)2.543 F .142(message and)108 152.4 R F0(w)
+2.642 E F1 .142(indicating that a w)2.642 F .143
+(arning message has been sent announcing that the mail has been)-.1 F(delayed.)
+108 164.4 Q 31($A)72 180.6 S .83(macro de\214nition.)118.55 180.6 R .83(The v)
+5.83 F .829(alues of certain macros \(as of this writing, only)-.25 F F0($r)
+3.329 E F1(and)3.329 E F0($s)3.329 E F1 3.329(\)a)C .829(re passed)466.241
+180.6 R(through to the queue run phase.)108 192.6 Q 29.33(BT)72 208.8 S .924
+(he body type.)114.11 208.8 R .925(The remainder of the line is a te)5.924 F
+.925(xt string de\214ning the body type.)-.15 F .925(If this \214eld is)5.925 F
+.009(missing, the body type is assumed to be \231unde\214ned\232 and no specia\
+l processing is attempted.)108 220.8 R(Le)5.008 E -.05(ga)-.15 G(l).05 E -.25
+(va)108 232.8 S(lues are \2317BIT\232 and \2318BITMIME\232.).25 E 4.072
+(As an e)97 249 R 4.072(xample, the follo)-.15 F 4.073
+(wing is a queue \214le sent to \231eric@mammoth.Berk)-.25 F(ele)-.1 E -.65(y.)
+-.15 G 4.073(EDU\232 and).65 F(\231bostic@ok)72 263 Q(eef)-.1 E(fe.CS.Berk)-.25
+E(ele)-.1 E -.65(y.)-.15 G(EDU\232).65 E/F3 7/Times-Roman@0 SF(1)219.09 259 Q
+F1(:)222.59 263 Q(P835771)112 279.2 Q(T404261372)112 291.2 Q(DdfAAA13557)112
+303.2 Q(Seric)112 315.2 Q(Eo)112 327.2 Q(wner)-.25 E(-sendmail@v)-.2 E
+(angogh.CS.Berk)-.25 E(ele)-.1 E -.65(y.)-.15 G(EDU).65 E(Ceric:sendmail@v)112
+339.2 Q(angogh.CS.Berk)-.25 E(ele)-.1 E -.65(y.)-.15 G(EDU).65 E
+(Reric@mammoth.Berk)112 351.2 Q(ele)-.1 E -.65(y.)-.15 G(EDU).65 E(Rbostic@ok)
+112 363.2 Q(eef)-.1 E(fe.CS.Berk)-.25 E(ele)-.1 E -.65(y.)-.15 G(EDU).65 E
+(H?P?return-path: <o)112 375.2 Q(wner)-.25 E(-sendmail@v)-.2 E(angogh.CS.Berk)
+-.25 E(ele)-.1 E -.65(y.)-.15 G(EDU>).65 E(Hrecei)112 387.2 Q -.15(ve)-.25 G
+(d: by v).15 E(angogh.CS.Berk)-.25 E(ele)-.1 E -.65(y.)-.15 G
+(EDU \(5.108/2.7\) id AAA06703;).65 E(Fri, 17 Jul 92 00:28:55 -0700)132 399.2 Q
+(Hrecei)112 411.2 Q -.15(ve)-.25 G(d: from mail.CS.Berk).15 E(ele)-.1 E -.65
+(y.)-.15 G(EDU by v).65 E(angogh.CS.Berk)-.25 E(ele)-.1 E -.65(y.)-.15 G
+(EDU \(5.108/2.7\)).65 E(id AAA06698; Fri, 17 Jul 92 00:28:54 -0700)132 423.2 Q
+(Hrecei)112 435.2 Q -.15(ve)-.25 G(d: from [128.32.31.21] by mail.CS.Berk).15 E
+(ele)-.1 E -.65(y.)-.15 G(EDU \(5.96/2.5\)).65 E
+(id AA22777; Fri, 17 Jul 92 03:29:14 -0400)132 447.2 Q(Hrecei)112 459.2 Q -.15
+(ve)-.25 G(d: by foo.bar).15 E(.baz.de \(5.57/Ultrix3.0-C\))-.55 E
+(id AA22757; Fri, 17 Jul 92 09:31:25 GMT)132 471.2 Q(H?F?from: eric@foo.bar)112
+483.2 Q(.baz.de \(Eric Allman\))-.55 E(H?x?full-name: Eric Allman)112 495.2 Q
+(Hmessage-id: <9207170931.AA22757@foo.bar)112 507.2 Q(.baz.de>)-.55 E(HT)112
+519.2 Q(o: sendmail@v)-.8 E(angogh.CS.Berk)-.25 E(ele)-.1 E -.65(y.)-.15 G(EDU)
+.65 E(Hsubject: this is an e)112 531.2 Q(xample message)-.15 E 1.083(This sho)
+72 547.4 R 1.084(ws the name of the data \214le, the person who sent the messa\
+ge, the submission time \(in seconds)-.25 F .26
+(since January 1, 1970\), the message priority)72 559.4 R 2.76(,t)-.65 G .259
+(he message class, the recipients, and the headers for the mes-)257.03 559.4 R
+(sage.)72 571.4 Q .32 LW 76 669.2 72 669.2 DL 80 669.2 76 669.2 DL 84 669.2 80
+669.2 DL 88 669.2 84 669.2 DL 92 669.2 88 669.2 DL 96 669.2 92 669.2 DL 100
+669.2 96 669.2 DL 104 669.2 100 669.2 DL 108 669.2 104 669.2 DL 112 669.2 108
+669.2 DL 116 669.2 112 669.2 DL 120 669.2 116 669.2 DL 124 669.2 120 669.2 DL
+128 669.2 124 669.2 DL 132 669.2 128 669.2 DL 136 669.2 132 669.2 DL 140 669.2
+136 669.2 DL 144 669.2 140 669.2 DL 148 669.2 144 669.2 DL 152 669.2 148 669.2
+DL 156 669.2 152 669.2 DL 160 669.2 156 669.2 DL 164 669.2 160 669.2 DL 168
+669.2 164 669.2 DL 172 669.2 168 669.2 DL 176 669.2 172 669.2 DL 180 669.2 176
+669.2 DL 184 669.2 180 669.2 DL 188 669.2 184 669.2 DL 192 669.2 188 669.2 DL
+196 669.2 192 669.2 DL 200 669.2 196 669.2 DL 204 669.2 200 669.2 DL 208 669.2
+204 669.2 DL 212 669.2 208 669.2 DL 216 669.2 212 669.2 DL/F4 5/Times-Roman@0
+SF(1)93.6 679.6 Q/F5 8/Times-Roman@0 SF .719(This e)3.2 J .719
+(xample is contri)-.12 F -.12(ve)-.2 G 2.719(da).12 G .719
+(nd probably inaccurate for your en)186.968 682.8 R 2.719(vironment. Glance)
+-.32 F -.12(ove)2.718 G 2.718(ri).12 G 2.718(tt)384.998 682.8 S 2.718(og)
+392.164 682.8 S .718(et an idea; nothing can replace)402.882 682.8 R
+(looking at what your o)72 692.4 Q(wn system generates.)-.2 E EP
+%%Page: 64 59
+%%BeginPageSetup
+BP
+%%EndPageSetup
+/F0 12/Times-Bold@0 SF 3(APPENDIX C)249.672 98.4 R(SUMMAR)198.282 141.6 Q 3(YO)
+-.42 G 3(FS)274.182 141.6 S(UPPOR)291.186 141.6 Q 3(TF)-.48 G(ILES)350.37 141.6
+Q/F1 10/Times-Roman@0 SF 1.519(This is a summary of the support \214les that)97
+201 R/F2 10/Times-Italic@0 SF(sendmail)4.019 E F1 1.52(creates or generates.)
+4.019 F(Man)6.52 E 4.02(yo)-.15 G 4.02(ft)444.74 201 S 1.52(hese can be)454.87
+201 R(changed by editing the sendmail.cf \214le; check there to \214nd the act\
+ual pathnames.)72 213 Q(/usr/sbin/sendmail)72 229.2 Q(The binary of)144 241.2 Q
+F2(sendmail)2.5 E F1(.)A(/usr/bin/ne)72 257.4 Q -.1(wa)-.25 G(liases).1 E 3.735
+(Al)144 269.4 S 1.235
+(ink to /usr/sbin/sendmail; causes the alias database to be reb)157.735 269.4 R
+3.734(uilt. Running)-.2 F 1.234(this pro-)3.734 F(gram is completely equi)144
+281.4 Q -.25(va)-.25 G(lent to gi).25 E(ving)-.25 E F2(sendmail)2.5 E F1(the)
+2.5 E/F3 10/Times-Bold@0 SF(\255bi)2.5 E F1(\215ag.)2.5 E 13.38
+(/usr/bin/mailq Prints)72 297.6 R 3.702(al)3.702 G 1.202
+(isting of the mail queue.)181.964 297.6 R 1.203(This program is equi)6.202 F
+-.25(va)-.25 G 1.203(lent to using the).25 F F3(\255bp)3.703 E F1 1.203
+(\215ag to)3.703 F F2(sendmail)144 309.6 Q F1(.)A 5.9(/etc/sendmail.cf The)72
+325.8 R(con\214guration \214le, in te)2.5 E(xtual form.)-.15 E
+(/usr/lib/sendmail.hf)72 342 Q(The SMTP help \214le.)144 354 Q 7
+(/etc/sendmail.st A)72 370.2 R(statistics \214le; need not be present.)2.5 E
+.89(/etc/sendmail.pid Created)72 386.4 R .318
+(in daemon mode; it contains the process id of the current SMTP daemon.)2.818 F
+.318(If you)5.318 F .337(use this in scripts; use `)144 398.4 R .337
+(`head \2551')-.74 F 2.838('t)-.74 G 2.838(og)285.78 398.4 S .338
+(et just the \214rst line; later v)298.618 398.4 R .338(ersions of)-.15 F F2
+(sendmail)2.838 E F1(may)2.838 E(add information to subsequent lines.)144 410.4
+Q 25.62(/etc/aliases The)72 426.6 R(te)2.5 E(xtual v)-.15 E
+(ersion of the alias \214le.)-.15 E(/etc/aliases.{pag,dir})72 442.8 Q
+(The alias \214le in)144 454.8 Q F2(dbm)2.5 E F1(\(3\) format.)1.666 E(/v)72
+471 Q(ar/spool/mqueue)-.25 E
+(The directory in which the mail queue and temporary \214les reside.)144 483 Q
+(/v)72 499.2 Q(ar/spool/mqueue/qf*)-.25 E
+(Control \(queue\) \214les for messages.)144 511.2 Q(/v)72 527.4 Q
+(ar/spool/mqueue/df*)-.25 E(Data \214les.)144 539.4 Q(/v)72 555.6 Q
+(ar/spool/mqueue/tf*)-.25 E -.7(Te)144 567.6 S(mporary v).7 E
+(ersions of the qf \214les, used during queue \214le reb)-.15 E(uild.)-.2 E(/v)
+72 583.8 Q(ar/spool/mqueue/xf*)-.25 E 2.5(At)144 595.8 S
+(ranscript of the current session.)156.5 595.8 Q F3 193.36(SMM:08-64 Sendmail)
+72 756 R(Installation and Operation Guide)2.5 E EP
+%%Page: 2 60
+%%BeginPageSetup
+BP
+%%EndPageSetup
+/F0 10/Times-Bold@0 SF 198.36(SMM:08-2 Sendmail)72 60 R
+(Installation and Operation Guide)2.5 E/F1 10/Times-Roman@0 SF
+(This page intentionally left blank;)256.225 300 Q
+(replace it with a blank sheet for double-sided output.)218.6 312 Q EP
+%%Page: 3 61
+%%BeginPageSetup
+BP
+%%EndPageSetup
+/F0 10/Times-Bold@0 SF(Sendmail Installation and Operation Guide)72 60 Q
+(SMM:08-3)457.9 60 Q/F1 12/Times-Roman@0 SF -1.116(TA)263.226 98.4 S
+(BLE OF CONTENTS)1.116 E/F2 10/Times-Roman@0 SF 2.5(1. B)72 124.8 R(ASIC INST)
+-.35 E(ALLA)-.93 E 1.18(TION .................................................\
+..............................................................)-1.11 F(7)499
+124.8 Q 2.5(1.1. Compiling)87 139.2 R .43(Sendmail ...........................\
+..............................................................................\
+.....)2.5 F(7)499 139.2 Q 2.5(1.1.1. Old)102 153.6 R -.15(ve)2.5 G
+(rsions of mak).15 E 2.93(e.)-.1 G 28.5(......................................\
+............................................................. 7)220.5 153.6 R
+2.5(1.1.2. Compilation)102 168 R 2.1(\215ags .................................\
+........................................................................)2.5 F
+(7)499 168 Q 2.5(1.1.3. Compilation)102 182.4 R(and installation)2.5 E 28.5(..\
+..............................................................................\
+........ 8)4.6 F 2.5(1.2. Con\214guration)87 196.8 R .99(Files ...............\
+..............................................................................\
+...................)2.5 F(8)499 196.8 Q 2.5(1.3. Details)87 211.2 R
+(of Installation Files)2.5 E 28.5(............................................\
+....................................................... 9)4.89 F 2.5
+(1.3.1. /usr/sbin/sendmail)102 225.6 R 28.5(..................................\
+....................................................................... 9)2.66
+F 2.5(1.3.2. /etc/sendmail.cf)102 240 R 23.5(.................................\
+........................................................................... 10)
+4.9 F 2.5(1.3.3. /usr/bin/ne)102 254.4 R -.1(wa)-.25 G 2.19(liases ...........\
+..............................................................................\
+..............).1 F(10)494 254.4 Q 2.5(1.3.4. /v)102 268.8 R 1.81(ar/spool/mqu\
+eue ..........................................................................\
+..............................)-.25 F(10)494 268.8 Q 2.5(1.3.5. /etc/aliases*)
+102 283.2 R 23.5(.............................................................\
+..................................................... 10)4.62 F 2.5
+(1.3.6. /etc/rc)102 297.6 R 23.5(.............................................\
+..............................................................................\
+. 10)3.51 F 2.5(1.3.7. /usr/lib/sendmail.hf)102 312 R 23.5(...................\
+..............................................................................\
+...... 12)2.94 F 2.5(1.3.8. /etc/sendmail.st)102 326.4 R 23.5(................\
+..............................................................................\
+............... 12)3.5 F 2.5(1.3.9. /usr/bin/ne)102 340.8 R -.1(wa)-.25 G 2.19
+(liases ......................................................................\
+.................................).1 F(12)494 340.8 Q 2.5
+(1.3.10. /usr/bin/mailq)102 355.2 R 23.5(.....................................\
+........................................................................ 12)
+4.88 F 2.5(2. NORMAL)72 369.6 R(OPERA)2.5 E 1.56(TIONS .......................\
+..............................................................................\
+........)-1.11 F(12)494 369.6 Q 2.5(2.1. The)87 384 R(System Log)2.5 E 23.5(..\
+..............................................................................\
+.................................... 12)4.89 F 2.5(2.1.1. F)102 398.4 R 2.26(o\
+rmat .........................................................................\
+.................................................)-.15 F(12)494 398.4 Q 2.5
+(2.1.2. Le)102 412.8 R -.15(ve)-.25 G 2.24(ls ................................\
+..............................................................................\
+.............).15 F(12)494 412.8 Q 2.5(2.2. The)87 427.2 R(Mail Queue)2.5 E
+23.5(.........................................................................\
+............................................ 12)2.96 F 2.5(2.2.1. Printing)102
+441.6 R(the queue)2.5 E 23.5(.................................................\
+........................................................ 13)2.67 F 2.5
+(2.2.2. F)102 456 R(orcing the queue)-.15 E 23.5(.............................\
+............................................................................ 1\
+3)3.94 F 2.5(2.3. The)87 470.4 R(Alias Database)2.5 E 23.5(...................\
+..............................................................................\
+............... 13)2.69 F 2.5(2.3.1. Reb)102 484.8 R
+(uilding the alias database)-.2 E 23.5(.......................................\
+................................................ 14)4.27 F 2.5
+(2.3.2. Potential)102 499.2 R .72(problems ...................................\
+.....................................................................)2.5 F(14)
+494 499.2 Q 2.5(2.3.3. List)102 513.6 R -.25(ow)2.5 G 1.81(ners ..............\
+..............................................................................\
+.......................).25 F(14)494 513.6 Q 2.5(2.4. User)87 528 R
+(Information Database)2.5 E 23.5(.............................................\
+....................................................... 15)2.7 F 2.5(2.5. Per)
+87 542.4 R(-User F)-.2 E(orw)-.15 E(arding \(.forw)-.1 E(ard Files\))-.1 E 23.5
+(.............................................................................\
+...... 15)4.09 F 2.5(2.6. Special)87 556.8 R(Header Lines)2.5 E 23.5(.........\
+..............................................................................\
+...................... 15)2.97 F 2.5(2.6.1. Return-Receipt-T)102 571.2 R .98(o\
+: ............................................................................\
+...........................)-.8 F(15)494 571.2 Q 2.5(2.6.2. Errors-T)102 585.6
+R 2.09(o: ....................................................................\
+.................................................)-.8 F(16)494 585.6 Q 2.5
+(2.6.3. Apparently-T)102 600 R 2.09(o: .......................................\
+......................................................................)-.8 F
+(16)494 600 Q 2.5(2.7. IDENT)87 614.4 R(Protocol Support)2.5 E 23.5(..........\
+..............................................................................\
+............... 16)2.95 F 2.5(3. ARGUMENTS)72 628.8 R 23.5(...................\
+..............................................................................\
+.............................. 16)3.78 F 2.5(3.1. Queue)87 643.2 R(Interv)2.5 E
+1.55(al ......................................................................\
+.................................................)-.25 F(16)494 643.2 Q 2.5
+(3.2. Daemon)87 657.6 R 1.29(Mode ............................................\
+...........................................................................)2.5
+F(17)494 657.6 Q 2.5(3.3. F)87 672 R(orcing the Queue)-.15 E 23.5(............\
+..............................................................................\
+....................... 17)4.22 F 2.5(3.4. Deb)87 686.4 R 1.76(ugging ........\
+..............................................................................\
+.......................................)-.2 F(17)494 686.4 Q 2.5(3.5. T)87
+700.8 R(rying a Dif)-.35 E(ferent Con\214guration File)-.25 E 23.5(...........\
+........................................................................ 17)
+4.67 F 2.5(3.6. Changing)87 715.2 R(the V)2.5 E(alues of Options)-1.11 E 23.5(\
+..............................................................................\
+.............. 17)3.23 F EP
+%%Page: 4 62
+%%BeginPageSetup
+BP
+%%EndPageSetup
+/F0 10/Times-Bold@0 SF 198.36(SMM:08-4 Sendmail)72 60 R
+(Installation and Operation Guide)2.5 E/F1 10/Times-Roman@0 SF 2.5
+(3.7. Logging)87 96 R -.35(Tr)2.5 G(af).35 E .5(\214c ........................\
+..............................................................................\
+................)-.25 F(18)494 96 Q 2.5(3.8. Dumping)87 110.4 R .72(State ....\
+..............................................................................\
+.....................................)2.5 F(18)494 110.4 Q 2.5(4. TUNING)72
+124.8 R 23.5(.................................................................\
+........................................................................ 18)
+2.68 F 2.5(4.1. T)87 139.2 R 1.07(imeouts ....................................\
+..............................................................................\
+..............)-.35 F(18)494 139.2 Q 2.5(4.1.1. Queue)102 153.6 R(interv)2.5 E
+2.1(al .......................................................................\
+.......................................)-.25 F(18)494 153.6 Q 2.5(4.1.2. Read)
+102 168 R 1(timeouts .........................................................\
+......................................................)2.5 F(18)494 168 Q 2.5
+(4.1.3. Message)102 182.4 R 1.56(timeouts ....................................\
+.....................................................................)2.5 F(19)
+494 182.4 Q 2.5(4.2. F)87 196.8 R(orking During Queue Runs)-.15 E 23.5(.......\
+..............................................................................\
+............ 20)4.49 F 2.5(4.3. Queue)87 211.2 R .73(Priorities ..............\
+..............................................................................\
+.........................)2.5 F(20)494 211.2 Q 2.5(4.4. Load)87 225.6 R .44(Li\
+miting .......................................................................\
+.................................................)2.5 F(20)494 225.6 Q 2.5
+(4.5. Deli)87 240 R -.15(ve)-.25 G(ry Mode).15 E 23.5(........................\
+..............................................................................\
+................. 21)3.08 F 2.5(4.6. Log)87 254.4 R(Le)2.5 E -.15(ve)-.25 G
+2.52(l.).15 G 23.5(...........................................................\
+................................................................... 21)153
+254.4 R 2.5(4.7. File)87 268.8 R .72(Modes ...................................\
+..............................................................................\
+............)2.5 F(22)494 268.8 Q 2.5(4.7.1. T)102 283.2 R 2.5(os)-.8 G
+(uid or not to suid?)146.2 283.2 Q 23.5(......................................\
+........................................................... 22)6.52 F 2.5
+(4.7.2. Should)102 297.6 R(my alias database be writable?)2.5 E 23.5
+(........................................................................ 22)
+5.47 F 2.5(4.8. Connection)87 312 R 1.56(Caching .............................\
+..............................................................................\
+...)2.5 F(22)494 312 Q 2.5(4.9. Name)87 326.4 R(Serv)2.5 E(er Access)-.15 E
+23.5(.........................................................................\
+..................................... 22)2.85 F 2.5(4.10. Mo)87 340.8 R
+(ving the Per)-.15 E(-User F)-.2 E(orw)-.15 E(ard Files)-.1 E 23.5(...........\
+......................................................................... 23)
+3.84 F 2.5(4.11. Free)87 355.2 R 1.85(Space ..................................\
+..............................................................................\
+...........)2.5 F(23)494 355.2 Q 2.5(4.12. Pri)87 369.6 R -.25(va)-.25 G .3
+-.15(cy F).25 H 1.93(lags ....................................................\
+...................................................................).15 F(24)
+494 369.6 Q 2.5(4.13. Send)87 384 R(to Me T)2.5 E 2.08(oo ....................\
+..............................................................................\
+.................)-.8 F(24)494 384 Q 2.5(5. THE)72 398.4 R
+(WHOLE SCOOP ON THE CONFIGURA)2.5 E(TION FILE)-1.11 E 23.5
+(........................................................ 24)4.64 F 2.5
+(5.1. Con\214guration)87 412.8 R(File Lines)2.5 E 23.5(.......................\
+..............................................................................\
+... 24)2.66 F 2.5(5.1.1. R)102 427.2 R(and S \212 re)2.5 E(writing rules)-.25 E
+23.5(.........................................................................\
+................... 24)3.48 F 2.5(5.1.1.1. The)117 441.6 R(left hand side)2.5 E
+23.5(.........................................................................\
+....................... 25)4.07 F 2.5(5.1.1.2. The)117 456 R(right hand side)
+2.5 E 23.5(...................................................................\
+........................... 25)3.51 F 2.5(5.1.1.3. Semantics)117 470.4 R(of re)
+2.5 E(writing rule sets)-.25 E 23.5
+(.......................................................................... 26)
+4.6 F 2.5(5.1.1.4. IPC)117 484.8 R 1(mailers .................................\
+.........................................................................)2.5 F
+(27)494 484.8 Q 2.5(5.1.2. D)102 499.2 R 2.5<8a64>2.5 G(e\214ne macro)156.72
+499.2 Q 23.5(.................................................................\
+....................................... 28)4.35 F 2.5(5.1.3. C)102 513.6 R
+(and F \212 de\214ne classes)2.5 E 23.5(......................................\
+....................................................... 30)4.62 F 2.5(5.1.4. M)
+102 528 R 2.5<8a64>2.5 G(e\214ne mailer)158.39 528 Q 23.5(....................\
+..............................................................................\
+..... 31)4.62 F 2.5(5.1.5. H)102 542.4 R 2.5<8a64>2.5 G(e\214ne header)156.72
+542.4 Q 23.5(.................................................................\
+....................................... 33)2.69 F 2.5(5.1.6. O)102 556.8 R 2.5
+<8a73>2.5 G(et option)155.61 556.8 Q 23.5(....................................\
+......................................................................... 33)
+4.61 F 2.5(5.1.7. P)102 571.2 R 2.5<8a70>2.5 G(recedence de\214nitions)155.06
+571.2 Q 23.5(.................................................................\
+......................... 38)3.24 F 2.5(5.1.8. V)102 585.6 R 2.5<8a63>2.5 G
+(on\214guration v)156.16 585.6 Q(ersion le)-.15 E -.15(ve)-.25 G 4.62(l.).15 G
+23.5(.........................................................................\
+........ 39)265.5 585.6 R 2.5(5.1.9. K)102 600 R 2.5<8a6b>2.5 G .3 -.15
+(ey \214)156.62 600 T(le declaration).15 E 23.5(..............................\
+................................................................ 39)4.88 F 2.5
+(5.2. Building)87 614.4 R 2.5(aC)2.5 G(on\214guration File From Scratch)158.12
+614.4 Q 23.5
+(......................................................................... 41)
+3.77 F 2.5(5.2.1. What)102 628.8 R(you are trying to do)2.5 E 23.5(...........\
+..............................................................................\
+.... 42)2.96 F 2.5(5.2.2. Philosoph)102 643.2 R 3.54(y.)-.05 G 23.5(..........\
+..............................................................................\
+........................... 42)180.5 643.2 R 2.5(5.2.2.1. Lar)117 657.6 R
+(ge site, man)-.18 E 2.5(yh)-.15 G(osts \212 minimum information)226.1 657.6 Q
+23.5(................................................ 42)2.72 F 2.5
+(5.2.2.2. Small)117 672 R(site \212 complete information)2.5 E 23.5
+(.................................................................... 43)4.89 F
+2.5(5.2.2.3. Single)117 686.4 R 1.27(host ....................................\
+.......................................................................)2.5 F
+(43)494 686.4 Q 2.5(5.2.2.4. A)117 700.8 R(completely dif)2.5 E
+(ferent philosoph)-.25 E 3.26(y.)-.05 G 23.5
+(..................................................................... 43)295.5
+700.8 R 2.5(5.2.3. Rele)102 715.2 R -.25(va)-.25 G(nt issues).25 E 23.5(......\
+..............................................................................\
+......................... 44)4.56 F EP
+%%Page: 5 63
+%%BeginPageSetup
+BP
+%%EndPageSetup
+/F0 10/Times-Bold@0 SF(Sendmail Installation and Operation Guide)72 60 Q
+(SMM:08-5)457.9 60 Q/F1 10/Times-Roman@0 SF 2.5(5.2.4. Ho)102 96 R 2.5(wt)-.25
+G 2.5(op)153.97 96 S 2.38(roceed .............................................\
+...............................................................)166.47 96 R(44)
+494 96 Q 2.5(5.2.5. T)102 110.4 R(esting the re)-.7 E
+(writing rules \212 the \255bt \215ag)-.25 E 23.5
+(.................................................................... 44)2.99 F
+2.5(5.2.6. Building)102 124.8 R(mailer descriptions)2.5 E 23.5(...............\
+......................................................................... 45)
+4.61 F 2.5(5.3. The)87 139.2 R(User Database)2.5 E 23.5(......................\
+..............................................................................\
+............ 46)4.92 F 2.5(5.3.1. Structure)102 153.6 R(of the user database)
+2.5 E 23.5(...................................................................\
+.................... 47)2.7 F 2.5(5.3.2. User)102 168 R(database semantics)2.5
+E 23.5(.......................................................................\
+........................ 47)3.25 F 2.5(5.3.3. Creating)102 184.4 R
+(the database)2.5 E/F2 7/Times-Roman@0 SF(18)215.59 180.4 Q F1 23.5(..........\
+..............................................................................\
+......... 48)225.5 184.4 R 2.5(6. O)72 198.8 R(THER CONFIGURA)-.4 E 1.97(TION \
+..............................................................................\
+...........................)-1.11 F(48)494 198.8 Q 2.5(6.1. P)87 213.2 R
+(arameters in src/Mak)-.15 E 1.55(e\214le ....................................\
+................................................................)-.1 F(48)494
+213.2 Q 2.5(6.2. P)87 227.6 R(arameters in src/conf.h)-.15 E 23.5(............\
+..............................................................................\
+.............. 49)4.23 F 2.5(6.3. Con\214guration)87 242 R(in src/conf.c)2.5 E
+23.5(.........................................................................\
+........................... 51)3.51 F 2.5(6.3.1. Built-in)102 256.4 R
+(Header Semantics)2.5 E 23.5(.................................................\
+.......................................... 51)4.9 F 2.5(6.3.2. Restricting)102
+270.8 R(Use of Email)2.5 E 23.5(..............................................\
+................................................ 52)4.34 F 2.5(6.3.3. Load)102
+285.2 R -1.17 -.74(Av e)2.5 H(rage Computation).74 E 23.5(....................\
+...................................................................... 53)2.74
+F 2.5(6.3.4. Ne)102 299.6 R 2.5(wD)-.25 G(atabase Map Classes)157.85 299.6 Q
+23.5(.........................................................................\
+................ 53)4.89 F 2.5(6.3.5. Queueing)102 314 R 1.56(Function .......\
+..............................................................................\
+..................)2.5 F(53)494 314 Q 2.5(6.3.6. Refusing)102 328.4 R
+(Incoming SMTP Connections)2.5 E 23.5
+(....................................................................... 54)
+2.94 F 2.5(6.3.7. Load)102 342.8 R -1.17 -.74(Av e)2.5 H(rage Computation).74 E
+23.5(.........................................................................\
+................. 54)2.74 F 2.5(6.4. Con\214guration)87 357.2 R
+(in src/daemon.c)2.5 E 23.5(..................................................\
+............................................ 54)4.62 F 2.5(7. CHANGES)72 371.6
+R(IN VERSION 8)2.5 E 23.5(....................................................\
+...................................................... 54)4.9 F 2.5
+(7.1. Connection)87 386 R 1.56(Caching .......................................\
+.......................................................................)2.5 F
+(55)494 386 Q 2.5(7.2. MX)87 400.4 R 2.39(Piggybacking .......................\
+..............................................................................\
+............)2.5 F(55)494 400.4 Q 2.5(7.3. RFC)87 414.8 R(1123 Compliance)2.5 E
+23.5(.........................................................................\
+................................. 55)3.77 F 2.5(7.4. Extended)87 429.2 R
+(SMTP Support)2.5 E 23.5(.....................................................\
+.................................................. 55)2.94 F 2.5
+(7.5. Eight-Bit)87 443.6 R .44(Clean .........................................\
+.............................................................................)
+2.5 F(55)494 443.6 Q 2.5(7.6. User)87 458 R .47(Database .....................\
+..............................................................................\
+.....................)2.5 F(55)494 458 Q 2.5(7.7. Impro)87 472.4 R -.15(ve)-.15
+G 2.5(dB).15 G(IND Support)154.75 472.4 Q 23.5(...............................\
+........................................................................ 55)
+3.81 F 2.5(7.8. K)87 486.8 R -.15(ey)-.25 G(ed Files).15 E 23.5(..............\
+..............................................................................\
+................................ 56)3.35 F 2.5(7.9. Multi-W)87 501.2 R
+(ord Classes)-.8 E 23.5(......................................................\
+......................................................... 56)3.47 F 2.5
+(7.10. Deferred)87 515.6 R(Macro Expansion)2.5 E 23.5(........................\
+......................................................................... 56)
+4.65 F 2.5(7.11. IDENT)87 530 R(Protocol Support)2.5 E 23.5(..................\
+..............................................................................\
+..... 56)2.95 F 2.5(7.12. P)87 544.4 R(arsing Bug Fix)-.15 E .46(es ..........\
+..............................................................................\
+........................)-.15 F(56)494 544.4 Q 2.5(7.13. Separate)87 558.8 R
+(En)2.5 E -.15(ve)-.4 G(lope/Header Processing).15 E 23.5(....................\
+............................................................ 56)4.37 F 2.5
+(7.14. Owner)87 573.2 R(-List Propag)-.2 E(ates to En)-.05 E -.15(ve)-.4 G 1.27
+(lope ........................................................................\
+............).15 F(56)494 573.2 Q 2.5(7.15. Dynamic)87 587.6 R
+(Header Allocation)2.5 E 23.5(................................................\
+................................................ 56)3.25 F 2.5(7.16. Ne)87 602
+R 2.5(wC)-.25 G(ommand Line Flags)139.8 602 Q 23.5(...........................\
+....................................................................... 56)3.2
+F 2.5(7.17. Enhanced)87 616.4 R(Command Line Flags)2.5 E 23.5(................\
+......................................................................... 56)
+4.9 F 2.5(7.18. Ne)87 630.8 R 2.5(wa)-.25 G(nd Old Con\214guration Line T)
+137.57 630.8 Q .4(ypes .......................................................\
+.......................)-.8 F(57)494 630.8 Q 2.5(7.19. Ne)87 645.2 R 2.5(wO)
+-.25 G .7(ptions .............................................................\
+...........................................................)140.35 645.2 R(57)
+494 645.2 Q 2.5(7.20. Extended)87 659.6 R 1.56(Options .......................\
+..............................................................................\
+...........)2.5 F(57)494 659.6 Q 2.5(7.21. Ne)87 674 R 2.5(wM)-.25 G
+(ailer Flags)142.02 674 Q 23.5(...............................................\
+................................................................. 57)4.04 F 2.5
+(7.22. Ne)87 688.4 R 2.5(wP)-.25 G(re-De\214ned Macros)138.69 688.4 Q 23.5(...\
+..............................................................................\
+................... 58)4.06 F 2.5(7.23. Ne)87 702.8 R 2.5(wL)-.25 G(HS T)139.24
+702.8 Q(ok)-.8 E 1.33(en .....................................................\
+.............................................................)-.1 F(58)494
+702.8 Q 2.5(7.24. Bigger)87 717.2 R(Def)2.5 E(aults ..........................\
+..............................................................................\
+............)-.1 E(58)494 717.2 Q EP
+%%Page: 6 64
+%%BeginPageSetup
+BP
+%%EndPageSetup
+/F0 10/Times-Bold@0 SF 198.36(SMM:08-6 Sendmail)72 60 R
+(Installation and Operation Guide)2.5 E/F1 10/Times-Roman@0 SF 2.5(7.25. Dif)87
+96 R(ferent Def)-.25 E(ault T)-.1 E(uning P)-.45 E 1.99(arameters ............\
+......................................................................)-.15 F
+(58)494 96 Q 2.5(7.26. Auto-Quoting)87 110.4 R(in Addresses)2.5 E 23.5(.......\
+..............................................................................\
+............ 58)3.51 F 2.5(7.27. Symbolic)87 124.8 R(Names On Error Mailer)2.5
+E 23.5(.......................................................................\
+............... 58)4.91 F 2.5(7.28. SMTP)87 139.2 R(VRFY Doesn')2.5 E 2.5(tE)
+-.18 G 1.18(xpand ............................................................\
+................................)209.88 139.2 R(58)494 139.2 Q 2.5(7.29. [IPC])
+87 153.6 R(Mailers Allo)2.5 E 2.5(wM)-.25 G(ultiple Hosts)205.91 153.6 Q 23.5(\
+..............................................................................\
+..... 58)3.75 F 2.5(7.30. Aliases)87 168 R 1.29(Extended .....................\
+..............................................................................\
+..............)2.5 F(59)494 168 Q 2.5(7.31. Portability)87 182.4 R
+(and Security Enhancements)2.5 E 23.5(........................................\
+....................................... 59)2.68 F 2.5(7.32. Miscellaneous)87
+196.8 R 1.29(Changes .........................................................\
+..............................................)2.5 F(59)494 196.8 Q 2.5(8. A)72
+211.2 R(CKNO)-.4 E .1(WLEDGEMENTS ............................................\
+................................................................)-.35 F(59)494
+211.2 Q(Appendix A.)72 225.6 Q(COMMAND LINE FLA)5 E 1.97(GS ..................\
+.......................................................................)-.4 F
+(60)494 225.6 Q(Appendix B.)72 240 Q -.1(QU)5 G(EUE FILE FORMA).1 E 1.38(TS ..\
+..............................................................................\
+............)-1.11 F(62)494 240 Q(Appendix C.)72 254.4 Q(SUMMAR)5 E 2.5(YO)-.65
+G 2.5(FS)188.85 254.4 S(UPPOR)202.47 254.4 Q 2.5(TF)-.6 G 1.12(ILES ..........\
+....................................................................)248.27
+254.4 R(64)494 254.4 Q EP
+%%Trailer
+end
+%%EOF
diff --git a/usr.sbin/sendmail/doc/usenix/Makefile b/usr.sbin/sendmail/doc/usenix/Makefile
new file mode 100644
index 0000000..ea0665c
--- /dev/null
+++ b/usr.sbin/sendmail/doc/usenix/Makefile
@@ -0,0 +1,12 @@
+# @(#)Makefile 8.2 (Berkeley) 2/28/94
+
+SRCS= usenix.me
+MACROS= -me
+
+all: usenix.ps
+
+usenix.ps: ${SRCS}
+ rm -f ${.TARGET}
+ ${PIC} ${SRCS} | ${ROFF} > ${.TARGET}
+
+.include <bsd.doc.mk>
diff --git a/usr.sbin/sendmail/doc/usenix/usenix.me b/usr.sbin/sendmail/doc/usenix/usenix.me
new file mode 100644
index 0000000..0fbb672
--- /dev/null
+++ b/usr.sbin/sendmail/doc/usenix/usenix.me
@@ -0,0 +1,1076 @@
+.nr si 3n
+.he 'Mail Systems and Addressing in 4.2bsd''%'
+.fo 'Version 8.2'USENIX \- Jan 83'Last Mod 11/27/93'
+.if n .ls 2
+.+c
+.(l C
+.sz 14
+Mail Systems and Addressing
+in 4.2bsd
+.sz
+.sp
+Eric Allman*
+.sp 0.5
+.i
+Britton-Lee, Inc.
+1919 Addison Street, Suite 105.
+Berkeley, California 94704.
+.sp 0.5
+.r
+eric@Berkeley.ARPA
+ucbvax!eric
+.)l
+.sp
+.(l F
+.ce
+ABSTRACT
+.sp \n(psu
+Routing mail through a heterogeneous internet presents many new
+problems.
+Among the worst of these is that of address mapping.
+Historically, this has been handled on an ad hoc basis.
+However,
+this approach has become unmanageable as internets grow.
+.sp \n(psu
+Sendmail acts a unified
+.q "post office"
+to which all mail can be
+submitted.
+Address interpretation is controlled by a production
+system,
+which can parse both old and new format addresses.
+The
+new format is
+.q "domain-based,"
+a flexible technique that can
+handle many common situations.
+Sendmail is not intended to perform
+user interface functions.
+.sp \n(psu
+Sendmail will replace delivermail in the Berkeley 4.2 distribution.
+Several major hosts are now or will soon be running sendmail.
+This change will affect any users that route mail through a sendmail
+gateway.
+The changes that will be user visible are emphasized.
+.)l
+.sp 2
+.(f
+*A considerable part of this work
+was done while under the employ
+of the INGRES Project
+at the University of California at Berkeley.
+.)f
+.pp
+The mail system to appear in 4.2bsd
+will contain a number of changes.
+Most of these changes are based on the replacement of
+.i delivermail
+with a new module called
+.i sendmail.
+.i Sendmail
+implements a general internetwork mail routing facility,
+featuring aliasing and forwarding,
+automatic routing to network gateways,
+and flexible configuration.
+Of key interest to the mail system user
+will be the changes in the network addressing structure.
+.pp
+In a simple network,
+each node has an address,
+and resources can be identified
+with a host-resource pair;
+in particular,
+the mail system can refer to users
+using a host-username pair.
+Host names and numbers have to be administered by a central authority,
+but usernames can be assigned locally to each host.
+.pp
+In an internet,
+multiple networks with different characteristics
+and managements
+must communicate.
+In particular,
+the syntax and semantics of resource identification change.
+Certain special cases can be handled trivially
+by
+.i "ad hoc"
+techniques,
+such as
+providing network names that appear local to hosts
+on other networks,
+as with the Ethernet at Xerox PARC.
+However, the general case is extremely complex.
+For example,
+some networks require that the route the message takes
+be explicitly specified by the sender,
+simplifying the database update problem
+since only adjacent hosts must be entered
+into the system tables,
+while others use logical addressing,
+where the sender specifies the location of the recipient
+but not how to get there.
+Some networks use a left-associative syntax
+and others use a right-associative syntax,
+causing ambiguity in mixed addresses.
+.pp
+Internet standards seek to eliminate these problems.
+Initially, these proposed expanding the address pairs
+to address triples,
+consisting of
+{network, host, username}
+triples.
+Network numbers must be universally agreed upon,
+and hosts can be assigned locally
+on each network.
+The user-level presentation was changed
+to address domains,
+comprised of a local resource identification
+and a hierarchical domain specification
+with a common static root.
+The domain technique
+separates the issue of physical versus logical addressing.
+For example,
+an address of the form
+.q "eric@a.cc.berkeley.arpa"
+describes the logical
+organization of the address space
+(user
+.q eric
+on host
+.q a
+in the Computer Center
+at Berkeley)
+but not the physical networks used
+(for example, this could go over different networks
+depending on whether
+.q a
+were on an ethernet
+or a store-and-forward network).
+.pp
+.i Sendmail
+is intended to help bridge the gap
+between the totally
+.i "ad hoc"
+world
+of networks that know nothing of each other
+and the clean, tightly-coupled world
+of unique network numbers.
+It can accept old arbitrary address syntaxes,
+resolving ambiguities using heuristics
+specified by the system administrator,
+as well as domain-based addressing.
+It helps guide the conversion of message formats
+between disparate networks.
+In short,
+.i sendmail
+is designed to assist a graceful transition
+to consistent internetwork addressing schemes.
+.sp
+.pp
+Section 1 defines some of the terms
+frequently left fuzzy
+when working in mail systems.
+Section 2 discusses the design goals for
+.i sendmail .
+In section 3,
+the new address formats
+and basic features of
+.i sendmail
+are described.
+Section 4 discusses some of the special problems
+of the UUCP network.
+The differences between
+.i sendmail
+and
+.i delivermail
+are presented in section 5.
+.sp
+.(l F
+.b DISCLAIMER:
+A number of examples
+in this paper
+use names of actual people
+and organizations.
+This is not intended
+to imply a commitment
+or even an intellectual agreement
+on the part of these people or organizations.
+In particular,
+Bell Telephone Laboratories (BTL),
+Digital Equipment Corporation (DEC),
+Lawrence Berkeley Laboratories (LBL),
+Britton-Lee Incorporated (BLI),
+and the University of California at Berkeley
+are not committed to any of these proposals at this time.
+Much of this paper
+represents no more than
+the personal opinions of the author.
+.)l
+.sh 1 "DEFINITIONS"
+.pp
+There are four basic concepts
+that must be clearly distinguished
+when dealing with mail systems:
+the user (or the user's agent),
+the user's identification,
+the user's address,
+and the route.
+These are distinguished primarily by their position independence.
+.sh 2 "User and Identification"
+.pp
+The user is the being
+(a person or program)
+that is creating or receiving a message.
+An
+.i agent
+is an entity operating on behalf of the user \*-
+such as a secretary who handles my mail.
+or a program that automatically returns a
+message such as
+.q "I am at the UNICOM conference."
+.pp
+The identification is the tag
+that goes along with the particular user.
+This tag is completely independent of location.
+For example,
+my identification is the string
+.q "Eric Allman,"
+and this identification does not change
+whether I am located at U.C. Berkeley,
+at Britton-Lee,
+or at a scientific institute in Austria.
+.pp
+Since the identification is frequently ambiguous
+(e.g., there are two
+.q "Robert Henry" s
+at Berkeley)
+it is common to add other disambiguating information
+that is not strictly part of the identification
+(e.g.,
+Robert
+.q "Code Generator"
+Henry
+versus
+Robert
+.q "System Administrator"
+Henry).
+.sh 2 "Address"
+.pp
+The address specifies a location.
+As I move around,
+my address changes.
+For example,
+my address might change from
+.q eric@Berkeley.ARPA
+to
+.q eric@bli.UUCP
+or
+.q allman@IIASA.Austria
+depending on my current affiliation.
+.pp
+However,
+an address is independent of the location of anyone else.
+That is,
+my address remains the same to everyone who might be sending me mail.
+For example,
+a person at MIT and a person at USC
+could both send to
+.q eric@Berkeley.ARPA
+and have it arrive to the same mailbox.
+.pp
+Ideally a
+.q "white pages"
+service would be provided to map user identifications
+into addresses
+(for example, see
+[Solomon81]).
+Currently this is handled by passing around
+scraps of paper
+or by calling people on the telephone
+to find out their address.
+.sh 2 "Route"
+.pp
+While an address specifies
+.i where
+to find a mailbox,
+a route specifies
+.i how
+to find the mailbox.
+Specifically,
+it specifies a path
+from sender to receiver.
+As such, the route is potentially different
+for every pair of people in the electronic universe.
+.pp
+Normally the route is hidden from the user
+by the software.
+However,
+some networks put the burden of determining the route
+onto the sender.
+Although this simplifies the software,
+it also greatly impairs the usability
+for most users.
+The UUCP network is an example of such a network.
+.sh 1 "DESIGN GOALS"
+.pp
+Design goals for
+.i sendmail \**
+.(f
+\**This section makes no distinction between
+.i delivermail
+and
+.i sendmail.
+.)f
+include:
+.np
+Compatibility with the existing mail programs,
+including Bell version 6 mail,
+Bell version 7 mail,
+Berkeley
+.i Mail
+[Shoens79],
+BerkNet mail
+[Schmidt79],
+and hopefully UUCP mail
+[Nowitz78].
+ARPANET mail
+[Crocker82]
+was also required.
+.np
+Reliability, in the sense of guaranteeing
+that every message is correctly delivered
+or at least brought to the attention of a human
+for correct disposal;
+no message should ever be completely lost.
+This goal was considered essential
+because of the emphasis on mail in our environment.
+It has turned out to be one of the hardest goals to satisfy,
+especially in the face of the many anomalous message formats
+produced by various ARPANET sites.
+For example,
+certain sites generate improperly formated addresses,
+occasionally
+causing error-message loops.
+Some hosts use blanks in names,
+causing problems with
+mail programs that assume that an address
+is one word.
+The semantics of some fields
+are interpreted slightly differently
+by different sites.
+In summary,
+the obscure features of the ARPANET mail protocol
+really
+.i are
+used and
+are difficult to support,
+but must be supported.
+.np
+Existing software to do actual delivery
+should be used whenever possible.
+This goal derives as much from political and practical considerations
+as technical.
+.np
+Easy expansion to
+fairly complex environments,
+including multiple
+connections to a single network type
+(such as with multiple UUCP or Ethernets).
+This goal requires consideration of the contents of an address
+as well as its syntax
+in order to determine which gateway to use.
+.np
+Configuration information should not be compiled into the code.
+A single compiled program should be able to run as is at any site
+(barring such basic changes as the CPU type or the operating system).
+We have found this seemingly unimportant goal
+to be critical in real life.
+Besides the simple problems that occur when any program gets recompiled
+in a different environment,
+many sites like to
+.q fiddle
+with anything that they will be recompiling anyway.
+.np
+.i Sendmail
+must be able to let various groups maintain their own mailing lists,
+and let individuals specify their own forwarding,
+without modifying the system alias file.
+.np
+Each user should be able to specify which mailer to execute
+to process mail being delivered for him.
+This feature allows users who are using specialized mailers
+that use a different format to build their environment
+without changing the system,
+and facilitates specialized functions
+(such as returning an
+.q "I am on vacation"
+message).
+.np
+Network traffic should be minimized
+by batching addresses to a single host where possible,
+without assistance from the user.
+.pp
+These goals motivated the architecture illustrated in figure 1.
+.(z
+.hl
+.ie t \
+. sp 18
+.el \{\
+.(c
++---------+ +---------+ +---------+
+| sender1 | | sender2 | | sender3 |
++---------+ +---------+ +---------+
+ | | |
+ +----------+ + +----------+
+ | | |
+ v v v
+ +-------------+
+ | sendmail |
+ +-------------+
+ | | |
+ +----------+ + +----------+
+ | | |
+ v v v
++---------+ +---------+ +---------+
+| mailer1 | | mailer2 | | mailer3 |
++---------+ +---------+ +---------+
+.)c
+.\}
+
+.ce
+Figure 1 \*- Sendmail System Structure.
+.hl
+.)z
+The user interacts with a mail generating and sending program.
+When the mail is created,
+the generator calls
+.i sendmail ,
+which routes the message to the correct mailer(s).
+Since some of the senders may be network servers
+and some of the mailers may be network clients,
+.i sendmail
+may be used as an internet mail gateway.
+.sh 1 "USAGE"
+.sh 2 "Address Formats"
+.pp
+Arguments may be flags or addresses.
+Flags set various processing options.
+Following flag arguments,
+address arguments may be given.
+Addresses follow the syntax in RFC822
+[Crocker82]
+for ARPANET
+address formats.
+In brief, the format is:
+.np
+Anything in parentheses is thrown away
+(as a comment).
+.np
+Anything in angle brackets (\c
+.q "<\|>" )
+is preferred
+over anything else.
+This rule implements the ARPANET standard that addresses of the form
+.(b
+user name <machine-address>
+.)b
+will send to the electronic
+.q machine-address
+rather than the human
+.q "user name."
+.np
+Double quotes
+(\ "\ )
+quote phrases;
+backslashes quote characters.
+Backslashes are more powerful
+in that they will cause otherwise equivalent phrases
+to compare differently \*- for example,
+.i user
+and
+.i
+"user"
+.r
+are equivalent,
+but
+.i \euser
+is different from either of them.
+This might be used
+to avoid normal aliasing
+or duplicate suppression algorithms.
+.pp
+Parentheses, angle brackets, and double quotes
+must be properly balanced and nested.
+The rewriting rules control remaining parsing\**.
+.(f
+\**Disclaimer: Some special processing is done
+after rewriting local names; see below.
+.)f
+.pp
+Although old style addresses are still accepted
+in most cases,
+the preferred address format
+is based on ARPANET-style domain-based addresses
+[Su82a].
+These addresses are based on a hierarchical, logical decomposition
+of the address space.
+The addresses are hierarchical in a sense
+similar to the U.S. postal addresses:
+the messages may first be routed to the correct state,
+with no initial consideration of the city
+or other addressing details.
+The addresses are logical
+in that each step in the hierarchy
+corresponds to a set of
+.q "naming authorities"
+rather than a physical network.
+.pp
+For example,
+the address:
+.(l
+eric@HostA.BigSite.ARPA
+.)l
+would first look up the domain
+BigSite
+in the namespace administrated by
+ARPA.
+A query could then be sent to
+BigSite
+for interpretation of
+HostA.
+Eventually the mail would arrive at
+HostA,
+which would then do final delivery
+to user
+.q eric.
+.sh 2 "Mail to Files and Programs"
+.pp
+Files and programs are legitimate message recipients.
+Files provide archival storage of messages,
+useful for project administration and history.
+Programs are useful as recipients in a variety of situations,
+for example,
+to maintain a public repository of systems messages
+(such as the Berkeley
+.i msgs
+program).
+.pp
+Any address passing through the initial parsing algorithm
+as a local address
+(i.e, not appearing to be a valid address for another mailer)
+is scanned for two special cases.
+If prefixed by a vertical bar (\c
+.q \^|\^ )
+the rest of the address is processed as a shell command.
+If the user name begins with a slash mark (\c
+.q /\^ )
+the name is used as a file name,
+instead of a login name.
+.sh 2 "Aliasing, Forwarding, Inclusion"
+.pp
+.i Sendmail
+reroutes mail three ways.
+Aliasing applies system wide.
+Forwarding allows each user to reroute incoming mail
+destined for that account.
+Inclusion directs
+.i sendmail
+to read a file for a list of addresses,
+and is normally used
+in conjunction with aliasing.
+.sh 3 "Aliasing"
+.pp
+Aliasing maps local addresses to address lists using a system-wide file.
+This file is hashed to speed access.
+Only addresses that parse as local
+are allowed as aliases;
+this guarantees a unique key
+(since there are no nicknames for the local host).
+.sh 3 "Forwarding"
+.pp
+After aliasing,
+if an recipient address specifies a local user
+.i sendmail
+searches for a
+.q .forward
+file in the recipient's home directory.
+If it exists,
+the message is
+.i not
+sent to that user,
+but rather to the list of addresses in that file.
+Often
+this list will contain only one address,
+and the feature will be used for network mail forwarding.
+.pp
+Forwarding also permits a user to specify a private incoming mailer.
+For example,
+forwarding to:
+.(b
+"\^|\|/usr/local/newmail myname"
+.)b
+will use a different incoming mailer.
+.sh 3 "Inclusion"
+.pp
+Inclusion is specified in RFC 733 [Crocker77] syntax:
+.(b
+:Include: pathname
+.)b
+An address of this form reads the file specified by
+.i pathname
+and sends to all users listed in that file.
+.pp
+The intent is
+.i not
+to support direct use of this feature,
+but rather to use this as a subset of aliasing.
+For example,
+an alias of the form:
+.(b
+project: :include:/usr/project/userlist
+.)b
+is a method of letting a project maintain a mailing list
+without interaction with the system administration,
+even if the alias file is protected.
+.pp
+It is not necessary to rebuild the index on the alias database
+when a :include: list is changed.
+.sh 2 "Message Collection"
+.pp
+Once all recipient addresses are parsed and verified,
+the message is collected.
+The message comes in two parts:
+a message header and a message body,
+separated by a blank line.
+The body is an uninterpreted
+sequence of text lines.
+.pp
+The header is formated as a series of lines
+of the form
+.(b
+ field-name: field-value
+.)b
+Field-value can be split across lines by starting the following
+lines with a space or a tab.
+Some header fields have special internal meaning,
+and have appropriate special processing.
+Other headers are simply passed through.
+Some header fields may be added automatically,
+such as time stamps.
+.sh 1 "THE UUCP PROBLEM"
+.pp
+Of particular interest
+is the UUCP network.
+The explicit routing
+used in the UUCP environment
+causes a number of serious problems.
+First,
+giving out an address
+is impossible
+without knowing the address of your potential correspondent.
+This is typically handled
+by specifying the address
+relative to some
+.q "well-known"
+host
+(e.g.,
+ucbvax or decvax).
+Second,
+it is often difficult to compute
+the set of addresses
+to reply to
+without some knowledge
+of the topology of the network.
+Although it may be easy for a human being
+to do this
+under many circumstances,
+a program does not have equally sophisticated heuristics
+built in.
+Third,
+certain addresses will become painfully and unnecessarily long,
+as when a message is routed through many hosts in the USENET.
+And finally,
+certain
+.q "mixed domain"
+addresses
+are impossible to parse unambiguously \*-
+e.g.,
+.(l
+decvax!ucbvax!lbl-h!user@LBL-CSAM
+.)l
+might have many possible resolutions,
+depending on whether the message was first routed
+to decvax
+or to LBL-CSAM.
+.pp
+To solve this problem,
+the UUCP syntax
+would have to be changed to use addresses
+rather than routes.
+For example,
+the address
+.q decvax!ucbvax!eric
+might be expressed as
+.q eric@ucbvax.UUCP
+(with the hop through decvax implied).
+This address would itself be a domain-based address;
+for example,
+an address might be of the form:
+.(l
+mark@d.cbosg.btl.UUCP
+.)l
+Hosts outside of Bell Telephone Laboratories
+would then only need to know
+how to get to a designated BTL relay,
+and the BTL topology
+would only be maintained inside Bell.
+.pp
+There are three major problems
+associated with turning UUCP addresses
+into something reasonable:
+defining the namespace,
+creating and propagating the necessary software,
+and building and maintaining the database.
+.sh 2 "Defining the Namespace"
+.pp
+Putting all UUCP hosts into a flat namespace
+(e.g.,
+.q \&...@host.UUCP )
+is not practical for a number of reasons.
+First,
+with over 1600 sites already,
+and (with the increasing availability of inexpensive microcomputers
+and autodialers)
+several thousand more coming within a few years,
+the database update problem
+is simply intractable
+if the namespace is flat.
+Second,
+there are almost certainly name conflicts today.
+Third,
+as the number of sites grow
+the names become ever less mnemonic.
+.pp
+It seems inevitable
+that there be some sort of naming authority
+for the set of top level names
+in the UUCP domain,
+as unpleasant a possibility
+as that may seem.
+It will simply not be possible
+to have one host resolving all names.
+It may however be possible
+to handle this
+in a fashion similar to that of assigning names of newsgroups
+in USENET.
+However,
+it will be essential to encourage everyone
+to become subdomains of an existing domain
+whenever possible \*-
+even though this will certainly bruise some egos.
+For example,
+if a new host named
+.q blid
+were to be added to the UUCP network,
+it would probably actually be addressed as
+.q d.bli.UUCP
+(i.e.,
+as host
+.q d
+in the pseudo-domain
+.q bli
+rather than as host
+.q blid
+in the UUCP domain).
+.sh 2 "Creating and Propagating the Software"
+.pp
+The software required to implement a consistent namespace
+is relatively trivial.
+Two modules are needed,
+one to handle incoming mail
+and one to handle outgoing mail.
+.pp
+The incoming module
+must be prepared to handle either old or new style addresses.
+New-style addresses
+can be passed through unchanged.
+Old style addresses
+must be turned into new style addresses
+where possible.
+.pp
+The outgoing module
+is slightly trickier.
+It must do a database lookup on the recipient addresses
+(passed on the command line)
+to determine what hosts to send the message to.
+If those hosts do not accept new-style addresses,
+it must transform all addresses in the header of the message
+into old style using the database lookup.
+.pp
+Both of these modules
+are straightforward
+except for the issue of modifying the header.
+It seems prudent to choose one format
+for the message headers.
+For a number of reasons,
+Berkeley has elected to use the ARPANET protocols
+for message formats.
+However,
+this protocol is somewhat difficult to parse.
+.pp
+Propagation is somewhat more difficult.
+There are a large number of hosts
+connected to UUCP
+that will want to run completely standard systems
+(for very good reasons).
+The strategy is not to convert the entire network \*-
+only enough of it it alleviate the problem.
+.sh 2 "Building and Maintaining the Database"
+.pp
+This is by far the most difficult problem.
+A prototype for this database
+already exists,
+but it is maintained by hand
+and does not pretend to be complete.
+.pp
+This problem will be reduced considerably
+if people choose to group their hosts
+into subdomains.
+This would require a global update
+only when a new top level domain
+joined the network.
+A message to a host in a subdomain
+could simply be routed to a known domain gateway
+for further processing.
+For example,
+the address
+.q eric@a.bli.UUCP
+might be routed to the
+.q bli
+gateway
+for redistribution;
+new hosts could be added
+within BLI
+without notifying the rest of the world.
+Of course,
+other hosts
+.i could
+be notified as an efficiency measure.
+.pp
+There may be more than one domain gateway.
+A domain such as BTL,
+for instance,
+might have a dozen gateways to the outside world;
+a non-BTL site
+could choose the closest gateway.
+The only restriction
+would be that all gateways
+maintain a consistent view of the domain
+they represent.
+.sh 2 "Logical Structure"
+.pp
+Logically,
+domains are organized into a tree.
+There need not be a host actually associated
+with each level in the tree \*-
+for example,
+there will be no host associated with the name
+.q UUCP.
+Similarly,
+an organization might group names together for administrative reasons;
+for example,
+the name
+.(l
+CAD.research.BigCorp.UUCP
+.)l
+might not actually have a host representing
+.q research.
+.pp
+However,
+it may frequently be convenient to have a host
+or hosts
+that
+.q represent
+a domain.
+For example,
+if a single host exists that
+represents
+Berkeley,
+then mail from outside Berkeley
+can forward mail to that host
+for further resolution
+without knowing Berkeley's
+(rather volatile)
+topology.
+This is not unlike the operation
+of the telephone network.
+.pp
+This may also be useful
+inside certain large domains.
+For example,
+at Berkeley it may be presumed
+that most hosts know about other hosts
+inside the Berkeley domain.
+But if they process an address
+that is unknown,
+they can pass it
+.q upstairs
+for further examination.
+Thus as new hosts are added
+only one host
+(the domain master)
+.i must
+be updated immediately;
+other hosts can be updated as convenient.
+.pp
+Ideally this name resolution process
+would be performed by a name server
+(e.g., [Su82b])
+to avoid unnecessary copying
+of the message.
+However,
+in a batch network
+such as UUCP
+this could result in unnecessary delays.
+.sh 1 "COMPARISON WITH DELIVERMAIL"
+.pp
+.i Sendmail
+is an outgrowth of
+.i delivermail .
+The primary differences are:
+.np
+Configuration information is not compiled in.
+This change simplifies many of the problems
+of moving to other machines.
+It also allows easy debugging of new mailers.
+.np
+Address parsing is more flexible.
+For example,
+.i delivermail
+only supported one gateway to any network,
+whereas
+.i sendmail
+can be sensitive to host names
+and reroute to different gateways.
+.np
+Forwarding and
+:include:
+features eliminate the requirement that the system alias file
+be writable by any user
+(or that an update program be written,
+or that the system administration make all changes).
+.np
+.i Sendmail
+supports message batching across networks
+when a message is being sent to multiple recipients.
+.np
+A mail queue is provided in
+.i sendmail.
+Mail that cannot be delivered immediately
+but can potentially be delivered later
+is stored in this queue for a later retry.
+The queue also provides a buffer against system crashes;
+after the message has been collected
+it may be reliably redelivered
+even if the system crashes during the initial delivery.
+.np
+.i Sendmail
+uses the networking support provided by 4.2BSD
+to provide a direct interface networks such as the ARPANET
+and/or Ethernet
+using SMTP (the Simple Mail Transfer Protocol)
+over a TCP/IP connection.
+.+c
+.ce
+REFERENCES
+.nr ii 1.5i
+.ip [Crocker77]
+Crocker, D. H.,
+Vittal, J. J.,
+Pogran, K. T.,
+and
+Henderson, D. A. Jr.,
+.ul
+Standard for the Format of ARPA Network Text Messages.
+RFC 733,
+NIC 41952.
+In [Feinler78].
+November 1977.
+.ip [Crocker82]
+Crocker, D. H.,
+.ul
+Standard for the Format of Arpa Internet Text Messages.
+RFC 822.
+Network Information Center,
+SRI International,
+Menlo Park, California.
+August 1982.
+.ip [Feinler78]
+Feinler, E.,
+and
+Postel, J.
+(eds.),
+.ul
+ARPANET Protocol Handbook.
+NIC 7104,
+Network Information Center,
+SRI International,
+Menlo Park, California.
+1978.
+.ip [Nowitz78]
+Nowitz, D. A.,
+and
+Lesk, M. E.,
+.ul
+A Dial-Up Network of UNIX Systems.
+Bell Laboratories.
+In
+UNIX Programmer's Manual, Seventh Edition,
+Volume 2.
+August, 1978.
+.ip [Schmidt79]
+Schmidt, E.,
+.ul
+An Introduction to the Berkeley Network.
+University of California, Berkeley California.
+1979.
+.ip [Shoens79]
+Shoens, K.,
+.ul
+Mail Reference Manual.
+University of California, Berkeley.
+In UNIX Programmer's Manual,
+Seventh Edition,
+Volume 2C.
+December 1979.
+.ip [Solomon81]
+Solomon, M.,
+Landweber, L.,
+and
+Neuhengen, D.,
+.ul
+The Design of the CSNET Name Server.
+CS-DN-2.
+University of Wisconsin,
+Madison.
+October 1981.
+.ip [Su82a]
+Su, Zaw-Sing,
+and
+Postel, Jon,
+.ul
+The Domain Naming Convention for Internet User Applications.
+RFC819.
+Network Information Center,
+SRI International,
+Menlo Park, California.
+August 1982.
+.ip [Su82b]
+Su, Zaw-Sing,
+.ul
+A Distributed System for Internet Name Service.
+RFC830.
+Network Information Center,
+SRI International,
+Menlo Park, California.
+October 1982.
diff --git a/usr.sbin/sendmail/doc/usenix/usenix.ps b/usr.sbin/sendmail/doc/usenix/usenix.ps
new file mode 100644
index 0000000..31f2f67
--- /dev/null
+++ b/usr.sbin/sendmail/doc/usenix/usenix.ps
@@ -0,0 +1,1004 @@
+%!PS-Adobe-3.0
+%%Creator: groff version 1.08
+%%DocumentNeededResources: font Times-Roman
+%%+ font Times-Italic
+%%+ font Times-Bold
+%%DocumentSuppliedResources: procset grops 1.08 0
+%%Pages: 9
+%%PageOrder: Ascend
+%%Orientation: Portrait
+%%EndComments
+%%BeginProlog
+%%BeginResource: procset grops 1.08 0
+/setpacking where{
+pop
+currentpacking
+true setpacking
+}if
+/grops 120 dict dup begin
+/SC 32 def
+/A/show load def
+/B{0 SC 3 -1 roll widthshow}bind def
+/C{0 exch ashow}bind def
+/D{0 exch 0 SC 5 2 roll awidthshow}bind def
+/E{0 rmoveto show}bind def
+/F{0 rmoveto 0 SC 3 -1 roll widthshow}bind def
+/G{0 rmoveto 0 exch ashow}bind def
+/H{0 rmoveto 0 exch 0 SC 5 2 roll awidthshow}bind def
+/I{0 exch rmoveto show}bind def
+/J{0 exch rmoveto 0 SC 3 -1 roll widthshow}bind def
+/K{0 exch rmoveto 0 exch ashow}bind def
+/L{0 exch rmoveto 0 exch 0 SC 5 2 roll awidthshow}bind def
+/M{rmoveto show}bind def
+/N{rmoveto 0 SC 3 -1 roll widthshow}bind def
+/O{rmoveto 0 exch ashow}bind def
+/P{rmoveto 0 exch 0 SC 5 2 roll awidthshow}bind def
+/Q{moveto show}bind def
+/R{moveto 0 SC 3 -1 roll widthshow}bind def
+/S{moveto 0 exch ashow}bind def
+/T{moveto 0 exch 0 SC 5 2 roll awidthshow}bind def
+/SF{
+findfont exch
+[exch dup 0 exch 0 exch neg 0 0]makefont
+dup setfont
+[exch/setfont cvx]cvx bind def
+}bind def
+/MF{
+findfont
+[5 2 roll
+0 3 1 roll
+neg 0 0]makefont
+dup setfont
+[exch/setfont cvx]cvx bind def
+}bind def
+/level0 0 def
+/RES 0 def
+/PL 0 def
+/LS 0 def
+/PLG{
+gsave newpath clippath pathbbox grestore
+exch pop add exch pop
+}bind def
+/BP{
+/level0 save def
+1 setlinecap
+1 setlinejoin
+72 RES div dup scale
+LS{
+90 rotate
+}{
+0 PL translate
+}ifelse
+1 -1 scale
+}bind def
+/EP{
+level0 restore
+showpage
+}bind def
+/DA{
+newpath arcn stroke
+}bind def
+/SN{
+transform
+.25 sub exch .25 sub exch
+round .25 add exch round .25 add exch
+itransform
+}bind def
+/DL{
+SN
+moveto
+SN
+lineto stroke
+}bind def
+/DC{
+newpath 0 360 arc closepath
+}bind def
+/TM matrix def
+/DE{
+TM currentmatrix pop
+translate scale newpath 0 0 .5 0 360 arc closepath
+TM setmatrix
+}bind def
+/RC/rcurveto load def
+/RL/rlineto load def
+/ST/stroke load def
+/MT/moveto load def
+/CL/closepath load def
+/FL{
+currentgray exch setgray fill setgray
+}bind def
+/BL/fill load def
+/LW/setlinewidth load def
+/RE{
+findfont
+dup maxlength 1 index/FontName known not{1 add}if dict begin
+{
+1 index/FID ne{def}{pop pop}ifelse
+}forall
+/Encoding exch def
+dup/FontName exch def
+currentdict end definefont pop
+}bind def
+/DEFS 0 def
+/EBEGIN{
+moveto
+DEFS begin
+}bind def
+/EEND/end load def
+/CNT 0 def
+/level1 0 def
+/PBEGIN{
+/level1 save def
+translate
+div 3 1 roll div exch scale
+neg exch neg exch translate
+0 setgray
+0 setlinecap
+1 setlinewidth
+0 setlinejoin
+10 setmiterlimit
+[]0 setdash
+/setstrokeadjust where{
+pop
+false setstrokeadjust
+}if
+/setoverprint where{
+pop
+false setoverprint
+}if
+newpath
+/CNT countdictstack def
+userdict begin
+/showpage{}def
+}bind def
+/PEND{
+clear
+countdictstack CNT sub{end}repeat
+level1 restore
+}bind def
+end def
+/setpacking where{
+pop
+setpacking
+}if
+%%EndResource
+%%IncludeResource: font Times-Roman
+%%IncludeResource: font Times-Italic
+%%IncludeResource: font Times-Bold
+grops begin/DEFS 1 dict def DEFS begin/u{.001 mul}bind def end/RES 72 def/PL
+792 def/LS false def/ENC0[/asciicircum/asciitilde/Scaron/Zcaron/scaron/zcaron
+/Ydieresis/trademark/quotesingle/.notdef/.notdef/.notdef/.notdef/.notdef
+/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef
+/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/space
+/exclam/quotedbl/numbersign/dollar/percent/ampersand/quoteright/parenleft
+/parenright/asterisk/plus/comma/hyphen/period/slash/zero/one/two/three/four
+/five/six/seven/eight/nine/colon/semicolon/less/equal/greater/question/at/A/B/C
+/D/E/F/G/H/I/J/K/L/M/N/O/P/Q/R/S/T/U/V/W/X/Y/Z/bracketleft/backslash
+/bracketright/circumflex/underscore/quoteleft/a/b/c/d/e/f/g/h/i/j/k/l/m/n/o/p/q
+/r/s/t/u/v/w/x/y/z/braceleft/bar/braceright/tilde/.notdef/quotesinglbase
+/guillemotleft/guillemotright/bullet/florin/fraction/perthousand/dagger
+/daggerdbl/endash/emdash/ff/fi/fl/ffi/ffl/dotlessi/dotlessj/grave/hungarumlaut
+/dotaccent/breve/caron/ring/ogonek/quotedblleft/quotedblright/oe/lslash
+/quotedblbase/OE/Lslash/.notdef/exclamdown/cent/sterling/currency/yen/brokenbar
+/section/dieresis/copyright/ordfeminine/guilsinglleft/logicalnot/minus
+/registered/macron/degree/plusminus/twosuperior/threesuperior/acute/mu
+/paragraph/periodcentered/cedilla/onesuperior/ordmasculine/guilsinglright
+/onequarter/onehalf/threequarters/questiondown/Agrave/Aacute/Acircumflex/Atilde
+/Adieresis/Aring/AE/Ccedilla/Egrave/Eacute/Ecircumflex/Edieresis/Igrave/Iacute
+/Icircumflex/Idieresis/Eth/Ntilde/Ograve/Oacute/Ocircumflex/Otilde/Odieresis
+/multiply/Oslash/Ugrave/Uacute/Ucircumflex/Udieresis/Yacute/Thorn/germandbls
+/agrave/aacute/acircumflex/atilde/adieresis/aring/ae/ccedilla/egrave/eacute
+/ecircumflex/edieresis/igrave/iacute/icircumflex/idieresis/eth/ntilde/ograve
+/oacute/ocircumflex/otilde/odieresis/divide/oslash/ugrave/uacute/ucircumflex
+/udieresis/yacute/thorn/ydieresis]def/Times-Bold@0 ENC0/Times-Bold RE
+/Times-Italic@0 ENC0/Times-Italic RE/Times-Roman@0 ENC0/Times-Roman RE
+%%EndProlog
+%%Page: 1 1
+%%BeginPageSetup
+BP
+%%EndPageSetup
+/F0 14/Times-Roman@0 SF(Mail Systems and Addressing)204.196 141 Q(in 4.2bsd)
+262.331 157.8 Q/F1 10/Times-Roman@0 SF(Eric Allman*)260.92 181.8 Q/F2 10
+/Times-Italic@0 SF(Britton-Lee)254.86 199.8 Q 2.5(,I)-.1 G(nc.)309.2 199.8 Q
+(1919 Addison Str)225.13 211.8 Q(eet, Suite 105.)-.37 E(Berk)232.645 223.8 Q
+(ele)-.1 E 1.1 -.55(y, C)-.3 H(alifornia 94704.).55 E F1(eric@Berk)244.175
+241.8 Q(ele)-.1 E -.65(y.)-.15 G(ARP).65 E(A)-.92 E(ucb)264.6 253.8 Q -.25(va)
+-.15 G(x!eric).25 E(ABSTRA)262.085 286.2 Q(CT)-.4 E .966
+(Routing mail through a heterogeneous internet presents man)112 302.4 R 3.466
+(yn)-.15 G 1.466 -.25(ew p)373.438 302.4 T 3.466(roblems. Among).25 F .297
+(the w)112 314.4 R .297(orst of these is that of address mapping.)-.1 F
+(Historically)5.297 E 2.797(,t)-.65 G .298(his has been handled on an)355.03
+314.4 R(ad hoc basis.)112 326.4 Q(Ho)5 E(we)-.25 E -.15(ve)-.25 G .8 -.4(r, t)
+.15 H(his approach has become unmanageable as internets gro).4 E -.65(w.)-.25 G
+.099(Sendmail acts a uni\214ed \231post of)112 342.6 R .098
+(\214ce\232 to which all mail can be submitted.)-.25 F .098(Address inter)5.098
+F(-)-.2 E .754(pretation is controlled by a production system, which can parse\
+ both old and ne)112 354.6 R 3.255(wf)-.25 G(or)452.54 354.6 Q(-)-.2 E .242
+(mat addresses.)112 366.6 R .242(The ne)5.242 F 2.742(wf)-.25 G .242
+(ormat is \231domain-based,)216.578 366.6 R 2.742<9a618d>-.7 G -.15(ex)334.326
+366.6 S .241(ible technique that can handle).15 F(man)112 378.6 Q 2.606(yc)-.15
+G .106(ommon situations.)141.116 378.6 R .106
+(Sendmail is not intended to perform user interf)5.106 F .107(ace functions.)
+-.1 F .399(Sendmail will replace deli)112 394.8 R -.15(ve)-.25 G .399
+(rmail in the Berk).15 F(ele)-.1 E 2.899(y4)-.15 G .399(.2 distrib)320.504
+394.8 R 2.899(ution. Se)-.2 F -.15(ve)-.25 G .399(ral major hosts).15 F .421
+(are no)112 406.8 R 2.921(wo)-.25 G 2.921(rw)152.022 406.8 S .421
+(ill soon be running sendmail.)165.493 406.8 R .421(This change will af)5.421 F
+.422(fect an)-.25 F 2.922(yu)-.15 G .422(sers that route)407.056 406.8 R 1.5
+(mail through a sendmail g)112 418.8 R(ate)-.05 E -.1(wa)-.25 G 5.3 -.65(y. T)
+.1 H 1.5(he changes that will be user visible are empha-).65 F(sized.)112 430.8
+Q .906(The mail system to appear in 4.2bsd will contain a number of changes.)97
+475.2 R .906(Most of these changes are)5.906 F .469
+(based on the replacement of)72 487.2 R F2(delivermail)2.969 E F1 .469
+(with a ne)2.969 F 2.969(wm)-.25 G .469(odule called)292.871 487.2 R F2 2.97
+(sendmail. Sendmail)2.97 F F1 .47(implements a gen-)2.97 F 1.834
+(eral internetw)72 499.2 R 1.834(ork mail routing f)-.1 F(acility)-.1 E 4.333
+(,f)-.65 G 1.833(eaturing aliasing and forw)239.739 499.2 R 1.833
+(arding, automatic routing to netw)-.1 F(ork)-.1 E -.05(ga)72 511.2 S(te).05 E
+-.1(wa)-.25 G .205(ys, and \215e).1 F .205(xible con\214guration.)-.15 F .205
+(Of k)5.205 F .505 -.15(ey i)-.1 H .205
+(nterest to the mail system user will be the changes in the net-).15 F -.1(wo)
+72 523.2 S(rk addressing structure.).1 E .624(In a simple netw)97 539.4 R .624
+(ork, each node has an address, and resources can be identi\214ed with a host-\
+resource)-.1 F .374(pair; in particular)72 551.4 R 2.874(,t)-.4 G .374
+(he mail system can refer to users using a host-username pair)149.932 551.4 R
+5.374(.H)-.55 G .375(ost names and numbers)409.276 551.4 R(ha)72 563.4 Q .3
+-.15(ve t)-.2 H 2.5(ob).15 G 2.5(ea)108.31 563.4 S
+(dministered by a central authority)119.69 563.4 Q 2.5(,b)-.65 G
+(ut usernames can be assigned locally to each host.)263.82 563.4 Q .397
+(In an internet, multiple netw)97 579.6 R .396(orks with dif)-.1 F .396
+(ferent characteristics and managements must communicate.)-.25 F .389
+(In particular)72 591.6 R 2.889(,t)-.4 G .389
+(he syntax and semantics of resource identi\214cation change.)129.308 591.6 R
+.39(Certain special cases can be han-)5.389 F 1.033(dled tri)72 603.6 R 1.033
+(vially by)-.25 F F2 1.033(ad hoc)3.533 F F1 1.032(techniques, such as pro)
+3.533 F 1.032(viding netw)-.15 F 1.032
+(ork names that appear local to hosts on other)-.1 F(netw)72 615.6 Q 1.621
+(orks, as with the Ethernet at Xerox P)-.1 F 4.121(ARC. Ho)-.92 F(we)-.25 E
+-.15(ve)-.25 G 2.421 -.4(r, t).15 H 1.622(he general case is e).4 F 1.622
+(xtremely comple)-.15 F 4.122(x. F)-.15 F(or)-.15 E -.15(ex)72 627.6 S .29
+(ample, some netw).15 F .29(orks require that the route the message tak)-.1 F
+.29(es be e)-.1 F .29(xplicitly speci\214ed by the sender)-.15 F 2.79(,s)-.4 G
+(im-)490.11 627.6 Q 1.618(plifying the database update problem since only adja\
+cent hosts must be entered into the system tables,)72 639.6 R .573(while other\
+s use logical addressing, where the sender speci\214es the location of the rec\
+ipient b)72 651.6 R .573(ut not ho)-.2 F 3.072(wt)-.25 G(o)499 651.6 Q 1.065
+(get there.)72 663.6 R 1.065(Some netw)6.065 F 1.066(orks use a left-associati)
+-.1 F 1.366 -.15(ve s)-.25 H 1.066(yntax and others use a right-associati).15 F
+1.366 -.15(ve s)-.25 H 1.066(yntax, causing).15 F .32 LW 76 673.2 72 673.2 DL
+80 673.2 76 673.2 DL 84 673.2 80 673.2 DL 88 673.2 84 673.2 DL 92 673.2 88
+673.2 DL 96 673.2 92 673.2 DL 100 673.2 96 673.2 DL 104 673.2 100 673.2 DL 108
+673.2 104 673.2 DL 112 673.2 108 673.2 DL 116 673.2 112 673.2 DL 120 673.2 116
+673.2 DL 124 673.2 120 673.2 DL 128 673.2 124 673.2 DL 132 673.2 128 673.2 DL
+136 673.2 132 673.2 DL 140 673.2 136 673.2 DL 144 673.2 140 673.2 DL 148 673.2
+144 673.2 DL 152 673.2 148 673.2 DL 156 673.2 152 673.2 DL 160 673.2 156 673.2
+DL 164 673.2 160 673.2 DL 168 673.2 164 673.2 DL 172 673.2 168 673.2 DL 176
+673.2 172 673.2 DL 180 673.2 176 673.2 DL 184 673.2 180 673.2 DL 188 673.2 184
+673.2 DL 192 673.2 188 673.2 DL 196 673.2 192 673.2 DL 200 673.2 196 673.2 DL
+204 673.2 200 673.2 DL 208 673.2 204 673.2 DL 212 673.2 208 673.2 DL 216 673.2
+212 673.2 DL/F3 8/Times-Roman@0 SF .556(*A considerable part of this w)93.6
+685.2 R .556(ork w)-.08 F .556(as done while under the emplo)-.08 F 2.557(yo)
+-.08 G 2.557(ft)323.107 685.2 S .557(he INGRES Project at the Uni)330.552 685.2
+R -.12(ve)-.2 G .557(rsity of California at).12 F(Berk)72 694.8 Q(ele)-.08 E
+-.52(y.)-.12 G/F4 10/Times-Bold@0 SF(Mail Systems and Addr)72 756 Q
+(essing in 4.2bsd)-.18 E(1)499 756 Q EP
+%%Page: 2 2
+%%BeginPageSetup
+BP
+%%EndPageSetup
+/F0 10/Times-Bold@0 SF(Mail Systems and Addr)72 60 Q(essing in 4.2bsd)-.18 E(2)
+499 60 Q/F1 10/Times-Roman@0 SF(ambiguity in mix)72 96 Q(ed addresses.)-.15 E
+.679(Internet standards seek to eliminate these problems.)97 112.2 R(Initially)
+5.678 E 3.178(,t)-.65 G .678(hese proposed e)353.138 112.2 R .678
+(xpanding the address)-.15 F .331
+(pairs to address triples, consisting of {netw)72 124.2 R .331
+(ork, host, username} triples.)-.1 F(Netw)5.332 E .332(ork numbers must be uni)
+-.1 F -.15(ve)-.25 G -.2(r-).15 G 1.452
+(sally agreed upon, and hosts can be assigned locally on each netw)72 136.2 R
+3.952(ork. The)-.1 F(user)3.952 E(-le)-.2 E -.15(ve)-.25 G 3.952(lp).15 G 1.452
+(resentation w)440.718 136.2 R(as)-.1 E .249(changed to address domains, compr\
+ised of a local resource identi\214cation and a hierarchical domain speci\214-)
+72 148.2 R 1.54(cation with a common static root.)72 160.2 R 1.539
+(The domain technique separates the issue of ph)6.539 F 1.539(ysical v)-.05 F
+1.539(ersus logical)-.15 F 3.001(addressing. F)72 172.2 R .501(or e)-.15 F .502
+(xample, an address of the form \231eric@a.cc.berk)-.15 F(ele)-.1 E -.65(y.)
+-.15 G .502(arpa\232 describes the logical or).65 F -.05(ga)-.18 G(niza-).05 E
+.443(tion of the address space \(user \231eric\232 on host \231a\232 in the Co\
+mputer Center at Berk)72 184.2 R(ele)-.1 E .443(y\) b)-.15 F .443
+(ut not the ph)-.2 F(ysical)-.05 E(netw)72 196.2 Q .934(orks used \(for e)-.1 F
+.934(xample, this could go o)-.15 F -.15(ve)-.15 G 3.434(rd).15 G(if)274.722
+196.2 Q .934(ferent netw)-.25 F .935
+(orks depending on whether \231a\232 were on an)-.1 F
+(ethernet or a store-and-forw)72 208.2 Q(ard netw)-.1 E(ork\).)-.1 E/F2 10
+/Times-Italic@0 SF(Sendmail)97 224.4 Q F1 .493
+(is intended to help bridge the g)2.993 F .493(ap between the totally)-.05 F F2
+.493(ad hoc)2.993 F F1 -.1(wo)2.993 G .493(rld of netw).1 F .493(orks that kno)
+-.1 F(w)-.25 E .854(nothing of each other and the clean, tightly-coupled w)72
+236.4 R .854(orld of unique netw)-.1 F .855(ork numbers.)-.1 F .855
+(It can accept old)5.855 F .633(arbitrary address syntax)72 248.4 R .632(es, r\
+esolving ambiguities using heuristics speci\214ed by the system administrator)
+-.15 F 3.132(,a)-.4 G(s)500.11 248.4 Q .347(well as domain-based addressing.)72
+260.4 R .347(It helps guide the con)5.347 F -.15(ve)-.4 G .347
+(rsion of message formats between disparate net-).15 F -.1(wo)72 272.4 S 3.395
+(rks. In).1 F(short,)3.395 E F2(sendmail)3.395 E F1 .894
+(is designed to assist a graceful transition to consistent internetw)3.395 F
+.894(ork addressing)-.1 F(schemes.)72 284.4 Q .689
+(Section 1 de\214nes some of the terms frequently left fuzzy when w)97 312.6 R
+.69(orking in mail systems.)-.1 F .69(Section 2)5.69 F .595
+(discusses the design goals for)72 324.6 R F2(sendmail)3.095 E F1 5.595(.I)C
+3.095(ns)243.33 324.6 S .595(ection 3, the ne)255.315 324.6 R 3.095(wa)-.25 G
+.594(ddress formats and basic features of)332.705 324.6 R F2(send-)3.094 E
+(mail)72 336.6 Q F1 .893(are described.)3.393 F .893
+(Section 4 discusses some of the special problems of the UUCP netw)5.893 F
+3.394(ork. The)-.1 F(dif)3.394 E(fer)-.25 E(-)-.2 E(ences between)72 348.6 Q F2
+(sendmail)2.5 E F1(and)2.5 E F2(delivermail)2.5 E F1
+(are presented in section 5.)2.5 E F0(DISCLAIMER:)112 376.8 Q F1 3.333(An)3.333
+G .833(umber of e)199.216 376.8 R .832
+(xamples in this paper use names of actual people and)-.15 F(or)112 388.8 Q
+-.05(ga)-.18 G 4.572(nizations. This).05 F 2.072
+(is not intended to imply a commitment or e)4.572 F -.15(ve)-.25 G 4.573(na).15
+G 4.573(ni)409.987 388.8 S(ntellectual)422.34 388.8 Q 1.094
+(agreement on the part of these people or or)112 400.8 R -.05(ga)-.18 G 3.594
+(nizations. In).05 F(particular)3.594 E 3.594(,B)-.4 G 1.094(ell T)408.896
+400.8 R(elephone)-.7 E .656
+(Laboratories \(BTL\), Digital Equipment Corporation \(DEC\), La)112 412.8 R
+.657(wrence Berk)-.15 F(ele)-.1 E 3.157(yL)-.15 G(abo-)446.23 412.8 Q 2.136
+(ratories \(LBL\), Britton-Lee Incorporated \(BLI\), and the Uni)112 424.8 R
+-.15(ve)-.25 G 2.136(rsity of California at).15 F(Berk)112 436.8 Q(ele)-.1 E
+3.088(ya)-.15 G .588(re not committed to an)155.378 436.8 R 3.089(yo)-.15 G
+3.089(ft)261.219 436.8 S .589(hese proposals at this time.)270.418 436.8 R .589
+(Much of this paper)5.589 F
+(represents no more than the personal opinions of the author)112 448.8 Q(.)-.55
+E F0 2.5(1. DEFINITIONS)72 477 R F1 .266(There are four basic concepts that mu\
+st be clearly distinguished when dealing with mail systems:)112 493.2 R .514
+(the user \(or the user')87 505.2 R 3.014(sa)-.55 G .515(gent\), the user')
+182.6 505.2 R 3.015(si)-.55 G .515(denti\214cation, the user')253.025 505.2 R
+3.015(sa)-.55 G .515(ddress, and the route.)354.56 505.2 R .515(These are dis-)
+5.515 F(tinguished primarily by their position independence.)87 517.2 Q F0 2.5
+(1.1. User)87 541.2 R(and Identi\214cation)2.5 E F1 .264
+(The user is the being \(a person or program\) that is creating or recei)127
+557.4 R .263(ving a message.)-.25 F(An)5.263 E F2 -.1(age)2.763 G(nt).1 E F1
+.659(is an entity operating on behalf of the user \212 such as a secretary who\
+ handles my mail.)102 569.4 R .66(or a pro-)5.66 F(gram that automatically ret\
+urns a message such as \231I am at the UNICOM conference.)102 581.4 Q<9a>-.7 E
+.931(The identi\214cation is the tag that goes along with the particular user)
+127 597.6 R 5.931(.T)-.55 G .931(his tag is completely)418.707 597.6 R .216
+(independent of location.)102 609.6 R -.15(Fo)5.216 G 2.716(re).15 G .216
+(xample, my identi\214cation is the string \231Eric Allman,)225.324 609.6 R
+2.717<9a61>-.7 G .217(nd this identi-)448.006 609.6 R 1.228
+(\214cation does not change whether I am located at U.C. Berk)102 621.6 R(ele)
+-.1 E 2.527 -.65(y, a)-.15 H 3.727(tB).65 G 1.227
+(ritton-Lee, or at a scienti\214c)390.502 621.6 R(institute in Austria.)102
+633.6 Q 2.379
+(Since the identi\214cation is frequently ambiguous \(e.g., there are tw)127
+649.8 R 4.879<6f99>-.1 G 2.38(Robert Henry\232s at)426.48 649.8 R(Berk)102
+661.8 Q(ele)-.1 E .316(y\) it is common to add other disambiguating informatio\
+n that is not strictly part of the iden-)-.15 F
+(ti\214cation \(e.g., Robert \231Code Generator\232 Henry v)102 673.8 Q
+(ersus Robert \231System Administrator\232 Henry\).)-.15 E F0 -1(Ve)72 756 S
+(rsion 8.2)1 E(USENIX \255 J)249.805 756 Q(an 83)-.15 E(Last Mod 11/27/93)
+424.55 756 Q EP
+%%Page: 3 3
+%%BeginPageSetup
+BP
+%%EndPageSetup
+/F0 10/Times-Bold@0 SF(Mail Systems and Addr)72 60 Q(essing in 4.2bsd)-.18 E(3)
+499 60 Q 2.5(1.2. Addr)87 96 R(ess)-.18 E/F1 10/Times-Roman@0 SF .785
+(The address speci\214es a location.)127 112.2 R .786(As I mo)5.786 F 1.086
+-.15(ve a)-.15 H .786(round, my address changes.).15 F -.15(Fo)5.786 G 3.286
+(re).15 G .786(xample, my)455.994 112.2 R 9.712
+(address might change from \231eric@Berk)102 124.2 R(ele)-.1 E -.65(y.)-.15 G
+(ARP).65 E 9.711(A\232 to \231eric@bli.UUCP\232 or \231all-)-.92 F
+(man@IIASA.Austria\232 depending on my current af)102 136.2 Q(\214liation.)-.25
+E(Ho)127 152.4 Q(we)-.25 E -.15(ve)-.25 G 2.819 -.4(r, a).15 H 4.519(na).4 G
+2.019(ddress is independent of the location of an)188.018 152.4 R 2.019
+(yone else.)-.15 F 2.02(That is, my address)7.02 F .385(remains the same to e)
+102 164.4 R -.15(ve)-.25 G .385(ryone who might be sending me mail.).15 F -.15
+(Fo)5.385 G 2.885(re).15 G .385(xample, a person at MIT and a)379.22 164.4 R
+(person at USC could both send to \231eric@Berk)102 176.4 Q(ele)-.1 E -.65(y.)
+-.15 G(ARP).65 E(A\232 and ha)-.92 E .3 -.15(ve i)-.2 H 2.5(ta).15 G(rri)388.44
+176.4 Q .3 -.15(ve t)-.25 H 2.5(ot).15 G(he same mailbox.)422.48 176.4 Q .627
+(Ideally a \231white pages\232 service w)127 192.6 R .627(ould be pro)-.1 F
+.627(vided to map user identi\214cations into addresses)-.15 F .444(\(for e)102
+204.6 R .444(xample, see [Solomon81]\).)-.15 F .444
+(Currently this is handled by passing around scraps of paper or by)5.444 F
+(calling people on the telephone to \214nd out their address.)102 216.6 Q F0
+2.5(1.3. Route)87 240.6 R F1 .288(While an address speci\214es)127 256.8 R/F2
+10/Times-Italic@0 SF(wher)2.788 E(e)-.37 E F1 .289
+(to \214nd a mailbox, a route speci\214es)2.789 F F2(how)2.789 E F1 .289
+(to \214nd the mailbox.)2.789 F(Speci\214cally)102 268.8 Q 2.607(,i)-.65 G
+2.607(ts)156.457 268.8 S .106(peci\214es a path from sender to recei)165.734
+268.8 R -.15(ve)-.25 G 3.706 -.55(r. A).15 H 2.606(ss).55 G .106
+(uch, the route is potentially dif)343.364 268.8 R .106(ferent for)-.25 F -2.15
+-.25(ev e)102 280.8 T(ry pair of people in the electronic uni).25 E -.15(ve)
+-.25 G(rse.).15 E .258(Normally the route is hidden from the user by the softw)
+127 297 R 2.758(are. Ho)-.1 F(we)-.25 E -.15(ve)-.25 G 1.058 -.4(r, s).15 H
+.258(ome netw).4 F .258(orks put the)-.1 F -.2(bu)102 309 S 1.972
+(rden of determining the route onto the sender).2 F 6.971(.A)-.55 G 1.971
+(lthough this simpli\214es the softw)322.544 309 R 1.971(are, it also)-.1 F
+(greatly impairs the usability for most users.)102 321 Q(The UUCP netw)5 E
+(ork is an e)-.1 E(xample of such a netw)-.15 E(ork.)-.1 E F0 2.5(2. DESIGN)72
+345 R(GO)2.5 E(ALS)-.4 E F1(Design goals for)112 363.2 Q F2(sendmail)2.5 E/F3 7
+/Times-Roman@0 SF(1)216.71 359.2 Q F1(include:)222.71 363.2 Q 12.5
+(\(1\) Compatibility)92 379.4 R 1.363(with the e)3.863 F 1.363
+(xisting mail programs, including Bell v)-.15 F 1.363(ersion 6 mail, Bell v)
+-.15 F 1.364(ersion 7)-.15 F 3.589(mail, Berk)118.66 391.4 R(ele)-.1 E(y)-.15 E
+F2(Mail)6.089 E F1 3.589
+([Shoens79], BerkNet mail [Schmidt79], and hopefully UUCP mail)6.089 F([No)
+118.66 403.4 Q 2.5(witz78]. ARP)-.25 F(ANET mail [Crock)-.92 E(er82] w)-.1 E
+(as also required.)-.1 E 12.5(\(2\) Reliability)92 419.6 R 4.002(,i)-.65 G
+4.002(nt)169.522 419.6 S 1.502(he sense of guaranteeing that e)181.304 419.6 R
+-.15(ve)-.25 G 1.502(ry message is correctly deli).15 F -.15(ve)-.25 G 1.503
+(red or at least).15 F .368
+(brought to the attention of a human for correct disposal; no message should e)
+118.66 431.6 R -.15(ve)-.25 G 2.868(rb).15 G 2.868(ec)452.252 431.6 S
+(ompletely)464 431.6 Q 2.54(lost. This)118.66 443.6 R .04(goal w)2.54 F .041
+(as considered essential because of the emphasis on mail in our en)-.1 F 2.541
+(vironment. It)-.4 F 1.755
+(has turned out to be one of the hardest goals to satisfy)118.66 455.6 R 4.254
+(,e)-.65 G 1.754(specially in the f)363.756 455.6 R 1.754(ace of the man)-.1 F
+(y)-.15 E .977(anomalous message formats produced by v)118.66 467.6 R .977
+(arious ARP)-.25 F .977(ANET sites.)-.92 F -.15(Fo)5.977 G 3.478(re).15 G .978
+(xample, certain sites)420.114 467.6 R .069
+(generate improperly formated addresses, occasionally causing error)118.66
+479.6 R .069(-message loops.)-.2 F .068(Some hosts)5.069 F .766(use blanks in \
+names, causing problems with mail programs that assume that an address is one)
+118.66 491.6 R -.1(wo)118.66 503.6 S 3.924(rd. The).1 F 1.423
+(semantics of some \214elds are interpreted slightly dif)3.923 F 1.423
+(ferently by dif)-.25 F 1.423(ferent sites.)-.25 F(In)6.423 E(summary)118.66
+515.6 Q 3.022(,t)-.65 G .523(he obscure features of the ARP)163.532 515.6 R
+.523(ANET mail protocol really)-.92 F F2(ar)3.023 E(e)-.37 E F1 .523
+(used and are dif)3.023 F(\214cult)-.25 E(to support, b)118.66 527.6 Q
+(ut must be supported.)-.2 E 12.5(\(3\) Existing)92 543.8 R(softw)2.939 E .439
+(are to do actual deli)-.1 F -.15(ve)-.25 G .439(ry should be used whene).15 F
+-.15(ve)-.25 G 2.938(rp).15 G 2.938(ossible. This)387.658 543.8 R .438
+(goal deri)2.938 F -.15(ve)-.25 G 2.938(sa).15 G(s)500.11 543.8 Q
+(much from political and practical considerations as technical.)118.66 555.8 Q
+12.5(\(4\) Easy)92 572 R -.15(ex)2.898 G .398(pansion to f).15 F .398
+(airly comple)-.1 F 2.898(xe)-.15 G -.4(nv)261.06 572 S .399
+(ironments, including multiple connections to a single net-).4 F -.1(wo)118.66
+584 S .63(rk type \(such as with multiple UUCP or Ethernets\).).1 F .63
+(This goal requires consideration of the)5.63 F
+(contents of an address as well as its syntax in order to determine which g)
+118.66 596 Q(ate)-.05 E -.1(wa)-.25 G 2.5(yt).1 G 2.5(ou)443.48 596 S(se.)
+455.98 596 Q 12.5(\(5\) Con\214guration)92 612.2 R 1.048
+(information should not be compiled into the code.)3.548 F 3.549(As)6.049 G
+1.049(ingle compiled program)405.802 612.2 R .084
+(should be able to run as is at an)118.66 624.2 R 2.584(ys)-.15 G .083
+(ite \(barring such basic changes as the CPU type or the operat-)256.196 624.2
+R .342(ing system\).)118.66 636.2 R 1.942 -.8(We h)5.342 H -2.25 -.2(av e).8 H
+.343(found this seemingly unimportant goal to be critical in real life.)3.042 F
+(Besides)5.343 E .734(the simple problems that occur when an)118.66 648.2 R
+3.234(yp)-.15 G .734(rogram gets recompiled in a dif)295.568 648.2 R .733
+(ferent en)-.25 F(vironment,)-.4 E(man)118.66 660.2 Q 2.5(ys)-.15 G(ites lik)
+147.12 660.2 Q 2.5(et)-.1 G 2.5<6f99>183.69 660.2 S(\214ddle\232 with an)195.63
+660.2 Q(ything that the)-.15 E 2.5(yw)-.15 G(ill be recompiling an)327.27 660.2
+Q(yw)-.15 E(ay)-.1 E(.)-.65 E .32 LW 76 678.8 72 678.8 DL 80 678.8 76 678.8 DL
+84 678.8 80 678.8 DL 88 678.8 84 678.8 DL 92 678.8 88 678.8 DL 96 678.8 92
+678.8 DL 100 678.8 96 678.8 DL 104 678.8 100 678.8 DL 108 678.8 104 678.8 DL
+112 678.8 108 678.8 DL 116 678.8 112 678.8 DL 120 678.8 116 678.8 DL 124 678.8
+120 678.8 DL 128 678.8 124 678.8 DL 132 678.8 128 678.8 DL 136 678.8 132 678.8
+DL 140 678.8 136 678.8 DL 144 678.8 140 678.8 DL 148 678.8 144 678.8 DL 152
+678.8 148 678.8 DL 156 678.8 152 678.8 DL 160 678.8 156 678.8 DL 164 678.8 160
+678.8 DL 168 678.8 164 678.8 DL 172 678.8 168 678.8 DL 176 678.8 172 678.8 DL
+180 678.8 176 678.8 DL 184 678.8 180 678.8 DL 188 678.8 184 678.8 DL 192 678.8
+188 678.8 DL 196 678.8 192 678.8 DL 200 678.8 196 678.8 DL 204 678.8 200 678.8
+DL 208 678.8 204 678.8 DL 212 678.8 208 678.8 DL 216 678.8 212 678.8 DL/F4 5
+/Times-Roman@0 SF(1)93.6 689.2 Q/F5 8/Times-Roman@0 SF(This section mak)3.2 I
+(es no distinction between)-.08 E/F6 8/Times-Italic@0 SF(delivermail)2 E F5
+(and)2 E F6(sendmail.)2 E F0 -1(Ve)72 756 S(rsion 8.2)1 E(USENIX \255 J)249.805
+756 Q(an 83)-.15 E(Last Mod 11/27/93)424.55 756 Q EP
+%%Page: 4 4
+%%BeginPageSetup
+BP
+%%EndPageSetup
+/F0 10/Times-Bold@0 SF(Mail Systems and Addr)72 60 Q(essing in 4.2bsd)-.18 E(4)
+499 60 Q/F1 10/Times-Roman@0 SF(\(6\))92 96 Q/F2 10/Times-Italic@0 SF(Sendmail)
+118.66 96 Q F1 .184(must be able to let v)2.684 F .184
+(arious groups maintain their o)-.25 F .184(wn mailing lists, and let indi)-.25
+F(viduals)-.25 E(specify their o)118.66 108 Q(wn forw)-.25 E
+(arding, without modifying the system alias \214le.)-.1 E 12.5(\(7\) Each)92
+124.2 R .313(user should be able to specify which mailer to e)2.814 F -.15(xe)
+-.15 G .313(cute to process mail being deli).15 F -.15(ve)-.25 G .313(red for)
+.15 F 3.098(him. This)118.66 136.2 R .598(feature allo)3.098 F .598
+(ws users who are using specialized mailers that use a dif)-.25 F .598
+(ferent format to)-.25 F -.2(bu)118.66 148.2 S .25(ild their en).2 F .25
+(vironment without changing the system, and f)-.4 F .25
+(acilitates specialized functions \(such)-.1 F(as returning an \231I am on v)
+118.66 160.2 Q(acation\232 message\).)-.25 E 12.5(\(8\) Netw)92 176.4 R 1.552
+(ork traf)-.1 F 1.552(\214c should be minimized by batching addresses to a sin\
+gle host where possible,)-.25 F(without assistance from the user)118.66 188.4 Q
+(.)-.55 E .375(These goals moti)112 204.6 R -.25(va)-.25 G .375
+(ted the architecture illustrated in \214gure 1.).25 F .374
+(The user interacts with a mail gen-)5.375 F .49(erating and sending program.)
+87 216.6 R .491(When the mail is created, the generator calls)5.49 F F2
+(sendmail)2.991 E F1 2.991(,w)C .491(hich routes the)444.138 216.6 R .841
+(message to the correct mailer\(s\).)87 228.6 R .841
+(Since some of the senders may be netw)5.841 F .84(ork serv)-.1 F .84
+(ers and some of the)-.15 F(mailers may be netw)87 240.6 Q(ork clients,)-.1 E
+F2(sendmail)2.5 E F1(may be used as an internet mail g)2.5 E(ate)-.05 E -.1(wa)
+-.25 G -.65(y.).1 G F0 2.5(3. USA)72 264.6 R(GE)-.55 E 2.5(3.1. Addr)87 288.6 R
+(ess F)-.18 E(ormats)-.25 E F1(Ar)127 304.8 Q .886
+(guments may be \215ags or addresses.)-.18 F .886(Flags set v)5.886 F .886
+(arious processing options.)-.25 F -.15(Fo)5.886 G(llo).15 E .886(wing \215ag)
+-.25 F(ar)102 316.8 Q .611(guments, address ar)-.18 F .611(guments may be gi)
+-.18 F -.15(ve)-.25 G 3.111(n. Addresses).15 F(follo)3.111 E 3.111(wt)-.25 G
+.611(he syntax in RFC822 [Crock)365.558 316.8 R(er82])-.1 E(for ARP)102 328.8 Q
+(ANET address formats.)-.92 E(In brief, the format is:)5 E 12.5(\(1\) An)107
+345 R(ything in parentheses is thro)-.15 E(wn a)-.25 E -.1(wa)-.15 G 2.5(y\().1
+G(as a comment\).)299.65 345 Q 12.5(\(2\) An)107 361.2 R .051
+(ything in angle brack)-.15 F .051(ets \(\231<)-.1 F .051
+(>\232\) is preferred o)1.666 F -.15(ve)-.15 G 2.551(ra).15 G -.15(ny)348.064
+361.2 S .051(thing else.).15 F .051(This rule implements the)5.051 F(ARP)133.66
+373.2 Q(ANET standard that addresses of the form)-.92 E .4 LW 77 408 72 408 DL
+79 408 74 408 DL 84 408 79 408 DL 89 408 84 408 DL 94 408 89 408 DL 99 408 94
+408 DL 104 408 99 408 DL 109 408 104 408 DL 114 408 109 408 DL 119 408 114 408
+DL 124 408 119 408 DL 129 408 124 408 DL 134 408 129 408 DL 139 408 134 408 DL
+144 408 139 408 DL 149 408 144 408 DL 154 408 149 408 DL 159 408 154 408 DL 164
+408 159 408 DL 169 408 164 408 DL 174 408 169 408 DL 179 408 174 408 DL 184 408
+179 408 DL 189 408 184 408 DL 194 408 189 408 DL 199 408 194 408 DL 204 408 199
+408 DL 209 408 204 408 DL 214 408 209 408 DL 219 408 214 408 DL 224 408 219 408
+DL 229 408 224 408 DL 234 408 229 408 DL 239 408 234 408 DL 244 408 239 408 DL
+249 408 244 408 DL 254 408 249 408 DL 259 408 254 408 DL 264 408 259 408 DL 269
+408 264 408 DL 274 408 269 408 DL 279 408 274 408 DL 284 408 279 408 DL 289 408
+284 408 DL 294 408 289 408 DL 299 408 294 408 DL 304 408 299 408 DL 309 408 304
+408 DL 314 408 309 408 DL 319 408 314 408 DL 324 408 319 408 DL 329 408 324 408
+DL 334 408 329 408 DL 339 408 334 408 DL 344 408 339 408 DL 349 408 344 408 DL
+354 408 349 408 DL 359 408 354 408 DL 364 408 359 408 DL 369 408 364 408 DL 374
+408 369 408 DL 379 408 374 408 DL 384 408 379 408 DL 389 408 384 408 DL 394 408
+389 408 DL 399 408 394 408 DL 404 408 399 408 DL 409 408 404 408 DL 414 408 409
+408 DL 419 408 414 408 DL 424 408 419 408 DL 429 408 424 408 DL 434 408 429 408
+DL 439 408 434 408 DL 444 408 439 408 DL 449 408 444 408 DL 454 408 449 408 DL
+459 408 454 408 DL 464 408 459 408 DL 469 408 464 408 DL 474 408 469 408 DL 479
+408 474 408 DL 484 408 479 408 DL 489 408 484 408 DL 494 408 489 408 DL 499 408
+494 408 DL 504 408 499 408 DL(Figure 1 \212 Sendmail System Structure.)208 660
+Q 77 672 72 672 DL 79 672 74 672 DL 84 672 79 672 DL 89 672 84 672 DL 94 672 89
+672 DL 99 672 94 672 DL 104 672 99 672 DL 109 672 104 672 DL 114 672 109 672 DL
+119 672 114 672 DL 124 672 119 672 DL 129 672 124 672 DL 134 672 129 672 DL 139
+672 134 672 DL 144 672 139 672 DL 149 672 144 672 DL 154 672 149 672 DL 159 672
+154 672 DL 164 672 159 672 DL 169 672 164 672 DL 174 672 169 672 DL 179 672 174
+672 DL 184 672 179 672 DL 189 672 184 672 DL 194 672 189 672 DL 199 672 194 672
+DL 204 672 199 672 DL 209 672 204 672 DL 214 672 209 672 DL 219 672 214 672 DL
+224 672 219 672 DL 229 672 224 672 DL 234 672 229 672 DL 239 672 234 672 DL 244
+672 239 672 DL 249 672 244 672 DL 254 672 249 672 DL 259 672 254 672 DL 264 672
+259 672 DL 269 672 264 672 DL 274 672 269 672 DL 279 672 274 672 DL 284 672 279
+672 DL 289 672 284 672 DL 294 672 289 672 DL 299 672 294 672 DL 304 672 299 672
+DL 309 672 304 672 DL 314 672 309 672 DL 319 672 314 672 DL 324 672 319 672 DL
+329 672 324 672 DL 334 672 329 672 DL 339 672 334 672 DL 344 672 339 672 DL 349
+672 344 672 DL 354 672 349 672 DL 359 672 354 672 DL 364 672 359 672 DL 369 672
+364 672 DL 374 672 369 672 DL 379 672 374 672 DL 384 672 379 672 DL 389 672 384
+672 DL 394 672 389 672 DL 399 672 394 672 DL 404 672 399 672 DL 409 672 404 672
+DL 414 672 409 672 DL 419 672 414 672 DL 424 672 419 672 DL 429 672 424 672 DL
+434 672 429 672 DL 439 672 434 672 DL 444 672 439 672 DL 449 672 444 672 DL 454
+672 449 672 DL 459 672 454 672 DL 464 672 459 672 DL 469 672 464 672 DL 474 672
+469 672 DL 479 672 474 672 DL 484 672 479 672 DL 489 672 484 672 DL 494 672 489
+672 DL 499 672 494 672 DL 504 672 499 672 DL F0 -1(Ve)72 756 S(rsion 8.2)1 E
+(USENIX \255 J)249.805 756 Q(an 83)-.15 E(Last Mod 11/27/93)424.55 756 Q EP
+%%Page: 5 5
+%%BeginPageSetup
+BP
+%%EndPageSetup
+/F0 10/Times-Bold@0 SF(Mail Systems and Addr)72 60 Q(essing in 4.2bsd)-.18 E(5)
+499 60 Q/F1 10/Times-Roman@0 SF(user name <machine-address>)173.66 96 Q(will s\
+end to the electronic \231machine-address\232 rather than the human \231user n\
+ame.)133.66 112.2 Q<9a>-.7 E 12.5(\(3\) Double)107 128.4 R 2.246(quotes \()
+4.746 F -2.754 2.5("\) q)2.5 H 2.246
+(uote phrases; backslashes quote characters.)224.188 128.4 R 2.246
+(Backslashes are more)7.246 F(po)133.66 140.4 Q .654(werful in that the)-.25 F
+3.154(yw)-.15 G .655(ill cause otherwise equi)229.196 140.4 R -.25(va)-.25 G
+.655(lent phrases to compare dif).25 F .655(ferently \212 for)-.25 F -.15(ex)
+133.66 152.4 S(ample,).15 E/F2 10/Times-Italic@0 SF(user)3.873 E F1(and)3.873 E
+F2("user")3.872 E F1 1.372(are equi)3.872 F -.25(va)-.25 G 1.372(lent, b).25 F
+(ut)-.2 E F2(\\user)3.872 E F1 1.372(is dif)3.872 F 1.372
+(ferent from either of them.)-.25 F(This)6.372 E(might be used to a)133.66
+164.4 Q -.2(vo)-.2 G(id normal aliasing or duplicate suppression algorithms.).2
+E -.15(Pa)127 180.6 S 1.12(rentheses, angle brack).15 F 1.12
+(ets, and double quotes must be properly balanced and nested.)-.1 F(The)6.12 E
+(re)102 194.6 Q(writing rules control remaining parsing)-.25 E/F3 7
+/Times-Roman@0 SF(2)266.17 190.6 Q F1(.)269.67 194.6 Q .644(Although old style\
+ addresses are still accepted in most cases, the preferred address format is)
+127 210.8 R .299(based on ARP)102 222.8 R(ANET)-.92 E .299
+(-style domain-based addresses [Su82a].)-.92 F .299
+(These addresses are based on a hierar)5.299 F(-)-.2 E .13
+(chical, logical decomposition of the address space.)102 234.8 R .13
+(The addresses are hierarchical in a sense similar)5.13 F 1.133(to the U.S. po\
+stal addresses: the messages may \214rst be routed to the correct state, with \
+no initial)102 246.8 R .72
+(consideration of the city or other addressing details.)102 258.8 R .72
+(The addresses are logical in that each step in)5.72 F(the hierarch)102 270.8 Q
+2.5(yc)-.05 G
+(orresponds to a set of \231naming authorities\232 rather than a ph)161.37
+270.8 Q(ysical netw)-.05 E(ork.)-.1 E -.15(Fo)127 287 S 2.5(re).15 G
+(xample, the address:)147.53 287 Q(eric@HostA.BigSite.ARP)142 303.2 Q(A)-.92 E
+-.1(wo)102 319.4 S .851
+(uld \214rst look up the domain BigSite in the namespace administrated by ARP)
+.1 F 3.351(A. A)-.92 F .851(query could)3.351 F 1.476
+(then be sent to BigSite for interpretation of HostA.)102 331.4 R(Ev)6.475 E
+1.475(entually the mail w)-.15 F 1.475(ould arri)-.1 F 1.775 -.15(ve a)-.25 H
+3.975(tH).15 G(ostA,)482.61 331.4 Q(which w)102 343.4 Q
+(ould then do \214nal deli)-.1 E -.15(ve)-.25 G(ry to user \231eric.).15 E<9a>
+-.7 E F0 2.5(3.2. Mail)87 367.4 R(to Files and Pr)2.5 E(ograms)-.18 E F1 .609
+(Files and programs are le)127 383.6 R .609(gitimate message recipients.)-.15 F
+.609(Files pro)5.609 F .609(vide archi)-.15 F -.25(va)-.25 G 3.109(ls).25 G .61
+(torage of mes-)445.02 383.6 R .124
+(sages, useful for project administration and history)102 395.6 R 5.124(.P)-.65
+G .124(rograms are useful as recipients in a v)318.308 395.6 R .124(ariety of)
+-.25 F .69(situations, for e)102 407.6 R .691(xample, to maintain a public rep\
+ository of systems messages \(such as the Berk)-.15 F(ele)-.1 E(y)-.15 E F2
+(msgs)102 419.6 Q F1(program\).)2.5 E(An)127 435.8 Q 3.188(ya)-.15 G .688(ddre\
+ss passing through the initial parsing algorithm as a local address \(i.e, not\
+ appear)151.698 435.8 R(-)-.2 E .276(ing to be a v)102 447.8 R .276
+(alid address for another mailer\) is scanned for tw)-.25 F 2.776(os)-.1 G .277
+(pecial cases.)362.128 447.8 R .277(If pre\214x)5.277 F .277(ed by a v)-.15 F
+(erti-)-.15 E .18(cal bar \(\231)102 459.8 R .833<7c9a>.833 G 2.68(\)t)-.833 G
+.179(he rest of the address is processed as a shell command.)156.456 459.8 R
+.179(If the user name be)5.179 F .179(gins with a)-.15 F(slash mark \(\231/)102
+471.8 Q(\232\) the name is used as a \214le name, instead of a login name.).833
+E F0 2.5(3.3. Aliasing,)87 495.8 R -.25(Fo)2.5 G(rwarding, Inclusion).25 E F2
+(Sendmail)127 512 Q F1 1.074(reroutes mail three w)3.574 F 3.574(ays. Aliasing)
+-.1 F 1.075(applies system wide.)3.575 F -.15(Fo)6.075 G(rw).15 E 1.075
+(arding allo)-.1 F 1.075(ws each)-.25 F .233
+(user to reroute incoming mail destined for that account.)102 524 R .233
+(Inclusion directs)5.233 F F2(sendmail)2.733 E F1 .233(to read a \214le for)
+2.733 F 2.5(al)102 536 S
+(ist of addresses, and is normally used in conjunction with aliasing.)111.72
+536 Q F0 2.5(3.3.1. Aliasing)102 560 R F1 .065
+(Aliasing maps local addresses to address lists using a system-wide \214le.)142
+576.2 R .065(This \214le is hashed)5.065 F 1.546(to speed access.)117 588.2 R
+1.545(Only addresses that parse as local are allo)6.546 F 1.545
+(wed as aliases; this guarantees a)-.25 F(unique k)117 600.2 Q .3 -.15(ey \()
+-.1 H(since there are no nicknames for the local host\).).15 E F0 2.5(3.3.2. F)
+102 624.2 R(orwarding)-.25 E F1 .641
+(After aliasing, if an recipient address speci\214es a local user)142 640.4 R
+F2(sendmail)3.141 E F1 .641(searches for a \231.for)3.141 F(-)-.2 E -.1(wa)117
+652.4 S .413(rd\232 \214le in the recipient').1 F 2.913(sh)-.55 G .413
+(ome directory)235.335 652.4 R 5.413(.I)-.65 G 2.913(fi)302.161 652.4 S 2.913
+(te)311.184 652.4 S .413(xists, the message is)321.167 652.4 R F2(not)2.913 E
+F1 .412(sent to that user)2.913 F 2.912(,b)-.4 G(ut)496.22 652.4 Q .745
+(rather to the list of addresses in that \214le.)117 664.4 R .746
+(Often this list will contain only one address, and the)5.746 F
+(feature will be used for netw)117 676.4 Q(ork mail forw)-.1 E(arding.)-.1 E
+.32 LW 76 686 72 686 DL 80 686 76 686 DL 84 686 80 686 DL 88 686 84 686 DL 92
+686 88 686 DL 96 686 92 686 DL 100 686 96 686 DL 104 686 100 686 DL 108 686 104
+686 DL 112 686 108 686 DL 116 686 112 686 DL 120 686 116 686 DL 124 686 120 686
+DL 128 686 124 686 DL 132 686 128 686 DL 136 686 132 686 DL 140 686 136 686 DL
+144 686 140 686 DL 148 686 144 686 DL 152 686 148 686 DL 156 686 152 686 DL 160
+686 156 686 DL 164 686 160 686 DL 168 686 164 686 DL 172 686 168 686 DL 176 686
+172 686 DL 180 686 176 686 DL 184 686 180 686 DL 188 686 184 686 DL 192 686 188
+686 DL 196 686 192 686 DL 200 686 196 686 DL 204 686 200 686 DL 208 686 204 686
+DL 212 686 208 686 DL 216 686 212 686 DL/F4 5/Times-Roman@0 SF(2)93.6 696.4 Q
+/F5 8/Times-Roman@0 SF(Disclaimer: Some special processing is done after re)3.2
+I(writing local names; see belo)-.2 E -.52(w.)-.2 G F0 -1(Ve)72 756 S
+(rsion 8.2)1 E(USENIX \255 J)249.805 756 Q(an 83)-.15 E(Last Mod 11/27/93)
+424.55 756 Q EP
+%%Page: 6 6
+%%BeginPageSetup
+BP
+%%EndPageSetup
+/F0 10/Times-Bold@0 SF(Mail Systems and Addr)72 60 Q(essing in 4.2bsd)-.18 E(6)
+499 60 Q/F1 10/Times-Roman@0 SF -.15(Fo)142 96 S(rw).15 E 1.152
+(arding also permits a user to specify a pri)-.1 F -.25(va)-.25 G 1.151
+(te incoming mailer).25 F 6.151(.F)-.55 G 1.151(or e)437.348 96 R 1.151
+(xample, for)-.15 F(-)-.2 E -.1(wa)117 108 S(rding to:).1 E -2.5 .833("| /)157
+124.2 T(usr/local/ne)-.833 E(wmail myname")-.25 E(will use a dif)117 140.4 Q
+(ferent incoming mailer)-.25 E(.)-.55 E F0 2.5(3.3.3. Inclusion)102 164.4 R F1
+(Inclusion is speci\214ed in RFC 733 [Crock)142 180.6 Q(er77] syntax:)-.1 E
+(:Include: pathname)157 196.8 Q .391
+(An address of this form reads the \214le speci\214ed by)117 213 R/F2 10
+/Times-Italic@0 SF(pathname)2.891 E F1 .391
+(and sends to all users listed in that)2.891 F(\214le.)117 225 Q .645
+(The intent is)142 241.2 R F2(not)3.145 E F1 .644
+(to support direct use of this feature, b)3.145 F .644
+(ut rather to use this as a subset of)-.2 F 2.5(aliasing. F)117 253.2 R(or e)
+-.15 E(xample, an alias of the form:)-.15 E
+(project: :include:/usr/project/userlist)157 269.4 Q 1.93(is a method of letti\
+ng a project maintain a mailing list without interaction with the system)117
+285.6 R(administration, e)117 297.6 Q -.15(ve)-.25 G 2.5(ni).15 G 2.5(ft)203.54
+297.6 S(he alias \214le is protected.)212.15 297.6 Q 2.025
+(It is not necessary to reb)142 313.8 R 2.025(uild the inde)-.2 F 4.524(xo)-.15
+G 4.524(nt)317.828 313.8 S 2.024(he alias database when a :include: list is)
+330.132 313.8 R(changed.)117 325.8 Q F0 2.5(3.4. Message)87 349.8 R(Collection)
+2.5 E F1 .857(Once all recipient addresses are parsed and v)127 366 R .857
+(eri\214ed, the message is collected.)-.15 F .857(The message)5.857 F .574
+(comes in tw)102 378 R 3.074(op)-.1 G .574
+(arts: a message header and a message body)164.452 378 R 3.074(,s)-.65 G .574
+(eparated by a blank line.)349.734 378 R .573(The body is)5.574 F
+(an uninterpreted sequence of te)102 390 Q(xt lines.)-.15 E
+(The header is formated as a series of lines of the form)127 406.2 Q
+(\214eld-name: \214eld-v)178 422.4 Q(alue)-.25 E(Field-v)102 438.6 Q 1.366
+(alue can be split across lines by starting the follo)-.25 F 1.366
+(wing lines with a space or a tab)-.25 F 6.366(.S)-.4 G(ome)486.78 438.6 Q .211
+(header \214elds ha)102 450.6 R .511 -.15(ve s)-.2 H .211
+(pecial internal meaning, and ha).15 F .511 -.15(ve a)-.2 H .211
+(ppropriate special processing.).15 F .21(Other headers)5.21 F
+(are simply passed through.)102 462.6 Q
+(Some header \214elds may be added automatically)5 E 2.5(,s)-.65 G
+(uch as time stamps.)413.53 462.6 Q F0 2.5(4. THE)72 486.6 R(UUCP PR)2.5 E
+(OBLEM)-.3 E F1 .43(Of particular interest is the UUCP netw)112 502.8 R 2.93
+(ork. The)-.1 F -.15(ex)2.93 G .43(plicit routing used in the UUCP en).15 F
+(vironment)-.4 E .909(causes a number of serious problems.)87 514.8 R .909
+(First, gi)5.909 F .908(ving out an address is impossible without kno)-.25 F
+.908(wing the)-.25 F .453(address of your potential correspondent.)87 526.8 R
+.454(This is typically handled by specifying the address relati)5.453 F .754
+-.15(ve t)-.25 H(o).15 E 1.208(some \231well-kno)87 538.8 R 1.208
+(wn\232 host \(e.g., ucb)-.25 F -.25(va)-.15 G 3.708(xo).25 G 3.708(rd)253.47
+538.8 S(ecv)265.508 538.8 Q 3.708(ax\). Second,)-.25 F 1.207(it is often dif)
+3.708 F 1.207(\214cult to compute the set of)-.25 F .157
+(addresses to reply to without some kno)87 550.8 R .157
+(wledge of the topology of the netw)-.25 F 2.657(ork. Although)-.1 F .157
+(it may be easy)2.657 F .352(for a human being to do this under man)87 562.8 R
+2.851(yc)-.15 G .351(ircumstances, a program does not ha)259.713 562.8 R .651
+-.15(ve e)-.2 H .351(qually sophisticated).15 F 1.153(heuristics b)87 574.8 R
+1.153(uilt in.)-.2 F 1.154(Third, certain addresses will become painfully and \
+unnecessarily long, as when a)6.153 F .406(message is routed through man)87
+586.8 R 2.906(yh)-.15 G .406(osts in the USENET)225.81 586.8 R 5.406(.A)-.74 G
+.406(nd \214nally)322.804 586.8 R 2.905(,c)-.65 G .405(ertain \231mix)370.465
+586.8 R .405(ed domain\232 addresses)-.15 F
+(are impossible to parse unambiguously \212 e.g.,)87 598.8 Q(decv)127 615 Q
+(ax!ucb)-.25 E -.25(va)-.15 G(x!lbl-h!user@LBL-CSAM).25 E .378(might ha)87
+631.2 R .678 -.15(ve m)-.2 H(an).15 E 2.878(yp)-.15 G .379
+(ossible resolutions, depending on whether the message w)164.574 631.2 R .379
+(as \214rst routed to decv)-.1 F .379(ax or)-.25 F(to LBL-CSAM.)87 643.2 Q 2.32
+-.8(To s)112 659.4 T(olv).8 E 3.22(et)-.15 G .72
+(his problem, the UUCP syntax w)152.49 659.4 R .719(ould ha)-.1 F 1.019 -.15
+(ve t)-.2 H 3.219(ob).15 G 3.219(ec)346.956 659.4 S .719
+(hanged to use addresses rather than)359.055 659.4 R 3.718(routes. F)87 671.4 R
+1.218(or e)-.15 F 1.218(xample, the address \231decv)-.15 F(ax!ucb)-.25 E -.25
+(va)-.15 G 1.218(x!eric\232 might be e).25 F 1.218(xpressed as \231eric@ucb)
+-.15 F -.25(va)-.15 G(x.UUCP\232).25 E .079(\(with the hop through decv)87
+683.4 R .079(ax implied\).)-.25 F .079(This address w)5.079 F .078
+(ould itself be a domain-based address; for e)-.1 F(xam-)-.15 E
+(ple, an address might be of the form:)87 695.4 Q(mark@d.cbosg.btl.UUCP)127
+711.6 Q F0 -1(Ve)72 756 S(rsion 8.2)1 E(USENIX \255 J)249.805 756 Q(an 83)-.15
+E(Last Mod 11/27/93)424.55 756 Q EP
+%%Page: 7 7
+%%BeginPageSetup
+BP
+%%EndPageSetup
+/F0 10/Times-Bold@0 SF(Mail Systems and Addr)72 60 Q(essing in 4.2bsd)-.18 E(7)
+499 60 Q/F1 10/Times-Roman@0 SF .311(Hosts outside of Bell T)87 96 R .311
+(elephone Laboratories w)-.7 F .311(ould then only need to kno)-.1 F 2.811(wh)
+-.25 G .811 -.25(ow t)402.982 96 T 2.811(og).25 G .312(et to a designated)
+433.354 96 R(BTL relay)87 108 Q 2.5(,a)-.65 G(nd the BTL topology w)137.17 108
+Q(ould only be maintained inside Bell.)-.1 E .543(There are three major proble\
+ms associated with turning UUCP addresses into something reason-)112 124.2 R
+.465(able: de\214ning the namespace, creating and propag)87 136.2 R .465
+(ating the necessary softw)-.05 F .466(are, and b)-.1 F .466(uilding and main-)
+-.2 F(taining the database.)87 148.2 Q F0 2.5(4.1. De\214ning)87 172.2 R
+(the Namespace)2.5 E F1 1.015(Putting all UUCP hosts into a \215at namespace \
+\(e.g., \231...@host.UUCP\232\) is not practical for a)127 188.4 R .222
+(number of reasons.)102 200.4 R .222(First, with o)5.222 F -.15(ve)-.15 G 2.722
+(r1).15 G .222(600 sites already)253.292 200.4 R 2.722(,a)-.65 G .222
+(nd \(with the increasing a)329.958 200.4 R -.25(va)-.2 G .222
+(ilability of ine).25 F(x-)-.15 E(pensi)102 212.4 Q 1.973 -.15(ve m)-.25 H
+1.673(icrocomputers and autodialers\) se).15 F -.15(ve)-.25 G 1.672
+(ral thousand more coming within a fe).15 F 4.172(wy)-.25 G 1.672(ears, the)
+469.008 212.4 R .078
+(database update problem is simply intractable if the namespace is \215at.)102
+224.4 R .078(Second, there are almost cer)5.078 F(-)-.2 E 2.446
+(tainly name con\215icts today)102 236.4 R 7.446(.T)-.65 G 2.446
+(hird, as the number of sites gro)232.794 236.4 R 4.946(wt)-.25 G 2.446
+(he names become e)386.316 236.4 R -.15(ve)-.25 G 4.946(rl).15 G(ess)491.78
+236.4 Q(mnemonic.)102 248.4 Q .534(It seems ine)127 264.6 R .535
+(vitable that there be some sort of naming authority for the set of top le)-.25
+F -.15(ve)-.25 G 3.035(ln).15 G(ames)483.45 264.6 Q .157
+(in the UUCP domain, as unpleasant a possibility as that may seem.)102 276.6 R
+.157(It will simply not be possible to)5.157 F(ha)102 288.6 Q .536 -.15(ve o)
+-.2 H .236(ne host resolving all names.).15 F .236(It may ho)5.236 F(we)-.25 E
+-.15(ve)-.25 G 2.736(rb).15 G 2.736(ep)316.144 288.6 S .236
+(ossible to handle this in a f)328.32 288.6 R .237(ashion similar to)-.1 F
+1.582(that of assigning names of ne)102 300.6 R 1.582(wsgroups in USENET)-.25 F
+6.582(.H)-.74 G -.25(ow)334.758 300.6 S -2.15 -.25(ev e).25 H 2.382 -.4(r, i)
+.25 H 4.082(tw).4 G 1.582(ill be essential to encourage)386.582 300.6 R -2.15
+-.25(ev e)102 312.6 T .52(ryone to become subdomains of an e).25 F .52
+(xisting domain whene)-.15 F -.15(ve)-.25 G 3.02(rp).15 G .52(ossible \212 e)
+374.85 312.6 R -.15(ve)-.25 G 3.02(nt).15 G .52(hough this will)442.95 312.6 R
+.077(certainly bruise some e)102 324.6 R 2.577(gos. F)-.15 F .077(or e)-.15 F
+.077(xample, if a ne)-.15 F 2.577(wh)-.25 G .076
+(ost named \231blid\232 were to be added to the UUCP)310.843 324.6 R(netw)102
+336.6 Q .65(ork, it w)-.1 F .651(ould probably actually be addressed as \231d.\
+bli.UUCP\232 \(i.e., as host \231d\232 in the pseudo-)-.1 F
+(domain \231bli\232 rather than as host \231blid\232 in the UUCP domain\).)102
+348.6 Q F0 2.5(4.2. Cr)87 372.6 R(eating and Pr)-.18 E(opagating the Softwar)
+-.18 E(e)-.18 E F1 .078(The softw)127 388.8 R .078
+(are required to implement a consistent namespace is relati)-.1 F -.15(ve)-.25
+G .077(ly tri).15 F 2.577(vial. T)-.25 F .277 -.1(wo m)-.8 H(odules).1 E
+(are needed, one to handle incoming mail and one to handle outgoing mail.)102
+400.8 Q 1.136(The incoming module must be prepared to handle either old or ne)
+127 417 R 3.636(ws)-.25 G 1.136(tyle addresses.)416.448 417 R(Ne)6.136 E(w-)
+-.25 E .025(style addresses can be passed through unchanged.)102 429 R .024
+(Old style addresses must be turned into ne)5.025 F 2.524(ws)-.25 G(tyle)489
+429 Q(addresses where possible.)102 441 Q 2.247
+(The outgoing module is slightly trickier)127 457.2 R 7.247(.I)-.55 G 4.747(tm)
+309.932 457.2 S 2.247(ust do a database lookup on the recipient)325.239 457.2 R
+.823(addresses \(passed on the command line\) to determine what hosts to send \
+the message to.)102 469.2 R .823(If those)5.823 F .023(hosts do not accept ne)
+102 481.2 R .024(w-style addresses, it must transform all addresses in the hea\
+der of the message)-.25 F(into old style using the database lookup.)102 493.2 Q
+1.197(Both of these modules are straightforw)127 509.4 R 1.197(ard e)-.1 F
+1.197(xcept for the issue of modifying the header)-.15 F 6.197(.I)-.55 G(t)
+501.22 509.4 Q .944
+(seems prudent to choose one format for the message headers.)102 521.4 R -.15
+(Fo)5.944 G 3.444(ran).15 G .944(umber of reasons, Berk)391.448 521.4 R(ele)-.1
+E(y)-.15 E .824(has elected to use the ARP)102 533.4 R .824
+(ANET protocols for message formats.)-.92 F(Ho)5.823 E(we)-.25 E -.15(ve)-.25 G
+1.623 -.4(r, t).15 H .823(his protocol is some-).4 F(what dif)102 545.4 Q
+(\214cult to parse.)-.25 E(Propag)127 561.6 Q 1.903(ation is some)-.05 F 1.903
+(what more dif)-.25 F 4.403(\214cult. There)-.25 F 1.903(are a lar)4.403 F
+1.903(ge number of hosts connected to)-.18 F .812(UUCP that will w)102 573.6 R
+.811(ant to run completely standard systems \(for v)-.1 F .811
+(ery good reasons\).)-.15 F .811(The strate)5.811 F .811(gy is)-.15 F
+(not to con)102 585.6 Q -.15(ve)-.4 G(rt the entire netw).15 E
+(ork \212 only enough of it it alle)-.1 E(viate the problem.)-.25 E F0 2.5
+(4.3. Building)87 609.6 R(and Maintaining the Database)2.5 E F1 .127
+(This is by f)127 625.8 R .127(ar the most dif)-.1 F .128(\214cult problem.)
+-.25 F 2.628(Ap)5.128 G .128(rototype for this database already e)309.736 625.8
+R .128(xists, b)-.15 F .128(ut it is)-.2 F
+(maintained by hand and does not pretend to be complete.)102 637.8 Q .701(This\
+ problem will be reduced considerably if people choose to group their hosts in\
+to subdo-)127 654 R 3.219(mains. This)102 666 R -.1(wo)3.219 G .719
+(uld require a global update only when a ne).1 F 3.22(wt)-.25 G .72(op le)
+356.47 666 R -.15(ve)-.25 G 3.22(ld).15 G .72(omain joined the netw)396.95 666
+R(ork.)-.1 E 2.805(Am)102 678 S .305
+(essage to a host in a subdomain could simply be routed to a kno)119.805 678 R
+.304(wn domain g)-.25 F(ate)-.05 E -.1(wa)-.25 G 2.804(yf).1 G .304(or further)
+465.656 678 R 3.073(processing. F)102 690 R .573(or e)-.15 F .573(xample, the \
+address \231eric@a.bli.UUCP\232 might be routed to the \231bli\232 g)-.15 F
+(ate)-.05 E -.1(wa)-.25 G 3.074(yf).1 G(or)495.67 690 Q(redistrib)102 702 Q
+1.376(ution; ne)-.2 F 3.876(wh)-.25 G 1.375
+(osts could be added within BLI without notifying the rest of the w)187.632 702
+R 3.875(orld. Of)-.1 F(course, other hosts)102 714 Q/F2 10/Times-Italic@0 SF
+(could)2.5 E F1(be noti\214ed as an ef)2.5 E(\214cienc)-.25 E 2.5(ym)-.15 G
+(easure.)321.01 714 Q F0 -1(Ve)72 756 S(rsion 8.2)1 E(USENIX \255 J)249.805 756
+Q(an 83)-.15 E(Last Mod 11/27/93)424.55 756 Q EP
+%%Page: 8 8
+%%BeginPageSetup
+BP
+%%EndPageSetup
+/F0 10/Times-Bold@0 SF(Mail Systems and Addr)72 60 Q(essing in 4.2bsd)-.18 E(8)
+499 60 Q/F1 10/Times-Roman@0 SF .966(There may be more than one domain g)127 96
+R(ate)-.05 E -.1(wa)-.25 G 4.767 -.65(y. A).1 H .967
+(domain such as BTL, for instance, might)4.117 F(ha)102 108 Q .653 -.15(ve a d)
+-.2 H .353(ozen g).15 F(ate)-.05 E -.1(wa)-.25 G .353(ys to the outside w).1 F
+.352(orld; a non-BTL site could choose the closest g)-.1 F(ate)-.05 E -.1(wa)
+-.25 G 4.152 -.65(y. T).1 H(he).65 E .308(only restriction w)102 120 R .308
+(ould be that all g)-.1 F(ate)-.05 E -.1(wa)-.25 G .308
+(ys maintain a consistent vie).1 F 2.808(wo)-.25 G 2.808(ft)390.998 120 S .308
+(he domain the)399.916 120 R 2.808(yr)-.15 G(epresent.)468.18 120 Q F0 2.5
+(4.4. Logical)87 144 R(Structur)2.5 E(e)-.18 E F1(Logically)127 160.2 Q 3.803
+(,d)-.65 G 1.303(omains are or)175.983 160.2 R -.05(ga)-.18 G 1.303
+(nized into a tree.).05 F 1.303(There need not be a host actually associated)
+6.303 F .462(with each le)102 172.2 R -.15(ve)-.25 G 2.962(li).15 G 2.962(nt)
+168.806 172.2 S .462(he tree \212 for e)179.548 172.2 R .462
+(xample, there will be no host associated with the name \231UUCP)-.15 F -.7
+<2e9a>-1.11 G(Similarly)102 184.2 Q 3.115(,a)-.65 G 3.115(no)148.635 184.2 S
+-2.19 -.18(rg a)161.75 184.2 T .614
+(nization might group names together for administrati).18 F .914 -.15(ve r)-.25
+H .614(easons; for e).15 F .614(xample, the)-.15 F(name)102 196.2 Q
+(CAD.research.BigCorp.UUCP)142 212.4 Q(might not actually ha)102 228.6 Q .3
+-.15(ve a h)-.2 H(ost representing \231research.).15 E<9a>-.7 E(Ho)127 244.8 Q
+(we)-.25 E -.15(ve)-.25 G 1.531 -.4(r, i).15 H 3.231(tm).4 G .731
+(ay frequently be con)184.902 244.8 R -.15(ve)-.4 G .731(nient to ha).15 F
+1.031 -.15(ve a h)-.2 H .732(ost or hosts that \231represent\232 a domain.).15
+F -.15(Fo)102 256.8 S 3.466(re).15 G .966(xample, if a single host e)123.496
+256.8 R .966(xists that represents Berk)-.15 F(ele)-.1 E 2.266 -.65(y, t)-.15 H
+.966(hen mail from outside Berk).65 F(ele)-.1 E 3.466(yc)-.15 G(an)494.56 256.8
+Q(forw)102 268.8 Q .796
+(ard mail to that host for further resolution without kno)-.1 F .796(wing Berk)
+-.25 F(ele)-.1 E(y')-.15 E 3.296(s\()-.55 G .797(rather v)417.066 268.8 R .797
+(olatile\) topol-)-.2 F(ogy)102 280.8 Q 5(.T)-.65 G(his is not unlik)129.96
+280.8 Q 2.5(et)-.1 G(he operation of the telephone netw)198.76 280.8 Q(ork.)-.1
+E .053(This may also be useful inside certain lar)127 297 R .053(ge domains.)
+-.18 F -.15(Fo)5.053 G 2.553(re).15 G .053(xample, at Berk)365.352 297 R(ele)
+-.1 E 2.553(yi)-.15 G 2.553(tm)450.801 297 S .053(ay be pre-)463.914 297 R .722
+(sumed that most hosts kno)102 309 R 3.222(wa)-.25 G .722
+(bout other hosts inside the Berk)225.64 309 R(ele)-.1 E 3.223(yd)-.15 G 3.223
+(omain. But)380.825 309 R .723(if the)3.223 F 3.223(yp)-.15 G .723(rocess an)
+466.347 309 R .405(address that is unkno)102 321 R .405(wn, the)-.25 F 2.905
+(yc)-.15 G .405(an pass it \231upstairs\232 for further e)229.165 321 R 2.905
+(xamination. Thus)-.15 F .405(as ne)2.905 F 2.905(wh)-.25 G .405(osts are)
+473.325 321 R .488(added only one host \(the domain master\))102 333 R/F2 10
+/Times-Italic@0 SF(must)2.989 E F1 .489
+(be updated immediately; other hosts can be updated)2.989 F(as con)102 345 Q
+-.15(ve)-.4 G(nient.).15 E .583(Ideally this name resolution process w)127
+361.2 R .583(ould be performed by a name serv)-.1 F .582
+(er \(e.g., [Su82b]\) to)-.15 F -.2(avo)102 373.2 S .507(id unnecessary cop).2
+F .507(ying of the message.)-.1 F(Ho)5.507 E(we)-.25 E -.15(ve)-.25 G 1.307 -.4
+(r, i).15 H 3.007(nab).4 G .507(atch netw)346.623 373.2 R .508
+(ork such as UUCP this could)-.1 F(result in unnecessary delays.)102 385.2 Q F0
+2.5(5. COMP)72 409.2 R(ARISON WITH DELIVERMAIL)-.74 E F2(Sendmail)112 425.4 Q
+F1(is an outgro)2.5 E(wth of)-.25 E F2(delivermail)2.5 E F1 5(.T)C
+(he primary dif)286.18 425.4 Q(ferences are:)-.25 E 12.5(\(1\) Con\214guration)
+92 441.6 R .573(information is not compiled in.)3.073 F .572
+(This change simpli\214es man)5.572 F 3.072(yo)-.15 G 3.072(ft)433.684 441.6 S
+.572(he problems of)442.866 441.6 R(mo)118.66 453.6 Q(ving to other machines.)
+-.15 E(It also allo)5 E(ws easy deb)-.25 E(ugging of ne)-.2 E 2.5(wm)-.25 G
+(ailers.)388.06 453.6 Q 12.5(\(2\) Address)92 469.8 R .491
+(parsing is more \215e)2.991 F 2.991(xible. F)-.15 F .491(or e)-.15 F(xample,)
+-.15 E F2(delivermail)2.992 E F1 .492(only supported one g)2.992 F(ate)-.05 E
+-.1(wa)-.25 G 2.992(yt).1 G 2.992(oa)481.718 469.8 S -.15(ny)494.15 469.8 S
+(netw)118.66 481.8 Q(ork, whereas)-.1 E F2(sendmail)2.5 E F1(can be sensiti)2.5
+E .3 -.15(ve t)-.25 H 2.5(oh).15 G(ost names and reroute to dif)310.9 481.8 Q
+(ferent g)-.25 E(ate)-.05 E -.1(wa)-.25 G(ys.).1 E 12.5(\(3\) F)92 498 R(orw)
+-.15 E 2.878(arding and :include: features eliminate the requirement that the \
+system alias \214le be)-.1 F 1.073(writable by an)118.66 510 R 3.573(yu)-.15 G
+1.073
+(ser \(or that an update program be written, or that the system administration)
+191.439 510 R(mak)118.66 522 Q 2.5(ea)-.1 G(ll changes\).)147.16 522 Q(\(4\))92
+538.2 Q F2(Sendmail)118.66 538.2 Q F1 .443
+(supports message batching across netw)2.944 F .443
+(orks when a message is being sent to multiple)-.1 F(recipients.)118.66 550.2 Q
+12.5(\(5\) A)92 566.4 R 1.945(mail queue is pro)4.445 F 1.946(vided in)-.15 F
+F2(sendmail.)4.446 E F1 1.946(Mail that cannot be deli)6.946 F -.15(ve)-.25 G
+1.946(red immediately b).15 F 1.946(ut can)-.2 F .439(potentially be deli)
+118.66 578.4 R -.15(ve)-.25 G .438
+(red later is stored in this queue for a later retry).15 F 5.438(.T)-.65 G .438
+(he queue also pro)404.088 578.4 R .438(vides a)-.15 F -.2(bu)118.66 590.4 S
+-.25(ff).2 G .838(er ag).25 F .839(ainst system crashes; after the message has\
+ been collected it may be reliably redeli)-.05 F(v-)-.25 E(ered e)118.66 602.4
+Q -.15(ve)-.25 G 2.5(ni).15 G 2.5(ft)162.13 602.4 S
+(he system crashes during the initial deli)170.74 602.4 Q -.15(ve)-.25 G(ry).15
+E(.)-.65 E(\(6\))92 618.6 Q F2(Sendmail)118.66 618.6 Q F1 1.351(uses the netw)
+3.851 F 1.351(orking support pro)-.1 F 1.351(vided by 4.2BSD to pro)-.15 F 1.35
+(vide a direct interf)-.15 F 1.35(ace net-)-.1 F -.1(wo)118.66 630.6 S .283
+(rks such as the ARP).1 F .284
+(ANET and/or Ethernet using SMTP \(the Simple Mail T)-.92 F .284
+(ransfer Protocol\))-.35 F -.15(ove)118.66 642.6 S 2.5(raT).15 G
+(CP/IP connection.)151.68 642.6 Q F0 -1(Ve)72 756 S(rsion 8.2)1 E
+(USENIX \255 J)249.805 756 Q(an 83)-.15 E(Last Mod 11/27/93)424.55 756 Q EP
+%%Page: 9 9
+%%BeginPageSetup
+BP
+%%EndPageSetup
+/F0 10/Times-Roman@0 SF(REFERENCES)264.105 132 Q([Crock)87 148.2 Q 56.73
+(er77] Crock)-.1 F(er)-.1 E 3.535(,D)-.4 G 3.535(.H)239.965 148.2 S 1.035(., V)
+253.22 148.2 R 1.035(ittal, J. J., Pogran, K. T)-.6 F 1.035
+(., and Henderson, D. A. Jr)-.74 F(.,)-.55 E/F1 10/Times-Italic@0 SF(Stan-)
+3.535 E(dar)195 160.2 Q 2.627(df)-.37 G .127(or the F)218.927 160.2 R .127
+(ormat of ARP)-1.05 F 2.627(AN)-.9 G .128(etwork T)320.112 160.2 R -.2(ex)-.92
+G 2.628(tM).2 G(essa)377.018 160.2 Q -.1(ge)-.1 G(s.).1 E F0 .128
+(RFC 733, NIC 41952.)5.128 F(In [Feinler78].)195 172.2 Q(No)5 E -.15(ve)-.15 G
+(mber 1977.).15 E([Crock)87 188.4 Q 56.73(er82] Crock)-.1 F(er)-.1 E 4.272(,D)
+-.4 G 4.272(.H)240.702 188.4 S(.,)254.694 188.4 Q F1(Standar)4.272 E 4.272(df)
+-.37 G 1.772(or the F)307.318 188.4 R 1.772(ormat of Arpa Internet T)-1.05 F
+-.2(ex)-.92 G 4.271(tM).2 G(essa)471.15 188.4 Q -.1(ge)-.1 G(s.).1 E F0 .025
+(RFC 822.)195 200.4 R(Netw)5.025 E .025(ork Information Center)-.1 F 2.526(,S)
+-.4 G .026(RI International, Menlo P)363.506 200.4 R .026(ark, Cali-)-.15 F 2.5
+(fornia. August)195 212.4 R(1982.)2.5 E 60.51([Feinler78] Feinler)87 228.6 R
+2.938(,E)-.4 G .438(., and Postel, J.)234.478 228.6 R(\(eds.\),)5.438 E F1(ARP)
+2.938 E .438(ANET Pr)-.9 F .438(otocol Handbook.)-.45 F F0 .438(NIC 7104,)5.438
+F(Netw)195 240.6 Q 3.011(ork Information Center)-.1 F 5.511(,S)-.4 G 3.012
+(RI International, Menlo P)328.513 240.6 R 3.012(ark, California.)-.15 F(1978.)
+195 252.6 Q([No)87 268.8 Q 59.65(witz78] No)-.25 F .479
+(witz, D. A., and Lesk, M. E.,)-.25 F F1 2.978(AD)2.978 G .478
+(ial-Up Network of UNIX Systems.)344.67 268.8 R F0(Bell)5.478 E 3.528
+(Laboratories. In)195 280.8 R 1.029(UNIX Programmer')3.528 F 3.529(sM)-.55 G
+1.029(anual, Se)363.524 280.8 R -.15(ve)-.25 G 1.029(nth Edition, V).15 F 1.029
+(olume 2.)-1.29 F(August, 1978.)195 292.8 Q 55.5([Schmidt79] Schmidt,)87 309 R
+(E.,)2.631 E F1 .131(An Intr)2.631 F .131(oduction to the Berk)-.45 F(ele)-.1 E
+2.631(yN)-.3 G(etwork.)382.277 309 Q F0(Uni)5.131 E -.15(ve)-.25 G .131
+(rsity of Califor).15 F(-)-.2 E(nia, Berk)195 321 Q(ele)-.1 E 2.5(yC)-.15 G 2.5
+(alifornia. 1979.)257.24 321 R 59.95([Shoens79] Shoens,)87 337.2 R(K.,)3.227 E
+F1 .728(Mail Refer)3.227 F .728(ence Manual.)-.37 F F0(Uni)5.728 E -.15(ve)-.25
+G .728(rsity of California, Berk).15 F(ele)-.1 E 4.528 -.65(y. I)-.15 H(n).65 E
+3.478(UNIX Programmer')195 349.2 R 5.977(sM)-.55 G 3.477(anual, Se)297.495
+349.2 R -.15(ve)-.25 G 3.477(nth Edition, V).15 F 3.477(olume 2C.)-1.29 F
+(December)8.477 E(1979.)195 361.2 Q 52.72([Solomon81] Solomon,)87 377.4 R .251
+(M., Landweber)2.75 F 2.751(,L)-.4 G .251(., and Neuhengen, D.,)308.952 377.4 R
+F1 .251(The Design of the CSNET)2.751 F .397(Name Server)195 389.4 R(.)-1.11 E
+F0 2.896(CS-DN-2. Uni)5.397 F -.15(ve)-.25 G .396(rsity of W).15 F .396
+(isconsin, Madison.)-.4 F .396(October 1981.)5.396 F 73.84([Su82a] Su,)87 405.6
+R(Za)2.844 E .344(w-Sing, and Postel, Jon,)-.15 F F1 .344
+(The Domain Naming Con)2.844 F .344(vention for Internet)-.4 F 2.71
+(User Applications.)195 417.6 R F0 5.21(RFC819. Netw)7.71 F 2.71
+(ork Information Center)-.1 F 5.21(,S)-.4 G 2.71(RI Interna-)457.14 417.6 R
+(tional, Menlo P)195 429.6 Q(ark, California.)-.15 E(August 1982.)5 E 73.28
+([Su82b] Su,)87 445.8 R(Za)4.174 E(w-Sing,)-.15 E F1 4.174(AD)4.174 G(istrib)
+275.702 445.8 Q 1.675(uted System for Internet Name Service)-.2 F(.)-.15 E F0
+(RFC830.)6.675 E(Netw)195 457.8 Q 3.012(ork Information Center)-.1 F 5.512(,S)
+-.4 G 3.011(RI International, Menlo P)328.516 457.8 R 3.011(ark, California.)
+-.15 F(October 1982.)195 469.8 Q/F2 10/Times-Bold@0 SF(Mail Systems and Addr)72
+756 Q(essing in 4.2bsd)-.18 E(9)499 756 Q EP
+%%Trailer
+end
+%%EOF
diff --git a/usr.sbin/sendmail/mailstats/Makefile b/usr.sbin/sendmail/mailstats/Makefile
new file mode 100644
index 0000000..d6a04f0
--- /dev/null
+++ b/usr.sbin/sendmail/mailstats/Makefile
@@ -0,0 +1,8 @@
+# @(#)Makefile 8.1 (Berkeley) 6/7/93
+
+PROG= mailstats
+CFLAGS+=-I${.CURDIR}/../src
+NOMAN= noman
+
+.include "../../Makefile.inc"
+.include <bsd.prog.mk>
diff --git a/usr.sbin/sendmail/mailstats/mailstats.c b/usr.sbin/sendmail/mailstats/mailstats.c
new file mode 100644
index 0000000..1e11b01
--- /dev/null
+++ b/usr.sbin/sendmail/mailstats/mailstats.c
@@ -0,0 +1,209 @@
+/*
+ * Copyright (c) 1983 Eric P. Allman
+ * Copyright (c) 1988, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ */
+
+#ifndef lint
+static char copyright[] =
+"@(#) Copyright (c) 1988, 1993\n\
+ The Regents of the University of California. All rights reserved.\n";
+#endif /* not lint */
+
+#ifndef lint
+static char sccsid[] = "@(#)mailstats.c 8.3 (Berkeley) 12/27/93";
+#endif /* not lint */
+
+#include <sendmail.h>
+#include <mailstats.h>
+#include <pathnames.h>
+
+#define MNAMELEN 20 /* max length of mailer name */
+
+main(argc, argv)
+ int argc;
+ char **argv;
+{
+ extern char *optarg;
+ extern int optind;
+ struct statistics stat;
+ register int i;
+ int mno;
+ int ch, fd;
+ char *sfile;
+ char *cfile;
+ FILE *cfp;
+ bool mnames;
+ long frmsgs = 0, frbytes = 0, tomsgs = 0, tobytes = 0;
+ char mtable[MAXMAILERS][MNAMELEN+1];
+ char sfilebuf[100];
+ char buf[MAXLINE];
+ extern char *ctime();
+
+ cfile = _PATH_SENDMAILCF;
+ sfile = NULL;
+ mnames = TRUE;
+ while ((ch = getopt(argc, argv, "C:f:o")) != EOF)
+ {
+ switch (ch)
+ {
+ case 'C':
+ cfile = optarg;
+ break;
+
+ case 'f':
+ sfile = optarg;
+ break;
+
+ case 'o':
+ mnames = FALSE;
+ break;
+
+ case '?':
+ default:
+ usage:
+ fputs("usage: mailstats [-C cffile] [-f stfile]\n", stderr);
+ exit(EX_USAGE);
+ }
+ }
+ argc -= optind;
+ argv += optind;
+
+ if (argc != 0)
+ goto usage;
+
+ if ((cfp = fopen(cfile, "r")) == NULL)
+ {
+ fprintf(stderr, "mailstats: ");
+ perror(cfile);
+ exit(EX_NOINPUT);
+ }
+
+ mno = 0;
+ (void) strcpy(mtable[mno++], "prog");
+ (void) strcpy(mtable[mno++], "*file*");
+ (void) strcpy(mtable[mno++], "*include*");
+
+ while (fgets(buf, sizeof(buf), cfp) != NULL)
+ {
+ register char *b;
+ char *s;
+ register char *m;
+
+ b = buf;
+ switch (*b++)
+ {
+ case 'M': /* mailer definition */
+ break;
+
+ case 'O': /* option -- see if .st file */
+ if (*b++ != 'S')
+ continue;
+
+ /* yep -- save this */
+ strcpy(sfilebuf, b);
+ b = strchr(sfilebuf, '\n');
+ if (b != NULL)
+ *b = '\0';
+ if (sfile == NULL)
+ sfile = sfilebuf;
+
+ default:
+ continue;
+ }
+
+ if (mno >= MAXMAILERS)
+ {
+ fprintf(stderr,
+ "Too many mailers defined, %d max.\n",
+ MAXMAILERS);
+ exit(EX_SOFTWARE);
+ }
+ m = mtable[mno];
+ s = m + MNAMELEN; /* is [MNAMELEN+1] */
+ while (*b != ',' && !isspace(*b) && *b != '\0' && m < s)
+ *m++ = *b++;
+ *m = '\0';
+ for (i = 0; i < mno; i++)
+ {
+ if (strcmp(mtable[i], mtable[mno]) == 0)
+ break;
+ }
+ if (i == mno)
+ mno++;
+ }
+ (void) fclose(cfp);
+ for (; mno < MAXMAILERS; mno++)
+ mtable[mno][0]='\0';
+
+ if (sfile == NULL)
+ {
+ fprintf(stderr, "mailstats: no statistics file located\n");
+ exit (EX_OSFILE);
+ }
+
+ if ((fd = open(sfile, O_RDONLY)) < 0) {
+ fputs("mailstats: ", stderr);
+ perror(sfile);
+ exit(EX_NOINPUT);
+ }
+ if (read(fd, &stat, sizeof(stat)) != sizeof(stat) ||
+ stat.stat_size != sizeof(stat))
+ {
+ fputs("mailstats: file size changed.\n", stderr);
+ exit(EX_OSERR);
+ }
+
+ printf("Statistics from %s", ctime(&stat.stat_itime));
+ printf(" M msgsfr bytes_from msgsto bytes_to%s\n",
+ mnames ? " Mailer" : "");
+ for (i = 0; i < MAXMAILERS; i++)
+ {
+ if (stat.stat_nf[i] || stat.stat_nt[i])
+ {
+ printf("%2d %6ld %10ldK %6ld %10ldK", i,
+ stat.stat_nf[i], stat.stat_bf[i],
+ stat.stat_nt[i], stat.stat_bt[i]);
+ if (mnames)
+ printf(" %s", mtable[i]);
+ printf("\n");
+ frmsgs += stat.stat_nf[i];
+ frbytes += stat.stat_bf[i];
+ tomsgs += stat.stat_nt[i];
+ tobytes += stat.stat_bt[i];
+ }
+ }
+ printf("========================================\n");
+ printf(" T %6ld %10ldK %6ld %10ldK\n",
+ frmsgs, frbytes, tomsgs, tobytes);
+ exit(EX_OK);
+}
diff --git a/usr.sbin/sendmail/makemap/Makefile b/usr.sbin/sendmail/makemap/Makefile
new file mode 100644
index 0000000..462583a
--- /dev/null
+++ b/usr.sbin/sendmail/makemap/Makefile
@@ -0,0 +1,8 @@
+# @(#)Makefile 8.1 (Berkeley) 6/7/93
+
+PROG= makemap
+MAN8= makemap.0
+CFLAGS+=-I${.CURDIR}/../src -DNDBM -DNEWDB
+
+.include "../../Makefile.inc"
+.include <bsd.prog.mk>
diff --git a/usr.sbin/sendmail/makemap/makemap.8 b/usr.sbin/sendmail/makemap/makemap.8
new file mode 100644
index 0000000..2ee45c2
--- /dev/null
+++ b/usr.sbin/sendmail/makemap/makemap.8
@@ -0,0 +1,128 @@
+.\" Copyright (c) 1988, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)makemap.8 8.2 (Berkeley) 9/22/93
+.\"
+.Dd November 16, 1992
+.Dt MAKEMAP 8
+.Os BSD 4.4
+.Sh NAME
+.Nm makemap
+.Nd create database maps for sendmail
+.Sh SYNOPSIS
+.Nm
+.Op Fl N
+.Op Fl f
+.Op Fl o
+.Op Fl r
+.Op Fl v
+.Ar maptype
+.Ar mapname
+.Sh DESCRIPTION
+.Nm
+creates the database maps used by the keyed map lookups in
+.Xr sendmail 8 .
+It reads input from the standard input
+and outputs them to the indicated
+.Ar mapname .
+.Pp
+Depending on how it is compiled,
+.Nm
+handles up to three different database formats,
+selected using the
+.Ar maptype
+parameter.
+They may be
+.Bl -tag -width Fl
+.It Li dbm
+DBM format maps.
+This requires the
+.Xr ndbm 3
+library.
+.It Li btree
+B-Tree format maps.
+This requires the new Berkeley
+.Xr db 3
+library.
+.It Li hash
+Hash format maps.
+This also requires the
+.Xr db 3
+library.
+.El
+.Pp
+In all cases,
+.Nm
+reads lines from the standard input consisting of two
+words separated by white space.
+The first is the database key,
+the second is the value.
+The value may contain
+``%\fIn\fP''
+strings to indicated parameter substitution.
+Literal parentheses should be doubled
+(``%%'').
+Blank lines and lines beginning with ``#'' are ignored.
+.Ss Flags
+.Bl -tag -width Fl
+.It Fl N
+Include the null byte that terminates strings
+in the map.
+This must match the \-N flag in the sendmail.cf
+``K'' line.
+.It Fl f
+Normally all upper case letters in the key
+are folded to lower case.
+This flag disables that behaviour.
+This is intended to mesh with the
+\-f flag in the
+\fBK\fP
+line in sendmail.cf.
+The value is never case folded.
+.It Fl o
+Append to an old file.
+This allows you to augment an existing file.
+.It Fl r
+Allow replacement of existing keys.
+Normally
+.Nm
+complains if you repeat a key,
+and does not do the insert.
+.It Fl v
+Verbosely print what it is doing.
+.El
+.Sh SEE ALSO
+.Xr sendmail 8
+.Sh HISTORY
+The
+.Nm
+command appeared in
+.Bx 4.4 .
diff --git a/usr.sbin/sendmail/makemap/makemap.c b/usr.sbin/sendmail/makemap/makemap.c
new file mode 100644
index 0000000..f2d4aea
--- /dev/null
+++ b/usr.sbin/sendmail/makemap/makemap.c
@@ -0,0 +1,373 @@
+/*
+ * Copyright (c) 1992 Eric P. Allman.
+ * Copyright (c) 1992, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)makemap.c 8.6 (Berkeley) 11/22/93";
+#endif /* not lint */
+
+#include <stdio.h>
+#include <sysexits.h>
+#include <sys/types.h>
+#include <sys/file.h>
+#include <ctype.h>
+#include <string.h>
+#include "useful.h"
+#include "conf.h"
+
+#ifdef NDBM
+#include <ndbm.h>
+#endif
+
+#ifdef NEWDB
+#include <db.h>
+#endif
+
+enum type { T_DBM, T_BTREE, T_HASH, T_ERR, T_UNKNOWN };
+
+union dbent
+{
+#ifdef NDBM
+ datum dbm;
+#endif
+#ifdef NEWDB
+ DBT db;
+#endif
+ struct
+ {
+ char *data;
+ int size;
+ } xx;
+};
+
+#define BUFSIZE 1024
+
+main(argc, argv)
+ int argc;
+ char **argv;
+{
+ char *progname;
+ bool inclnull = FALSE;
+ bool notrunc = FALSE;
+ bool allowreplace = FALSE;
+ bool verbose = FALSE;
+ bool foldcase = TRUE;
+ int exitstat;
+ int opt;
+ char *typename;
+ char *mapname;
+ char *ext;
+ int lineno;
+ int st;
+ int mode;
+ enum type type;
+ union
+ {
+#ifdef NDBM
+ DBM *dbm;
+#endif
+#ifdef NEWDB
+ DB *db;
+#endif
+ void *dbx;
+ } dbp;
+ union dbent key, val;
+ char ibuf[BUFSIZE];
+ char fbuf[MAXNAME];
+ extern char *optarg;
+ extern int optind;
+
+ progname = argv[0];
+
+ while ((opt = getopt(argc, argv, "Nforv")) != EOF)
+ {
+ switch (opt)
+ {
+ case 'N':
+ inclnull = TRUE;
+ break;
+
+ case 'f':
+ foldcase = FALSE;
+ break;
+
+ case 'o':
+ notrunc = TRUE;
+ break;
+
+ case 'r':
+ allowreplace = TRUE;
+ break;
+
+ case 'v':
+ verbose = TRUE;
+ break;
+
+ default:
+ type = T_ERR;
+ break;
+ }
+ }
+
+ argc -= optind;
+ argv += optind;
+ if (argc != 2)
+ type = T_ERR;
+ else
+ {
+ typename = argv[0];
+ mapname = argv[1];
+ ext = NULL;
+
+ if (strcmp(typename, "dbm") == 0)
+ {
+ type = T_DBM;
+ }
+ else if (strcmp(typename, "btree") == 0)
+ {
+ type = T_BTREE;
+ ext = ".db";
+ }
+ else if (strcmp(typename, "hash") == 0)
+ {
+ type = T_HASH;
+ ext = ".db";
+ }
+ else
+ type = T_UNKNOWN;
+ }
+
+ switch (type)
+ {
+ case T_ERR:
+ fprintf(stderr, "Usage: %s [-N] [-o] [-v] type mapname\n", progname);
+ exit(EX_USAGE);
+
+ case T_UNKNOWN:
+ fprintf(stderr, "%s: Unknown database type %s\n",
+ progname, typename);
+ exit(EX_USAGE);
+
+#ifndef NDBM
+ case T_DBM:
+#endif
+#ifndef NEWDB
+ case T_BTREE:
+ case T_HASH:
+#endif
+ fprintf(stderr, "%s: Type %s not supported in this version\n",
+ progname, typename);
+ exit(EX_UNAVAILABLE);
+ }
+
+ /*
+ ** Adjust file names.
+ */
+
+ if (ext != NULL)
+ {
+ int el, fl;
+
+ el = strlen(ext);
+ fl = strlen(mapname);
+ if (fl < el || strcmp(&mapname[fl - el], ext) != 0)
+ {
+ strcpy(fbuf, mapname);
+ strcat(fbuf, ext);
+ mapname = fbuf;
+ }
+ }
+
+ /*
+ ** Create the database.
+ */
+
+ mode = O_RDWR;
+ if (!notrunc)
+ mode |= O_CREAT|O_TRUNC;
+ switch (type)
+ {
+#ifdef NDBM
+ case T_DBM:
+ dbp.dbm = dbm_open(mapname, mode, 0644);
+ break;
+#endif
+
+#ifdef NEWDB
+ case T_HASH:
+ dbp.db = dbopen(mapname, mode, 0644, DB_HASH, NULL);
+ break;
+
+ case T_BTREE:
+ dbp.db = dbopen(mapname, mode, 0644, DB_BTREE, NULL);
+ break;
+#endif
+
+ default:
+ fprintf(stderr, "%s: internal error: type %d\n", progname, type);
+ exit(EX_SOFTWARE);
+ }
+
+ if (dbp.dbx == NULL)
+ {
+ fprintf(stderr, "%s: cannot create type %s map %s\n",
+ progname, typename, mapname);
+ exit(EX_CANTCREAT);
+ }
+
+ /*
+ ** Copy the data
+ */
+
+ lineno = 0;
+ exitstat = EX_OK;
+ while (fgets(ibuf, sizeof ibuf, stdin) != NULL)
+ {
+ register char *p;
+
+ lineno++;
+
+ /*
+ ** Parse the line.
+ */
+
+ p = strchr(ibuf, '\n');
+ if (p != NULL)
+ *p = '\0';
+ else if (!feof(stdin))
+ {
+ fprintf(stderr, "%s: %s: line %d: line too long (%d bytes max)\n",
+ progname, mapname, lineno, sizeof ibuf);
+ continue;
+ }
+
+ if (ibuf[0] == '\0' || ibuf[0] == '#')
+ continue;
+ if (isspace(ibuf[0]))
+ {
+ fprintf(stderr, "%s: %s: line %d: syntax error (leading space)\n",
+ progname, mapname, lineno);
+ continue;
+ }
+ key.xx.data = ibuf;
+ for (p = ibuf; *p != '\0' && !isspace(*p); p++)
+ {
+ if (foldcase && isupper(*p))
+ *p = tolower(*p);
+ }
+ key.xx.size = p - key.xx.data;
+ if (inclnull)
+ key.xx.size++;
+ if (*p != '\0')
+ *p++ = '\0';
+ while (isspace(*p))
+ p++;
+ if (*p == '\0')
+ {
+ fprintf(stderr, "%s: %s: line %d: no RHS for LHS %s\n",
+ progname, mapname, lineno, key.xx.data);
+ continue;
+ }
+ val.xx.data = p;
+ val.xx.size = strlen(p);
+ if (inclnull)
+ val.xx.size++;
+
+ /*
+ ** Do the database insert.
+ */
+
+ if (verbose)
+ {
+ printf("key=`%s', val=`%s'\n", key.xx.data, val.xx.data);
+ }
+
+ switch (type)
+ {
+#ifdef NDBM
+ case T_DBM:
+ st = dbm_store(dbp.dbm, key.dbm, val.dbm,
+ allowreplace ? DBM_REPLACE : DBM_INSERT);
+ break;
+#endif
+
+#ifdef NEWDB
+ case T_BTREE:
+ case T_HASH:
+ st = (*dbp.db->put)(dbp.db, &key.db, &val.db,
+ allowreplace ? 0 : R_NOOVERWRITE);
+ break;
+#endif
+ }
+
+ if (st < 0)
+ {
+ fprintf(stderr, "%s: %s: line %d: key %s: put error\n",
+ progname, mapname, lineno, key.xx.data);
+ perror(mapname);
+ exitstat = EX_IOERR;
+ }
+ else if (st > 0)
+ {
+ fprintf(stderr, "%s: %s: line %d: key %s: duplicate key\n",
+ progname, mapname, lineno, key.xx.data);
+ }
+ }
+
+ /*
+ ** Now close the database.
+ */
+
+ switch (type)
+ {
+#ifdef NDBM
+ case T_DBM:
+ dbm_close(dbp.dbm);
+ break;
+#endif
+
+#ifdef NEWDB
+ case T_HASH:
+ case T_BTREE:
+ if ((*dbp.db->close)(dbp.db) < 0)
+ {
+ fprintf(stderr, "%s: %s: error on close\n",
+ progname, mapname);
+ perror(mapname);
+ exitstat = EX_IOERR;
+ }
+#endif
+ }
+
+ exit (exitstat);
+}
diff --git a/usr.sbin/sendmail/praliases/Makefile b/usr.sbin/sendmail/praliases/Makefile
new file mode 100644
index 0000000..498e171
--- /dev/null
+++ b/usr.sbin/sendmail/praliases/Makefile
@@ -0,0 +1,9 @@
+# @(#)Makefile 8.1 (Berkeley) 6/7/93
+
+PROG= praliases
+CFLAGS+=-I${.CURDIR}/../src
+DPADD= ${LIBDBM}
+NOMAN= noman
+
+.include "../../Makefile.inc"
+.include <bsd.prog.mk>
diff --git a/usr.sbin/sendmail/praliases/praliases.c b/usr.sbin/sendmail/praliases/praliases.c
new file mode 100644
index 0000000..2c22279
--- /dev/null
+++ b/usr.sbin/sendmail/praliases/praliases.c
@@ -0,0 +1,132 @@
+/*
+ * Copyright (c) 1983 Eric P. Allman
+ * Copyright (c) 1988, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char copyright[] =
+"@(#) Copyright (c) 1988, 1993\n\
+ The Regents of the University of California. All rights reserved.\n";
+#endif /* not lint */
+
+#ifndef lint
+static char sccsid[] = "@(#)praliases.c 8.3 (Berkeley) 3/6/94";
+#endif /* not lint */
+
+#include <ndbm.h>
+#include <sendmail.h>
+#ifdef NEWDB
+#include <db.h>
+#endif
+
+int
+main(argc, argv)
+ int argc;
+ char **argv;
+{
+ extern char *optarg;
+ extern int optind;
+ DBM *dbp;
+ datum content, key;
+ char *filename;
+ int ch;
+#ifdef NEWDB
+ const DB *db;
+ DBT newdbkey, newdbcontent;
+ char buf[MAXNAME];
+#endif
+
+ filename = "/etc/aliases";
+ while ((ch = getopt(argc, argv, "f:")) != EOF)
+ switch((char)ch) {
+ case 'f':
+ filename = optarg;
+ break;
+ case '?':
+ default:
+ (void)fprintf(stderr, "usage: praliases [-f file]\n");
+ exit(EX_USAGE);
+ }
+ argc -= optind;
+ argv += optind;
+
+#ifdef NEWDB
+ (void) strcpy(buf, filename);
+ (void) strcat(buf, ".db");
+ if (db = dbopen(buf, O_RDONLY, 0444 , DB_HASH, NULL)) {
+ if (!argc) {
+ while(!db->seq(db, &newdbkey, &newdbcontent, R_NEXT))
+ printf("%.*s:%.*s\n",
+ newdbkey.size, newdbkey.data,
+ newdbcontent.size, newdbcontent.data);
+ }
+ else for (; *argv; ++argv) {
+ newdbkey.data = *argv;
+ newdbkey.size = strlen(*argv) + 1;
+ if (!db->get(db, &newdbkey, &newdbcontent, 0))
+ printf("%s:%.*s\n", newdbkey.data,
+ newdbcontent.size, newdbcontent.data);
+ else
+ printf("%s: No such key\n",
+ newdbkey.data);
+ }
+ }
+ else {
+#endif
+ if ((dbp = dbm_open(filename, O_RDONLY, 0)) == NULL) {
+ (void)fprintf(stderr,
+ "praliases: %s: %s\n", filename, strerror(errno));
+ exit(EX_OSFILE);
+ }
+ if (!argc)
+ for (key = dbm_firstkey(dbp);
+ key.dptr != NULL; key = dbm_nextkey(dbp)) {
+ content = dbm_fetch(dbp, key);
+ (void)printf("%.*s:%.*s\n",
+ key.dsize, key.dptr,
+ content.dsize, content.dptr);
+ }
+ else for (; *argv; ++argv) {
+ key.dptr = *argv;
+ key.dsize = strlen(*argv) + 1;
+ content = dbm_fetch(dbp, key);
+ if (!content.dptr)
+ (void)printf("%s: No such key\n", key.dptr);
+ else
+ (void)printf("%s:%.*s\n", key.dptr,
+ content.dsize, content.dptr);
+ }
+#ifdef NEWDB
+ }
+#endif
+ exit(EX_OK);
+}
diff --git a/usr.sbin/sendmail/src/Makefile b/usr.sbin/sendmail/src/Makefile
new file mode 100644
index 0000000..773318c4
--- /dev/null
+++ b/usr.sbin/sendmail/src/Makefile
@@ -0,0 +1,42 @@
+# @(#)Makefile 8.4 (Berkeley) 2/3/94
+
+PROG= sendmail
+
+# define the database format to use for aliases et al. Can be -DNEWDB (for
+# the new BSD database package -- this is preferred) or -DNDBM for the NDBM
+# database package. The old putrescent V7 DBM package is no longer
+# supported.
+# You can define both NEWDB and NDBM during a transition period; old
+# databases are read, but the new format will be used on any rebuilds. On
+# really gnarly systems, you can set this to null; it will crawl like a high
+# spiral snail, but it will work.
+DBMDEF= -DNEWDB -DNDBM
+
+CFLAGS+=-I${.CURDIR} ${DBMDEF} -DNETISO
+
+SRCS= alias.c arpadate.c clock.c collect.c conf.c convtime.c daemon.c \
+ deliver.c domain.c envelope.c err.c headers.c macro.c main.c map.c \
+ mci.c parseaddr.c queue.c readcf.c recipient.c savemail.c srvrsmtp.c \
+ stab.c stats.c sysexits.c trace.c udb.c usersmtp.c \
+ util.c version.c
+DPADD=
+LDADD=
+MAN1= mailq.0 newaliases.0
+MAN5= aliases.0
+MAN8= sendmail.0
+LINKS= /usr/sbin/sendmail /usr/bin/newaliases \
+ /usr/sbin/sendmail /usr/bin/mailq
+BINDIR= /usr/sbin
+BINOWN= root
+BINGRP= kmem
+BINMODE=6555
+
+beforeinstall:
+# install -c -o ${BINOWN} -g ${BINGRP} -m 644 /dev/null \
+# ${DESTDIR}/etc/sendmail.fc
+ install -c -o ${BINOWN} -g ${BINGRP} -m 644 /dev/null \
+ ${DESTDIR}/var/log/sendmail.st
+ install -c -o ${BINOWN} -g ${BINGRP} -m 444 ${.CURDIR}/sendmail.hf \
+ ${DESTDIR}/usr/share/misc
+
+.include <bsd.prog.mk>
diff --git a/usr.sbin/sendmail/src/READ_ME b/usr.sbin/sendmail/src/READ_ME
new file mode 100644
index 0000000..cc0b419
--- /dev/null
+++ b/usr.sbin/sendmail/src/READ_ME
@@ -0,0 +1,872 @@
+# Copyright (c) 1983 Eric P. Allman
+# Copyright (c) 1988 The Regents of the University of California.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+# 3. All advertising materials mentioning features or use of this software
+# must display the following acknowledgement:
+# This product includes software developed by the University of
+# California, Berkeley and its contributors.
+# 4. Neither the name of the University nor the names of its contributors
+# may be used to endorse or promote products derived from this software
+# without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+#
+# @(#)READ_ME 8.61 (Berkeley) 4/17/94
+#
+
+This directory contains the source files for sendmail.
+
+For detailed instructions, please read the document ../doc/op.me:
+
+ eqn ../doc/op.me | pic | ditroff -me
+
+The Makefile is for the new (4.4BSD) Berkeley make and uses syntax
+that is not recognized by older makes. It also has assumptions
+about the 4.4 file system layout built in. See below for details
+about other Makefiles.
+
+There is also a Makefile.dist which is much less clever, but works on
+the old traditional make. You can use this using:
+
+ make -f Makefile.dist
+
+**************************************************
+** Read below for more details of Makefiles. **
+**************************************************
+
+There is also a shell script (makesendmail) that tries to be clever
+about using object subdirectories. It's pretty straightforward, and
+may help if you share a source tree among different architectures.
+
+**************************************************************************
+** IMPORTANT: DO NOT USE OPTIMIZATION (``-O'') IF YOU ARE RUNNING **
+** GCC 2.4.x or 2.5.x. THERE IS A BUG IN THE GCC OPTIMIZER THAT **
+** CAUSES SENDMAIL COMPILES TO FAIL MISERABLY. **
+**************************************************************************
+
+Jim Wilson of Cygnus believes he has found the problem -- it will
+probably be fixed in GCC 2.5.6 -- but until this is verified, be
+very suspicious of gcc -O.
+
+**************************************************************************
+** IMPORTANT: Read the appropriate paragraphs in the section on **
+** ``Operating System and Compile Quirks''. **
+**************************************************************************
+
+
++-----------+
+| MAKEFILES |
++-----------+
+
+The "Makefile"s in these directories are from 4.4 BSD, and hence
+really only work properly if you are on a 4.4 system. In particular,
+they use new syntax that will not be recognized on old make programs,
+and some of them do things like ``.include ../../Makefile.inc'' to
+pick up some system defines. If you are getting sendmail separately,
+these files won't be included in the distribution, as they are
+outside of the sendmail tree.
+
+Instead, you should use one of the other Makefiles, such as
+Makefile.SunOS for a SunOS system, and so forth. These should
+work with the version of make that is appropriate for that
+system.
+
+There are a bunch of other Makefiles for other systems with names
+like Makefile.HPUX for an HP-UX system. They use the version of
+make that is native for that system. These are the Makefiles that
+I use, and they have "Berkeley quirks" in them. I can't guarantee
+that they will work unmodified in your environment. Many of them
+include -I/usr/sww/include/db and -L/usr/sww/lib -- this is Berkeley's
+location (the ``Software Warehouse'') for the new database libraries,
+described below. You don't have to remove these definitions if you
+don't have these directories.
+
+Please look for an appropriate Makefile before you start trying to
+compile with Makefile or Makefile.dist.
+
+If you want to port the new Berkeley make, you can get it from
+ftp.uu.net in the directory /systems/unix/bsd-sources/usr.bin/make.
+Diffs and instructions for building this version of make under
+SunOS 4.1.x are available on ftp.css.itd.umich.edu in
+/pub/systems/sun/Net2-make.sun4.diff.Z. Diffs and instructions
+for building this version of make under IBM AIX 3.2.4 are available
+on ftp.uni-stuttgart.de in /sw/src/patches/bsd-make-rus-patches.
+Paul Southworth <pauls@umich.edu> published a description of porting
+this make in comp.unix.bsd.
+
+The complete text of the Makefile.inc that is in the parent of the
+sendmail directory is:
+
+ # @(#)Makefile.inc 8.1 (Berkeley) 6/6/93
+
+ BINDIR?= /usr/sbin
+
+
++----------------------+
+| DATABASE DEFINITIONS |
++----------------------+
+
+There are several database formats that can be used for the alias files
+and for general maps. When used for alias files they interact in an
+attempt to be back compatible.
+
+The three options are NEWDB (the new Berkeley DB package), NDBM (the
+older DBM implementation -- the very old V7 implementation is no
+longer supported), and NIS (Network Information Services). Used alone
+these just include the support they indicate. [If you are using NEWDB,
+get the latest version from FTP.CS.Berkeley.EDU in /ucb/4bsd. DO NOT
+use the version from the Net2 distribution! However, if you are on
+BSD/386 or 386BSD-based systems, use the one that already exists
+on your system. You may need to #define OLD_NEWDB 1 to do this.]
+
+[NOTE WELL: it is CRITICAL that you remove ndbm.o from libdb.a and
+ndbm.h from the appropriate include directories if you want to get
+ndbm support. These files OVERRIDE calls to ndbm routines -- in
+particular, if you leave ndbm.h in, you can find yourself using
+the new db package even if you don't define NEWDB.]
+
+If NEWDB and NDBM are defined (but not NIS), then sendmail will read
+NDBM format alias files, but the next time a newaliases is run the
+format will be converted to NEWDB; that format will be used forever
+more. This is intended as a transition feature. [Note however that
+the NEWDB library also catches and maps NDBM calls; you will have to
+back out this feature to get this to work. See ``Quirks'' section
+below for details.]
+
+If all three are defined, sendmail operates as described above, and also
+looks for the file /var/yp/Makefile. If it exists, newaliases will
+build BOTH the NEWDB and NDBM format alias files. However, it will
+only use the NEWDB file; the NDBM format file is used only by the
+NIS subsystem.
+
+If NDBM and NIS are defined (regardless of the definition of NEWDB
+or the existance of /var/yp/Makefile), sendmail adds the special
+tokens "YP_LAST_MODIFIED" and "YP_MASTER_NAME", both of which are
+required if the NDBM file is to be used as an NIS map.
+
+All of -DNEWDB, -DNDBM, and -DNIS are normally defined in the DBMDEF
+line in the Makefile.
+
+
++---------------+
+| COMPILE FLAGS |
++---------------+
+
+Whereever possible, I try to make sendmail pull in the correct
+compilation options needed to compile on various environments based on
+automatically defined symbols. Some machines don't seem to have useful
+symbols availble, requiring the following compilation flags in the
+Makefile:
+
+SOLARIS Define this if you are running Solaris 2.0 or higher.
+SOLARIS_2_3 Define this if you are running Solaris 2.3 or higher.
+SUNOS403 Define this if you are running SunOS 4.0.3.
+NeXT Define this if you are on a NeXT box. (This one may
+ be pre-defined for you.) There are other hacks you
+ have to make -- see below.
+_AIX3 Define this if you are IBM AIX 3.x.
+RISCOS Define this if you are running RISC/os from MIPS.
+IRIX Define this if you are running IRIX from SGI.
+_SCO_unix_ Define this if you are on SCO UNIX.
+_SCO_unix_4_2 Define this if you are on SCO Open Server 3.2v4.
+
+If you are a system that sendmail has already been ported to, you
+probably won't have to touch these. But if you are porting, you may
+have to tweak the following compilation flags in conf.h in order to
+get it to compile and link properly:
+
+SYSTEM5 Adjust for System V (not necessarily Release 4).
+SYS5SIGNALS Use System V signal semantics -- the signal handler
+ is automatically dropped when the signal is caught.
+ If this is not set, use POSIX/BSD semantics, where the
+ signal handler stays in force until an exec or an
+ explicit delete. Implied by SYSTEM5.
+SYS5SETPGRP Use System V setpgrp() semantics. Implied by SYSTEM5.
+HASFLOCK Set this if you prefer to use the flock(2) system call
+ rather than using fcntl-based locking. Fcntl locking
+ has some semantic gotchas, but many vendor systems
+ also interface it to lockd(8) to do NFS-style locking.
+ For this reason, this should not be set unless you
+ don't have an alternative.
+HASUNAME Set if you have the "uname" system call. Implied by
+ SYSTEM5.
+HASUNSETENV Define this if your system library has the "unsetenv"
+ subroutine.
+HASSETSID Define this if you have the setsid(2) system call. This
+ is implied if your system appears to be POSIX compliant.
+HASINITGROUPS Define this if you have the initgroups(3) routine.
+HASSETVBUF Define this if you have the setvbuf(3) library call.
+ If you don't, setlinebuf will be used instead. This
+ defaults on if your compiler defines __STDC__.
+HASSETREUID Define this if you have setreuid(2) ***AND*** root can
+ use setreuid to change to an arbitrary user. This second
+ condition is not satisfied on AIX 3.x. You may find that
+ your system has setresuid(2), (for example, on HP-UX) in
+ which case you will also have to #define setreuid(r, e)
+ to be the appropriate call. Some systems (such as Solaris)
+ have a compatibility routine that doesn't work properly,
+ but may have "saved user ids" properly implemented so you
+ can ``#define setreuid(r, e) seteuid(e)'' and have it work.
+ The important thing is that you have a call that will set
+ the effective uid independently of the real or saved uid
+ and be able to set the effective uid back again when done.
+ There's a test program in ../test/t_setreuid.c that will
+ try things on your system. Setting this improves the
+ security, since sendmail doesn't have to read .forward
+ and :include: files as root. There are certain attacks
+ that may be unpreventable without this call.
+HASLSTAT Define this if you have symbolic links (and thus the
+ lstat(2) system call). This improves security. Unlike
+ most other options, this one is on by default, so you
+ need to #undef it in conf.h if you don't have symbolic
+ links (these days everyone does).
+NEEDGETOPT Define this if you need a reimplementation of getopt(3).
+ On some systems, getopt does very odd things if called
+ to scan the arguments twice. This flag will ask sendmail
+ to compile in a local version of getopt that works
+ properly.
+NEEDSTRTOL Define this if your standard C library does not define
+ strtol(3). This will compile in a local version.
+NEEDVPRINTF Define this if your standard C library does not define
+ vprintf(3). Note that the resulting fake implementation
+ is not very elegant and may not even work on some
+ architectures.
+NEEDFSYNC Define this if your standard C library does not define
+ fsync(2). This will try to simulate the operation using
+ fcntl(2); if that is not available it does nothing, which
+ isn't great, but at least it compiles and runs.
+HASGETUSERSHELL Define this to 1 if you have getusershell(3) in your
+ standard C library. If this is not defined, or is defined
+ to be 0, sendmail will scan the /etc/shells file (no
+ NIS-style support, defaults to /bin/sh and /bin/csh if
+ that file does not exist) to get a list of unrestricted
+ user shells. This is used to determine whether users
+ are allowed to forward their mail to a program or a file.
+GIDSET_T The type of entries in a gidset passed as the second
+ argument to getgroups(2). Historically this has been an
+ int, so this is the default, but some systems (such as
+ IRIX) pass it as a gid_t, which is an unsigned short.
+ This will make a difference, so it is important to get
+ this right! However, it is only an issue if you have
+ group sets.
+SLEEP_T The type returned by the system sleep() function.
+ Defaults to "unsigned int". Don't worry about this
+ if you don't have compilation problems.
+ARBPTR_T The type of an arbitrary pointer -- defaults to "void *".
+ If you are an very old compiler you may need to define
+ this to be "char *".
+LA_TYPE The type of load average your kernel supports. These
+ can be one of:
+ LA_ZERO (1) -- it always returns the load average as
+ "zero" (and does so on all architectures).
+ LA_SUBR (4) if you have the getloadavg(3) routine,
+ LA_MACH (5) to use MACH-style load averages (calls
+ processor_set_info()),
+ LA_PROCSTR (7) to read /proc/loadavg and interpret it
+ as a string representing a floating-point
+ number (Linux-style),
+ LA_FLOAT (3) if you read kmem and interpret the value
+ as a floating point number,
+ LA_INT (2) to interpret as a long integer,
+ LA_SHORT (6) to interpret as a short integer.
+ These last three have several other parameters that they
+ try to divine: the name of your kernel, the name of the
+ variable in the kernel to examine, the number of bits of
+ precision in a fixed point load average, and so forth.
+ In desperation, use LA_ZERO. The actual code is in
+ conf.c -- it can be tweaked if you are brave.
+SFS_TYPE Encodes how your kernel can locate the amount of free
+ space on a disk partition. This can be set to SFS_NONE
+ (0) if you have no way of getting this information,
+ SFS_USTAT (1) if you have the ustat(2) system call,
+ SFS_4ARGS (2) if you have a four-argument statfs(2)
+ system call (and the include file is <sys/statfs.h>),
+ and SFS_VFS (3), SFS_MOUNT (4), SFS_STATFS (5) or
+ SFS_STATVFS (6) if you have the two-argument statfs(2)
+ system call, with includes in <sys/vfs.h>, <sys/mount.h>,
+ <sys/statfs.h>, or <sys/statvfs.h> respectively. The
+ default if nothing is defined is SFS_NONE.
+ERRLIST_PREDEFINED
+ If set, assumes that some header file defines sys_errlist.
+ This may be needed if you get type conflicts on this
+ variable -- otherwise don't worry about it.
+WAITUNION The wait(2) routine takes a "union wait" argument instead
+ of an integer argument. This is for compatibility with
+ old versions of BSD.
+SCANF You can set this to extend the F command to accept a
+ scanf string -- this gives you a primitive parser for
+ class definitions -- BUT it can make you vulnerable to
+ core dumps if the target file is poorly formed.
+SYSLOG_BUFSIZE You can define this to be the size of the buffer that
+ syslog accepts. If it is not defined, it assumes a
+ 1024-byte buffer. If the buffer is very small (under
+ 256 bytes) the log message format changes -- each
+ e-mail message will log many more messages, since it
+ will log each piece of information as a separate line
+ in syslog.
+BROKEN_RES_SEARCH
+ On Ultrix (and maybe other systems?) if you use the
+ res_search routine with an unknown host name, it returns
+ -1 but sets h_errno to 0 instead of HOST_NOT_FOUND. If
+ you set this, sendmail considers 0 to be the same as
+ HOST_NOT_FOUND.
+
+
++-----------------------+
+| COMPILE-TIME FEATURES |
++-----------------------+
+
+There are a bunch of features that you can decide to compile in, such
+as selecting various database packages and special protocol support.
+Several are assumed based on other compilation flags -- if you want to
+"un-assume" something, you probably need to edit conf.h. Compilation
+flags that add support for special features include:
+
+NDBM Include support for "new" DBM library for aliases and maps.
+ Normally defined in the Makefile.
+NEWDB Include support for Berkeley "db" package (hash & btree)
+ for aliases and maps. Normally defined in the Makefile.
+OLD_NEWDB If non-zero, the version of NEWDB you have is the old
+ one that does not include the "fd" call. This call was
+ added in version 1.5 of the Berkeley DB code. If you
+ use -DOLD_NEWDB=0 it forces you to use the new interface.
+NIS Define this to get NIS (YP) support for aliases and maps.
+ Normally defined in the Makefile.
+USERDB Include support for the User Information Database. Implied
+ by NEWDB in conf.h.
+IDENTPROTO Define this as 1 to get IDENT (RFC 1413) protocol support.
+ This is assumed unless you are running on Ultrix or
+ HP-UX, both of which have a problem in the UDP
+ implementation. You can define it to be 0 to explicitly
+ turn off IDENT protocol support.
+MIME Include support for MIME-encapsulated error messages.
+LOG Set this to get syslog(3) support. Defined by default
+ in conf.h. You want this if at all possible.
+NETINET Set this to get TCP/IP support. Defined by default
+ in conf.h. You probably want this.
+NETISO Define this to get ISO networking support.
+SMTP Define this to get the SMTP code. Implied by NETINET
+ or NETISO.
+NAMED_BIND Define this to get DNS (name daemon) support, including
+ MX support. The specs you must use this if you run
+ SMTP. Defined by default in conf.h.
+QUEUE Define this to get queueing code. Implied by NETINET
+ or NETISO; required by SMTP. This gives you other good
+ stuff -- it should be on.
+DAEMON Define this to get general network support. Implied by
+ NETINET or NETISO. Defined by default in conf.h. You
+ almost certainly want it on.
+MATCHGECOS Permit fuzzy matching of user names against the full
+ name (GECOS) field in the /etc/passwd file. This should
+ probably be on, since you can disable it from the config
+ file if you want to. Defined by default in conf.h.
+SETPROCTITLE Try to set the string printed by "ps" to something
+ informative about what sendmail is doing. Defined by
+ default in conf.h.
+
+
++---------------------+
+| DNS/RESOLVER ISSUES |
++---------------------+
+
+Many systems have old versions of the resolver library. At a minimum,
+you should be running BIND 4.8.3; older versions may compile, but they
+have known bugs that should give you pause.
+
+Common problems in old versions include "undefined" errors for
+dn_skipname.
+
+Some people have had a problem with BIND 4.9; it uses some routines
+that it expects to be externally defined such as strerror(). It may
+help to link with "-l44bsd" to solve this problem.
+
+!PLEASE! be sure to link with the same version of the resolver as
+the header files you used -- some people have used the 4.9 headers
+and linked with BIND 4.8 or vice versa, and it doesn't work.
+Unfortunately, it doesn't fail in an obvious way -- things just
+subtly don't work.
+
+
++-------------------------------------+
+| OPERATING SYSTEM AND COMPILE QUIRKS |
++-------------------------------------+
+
+GCC 2.5.x problems *** IMPORTANT ***
+ Date: Mon, 29 Nov 93 19:08:44 PST
+ From: wilson@cygnus.com (Jim Wilson)
+ Message-Id: <9311300308.AA04608@cygnus.com>
+ To: kenner@vlsi1.ultra.nyu.edu
+ Subject: [cattelan@thebarn.com: gcc 2.5.4-2.5.5 -O bug]
+ Cc: cattelan@thebarn.com, rms@gnu.ai.mit.edu, sendmail@cs.berkeley.edu
+
+ This fixes a problem that occurs when gcc 2.5.5 is used to compile
+ sendmail 8.6.4 with optimization on a sparc.
+
+ Mon Nov 29 19:00:14 1993 Jim Wilson (wilson@sphagnum.cygnus.com)
+
+ * reload.c (find_reloads_toplev): Replace obsolete reference to
+ BYTE_LOADS_*_EXTEND with LOAD_EXTEND_OP.
+
+ *** clean-ss-931128/reload.c Sun Nov 14 16:20:01 1993
+ --- ss-931128/reload.c Mon Nov 29 18:52:55 1993
+ *************** find_reloads_toplev (x, opnum, type, ind
+ *** 3888,3894 ****
+ force a reload in that case. So we should not do anything here. */
+
+ else if (regno >= FIRST_PSEUDO_REGISTER
+ ! #if defined(BYTE_LOADS_ZERO_EXTEND) || defined(BYTE_LOADS_SIGN_EXTEND)
+ && (GET_MODE_SIZE (GET_MODE (x))
+ <= GET_MODE_SIZE (GET_MODE (SUBREG_REG (x))))
+ #endif
+ --- 3888,3894 ----
+ force a reload in that case. So we should not do anything here. */
+
+ else if (regno >= FIRST_PSEUDO_REGISTER
+ ! #ifdef LOAD_EXTEND_OP
+ && (GET_MODE_SIZE (GET_MODE (x))
+ <= GET_MODE_SIZE (GET_MODE (SUBREG_REG (x))))
+ #endif
+
+
+SunOS 4.x (Solaris 1.x)
+ You may have to use -lresolv on SunOS. However, beware that
+ this links in a new version of gethostbyname that does not
+ understand NIS, so you must have all of your hosts in DNS.
+
+ Some people have reported problems with the SunOS version of
+ -lresolv and/or in.named, and suggest that you get a newer
+ version. The symptoms are delays when you connect to the
+ SMTP server on a SunOS machine or having your domain added to
+ addresses inappropriately. There is a version of BIND
+ version 4.9 on gatekeeper.DEC.COM in pub/BSD/bind/4.9.
+
+ There is substantial disagreement about whether you can make
+ this work with resolv+, which allows you to specify a search-path
+ of services. Some people report that it works fine, others
+ claim it doesn't work at all (including causing sendmail to
+ drop core when it tries to do multiple resolv+ lookups for a
+ single job). I haven't tried resolv+, as we use DNS exclusively.
+
+ Should you want to try resolv+, it is on ftp.uu.net in
+ /networking/ip/dns.
+
+Solaris 2.x (SunOS 5.x)
+ To compile for Solaris, be sure you use -DSOLARIS.
+
+ To the best of my knowledge, Solaris does not have the
+ gethostbyname problem described above. However, it does
+ have another one:
+
+ From a correspondent:
+
+ For solaris 2.2, I have
+
+ hosts: files dns
+
+ in /etc/nsswitch.conf and /etc/hosts has to have the fully
+ qualified host name. I think "files" has to be before "dns"
+ in /etc/nsswitch.conf during bootup.
+
+ From another correspondent:
+
+ When running sendmail under Solaris, the gethostbyname()
+ hack in conf.c which should perform proper canonicalization
+ of host names could fail. Result: the host name is not
+ canonicalized despite the hack, and you'll have to define $j
+ and $m in sendmail.cf somewhere.
+
+ The reason could be that /etc/nsswitch.conf is improperly
+ configured (at least from sendmail's point of view). For
+ example, the line
+
+ hosts: files nisplus dns
+
+ will make gethostbyname() look in /etc/hosts first, then ask
+ nisplus, then dns. However, if /etc/hosts does not contain
+ the full canonicalized hostname, then no amount of
+ gethostbyname()s will work.
+
+ Solution (or rather, a workaround): Ask nisplus first, then
+ dns, then local files:
+
+ hosts: nisplus dns [NOTFOUND=return] files
+
+ The Solaris "syslog" function is apparently limited to something
+ about 90 characters because of a kernel limitation. If you have
+ source code, you can probably up this number. You can get patches
+ that fix this problem: the patch ids are:
+
+ Solaris 2.1 100834
+ Solaris 2.2 100999
+ Solaris 2.3 101318
+
+ Be sure you have the appropriate patch installed or you won't
+ see system logging.
+
+OSF/1
+ If you are compiling on OSF/1 (DEC Alpha), you must use
+ -L/usr/shlib (otherwise it core dumps on startup). You may also
+ need -mld to get the nlist() function, although some versions
+ apparently don't need this.
+
+ Also, the enclosed makefile removed /usr/sbin/smtpd; if you need
+ it, just create the link to the sendmail binary.
+
+IRIX
+ The header files on SGI IRIX are completely prototyped, and as
+ a result you can sometimes get some warning messages during
+ compilation. These can be ignored. There are two errors in
+ deliver only if you are using gcc, both of the form ``warning:
+ passing arg N of `execve' from incompatible pointer type''.
+ Also, if you compile with -DNIS, you will get a complaint
+ about a declaration of struct dom_binding in a prototype
+ when compiling map.c; this is not important because the
+ function being prototyped is not used in that file.
+
+NeXT
+ If you are compiling on NeXT, you will have to create an empty
+ file "unistd.h" and create a file "dirent.h" containing:
+
+ #include <sys/dir.h>
+ #define dirent direct
+
+ (The Makefile.NeXT should try to do both of these for you.)
+
+ Apparently, there is a bug in getservbyname on Nextstep 3.0
+ that causes it to fail under some circumstances with the
+ message "SYSERR: service "smtp" unknown" logged. You should
+ be able to work around this by including the line:
+
+ OOPort=25
+
+ in your .cf file.
+
+ You may have to use -DNeXT.
+
+BSDI (BSD/386) 1.0, NetBSD 0.9, FreeBSD 1.0
+ The "m4" from BSDI won't handle the config files properly.
+ I haven't had a chance to test this myself.
+
+ The M4 shipped in FreeBSD and NetBSD 0.9 don't handle the config
+ files properly. One must use either GNU m4 1.1 or the PD-M4
+ recently posted in comp.os.386bsd.bugs (and maybe others).
+ NetBSD-current includes the PD-M4 (as stated in the NetBSD file
+ CHANGES).
+
+ FreeBSD 1.0 RELEASE has uname(2) now. Use -DUSEUNAME in order to
+ use it (look into Makefile.FreeBSD). NetBSD-current may have
+ it too but it has not been verified.
+
+ You cannot port the latest version of the Berkeley db library
+ and use it with sendmail without recompiling the world. This
+ is because C library routines use the older version which have
+ incompatible header files -- the result is that it can't read
+ other system files, such as /etc/passwd, unless you use the
+ new db format throughout your system. You should normally just
+ use the version of db supplied in your release. You may need
+ to use -DOLD_NEWDB=1 to make this work -- this turns off some
+ new interface calls (for file locking) that are not in older
+ versions of db. You'll get compile errors if you need this
+ flag and don't have it set.
+
+4.3BSD
+ If you are running a "virgin" version of 4.3BSD, you'll have
+ a very old resolver and be missing some header files. The
+ header files are simple -- create empty versions and everything
+ will work fine. For the resolver you should really port a new
+ version (4.8.3 or later) of the resolver; 4.9 is available on
+ gatekeeper.DEC.COM in pub/BSD/bind/4.9. If you are really
+ determined to continue to use your old, buggy version (or as
+ a shortcut to get sendmail working -- I'm sure you have the
+ best intentions to port a modern version of BIND), you can
+ copy ../contrib/oldbind.compat.c into src and add
+ oldbind.compat.o to OBJADD in the Makefile.
+
+A/UX
+ Date: Tue, 12 Oct 1993 18:28:28 -0400 (EDT)
+ From: "Eric C. Hagberg" <hagberg@med.cornell.edu>
+ Subject: Fix for A/UX ndbm
+
+ I guess this isn't really a sendmail bug, however, it is something
+ that A/UX users should be aware of when compiling sendmail 8.6.
+
+ Apparently, the calls that sendmail is using to the ndbm routines
+ in A/UX 3.0.x contain calls to "broken" routines, in that the
+ aliases database will break when it gets "just a little big"
+ (sorry I don't have exact numbers here, but it broke somewhere
+ around 20-25 aliases for me.), making all aliases non-functional
+ after exceeding this point.
+
+ What I did was to get the gnu-dbm-1.6 package, compile it, and
+ then re-compile sendmail with "-lgdbm", "-DNDBM", and using the
+ ndbm.h header file that comes with the gnu-package. This makes
+ things behave properly.
+
+ I suppose porting the New Berkeley db package is another route,
+ however, I made a quick attempt at it, and found it difficult
+ (not easy at least); the gnu-dbm package "configured" and
+ compiled easily.
+
+DG/UX
+ Apparently, /bin/mail doesn't work properly for delivery on
+ DG/UX -- the person who has this working, Douglas Anderson
+ <dlander@afterlife.ncsc.mil>, used procmail instead.
+
+Apollo DomainOS
+ If you are compiling on Apollo, you will have to create an empty
+ file "unistd.h" and create a file "dirent.h" containing:
+
+ #include <sys/dir.h>
+ #define dirent direct
+
+ (The Makefile.DomainOS will attempt to do both of these for you.)
+
+HP-UX 8.00
+ Date: Mon, 24 Jan 1994 13:25:45 +0200
+ From: Kimmo Suominen <Kimmo.Suominen@lut.fi>
+ Subject: 8.6.5 w/ HP-UX 8.00 on s300
+
+ Just compiled and fought with sendmail 8.6.5 on a HP9000/360 (ie. a
+ series 300 machine) running HP-UX 8.00.
+
+ I was getting segmentation fault when delivering to a local user.
+ With debugging I saw it was faulting when doing _free@libc... *sigh*
+ It seems the new implementation of malloc on s300 is buggy as of 8.0,
+ so I tried out the one in -lmalloc (malloc(3X)). With that it seems
+ to work just dandy.
+
+ When linking, you will get the following error:
+
+ ld: multiply defined symbol _freespace in file /usr/lib/libmalloc.a
+
+ but you can just ignore it. You might want to add this info to the
+ README file for the future...
+
+Linux
+ Something broke between versions 0.99.13 and 0.99.14 of Linux:
+ the flock() system call gives errors. If you are running .14,
+ you must not use flock. You can do this with -DHASFLOCK=0.
+
+AIX
+ This version of sendmail does not support MB, MG, and MR resource
+ records, which are supported by AIX sendmail.
+
+RISC/os
+ RISC/os from MIPS is a merged AT&T/Berkeley system. When you
+ compile on that platform you will get duplicate definitions
+ on many files. You can ignore these.
+
+System V Release 4 Based Systems
+ There is a single Makefile that is intended for all SVR4-based
+ systems (called Makefile.SVR4). It defines __svr4__, which is
+ predefined by some compilers. If your compiler already defines
+ this compile variable, you can delete the definition from the
+ Makefile.
+
+ It's been tested on Dell Issue 2.2.
+
+DELL SVR4
+ Date: Mon, 06 Dec 1993 10:42:29 EST
+ From: "Kimmo Suominen" <kim@grendel.lut.fi>
+ Message-ID: <2d0352f9.lento29@lento29.UUCP>
+ To: eric@cs.berkeley.edu
+ Cc: sendmail@cs.berkeley.edu
+ Subject: Notes for DELL SVR4
+
+ Eric,
+
+ Here are some notes for compiling Sendmail 8.6.4 on DELL SVR4. I ran
+ across these things when helping out some people who contacted me by
+ e-mail.
+
+ 1) Use gcc 2.4.5 (or later?). Dell distributes gcc 2.1 with their
+ Issue 2.2 Unix. It is too old, and gives you problems with
+ clock.c, because sigset_t won't get defined in <sys/signal.h>.
+ This is due to a problematic protection rule in there, and is
+ fixed with gcc 2.4.5.
+
+ 2) If you don't use the new Berkeley DB (-DNEWDB), then you need
+ to add "-lc -lucb" to the libraries to link with. This is because
+ the -ldbm distributed by Dell needs the bcopy, bcmp and bzero
+ functions. It is important that you specify both libraries in
+ the given order to be sure you only get the BSTRING functions
+ from the UCB library (and not the signal routines etc.).
+
+ 3) Don't leave out "-lelf" even if compiling with "-lc -lucb".
+ The UCB library also has another copy of the nlist routines,
+ but we do want the ones from "-lelf".
+
+ If anyone needs a compiled gcc 2.4.5 and/or a ported DB library, they
+ can use anonymous ftp to fetch them from lut.fi in the /kim directory.
+ They are copies of what I use on grendel.lut.fi, and offering them
+ does not imply that I would also support them. I have sent the DB
+ port for SVR4 back to Keith Bostic for inclusion in the official
+ distribution, but I haven't heard anything from him as of today.
+
+ - gcc-2.4.5-svr4.tar.gz (gcc 2.4.5 and the corresponding libg++)
+ - db-1.72.tar.gz (with source, objects and a installed copy)
+
+ Cheers
+ + Kim
+ --
+ * Kimmo.Suominen@lut.fi * SysVr4 enthusiast at GRENDEL.LUT.FI *
+ * KIM@FINFILES.BITNET * Postmaster and Hostmaster at LUT.FI *
+ * + 358 200 865 718 * Unix area moderator at NIC.FUNET.FI *
+
+
+Non-DNS based sites
+ This version of sendmail always tries to connect to the Domain
+ Name System (DNS) to resolve names, regardless of the setting
+ of the `I' option. On most systems that are not running DNS,
+ this will fail quickly and sendmail will continue, but on some
+ systems it has a long timeout. If you have this problem, you
+ will have to recompile without NAMED_BIND. Some people have
+ claimed that they have successfully used "OI+USEVC" to force
+ sendmail to use a virtual circuit -- this will always time out
+ quickly, but also tells sendmail that a failed connection
+ should requeue the message (probably not what you intended).
+ A future release of sendmail will correct this problem.
+
+Both NEWDB and NDBM
+ If you use both -DNDBM and -DNEWDB, you must delete the module
+ ndbm.o from libdb.a and delete the file "ndbm.h" from the files
+ that get installed (that is, use the OLD ndbm.h, not the new
+ ndbm.h). This compatibility module maps ndbm calls into DB
+ calls, and breaks things rather badly.
+
+GNU getopt
+ I'm told that GNU getopt has a problem in that it gets confused
+ by the double call. Use the version in conf.c instead.
+
+BIND 4.9.2 and Ultrix
+ If you are running on Ultrix, be sure you read the conf/Info.Ultrix
+ carefully -- there is information in there that you need to know
+ in order to avoid errors of the form:
+
+ /lib/libc.a(gethostent.o): sethostent: multiply defined
+ /lib/libc.a(gethostent.o): endhostent: multiply defined
+ /lib/libc.a(gethostent.o): gethostbyname: multiply defined
+ /lib/libc.a(gethostent.o): gethostbyaddr: multiply defined
+
+ during the link stage.
+
+
++--------------+
+| MANUAL PAGES |
++--------------+
+
+The manual pages have been written against the -mandoc macros
+instead of the -man macros. The latest version of groff has them
+included. You can also get a copy from FTP.UU.NET in directory
+/systems/unix/bsd-sources/share/tmac.
+
+
++-----------------+
+| DEBUGGING HOOKS |
++-----------------+
+
+As of 8.6.5, sendmail daemons will catch a SIGUSR1 signal and log
+some debugging output (logged at LOG_DEBUG severity). The
+information dumped is:
+
+ * The value of the $j macro.
+ * A warning if $j is not in the set $=w.
+ * A list of the open file descriptors.
+ * The contents of the connection cache.
+ * If ruleset 89 is defined, it is evaluated and the results printed.
+
+This allows you to get information regarding the runtime state of the
+daemon on the fly. This should not be done too frequently, since
+the process of rewriting may lose memory which will not be recovered.
+Also, ruleset 89 may call non-reentrant routines, so there is a small
+non-zero probability that this will cause other problems. It is
+really only for debugging serious problems.
+
+A typical formulation of ruleset 89 would be:
+
+ R$* $@ $>0 some test address
+
+
++-----------------------------+
+| DESCRIPTION OF SOURCE FILES |
++-----------------------------+
+
+The following list describes the files in this directory:
+
+Makefile The makefile used here; this version only works with
+ the new Berkeley make.
+Makefile.dist A trimmed down version of the makefile that works with
+ the old make.
+READ_ME This file.
+TRACEFLAGS My own personal list of the trace flags -- not guaranteed
+ to be particularly up to date.
+alias.c Does name aliasing in all forms.
+arpadate.c A subroutine which creates ARPANET standard dates.
+clock.c Routines to implement real-time oriented functions
+ in sendmail -- e.g., timeouts.
+collect.c The routine that actually reads the mail into a temp
+ file. It also does a certain amount of parsing of
+ the header, etc.
+conf.c The configuration file. This contains information
+ that is presumed to be quite static and non-
+ controversial, or code compiled in for efficiency
+ reasons. Most of the configuration is in sendmail.cf.
+conf.h Configuration that must be known everywhere.
+convtime.c A routine to sanely process times.
+daemon.c Routines to implement daemon mode. This version is
+ specifically for Berkeley 4.1 IPC.
+deliver.c Routines to deliver mail.
+domain.c Routines that interface with DNS (the Domain Name
+ System).
+err.c Routines to print error messages.
+envelope.c Routines to manipulate the envelope structure.
+headers.c Routines to process message headers.
+macro.c The macro expander. This is used internally to
+ insert information from the configuration file.
+main.c The main routine to sendmail. This file also
+ contains some miscellaneous routines.
+map.c Support for database maps.
+mci.c Routines that handle mail connection information caching.
+parseaddr.c The routines which do address parsing.
+queue.c Routines to implement message queueing.
+readcf.c The routine that reads the configuration file and
+ translates it to internal form.
+recipient.c Routines that manipulate the recipient list.
+savemail.c Routines which save the letter on processing errors.
+sendmail.h Main header file for sendmail.
+srvrsmtp.c Routines to implement server SMTP.
+stab.c Routines to manage the symbol table.
+stats.c Routines to collect and post the statistics.
+sysexits.c List of error messages associated with error codes
+ in sysexits.h.
+trace.c The trace package. These routines allow setting and
+ testing of trace flags with a high granularity.
+udb.c The user database interface module.
+usersmtp.c Routines to implement user SMTP.
+util.c Some general purpose routines used by sendmail.
+version.c The version number and information about this
+ version of sendmail. Theoretically, this gets
+ modified on every change.
+
+Eric Allman
+
+(Version 8.61, last update 4/17/94 07:05:32)
diff --git a/usr.sbin/sendmail/src/TRACEFLAGS b/usr.sbin/sendmail/src/TRACEFLAGS
new file mode 100644
index 0000000..f05c219
--- /dev/null
+++ b/usr.sbin/sendmail/src/TRACEFLAGS
@@ -0,0 +1,64 @@
+0, 1 main.c main skip background fork
+0, 4 main.c main canonical name, UUCP node name, a.k.a.s
+0, 15 main.c main print configuration
+0, 44 util.c printav print address of each string
+1 main.c main print from person
+2 main.c finis
+3 conf.c getla
+4 conf.c enoughspace
+5 clock.c setevent, clrevent, tick
+6 savemail.c savemail, returntosender
+7 queue.c queuename
+8 domain.c getmxrr, getcanonname
+9 daemon.c getauthinfo IDENT protocol
+9 daemon.c maphostname
+10 deliver.c deliver
+11 deliver.c openmailer, mailfile
+12 parseaddr.c remotename
+13 deliver.c sendall, sendenvelope
+14 headers.c commaize
+15 daemon.c getrequests
+16 daemon.c makeconnection
+17 deliver.c hostsignature
+17 domain.c mxrand
+18 usersmtp.c reply, smtpmessage, smtpinit, smtpmailfrom
+19 srvrsmtp.c smtp
+20 parseaddr.c parseaddr
+21 parseaddr.c rewrite
+22 parseaddr.c prescan
+24 parseaddr.c buildaddr, allocaddr
+25 recipient.c sendtolist
+26 recipient.c recipient
+27 alias.c alias
+27 alias.c readaliases
+27 alias.c forward
+27 recipient.c include
+28 udb.c udbexpand, udbsender
+29 parseaddr.c maplocaluser
+29 recipient.c recipient (local users), finduser
+30 collect.c collect
+30 collect.c eatfrom
+31 headers.c chompheader
+32 headers.c eatheader
+33 headers.c crackaddr
+34 headers.c putheader
+35 macro.c expand, define
+36 stab.c stab
+37 readcf.c (many)
+38 map.c initmaps
+39 map.c map_rewrite
+40 queue.c queueup, orderq, dowork
+41 queue.c orderq
+42 mci.c mci_get
+45 envelope.c setsender
+46 envelope.c openxscript
+49 conf.c checkcompat
+50 envelope.c dropenvelope
+51 queue.c unlockqueue
+52 main.c disconnect
+53 util.c xfclose
+54 err.c putoutmsg
+55 conf.c lockfile
+59 Extended Load Average implementation from Christophe Wolfhugel
+60 map.c
+91 mci.c syslogging of MCI cache information
diff --git a/usr.sbin/sendmail/src/alias.c b/usr.sbin/sendmail/src/alias.c
new file mode 100644
index 0000000..9952db5
--- /dev/null
+++ b/usr.sbin/sendmail/src/alias.c
@@ -0,0 +1,770 @@
+/*
+ * Copyright (c) 1983 Eric P. Allman
+ * Copyright (c) 1988, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+# include "sendmail.h"
+# include <pwd.h>
+
+#ifndef lint
+static char sccsid[] = "@(#)alias.c 8.25 (Berkeley) 4/14/94";
+#endif /* not lint */
+
+
+MAP *AliasDB[MAXALIASDB + 1]; /* actual database list */
+int NAliasDBs; /* number of alias databases */
+ /*
+** ALIAS -- Compute aliases.
+**
+** Scans the alias file for an alias for the given address.
+** If found, it arranges to deliver to the alias list instead.
+** Uses libdbm database if -DDBM.
+**
+** Parameters:
+** a -- address to alias.
+** sendq -- a pointer to the head of the send queue
+** to put the aliases in.
+** e -- the current envelope.
+**
+** Returns:
+** none
+**
+** Side Effects:
+** Aliases found are expanded.
+**
+** Deficiencies:
+** It should complain about names that are aliased to
+** nothing.
+*/
+
+alias(a, sendq, e)
+ register ADDRESS *a;
+ ADDRESS **sendq;
+ register ENVELOPE *e;
+{
+ register char *p;
+ int naliases;
+ char *owner;
+ char obuf[MAXNAME + 6];
+ extern char *aliaslookup();
+
+ if (tTd(27, 1))
+ printf("alias(%s)\n", a->q_paddr);
+
+ /* don't realias already aliased names */
+ if (bitset(QDONTSEND|QBADADDR|QVERIFIED, a->q_flags))
+ return;
+
+ if (NoAlias)
+ return;
+
+ e->e_to = a->q_paddr;
+
+ /*
+ ** Look up this name
+ */
+
+ p = aliaslookup(a->q_user, e);
+ if (p == NULL)
+ return;
+
+ /*
+ ** Match on Alias.
+ ** Deliver to the target list.
+ */
+
+ if (tTd(27, 1))
+ printf("%s (%s, %s) aliased to %s\n",
+ a->q_paddr, a->q_host, a->q_user, p);
+ if (bitset(EF_VRFYONLY, e->e_flags))
+ {
+ a->q_flags |= QVERIFIED;
+ e->e_nrcpts++;
+ return;
+ }
+ message("aliased to %s", p);
+#ifdef LOG
+ if (LogLevel > 9)
+ syslog(LOG_INFO, "%s: alias %s => %s",
+ e->e_id == NULL ? "NOQUEUE" : e->e_id,
+ a->q_paddr, p);
+#endif
+ a->q_flags &= ~QSELFREF;
+ AliasLevel++;
+ naliases = sendtolist(p, a, sendq, e);
+ AliasLevel--;
+ if (!bitset(QSELFREF, a->q_flags))
+ {
+ if (tTd(27, 5))
+ {
+ printf("alias: QDONTSEND ");
+ printaddr(a, FALSE);
+ }
+ a->q_flags |= QDONTSEND;
+ }
+
+ /*
+ ** Look for owner of alias
+ */
+
+ (void) strcpy(obuf, "owner-");
+ if (strncmp(a->q_user, "owner-", 6) == 0)
+ (void) strcat(obuf, "owner");
+ else
+ (void) strcat(obuf, a->q_user);
+ if (!bitnset(M_USR_UPPER, a->q_mailer->m_flags))
+ makelower(obuf);
+ owner = aliaslookup(obuf, e);
+ if (owner == NULL)
+ return;
+
+ /* reflect owner into envelope sender */
+ if (strpbrk(owner, ",:/|\"") != NULL)
+ owner = obuf;
+ a->q_owner = newstr(owner);
+
+ /* announce delivery to this alias; NORECEIPT bit set later */
+ if (e->e_xfp != NULL)
+ {
+ fprintf(e->e_xfp, "Message delivered to mailing list %s\n",
+ a->q_paddr);
+ e->e_flags |= EF_SENDRECEIPT;
+ }
+}
+ /*
+** ALIASLOOKUP -- look up a name in the alias file.
+**
+** Parameters:
+** name -- the name to look up.
+**
+** Returns:
+** the value of name.
+** NULL if unknown.
+**
+** Side Effects:
+** none.
+**
+** Warnings:
+** The return value will be trashed across calls.
+*/
+
+char *
+aliaslookup(name, e)
+ char *name;
+ ENVELOPE *e;
+{
+ register int dbno;
+ register MAP *map;
+ register char *p;
+
+ for (dbno = 0; dbno < NAliasDBs; dbno++)
+ {
+ auto int stat;
+
+ map = AliasDB[dbno];
+ if (!bitset(MF_OPEN, map->map_mflags))
+ continue;
+ p = (*map->map_class->map_lookup)(map, name, NULL, &stat);
+ if (p != NULL)
+ return p;
+ }
+ return NULL;
+}
+ /*
+** SETALIAS -- set up an alias map
+**
+** Called when reading configuration file.
+**
+** Parameters:
+** spec -- the alias specification
+**
+** Returns:
+** none.
+*/
+
+setalias(spec)
+ char *spec;
+{
+ register char *p;
+ register MAP *map;
+ char *class;
+ STAB *s;
+
+ if (tTd(27, 8))
+ printf("setalias(%s)\n", spec);
+
+ for (p = spec; p != NULL; )
+ {
+ char aname[50];
+
+ while (isspace(*p))
+ p++;
+ if (*p == '\0')
+ break;
+ spec = p;
+
+ if (NAliasDBs >= MAXALIASDB)
+ {
+ syserr("Too many alias databases defined, %d max", MAXALIASDB);
+ return;
+ }
+ (void) sprintf(aname, "Alias%d", NAliasDBs);
+ s = stab(aname, ST_MAP, ST_ENTER);
+ map = &s->s_map;
+ AliasDB[NAliasDBs] = map;
+ bzero(map, sizeof *map);
+
+ p = strpbrk(p, " ,/:");
+ if (p != NULL && *p == ':')
+ {
+ /* map name */
+ *p++ = '\0';
+ class = spec;
+ spec = p;
+ }
+ else
+ {
+ class = "implicit";
+ map->map_mflags = MF_OPTIONAL|MF_INCLNULL;
+ }
+
+ /* find end of spec */
+ if (p != NULL)
+ p = strchr(p, ',');
+ if (p != NULL)
+ *p++ = '\0';
+
+ /* look up class */
+ s = stab(class, ST_MAPCLASS, ST_FIND);
+ if (s == NULL)
+ {
+ if (tTd(27, 1))
+ printf("Unknown alias class %s\n", class);
+ }
+ else if (!bitset(MCF_ALIASOK, s->s_mapclass.map_cflags))
+ {
+ syserr("setalias: map class %s can't handle aliases",
+ class);
+ }
+ else
+ {
+ map->map_class = &s->s_mapclass;
+ if (map->map_class->map_parse(map, spec))
+ {
+ map->map_mflags |= MF_VALID|MF_ALIAS;
+ NAliasDBs++;
+ }
+ }
+ }
+}
+ /*
+** ALIASWAIT -- wait for distinguished @:@ token to appear.
+**
+** This can decide to reopen or rebuild the alias file
+**
+** Parameters:
+** map -- a pointer to the map descriptor for this alias file.
+** ext -- the filename extension (e.g., ".db") for the
+** database file.
+** isopen -- if set, the database is already open, and we
+** should check for validity; otherwise, we are
+** just checking to see if it should be created.
+**
+** Returns:
+** TRUE -- if the database is open when we return.
+** FALSE -- if the database is closed when we return.
+*/
+
+bool
+aliaswait(map, ext, isopen)
+ MAP *map;
+ char *ext;
+ int isopen;
+{
+ bool attimeout = FALSE;
+ time_t mtime;
+ struct stat stb;
+ char buf[MAXNAME];
+
+ if (tTd(27, 3))
+ printf("aliaswait(%s:%s)\n",
+ map->map_class->map_cname, map->map_file);
+ if (bitset(MF_ALIASWAIT, map->map_mflags))
+ return isopen;
+ map->map_mflags |= MF_ALIASWAIT;
+
+ if (SafeAlias > 0)
+ {
+ auto int st;
+ time_t toolong = curtime() + SafeAlias;
+ unsigned int sleeptime = 2;
+
+ while (isopen &&
+ map->map_class->map_lookup(map, "@", NULL, &st) == NULL)
+ {
+ if (curtime() > toolong)
+ {
+ /* we timed out */
+ attimeout = TRUE;
+ break;
+ }
+
+ /*
+ ** Close and re-open the alias database in case
+ ** the one is mv'ed instead of cp'ed in.
+ */
+
+ if (tTd(27, 2))
+ printf("aliaswait: sleeping for %d seconds\n",
+ sleeptime);
+
+ map->map_class->map_close(map);
+ sleep(sleeptime);
+ sleeptime *= 2;
+ if (sleeptime > 60)
+ sleeptime = 60;
+ isopen = map->map_class->map_open(map, O_RDONLY);
+ }
+ }
+
+ /* see if we need to go into auto-rebuild mode */
+ if (!bitset(MCF_REBUILDABLE, map->map_class->map_cflags))
+ {
+ if (tTd(27, 3))
+ printf("aliaswait: not rebuildable\n");
+ map->map_mflags &= ~MF_ALIASWAIT;
+ return isopen;
+ }
+ if (stat(map->map_file, &stb) < 0)
+ {
+ if (tTd(27, 3))
+ printf("aliaswait: no source file\n");
+ map->map_mflags &= ~MF_ALIASWAIT;
+ return isopen;
+ }
+ mtime = stb.st_mtime;
+ (void) strcpy(buf, map->map_file);
+ if (ext != NULL)
+ (void) strcat(buf, ext);
+ if (stat(buf, &stb) < 0 || stb.st_mtime < mtime || attimeout)
+ {
+ /* database is out of date */
+ if (AutoRebuild && stb.st_ino != 0 && stb.st_uid == geteuid())
+ {
+ message("auto-rebuilding alias database %s", buf);
+ if (isopen)
+ map->map_class->map_close(map);
+ rebuildaliases(map, TRUE);
+ isopen = map->map_class->map_open(map, O_RDONLY);
+ }
+ else
+ {
+#ifdef LOG
+ if (LogLevel > 3)
+ syslog(LOG_INFO, "alias database %s out of date",
+ buf);
+#endif /* LOG */
+ message("Warning: alias database %s out of date", buf);
+ }
+ }
+ map->map_mflags &= ~MF_ALIASWAIT;
+ return isopen;
+}
+ /*
+** REBUILDALIASES -- rebuild the alias database.
+**
+** Parameters:
+** map -- the database to rebuild.
+** automatic -- set if this was automatically generated.
+**
+** Returns:
+** none.
+**
+** Side Effects:
+** Reads the text version of the database, builds the
+** DBM or DB version.
+*/
+
+rebuildaliases(map, automatic)
+ register MAP *map;
+ bool automatic;
+{
+ FILE *af;
+ bool nolock = FALSE;
+ sigfunc_t oldsigint;
+
+ if (!bitset(MCF_REBUILDABLE, map->map_class->map_cflags))
+ return;
+
+ /* try to lock the source file */
+ if ((af = fopen(map->map_file, "r+")) == NULL)
+ {
+ if ((errno != EACCES && errno != EROFS) || automatic ||
+ (af = fopen(map->map_file, "r")) == NULL)
+ {
+ int saveerr = errno;
+
+ if (tTd(27, 1))
+ printf("Can't open %s: %s\n",
+ map->map_file, errstring(saveerr));
+ if (!automatic)
+ message("newaliases: cannot open %s: %s",
+ map->map_file, errstring(saveerr));
+ errno = 0;
+ return;
+ }
+ nolock = TRUE;
+ message("warning: cannot lock %s: %s",
+ map->map_file, errstring(errno));
+ }
+
+ /* see if someone else is rebuilding the alias file */
+ if (!nolock &&
+ !lockfile(fileno(af), map->map_file, NULL, LOCK_EX|LOCK_NB))
+ {
+ /* yes, they are -- wait until done */
+ message("Alias file %s is already being rebuilt",
+ map->map_file);
+ if (OpMode != MD_INITALIAS)
+ {
+ /* wait for other rebuild to complete */
+ (void) lockfile(fileno(af), map->map_file, NULL,
+ LOCK_EX);
+ }
+ (void) xfclose(af, "rebuildaliases1", map->map_file);
+ errno = 0;
+ return;
+ }
+
+ oldsigint = setsignal(SIGINT, SIG_IGN);
+
+ if (map->map_class->map_open(map, O_RDWR))
+ {
+#ifdef LOG
+ if (LogLevel > 7)
+ {
+ syslog(LOG_NOTICE, "alias database %s %srebuilt by %s",
+ map->map_file, automatic ? "auto" : "",
+ username());
+ }
+#endif /* LOG */
+ map->map_mflags |= MF_OPEN|MF_WRITABLE;
+ readaliases(map, af, automatic);
+ }
+ else
+ {
+ if (tTd(27, 1))
+ printf("Can't create database for %s: %s\n",
+ map->map_file, errstring(errno));
+ if (!automatic)
+ syserr("Cannot create database for alias file %s",
+ map->map_file);
+ }
+
+ /* close the file, thus releasing locks */
+ xfclose(af, "rebuildaliases2", map->map_file);
+
+ /* add distinguished entries and close the database */
+ if (bitset(MF_OPEN, map->map_mflags))
+ map->map_class->map_close(map);
+
+ /* restore the old signal */
+ (void) setsignal(SIGINT, oldsigint);
+}
+ /*
+** READALIASES -- read and process the alias file.
+**
+** This routine implements the part of initaliases that occurs
+** when we are not going to use the DBM stuff.
+**
+** Parameters:
+** map -- the alias database descriptor.
+** af -- file to read the aliases from.
+** automatic -- set if this was an automatic rebuild.
+**
+** Returns:
+** none.
+**
+** Side Effects:
+** Reads aliasfile into the symbol table.
+** Optionally, builds the .dir & .pag files.
+*/
+
+readaliases(map, af, automatic)
+ register MAP *map;
+ FILE *af;
+ int automatic;
+{
+ register char *p;
+ char *rhs;
+ bool skipping;
+ long naliases, bytes, longest;
+ ADDRESS al, bl;
+ char line[BUFSIZ];
+
+ /*
+ ** Read and interpret lines
+ */
+
+ FileName = map->map_file;
+ LineNumber = 0;
+ naliases = bytes = longest = 0;
+ skipping = FALSE;
+ while (fgets(line, sizeof (line), af) != NULL)
+ {
+ int lhssize, rhssize;
+
+ LineNumber++;
+ p = strchr(line, '\n');
+ if (p != NULL)
+ *p = '\0';
+ switch (line[0])
+ {
+ case '#':
+ case '\0':
+ skipping = FALSE;
+ continue;
+
+ case ' ':
+ case '\t':
+ if (!skipping)
+ syserr("554 Non-continuation line starts with space");
+ skipping = TRUE;
+ continue;
+ }
+ skipping = FALSE;
+
+ /*
+ ** Process the LHS
+ ** Find the colon separator, and parse the address.
+ ** It should resolve to a local name -- this will
+ ** be checked later (we want to optionally do
+ ** parsing of the RHS first to maximize error
+ ** detection).
+ */
+
+ for (p = line; *p != '\0' && *p != ':' && *p != '\n'; p++)
+ continue;
+ if (*p++ != ':')
+ {
+ syserr("554 missing colon");
+ continue;
+ }
+ if (parseaddr(line, &al, RF_COPYALL, ':', NULL, CurEnv) == NULL)
+ {
+ syserr("554 %.40s... illegal alias name", line);
+ continue;
+ }
+
+ /*
+ ** Process the RHS.
+ ** 'al' is the internal form of the LHS address.
+ ** 'p' points to the text of the RHS.
+ */
+
+ while (isascii(*p) && isspace(*p))
+ p++;
+ rhs = p;
+ for (;;)
+ {
+ register char c;
+ register char *nlp;
+
+ nlp = &p[strlen(p)];
+ if (nlp[-1] == '\n')
+ *--nlp = '\0';
+
+ if (CheckAliases)
+ {
+ /* do parsing & compression of addresses */
+ while (*p != '\0')
+ {
+ auto char *delimptr;
+
+ while ((isascii(*p) && isspace(*p)) ||
+ *p == ',')
+ p++;
+ if (*p == '\0')
+ break;
+ if (parseaddr(p, &bl, RF_COPYNONE, ',',
+ &delimptr, CurEnv) == NULL)
+ usrerr("553 %s... bad address", p);
+ p = delimptr;
+ }
+ }
+ else
+ {
+ p = nlp;
+ }
+
+ /* see if there should be a continuation line */
+ c = fgetc(af);
+ if (!feof(af))
+ (void) ungetc(c, af);
+ if (c != ' ' && c != '\t')
+ break;
+
+ /* read continuation line */
+ if (fgets(p, sizeof line - (p - line), af) == NULL)
+ break;
+ LineNumber++;
+
+ /* check for line overflow */
+ if (strchr(p, '\n') == NULL)
+ {
+ usrerr("554 alias too long");
+ break;
+ }
+ }
+ if (al.q_mailer != LocalMailer)
+ {
+ syserr("554 %s... cannot alias non-local names",
+ al.q_paddr);
+ continue;
+ }
+
+ /*
+ ** Insert alias into symbol table or DBM file
+ */
+
+ if (!bitnset(M_USR_UPPER, al.q_mailer->m_flags))
+ makelower(al.q_user);
+
+ lhssize = strlen(al.q_user);
+ rhssize = strlen(rhs);
+ map->map_class->map_store(map, al.q_user, rhs);
+
+ if (al.q_paddr != NULL)
+ free(al.q_paddr);
+ if (al.q_host != NULL)
+ free(al.q_host);
+ if (al.q_user != NULL)
+ free(al.q_user);
+
+ /* statistics */
+ naliases++;
+ bytes += lhssize + rhssize;
+ if (rhssize > longest)
+ longest = rhssize;
+ }
+
+ CurEnv->e_to = NULL;
+ FileName = NULL;
+ if (Verbose || !automatic)
+ message("%s: %d aliases, longest %d bytes, %d bytes total",
+ map->map_file, naliases, longest, bytes);
+# ifdef LOG
+ if (LogLevel > 7)
+ syslog(LOG_INFO, "%s: %d aliases, longest %d bytes, %d bytes total",
+ map->map_file, naliases, longest, bytes);
+# endif /* LOG */
+}
+ /*
+** FORWARD -- Try to forward mail
+**
+** This is similar but not identical to aliasing.
+**
+** Parameters:
+** user -- the name of the user who's mail we would like
+** to forward to. It must have been verified --
+** i.e., the q_home field must have been filled
+** in.
+** sendq -- a pointer to the head of the send queue to
+** put this user's aliases in.
+**
+** Returns:
+** none.
+**
+** Side Effects:
+** New names are added to send queues.
+*/
+
+forward(user, sendq, e)
+ ADDRESS *user;
+ ADDRESS **sendq;
+ register ENVELOPE *e;
+{
+ char *pp;
+ char *ep;
+
+ if (tTd(27, 1))
+ printf("forward(%s)\n", user->q_paddr);
+
+ if (user->q_mailer != LocalMailer || bitset(QBADADDR, user->q_flags))
+ return;
+ if (user->q_home == NULL)
+ {
+ syserr("554 forward: no home");
+ user->q_home = "/nosuchdirectory";
+ }
+
+ /* good address -- look for .forward file in home */
+ define('z', user->q_home, e);
+ define('u', user->q_user, e);
+ define('h', user->q_host, e);
+ if (ForwardPath == NULL)
+ ForwardPath = newstr("\201z/.forward");
+
+ for (pp = ForwardPath; pp != NULL; pp = ep)
+ {
+ int err;
+ char buf[MAXPATHLEN+1];
+
+ ep = strchr(pp, ':');
+ if (ep != NULL)
+ *ep = '\0';
+ expand(pp, buf, &buf[sizeof buf - 1], e);
+ if (ep != NULL)
+ *ep++ = ':';
+ if (tTd(27, 3))
+ printf("forward: trying %s\n", buf);
+
+ err = include(buf, TRUE, user, sendq, e);
+ if (err == 0)
+ break;
+ else if (transienterror(err))
+ {
+ /* we have to suspend this message */
+ if (tTd(27, 2))
+ printf("forward: transient error on %s\n", buf);
+#ifdef LOG
+ if (LogLevel > 2)
+ syslog(LOG_ERR, "%s: forward %s: transient error: %s",
+ e->e_id == NULL ? "NOQUEUE" : e->e_id,
+ buf, errstring(err));
+#endif
+ message("%s: %s: message queued", buf, errstring(err));
+ user->q_flags |= QQUEUEUP;
+ return;
+ }
+ }
+}
diff --git a/usr.sbin/sendmail/src/aliases.5 b/usr.sbin/sendmail/src/aliases.5
new file mode 100644
index 0000000..f40f64d
--- /dev/null
+++ b/usr.sbin/sendmail/src/aliases.5
@@ -0,0 +1,106 @@
+.\" Copyright (c) 1985, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)aliases.5 8.2 (Berkeley) 12/11/93
+.\"
+.Dd December 11, 1993
+.Dt ALIASES 5
+.Os BSD 4
+.Sh NAME
+.Nm aliases
+.Nd aliases file for sendmail
+.Sh SYNOPSIS
+.Nm aliases
+.Sh DESCRIPTION
+This file describes user
+.Tn ID
+aliases used by
+.Pa /usr/sbin/sendmail .
+The file resides in
+.Pa /etc
+and
+is formatted as a series of lines of the form
+.Bd -filled -offset indent
+name: name_1, name2, name_3, . . .
+.Ed
+.Pp
+The
+.Em name
+is the name to alias, and the
+.Em name_n
+are the aliases for that name.
+Lines beginning with white space are continuation lines.
+Lines beginning with
+.Ql #
+are comments.
+.Pp
+Aliasing occurs only on local names.
+Loops can not occur, since no message will be sent to any person more than once.
+.Pp
+After aliasing has been done, local and valid recipients who have a
+.Dq Pa .forward
+file in their home directory have messages forwarded to the
+list of users defined in that file.
+.Pp
+This is only the raw data file; the actual aliasing information is
+placed into a binary format in the file
+.Pa /etc/aliases.db
+using the program
+.Xr newaliases 1 .
+A
+.Xr newaliases
+command should be executed each time the aliases file is changed for the
+change to take effect.
+.Sh SEE ALSO
+.Xr newaliases 1 ,
+.Xr dbopen 3 ,
+.Xr dbm 3 ,
+.Xr sendmail 8
+.Rs
+.%T "SENDMAIL Installation and Operation Guide"
+.Re
+.Rs
+.%T "SENDMAIL An Internetwork Mail Router"
+.Re
+.Sh BUGS
+If you have compiled
+.Xr sendmail
+with DBM support instead of NEWDB,
+you may have encountered problems in
+.Xr dbm 3
+restricting a single alias to about 1000 bytes of information.
+You can get longer aliases by ``chaining''; that is, make the last name in
+the alias be a dummy name which is a continuation alias.
+.Sh HISTORY
+The
+.Nm
+file format appeared in
+.Bx 4.0 .
diff --git a/usr.sbin/sendmail/src/arpadate.c b/usr.sbin/sendmail/src/arpadate.c
new file mode 100644
index 0000000..d3f9ac5
--- /dev/null
+++ b/usr.sbin/sendmail/src/arpadate.c
@@ -0,0 +1,173 @@
+/*
+ * Copyright (c) 1983 Eric P. Allman
+ * Copyright (c) 1988, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)arpadate.c 8.1 (Berkeley) 6/7/93";
+#endif /* not lint */
+
+# include "sendmail.h"
+
+/*
+** ARPADATE -- Create date in ARPANET format
+**
+** Parameters:
+** ud -- unix style date string. if NULL, one is created.
+**
+** Returns:
+** pointer to an ARPANET date field
+**
+** Side Effects:
+** none
+**
+** WARNING:
+** date is stored in a local buffer -- subsequent
+** calls will overwrite.
+**
+** Bugs:
+** Timezone is computed from local time, rather than
+** from whereever (and whenever) the message was sent.
+** To do better is very hard.
+**
+** Some sites are now inserting the timezone into the
+** local date. This routine should figure out what
+** the format is and work appropriately.
+*/
+
+char *
+arpadate(ud)
+ register char *ud;
+{
+ register char *p;
+ register char *q;
+ register int off;
+ register int i;
+ register struct tm *lt;
+ time_t t;
+ struct tm gmt;
+ static char b[40];
+
+ /*
+ ** Get current time.
+ ** This will be used if a null argument is passed and
+ ** to resolve the timezone.
+ */
+
+ (void) time(&t);
+ if (ud == NULL)
+ ud = ctime(&t);
+
+ /*
+ ** Crack the UNIX date line in a singularly unoriginal way.
+ */
+
+ q = b;
+
+ p = &ud[0]; /* Mon */
+ *q++ = *p++;
+ *q++ = *p++;
+ *q++ = *p++;
+ *q++ = ',';
+ *q++ = ' ';
+
+ p = &ud[8]; /* 16 */
+ if (*p == ' ')
+ p++;
+ else
+ *q++ = *p++;
+ *q++ = *p++;
+ *q++ = ' ';
+
+ p = &ud[4]; /* Sep */
+ *q++ = *p++;
+ *q++ = *p++;
+ *q++ = *p++;
+ *q++ = ' ';
+
+ p = &ud[20]; /* 1979 */
+ *q++ = *p++;
+ *q++ = *p++;
+ *q++ = *p++;
+ *q++ = *p++;
+ *q++ = ' ';
+
+ p = &ud[11]; /* 01:03:52 */
+ for (i = 8; i > 0; i--)
+ *q++ = *p++;
+
+ /*
+ * should really get the timezone from the time in "ud" (which
+ * is only different if a non-null arg was passed which is different
+ * from the current time), but for all practical purposes, returning
+ * the current local zone will do (its all that is ever needed).
+ */
+ gmt = *gmtime(&t);
+ lt = localtime(&t);
+
+ off = (lt->tm_hour - gmt.tm_hour) * 60 + lt->tm_min - gmt.tm_min;
+
+ /* assume that offset isn't more than a day ... */
+ if (lt->tm_year < gmt.tm_year)
+ off -= 24 * 60;
+ else if (lt->tm_year > gmt.tm_year)
+ off += 24 * 60;
+ else if (lt->tm_yday < gmt.tm_yday)
+ off -= 24 * 60;
+ else if (lt->tm_yday > gmt.tm_yday)
+ off += 24 * 60;
+
+ *q++ = ' ';
+ if (off == 0) {
+ *q++ = 'G';
+ *q++ = 'M';
+ *q++ = 'T';
+ } else {
+ if (off < 0) {
+ off = -off;
+ *q++ = '-';
+ } else
+ *q++ = '+';
+
+ if (off >= 24*60) /* should be impossible */
+ off = 23*60+59; /* if not, insert silly value */
+
+ *q++ = (off / 600) + '0';
+ *q++ = (off / 60) % 10 + '0';
+ off %= 60;
+ *q++ = (off / 10) + '0';
+ *q++ = (off % 10) + '0';
+ }
+ *q = '\0';
+
+ return (b);
+}
diff --git a/usr.sbin/sendmail/src/clock.c b/usr.sbin/sendmail/src/clock.c
new file mode 100644
index 0000000..45ef1c2
--- /dev/null
+++ b/usr.sbin/sendmail/src/clock.c
@@ -0,0 +1,276 @@
+/*
+ * Copyright (c) 1983 Eric P. Allman
+ * Copyright (c) 1988, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)clock.c 8.8 (Berkeley) 1/12/94";
+#endif /* not lint */
+
+# include "sendmail.h"
+
+# ifndef sigmask
+# define sigmask(s) (1 << ((s) - 1))
+# endif
+
+/*
+** SETEVENT -- set an event to happen at a specific time.
+**
+** Events are stored in a sorted list for fast processing.
+** An event only applies to the process that set it.
+**
+** Parameters:
+** intvl -- intvl until next event occurs.
+** func -- function to call on event.
+** arg -- argument to func on event.
+**
+** Returns:
+** none.
+**
+** Side Effects:
+** none.
+*/
+
+static void tick __P((int));
+
+EVENT *
+setevent(intvl, func, arg)
+ time_t intvl;
+ int (*func)();
+ int arg;
+{
+ register EVENT **evp;
+ register EVENT *ev;
+ auto time_t now;
+
+ if (intvl <= 0)
+ {
+ syserr("554 setevent: intvl=%ld\n", intvl);
+ return (NULL);
+ }
+
+ (void) setsignal(SIGALRM, SIG_IGN);
+ (void) time(&now);
+
+ /* search event queue for correct position */
+ for (evp = &EventQueue; (ev = *evp) != NULL; evp = &ev->ev_link)
+ {
+ if (ev->ev_time >= now + intvl)
+ break;
+ }
+
+ /* insert new event */
+ ev = (EVENT *) xalloc(sizeof *ev);
+ ev->ev_time = now + intvl;
+ ev->ev_func = func;
+ ev->ev_arg = arg;
+ ev->ev_pid = getpid();
+ ev->ev_link = *evp;
+ *evp = ev;
+
+ if (tTd(5, 5))
+ printf("setevent: intvl=%ld, for=%ld, func=%x, arg=%d, ev=%x\n",
+ intvl, now + intvl, func, arg, ev);
+
+ tick(0);
+ return (ev);
+}
+ /*
+** CLREVENT -- remove an event from the event queue.
+**
+** Parameters:
+** ev -- pointer to event to remove.
+**
+** Returns:
+** none.
+**
+** Side Effects:
+** arranges for event ev to not happen.
+*/
+
+clrevent(ev)
+ register EVENT *ev;
+{
+ register EVENT **evp;
+
+ if (tTd(5, 5))
+ printf("clrevent: ev=%x\n", ev);
+ if (ev == NULL)
+ return;
+
+ /* find the parent event */
+ (void) setsignal(SIGALRM, SIG_IGN);
+ for (evp = &EventQueue; *evp != NULL; evp = &(*evp)->ev_link)
+ {
+ if (*evp == ev)
+ break;
+ }
+
+ /* now remove it */
+ if (*evp != NULL)
+ {
+ *evp = ev->ev_link;
+ free((char *) ev);
+ }
+
+ /* restore clocks and pick up anything spare */
+ tick(0);
+}
+ /*
+** TICK -- take a clock tick
+**
+** Called by the alarm clock. This routine runs events as needed.
+**
+** Parameters:
+** One that is ignored; for compatibility with signal handlers.
+**
+** Returns:
+** none.
+**
+** Side Effects:
+** calls the next function in EventQueue.
+*/
+
+static void
+tick(arg)
+ int arg;
+{
+ register time_t now;
+ register EVENT *ev;
+ int mypid = getpid();
+ int olderrno = errno;
+#ifdef SIG_UNBLOCK
+ sigset_t ss;
+#endif
+
+ (void) setsignal(SIGALRM, SIG_IGN);
+ (void) alarm(0);
+ now = curtime();
+
+ if (tTd(5, 4))
+ printf("tick: now=%ld\n", now);
+
+ while ((ev = EventQueue) != NULL &&
+ (ev->ev_time <= now || ev->ev_pid != mypid))
+ {
+ int (*f)();
+ int arg;
+ int pid;
+
+ /* process the event on the top of the queue */
+ ev = EventQueue;
+ EventQueue = EventQueue->ev_link;
+ if (tTd(5, 6))
+ printf("tick: ev=%x, func=%x, arg=%d, pid=%d\n", ev,
+ ev->ev_func, ev->ev_arg, ev->ev_pid);
+
+ /* we must be careful in here because ev_func may not return */
+ f = ev->ev_func;
+ arg = ev->ev_arg;
+ pid = ev->ev_pid;
+ free((char *) ev);
+ if (pid != getpid())
+ continue;
+ if (EventQueue != NULL)
+ {
+ if (EventQueue->ev_time > now)
+ (void) alarm((unsigned) (EventQueue->ev_time - now));
+ else
+ (void) alarm(3);
+ }
+
+ /* restore signals so that we can take ticks while in ev_func */
+ (void) setsignal(SIGALRM, tick);
+#ifdef SIG_UNBLOCK
+ /* unblock SIGALRM signal */
+ sigemptyset(&ss);
+ sigaddset(&ss, SIGALRM);
+ sigprocmask(SIG_UNBLOCK, &ss, NULL);
+#else
+#ifdef SIGVTALRM
+ /* reset 4.2bsd signal mask to allow future alarms */
+ (void) sigsetmask(sigblock(0) & ~sigmask(SIGALRM));
+#endif /* SIGVTALRM */
+#endif /* SIG_UNBLOCK */
+
+ /* call ev_func */
+ errno = olderrno;
+ (*f)(arg);
+ (void) alarm(0);
+ now = curtime();
+ }
+ (void) setsignal(SIGALRM, tick);
+ if (EventQueue != NULL)
+ (void) alarm((unsigned) (EventQueue->ev_time - now));
+ errno = olderrno;
+}
+ /*
+** SLEEP -- a version of sleep that works with this stuff
+**
+** Because sleep uses the alarm facility, I must reimplement
+** it here.
+**
+** Parameters:
+** intvl -- time to sleep.
+**
+** Returns:
+** none.
+**
+** Side Effects:
+** waits for intvl time. However, other events can
+** be run during that interval.
+*/
+
+static bool SleepDone;
+static int endsleep();
+
+#ifndef SLEEP_T
+# define SLEEP_T unsigned int
+#endif
+
+SLEEP_T
+sleep(intvl)
+ unsigned int intvl;
+{
+ if (intvl == 0)
+ return;
+ SleepDone = FALSE;
+ (void) setevent((time_t) intvl, endsleep, 0);
+ while (!SleepDone)
+ pause();
+}
+
+static
+endsleep()
+{
+ SleepDone = TRUE;
+}
diff --git a/usr.sbin/sendmail/src/collect.c b/usr.sbin/sendmail/src/collect.c
new file mode 100644
index 0000000..b77f6e9
--- /dev/null
+++ b/usr.sbin/sendmail/src/collect.c
@@ -0,0 +1,579 @@
+/*
+ * Copyright (c) 1983 Eric P. Allman
+ * Copyright (c) 1988, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)collect.c 8.14 (Berkeley) 4/18/94";
+#endif /* not lint */
+
+# include <errno.h>
+# include "sendmail.h"
+
+/*
+** COLLECT -- read & parse message header & make temp file.
+**
+** Creates a temporary file name and copies the standard
+** input to that file. Leading UNIX-style "From" lines are
+** stripped off (after important information is extracted).
+**
+** Parameters:
+** smtpmode -- if set, we are running SMTP: give an RFC821
+** style message to say we are ready to collect
+** input, and never ignore a single dot to mean
+** end of message.
+** requeueflag -- this message will be requeued later, so
+** don't do final processing on it.
+** e -- the current envelope.
+**
+** Returns:
+** none.
+**
+** Side Effects:
+** Temp file is created and filled.
+** The from person may be set.
+*/
+
+char *CollectErrorMessage;
+bool CollectErrno;
+
+collect(smtpmode, requeueflag, e)
+ bool smtpmode;
+ bool requeueflag;
+ register ENVELOPE *e;
+{
+ register FILE *tf;
+ bool ignrdot = smtpmode ? FALSE : IgnrDot;
+ char buf[MAXLINE], buf2[MAXLINE];
+ register char *workbuf, *freebuf;
+ bool inputerr = FALSE;
+ extern char *hvalue();
+ extern bool isheader(), flusheol();
+
+ CollectErrorMessage = NULL;
+ CollectErrno = 0;
+
+ /*
+ ** Create the temp file name and create the file.
+ */
+
+ e->e_df = queuename(e, 'd');
+ e->e_df = newstr(e->e_df);
+ if ((tf = dfopen(e->e_df, O_WRONLY|O_CREAT|O_TRUNC, FileMode)) == NULL)
+ {
+ syserr("Cannot create %s", e->e_df);
+ NoReturn = TRUE;
+ finis();
+ }
+
+ /*
+ ** Tell ARPANET to go ahead.
+ */
+
+ if (smtpmode)
+ message("354 Enter mail, end with \".\" on a line by itself");
+
+ /* set global timer to monitor progress */
+ sfgetset(TimeOuts.to_datablock);
+
+ /*
+ ** Try to read a UNIX-style From line
+ */
+
+ if (sfgets(buf, MAXLINE, InChannel, TimeOuts.to_datablock,
+ "initial message read") == NULL)
+ goto readerr;
+ fixcrlf(buf, FALSE);
+# ifndef NOTUNIX
+ if (!SaveFrom && strncmp(buf, "From ", 5) == 0)
+ {
+ if (!flusheol(buf, InChannel))
+ goto readerr;
+ eatfrom(buf, e);
+ if (sfgets(buf, MAXLINE, InChannel, TimeOuts.to_datablock,
+ "message header read") == NULL)
+ goto readerr;
+ fixcrlf(buf, FALSE);
+ }
+# endif /* NOTUNIX */
+
+ /*
+ ** Copy InChannel to temp file & do message editing.
+ ** To keep certain mailers from getting confused,
+ ** and to keep the output clean, lines that look
+ ** like UNIX "From" lines are deleted in the header.
+ */
+
+ workbuf = buf; /* `workbuf' contains a header field */
+ freebuf = buf2; /* `freebuf' can be used for read-ahead */
+ for (;;)
+ {
+ char *curbuf;
+ int curbuffree;
+ register int curbuflen;
+ char *p;
+
+ /* first, see if the header is over */
+ if (!isheader(workbuf))
+ {
+ fixcrlf(workbuf, TRUE);
+ break;
+ }
+
+ /* if the line is too long, throw the rest away */
+ if (!flusheol(workbuf, InChannel))
+ goto readerr;
+
+ /* it's okay to toss '\n' now (flusheol() needed it) */
+ fixcrlf(workbuf, TRUE);
+
+ curbuf = workbuf;
+ curbuflen = strlen(curbuf);
+ curbuffree = MAXLINE - curbuflen;
+ p = curbuf + curbuflen;
+
+ /* get the rest of this field */
+ for (;;)
+ {
+ int clen;
+
+ if (sfgets(freebuf, MAXLINE, InChannel,
+ TimeOuts.to_datablock,
+ "message header read") == NULL)
+ {
+ freebuf[0] = '\0';
+ break;
+ }
+
+ /* is this a continuation line? */
+ if (*freebuf != ' ' && *freebuf != '\t')
+ break;
+
+ if (!flusheol(freebuf, InChannel))
+ goto readerr;
+
+ fixcrlf(freebuf, TRUE);
+ clen = strlen(freebuf) + 1;
+
+ /* if insufficient room, dynamically allocate buffer */
+ if (clen >= curbuffree)
+ {
+ /* reallocate buffer */
+ int nbuflen = ((p - curbuf) + clen) * 2;
+ char *nbuf = xalloc(nbuflen);
+
+ p = nbuf + curbuflen;
+ curbuffree = nbuflen - curbuflen;
+ bcopy(curbuf, nbuf, curbuflen);
+ if (curbuf != buf && curbuf != buf2)
+ free(curbuf);
+ curbuf = nbuf;
+ }
+ *p++ = '\n';
+ bcopy(freebuf, p, clen - 1);
+ p += clen - 1;
+ curbuffree -= clen;
+ curbuflen += clen;
+ }
+ *p++ = '\0';
+
+ e->e_msgsize += curbuflen;
+
+ /*
+ ** The working buffer now becomes the free buffer, since
+ ** the free buffer contains a new header field.
+ **
+ ** This is premature, since we still havent called
+ ** chompheader() to process the field we just created
+ ** (so the call to chompheader() will use `freebuf').
+ ** This convolution is necessary so that if we break out
+ ** of the loop due to H_EOH, `workbuf' will always be
+ ** the next unprocessed buffer.
+ */
+
+ {
+ register char *tmp = workbuf;
+ workbuf = freebuf;
+ freebuf = tmp;
+ }
+
+ /*
+ ** Snarf header away.
+ */
+
+ if (bitset(H_EOH, chompheader(curbuf, FALSE, e)))
+ break;
+
+ /*
+ ** If the buffer was dynamically allocated, free it.
+ */
+
+ if (curbuf != buf && curbuf != buf2)
+ free(curbuf);
+ }
+
+ if (tTd(30, 1))
+ printf("EOH\n");
+
+ if (*workbuf == '\0')
+ {
+ /* throw away a blank line */
+ if (sfgets(buf, MAXLINE, InChannel, TimeOuts.to_datablock,
+ "message separator read") == NULL)
+ goto readerr;
+ }
+ else if (workbuf == buf2) /* guarantee `buf' contains data */
+ (void) strcpy(buf, buf2);
+
+ /*
+ ** Collect the body of the message.
+ */
+
+ for (;;)
+ {
+ register char *bp = buf;
+
+ fixcrlf(buf, TRUE);
+
+ /* check for end-of-message */
+ if (!ignrdot && buf[0] == '.' && (buf[1] == '\n' || buf[1] == '\0'))
+ break;
+
+ /* check for transparent dot */
+ if ((OpMode == MD_SMTP || OpMode == MD_DAEMON) &&
+ bp[0] == '.' && bp[1] == '.')
+ bp++;
+
+ /*
+ ** Figure message length, output the line to the temp
+ ** file, and insert a newline if missing.
+ */
+
+ e->e_msgsize += strlen(bp) + 1;
+ fputs(bp, tf);
+ fputs("\n", tf);
+ if (ferror(tf))
+ tferror(tf, e);
+ if (sfgets(buf, MAXLINE, InChannel, TimeOuts.to_datablock,
+ "message body read") == NULL)
+ goto readerr;
+ }
+
+ if (feof(InChannel) || ferror(InChannel))
+ {
+readerr:
+ if (tTd(30, 1))
+ printf("collect: read error\n");
+ inputerr = TRUE;
+ }
+
+ /* reset global timer */
+ sfgetset((time_t) 0);
+
+ if (fflush(tf) != 0)
+ tferror(tf, e);
+ if (fsync(fileno(tf)) < 0 || fclose(tf) < 0)
+ {
+ tferror(tf, e);
+ finis();
+ }
+
+ if (CollectErrorMessage != NULL && Errors <= 0)
+ {
+ if (CollectErrno != 0)
+ {
+ errno = CollectErrno;
+ syserr(CollectErrorMessage, e->e_df);
+ finis();
+ }
+ usrerr(CollectErrorMessage);
+ }
+ else if (inputerr && (OpMode == MD_SMTP || OpMode == MD_DAEMON))
+ {
+ /* An EOF when running SMTP is an error */
+ char *host;
+ char *problem;
+
+ host = RealHostName;
+ if (host == NULL)
+ host = "localhost";
+
+ if (feof(InChannel))
+ problem = "unexpected close";
+ else if (ferror(InChannel))
+ problem = "I/O error";
+ else
+ problem = "read timeout";
+# ifdef LOG
+ if (LogLevel > 0 && feof(InChannel))
+ syslog(LOG_NOTICE,
+ "collect: %s on connection from %s, sender=%s: %s\n",
+ problem, host, e->e_from.q_paddr, errstring(errno));
+# endif
+ if (feof(InChannel))
+ usrerr("451 collect: %s on connection from %s, from=%s",
+ problem, host, e->e_from.q_paddr);
+ else
+ syserr("451 collect: %s on connection from %s, from=%s",
+ problem, host, e->e_from.q_paddr);
+
+ /* don't return an error indication */
+ e->e_to = NULL;
+ e->e_flags &= ~EF_FATALERRS;
+ e->e_flags |= EF_CLRQUEUE;
+
+ /* and don't try to deliver the partial message either */
+ if (InChild)
+ ExitStat = EX_QUIT;
+ finis();
+ }
+
+ /*
+ ** Find out some information from the headers.
+ ** Examples are who is the from person & the date.
+ */
+
+ eatheader(e, !requeueflag);
+
+ /* collect statistics */
+ if (OpMode != MD_VERIFY)
+ markstats(e, (ADDRESS *) NULL);
+
+ /*
+ ** Add an Apparently-To: line if we have no recipient lines.
+ */
+
+ if (hvalue("to", e) == NULL && hvalue("cc", e) == NULL &&
+ hvalue("bcc", e) == NULL && hvalue("apparently-to", e) == NULL)
+ {
+ register ADDRESS *q;
+
+ /* create an Apparently-To: field */
+ /* that or reject the message.... */
+ for (q = e->e_sendqueue; q != NULL; q = q->q_next)
+ {
+ if (q->q_alias != NULL)
+ continue;
+ if (tTd(30, 3))
+ printf("Adding Apparently-To: %s\n", q->q_paddr);
+ addheader("Apparently-To", q->q_paddr, e);
+ }
+ }
+
+ /* check for message too large */
+ if (MaxMessageSize > 0 && e->e_msgsize > MaxMessageSize)
+ {
+ usrerr("552 Message exceeds maximum fixed size (%ld)",
+ MaxMessageSize);
+ }
+
+ if ((e->e_dfp = fopen(e->e_df, "r")) == NULL)
+ {
+ /* we haven't acked receipt yet, so just chuck this */
+ syserr("Cannot reopen %s", e->e_df);
+ finis();
+ }
+}
+ /*
+** FLUSHEOL -- if not at EOL, throw away rest of input line.
+**
+** Parameters:
+** buf -- last line read in (checked for '\n'),
+** fp -- file to be read from.
+**
+** Returns:
+** FALSE on error from sfgets(), TRUE otherwise.
+**
+** Side Effects:
+** none.
+*/
+
+bool
+flusheol(buf, fp)
+ char *buf;
+ FILE *fp;
+{
+ register char *p = buf;
+ char junkbuf[MAXLINE];
+
+ while (strchr(p, '\n') == NULL)
+ {
+ CollectErrorMessage = "553 header line too long";
+ CollectErrno = 0;
+ if (sfgets(junkbuf, MAXLINE, fp, TimeOuts.to_datablock,
+ "long line flush") == NULL)
+ return (FALSE);
+ p = junkbuf;
+ }
+
+ return (TRUE);
+}
+ /*
+** TFERROR -- signal error on writing the temporary file.
+**
+** Parameters:
+** tf -- the file pointer for the temporary file.
+**
+** Returns:
+** none.
+**
+** Side Effects:
+** Gives an error message.
+** Arranges for following output to go elsewhere.
+*/
+
+tferror(tf, e)
+ FILE *tf;
+ register ENVELOPE *e;
+{
+ CollectErrno = errno;
+ if (errno == ENOSPC)
+ {
+ struct stat st;
+ long avail;
+ long bsize;
+
+ NoReturn = TRUE;
+ if (fstat(fileno(tf), &st) < 0)
+ st.st_size = 0;
+ (void) freopen(e->e_df, "w", tf);
+ if (st.st_size <= 0)
+ fprintf(tf, "\n*** Mail could not be accepted");
+ else if (sizeof st.st_size > sizeof (long))
+ fprintf(tf, "\n*** Mail of at least %qd bytes could not be accepted\n",
+ st.st_size);
+ else
+ fprintf(tf, "\n*** Mail of at least %ld bytes could not be accepted\n",
+ st.st_size);
+ fprintf(tf, "*** at %s due to lack of disk space for temp file.\n",
+ MyHostName);
+ avail = freespace(QueueDir, &bsize);
+ if (avail > 0)
+ {
+ if (bsize > 1024)
+ avail *= bsize / 1024;
+ else if (bsize < 1024)
+ avail /= 1024 / bsize;
+ fprintf(tf, "*** Currently, %ld kilobytes are available for mail temp files.\n",
+ avail);
+ }
+ CollectErrorMessage = "452 Out of disk space for temp file";
+ }
+ else
+ {
+ CollectErrorMessage = "cannot write message body to disk (%s)";
+ }
+ (void) freopen("/dev/null", "w", tf);
+}
+ /*
+** EATFROM -- chew up a UNIX style from line and process
+**
+** This does indeed make some assumptions about the format
+** of UNIX messages.
+**
+** Parameters:
+** fm -- the from line.
+**
+** Returns:
+** none.
+**
+** Side Effects:
+** extracts what information it can from the header,
+** such as the date.
+*/
+
+# ifndef NOTUNIX
+
+char *DowList[] =
+{
+ "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", NULL
+};
+
+char *MonthList[] =
+{
+ "Jan", "Feb", "Mar", "Apr", "May", "Jun",
+ "Jul", "Aug", "Sep", "Oct", "Nov", "Dec",
+ NULL
+};
+
+eatfrom(fm, e)
+ char *fm;
+ register ENVELOPE *e;
+{
+ register char *p;
+ register char **dt;
+
+ if (tTd(30, 2))
+ printf("eatfrom(%s)\n", fm);
+
+ /* find the date part */
+ p = fm;
+ while (*p != '\0')
+ {
+ /* skip a word */
+ while (*p != '\0' && *p != ' ')
+ p++;
+ while (*p == ' ')
+ p++;
+ if (!(isascii(*p) && isupper(*p)) ||
+ p[3] != ' ' || p[13] != ':' || p[16] != ':')
+ continue;
+
+ /* we have a possible date */
+ for (dt = DowList; *dt != NULL; dt++)
+ if (strncmp(*dt, p, 3) == 0)
+ break;
+ if (*dt == NULL)
+ continue;
+
+ for (dt = MonthList; *dt != NULL; dt++)
+ if (strncmp(*dt, &p[4], 3) == 0)
+ break;
+ if (*dt != NULL)
+ break;
+ }
+
+ if (*p != '\0')
+ {
+ char *q;
+ extern char *arpadate();
+
+ /* we have found a date */
+ q = xalloc(25);
+ (void) strncpy(q, p, 25);
+ q[24] = '\0';
+ q = arpadate(q);
+ define('a', newstr(q), e);
+ }
+}
+
+# endif /* NOTUNIX */
diff --git a/usr.sbin/sendmail/src/conf.c b/usr.sbin/sendmail/src/conf.c
new file mode 100644
index 0000000..4ac109a
--- /dev/null
+++ b/usr.sbin/sendmail/src/conf.c
@@ -0,0 +1,2377 @@
+/*
+ * Copyright (c) 1983 Eric P. Allman
+ * Copyright (c) 1988, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)conf.c 8.89 (Berkeley) 4/18/94";
+#endif /* not lint */
+
+# include "sendmail.h"
+# include "pathnames.h"
+# include <sys/ioctl.h>
+# include <sys/param.h>
+# include <netdb.h>
+# include <pwd.h>
+
+/*
+** CONF.C -- Sendmail Configuration Tables.
+**
+** Defines the configuration of this installation.
+**
+** Configuration Variables:
+** HdrInfo -- a table describing well-known header fields.
+** Each entry has the field name and some flags,
+** which are described in sendmail.h.
+**
+** Notes:
+** I have tried to put almost all the reasonable
+** configuration information into the configuration
+** file read at runtime. My intent is that anything
+** here is a function of the version of UNIX you
+** are running, or is really static -- for example
+** the headers are a superset of widely used
+** protocols. If you find yourself playing with
+** this file too much, you may be making a mistake!
+*/
+
+
+
+
+/*
+** Header info table
+** Final (null) entry contains the flags used for any other field.
+**
+** Not all of these are actually handled specially by sendmail
+** at this time. They are included as placeholders, to let
+** you know that "someday" I intend to have sendmail do
+** something with them.
+*/
+
+struct hdrinfo HdrInfo[] =
+{
+ /* originator fields, most to least significant */
+ "resent-sender", H_FROM|H_RESENT,
+ "resent-from", H_FROM|H_RESENT,
+ "resent-reply-to", H_FROM|H_RESENT,
+ "sender", H_FROM,
+ "from", H_FROM,
+ "reply-to", H_FROM,
+ "full-name", H_ACHECK,
+ "return-receipt-to", H_FROM|H_RECEIPTTO,
+ "errors-to", H_FROM|H_ERRORSTO,
+
+ /* destination fields */
+ "to", H_RCPT,
+ "resent-to", H_RCPT|H_RESENT,
+ "cc", H_RCPT,
+ "resent-cc", H_RCPT|H_RESENT,
+ "bcc", H_RCPT|H_ACHECK,
+ "resent-bcc", H_RCPT|H_ACHECK|H_RESENT,
+ "apparently-to", H_RCPT,
+
+ /* message identification and control */
+ "message-id", 0,
+ "resent-message-id", H_RESENT,
+ "message", H_EOH,
+ "text", H_EOH,
+
+ /* date fields */
+ "date", 0,
+ "resent-date", H_RESENT,
+
+ /* trace fields */
+ "received", H_TRACE|H_FORCE,
+ "x400-received", H_TRACE|H_FORCE,
+ "via", H_TRACE|H_FORCE,
+ "mail-from", H_TRACE|H_FORCE,
+
+ /* miscellaneous fields */
+ "comments", H_FORCE,
+ "return-path", H_FORCE|H_ACHECK,
+
+ NULL, 0,
+};
+
+
+
+/*
+** Location of system files/databases/etc.
+*/
+
+char *PidFile = _PATH_SENDMAILPID; /* stores daemon proc id */
+
+
+
+/*
+** Privacy values
+*/
+
+struct prival PrivacyValues[] =
+{
+ "public", PRIV_PUBLIC,
+ "needmailhelo", PRIV_NEEDMAILHELO,
+ "needexpnhelo", PRIV_NEEDEXPNHELO,
+ "needvrfyhelo", PRIV_NEEDVRFYHELO,
+ "noexpn", PRIV_NOEXPN,
+ "novrfy", PRIV_NOVRFY,
+ "restrictmailq", PRIV_RESTRICTMAILQ,
+ "restrictqrun", PRIV_RESTRICTQRUN,
+ "authwarnings", PRIV_AUTHWARNINGS,
+ "noreceipts", PRIV_NORECEIPTS,
+ "goaway", PRIV_GOAWAY,
+ NULL, 0,
+};
+
+
+
+/*
+** Miscellaneous stuff.
+*/
+
+int DtableSize = 50; /* max open files; reset in 4.2bsd */
+
+
+/*
+** Following should be config parameters (and probably will be in
+** future releases). In the meantime, setting these is considered
+** unsupported, and is intentionally undocumented.
+*/
+
+#ifdef BROKENSMTPPEERS
+bool BrokenSmtpPeers = TRUE; /* set if you have broken SMTP peers */
+#else
+bool BrokenSmtpPeers = FALSE; /* set if you have broken SMTP peers */
+#endif
+#ifdef NOLOOPBACKCHECK
+bool CheckLoopBack = FALSE; /* set to check HELO loopback */
+#else
+bool CheckLoopBack = TRUE; /* set to check HELO loopback */
+#endif
+
+ /*
+** SETDEFAULTS -- set default values
+**
+** Because of the way freezing is done, these must be initialized
+** using direct code.
+**
+** Parameters:
+** e -- the default envelope.
+**
+** Returns:
+** none.
+**
+** Side Effects:
+** Initializes a bunch of global variables to their
+** default values.
+*/
+
+#define DAYS * 24 * 60 * 60
+
+setdefaults(e)
+ register ENVELOPE *e;
+{
+ SpaceSub = ' '; /* option B */
+ QueueLA = 8; /* option x */
+ RefuseLA = 12; /* option X */
+ WkRecipFact = 30000L; /* option y */
+ WkClassFact = 1800L; /* option z */
+ WkTimeFact = 90000L; /* option Z */
+ QueueFactor = WkRecipFact * 20; /* option q */
+ FileMode = (RealUid != geteuid()) ? 0644 : 0600;
+ /* option F */
+ DefUid = 1; /* option u */
+ DefGid = 1; /* option g */
+ CheckpointInterval = 10; /* option C */
+ MaxHopCount = 25; /* option h */
+ e->e_sendmode = SM_FORK; /* option d */
+ e->e_errormode = EM_PRINT; /* option e */
+ SevenBit = FALSE; /* option 7 */
+ MaxMciCache = 1; /* option k */
+ MciCacheTimeout = 300; /* option K */
+ LogLevel = 9; /* option L */
+ settimeouts(NULL); /* option r */
+ TimeOuts.to_q_return = 5 DAYS; /* option T */
+ TimeOuts.to_q_warning = 0; /* option T */
+ PrivacyFlags = 0; /* option p */
+ setdefuser();
+ setupmaps();
+ setupmailers();
+}
+
+
+/*
+** SETDEFUSER -- set/reset DefUser using DefUid (for initgroups())
+*/
+
+setdefuser()
+{
+ struct passwd *defpwent;
+ static char defuserbuf[40];
+
+ DefUser = defuserbuf;
+ if ((defpwent = getpwuid(DefUid)) != NULL)
+ strcpy(defuserbuf, defpwent->pw_name);
+ else
+ strcpy(defuserbuf, "nobody");
+}
+ /*
+** HOST_MAP_INIT -- initialize host class structures
+*/
+
+bool
+host_map_init(map, args)
+ MAP *map;
+ char *args;
+{
+ register char *p = args;
+
+ for (;;)
+ {
+ while (isascii(*p) && isspace(*p))
+ p++;
+ if (*p != '-')
+ break;
+ switch (*++p)
+ {
+ case 'a':
+ map->map_app = ++p;
+ break;
+ }
+ while (*p != '\0' && !(isascii(*p) && isspace(*p)))
+ p++;
+ if (*p != '\0')
+ *p++ = '\0';
+ }
+ if (map->map_app != NULL)
+ map->map_app = newstr(map->map_app);
+ return TRUE;
+}
+ /*
+** SETUPMAILERS -- initialize default mailers
+*/
+
+setupmailers()
+{
+ char buf[100];
+
+ strcpy(buf, "prog, P=/bin/sh, F=lsD, A=sh -c $u");
+ makemailer(buf);
+
+ strcpy(buf, "*file*, P=/dev/null, F=lsDFMPEu, A=FILE");
+ makemailer(buf);
+
+ strcpy(buf, "*include*, P=/dev/null, F=su, A=INCLUDE");
+ makemailer(buf);
+}
+ /*
+** SETUPMAPS -- set up map classes
+*/
+
+#define MAPDEF(name, ext, flags, parse, open, close, lookup, store) \
+ { \
+ extern bool parse __P((MAP *, char *)); \
+ extern bool open __P((MAP *, int)); \
+ extern void close __P((MAP *)); \
+ extern char *lookup __P((MAP *, char *, char **, int *)); \
+ extern void store __P((MAP *, char *, char *)); \
+ s = stab(name, ST_MAPCLASS, ST_ENTER); \
+ s->s_mapclass.map_cname = name; \
+ s->s_mapclass.map_ext = ext; \
+ s->s_mapclass.map_cflags = flags; \
+ s->s_mapclass.map_parse = parse; \
+ s->s_mapclass.map_open = open; \
+ s->s_mapclass.map_close = close; \
+ s->s_mapclass.map_lookup = lookup; \
+ s->s_mapclass.map_store = store; \
+ }
+
+setupmaps()
+{
+ register STAB *s;
+
+#ifdef NEWDB
+ MAPDEF("hash", ".db", MCF_ALIASOK|MCF_REBUILDABLE,
+ map_parseargs, hash_map_open, db_map_close,
+ db_map_lookup, db_map_store);
+ MAPDEF("btree", ".db", MCF_ALIASOK|MCF_REBUILDABLE,
+ map_parseargs, bt_map_open, db_map_close,
+ db_map_lookup, db_map_store);
+#endif
+
+#ifdef NDBM
+ MAPDEF("dbm", ".dir", MCF_ALIASOK|MCF_REBUILDABLE,
+ map_parseargs, ndbm_map_open, ndbm_map_close,
+ ndbm_map_lookup, ndbm_map_store);
+#endif
+
+#ifdef NIS
+ MAPDEF("nis", NULL, MCF_ALIASOK,
+ map_parseargs, nis_map_open, nis_map_close,
+ nis_map_lookup, nis_map_store);
+#endif
+
+ MAPDEF("stab", NULL, MCF_ALIASOK|MCF_ALIASONLY,
+ map_parseargs, stab_map_open, stab_map_close,
+ stab_map_lookup, stab_map_store);
+
+ MAPDEF("implicit", NULL, MCF_ALIASOK|MCF_ALIASONLY|MCF_REBUILDABLE,
+ map_parseargs, impl_map_open, impl_map_close,
+ impl_map_lookup, impl_map_store);
+
+ /* host DNS lookup */
+ MAPDEF("host", NULL, 0,
+ host_map_init, null_map_open, null_map_close,
+ host_map_lookup, null_map_store);
+
+ /* dequote map */
+ MAPDEF("dequote", NULL, 0,
+ dequote_init, null_map_open, null_map_close,
+ dequote_map, null_map_store);
+
+#if 0
+# ifdef USERDB
+ /* user database */
+ MAPDEF("udb", ".db", 0,
+ udb_map_parse, null_map_open, null_map_close,
+ udb_map_lookup, null_map_store);
+# endif
+#endif
+}
+
+#undef MAPDEF
+ /*
+** USERNAME -- return the user id of the logged in user.
+**
+** Parameters:
+** none.
+**
+** Returns:
+** The login name of the logged in user.
+**
+** Side Effects:
+** none.
+**
+** Notes:
+** The return value is statically allocated.
+*/
+
+char *
+username()
+{
+ static char *myname = NULL;
+ extern char *getlogin();
+ register struct passwd *pw;
+
+ /* cache the result */
+ if (myname == NULL)
+ {
+ myname = getlogin();
+ if (myname == NULL || myname[0] == '\0')
+ {
+ pw = getpwuid(RealUid);
+ if (pw != NULL)
+ myname = newstr(pw->pw_name);
+ }
+ else
+ {
+ uid_t uid = RealUid;
+
+ myname = newstr(myname);
+ if ((pw = getpwnam(myname)) == NULL ||
+ (uid != 0 && uid != pw->pw_uid))
+ {
+ pw = getpwuid(uid);
+ if (pw != NULL)
+ myname = newstr(pw->pw_name);
+ }
+ }
+ if (myname == NULL || myname[0] == '\0')
+ {
+ syserr("554 Who are you?");
+ myname = "postmaster";
+ }
+ }
+
+ return (myname);
+}
+ /*
+** TTYPATH -- Get the path of the user's tty
+**
+** Returns the pathname of the user's tty. Returns NULL if
+** the user is not logged in or if s/he has write permission
+** denied.
+**
+** Parameters:
+** none
+**
+** Returns:
+** pathname of the user's tty.
+** NULL if not logged in or write permission denied.
+**
+** Side Effects:
+** none.
+**
+** WARNING:
+** Return value is in a local buffer.
+**
+** Called By:
+** savemail
+*/
+
+char *
+ttypath()
+{
+ struct stat stbuf;
+ register char *pathn;
+ extern char *ttyname();
+ extern char *getlogin();
+
+ /* compute the pathname of the controlling tty */
+ if ((pathn = ttyname(2)) == NULL && (pathn = ttyname(1)) == NULL &&
+ (pathn = ttyname(0)) == NULL)
+ {
+ errno = 0;
+ return (NULL);
+ }
+
+ /* see if we have write permission */
+ if (stat(pathn, &stbuf) < 0 || !bitset(02, stbuf.st_mode))
+ {
+ errno = 0;
+ return (NULL);
+ }
+
+ /* see if the user is logged in */
+ if (getlogin() == NULL)
+ return (NULL);
+
+ /* looks good */
+ return (pathn);
+}
+ /*
+** CHECKCOMPAT -- check for From and To person compatible.
+**
+** This routine can be supplied on a per-installation basis
+** to determine whether a person is allowed to send a message.
+** This allows restriction of certain types of internet
+** forwarding or registration of users.
+**
+** If the hosts are found to be incompatible, an error
+** message should be given using "usrerr" and 0 should
+** be returned.
+**
+** 'NoReturn' can be set to suppress the return-to-sender
+** function; this should be done on huge messages.
+**
+** Parameters:
+** to -- the person being sent to.
+**
+** Returns:
+** an exit status
+**
+** Side Effects:
+** none (unless you include the usrerr stuff)
+*/
+
+checkcompat(to, e)
+ register ADDRESS *to;
+ register ENVELOPE *e;
+{
+# ifdef lint
+ if (to == NULL)
+ to++;
+# endif /* lint */
+
+ if (tTd(49, 1))
+ printf("checkcompat(to=%s, from=%s)\n",
+ to->q_paddr, e->e_from.q_paddr);
+
+# ifdef EXAMPLE_CODE
+ /* this code is intended as an example only */
+ register STAB *s;
+
+ s = stab("arpa", ST_MAILER, ST_FIND);
+ if (s != NULL && e->e_from.q_mailer != LocalMailer &&
+ to->q_mailer == s->s_mailer)
+ {
+ usrerr("553 No ARPA mail through this machine: see your system administration");
+ /* NoReturn = TRUE; to supress return copy */
+ return (EX_UNAVAILABLE);
+ }
+# endif /* EXAMPLE_CODE */
+ return (EX_OK);
+}
+ /*
+** SETSIGNAL -- set a signal handler
+**
+** This is essentially old BSD "signal(3)".
+*/
+
+sigfunc_t
+setsignal(sig, handler)
+ int sig;
+ sigfunc_t handler;
+{
+#if defined(SYS5SIGNALS) || defined(BSD4_3) || defined(_AUX_SOURCE)
+ return signal(sig, handler);
+#else
+ struct sigaction n, o;
+
+ bzero(&n, sizeof n);
+ n.sa_handler = handler;
+ if (sigaction(sig, &n, &o) < 0)
+ return SIG_ERR;
+ return o.sa_handler;
+#endif
+}
+ /*
+** HOLDSIGS -- arrange to hold all signals
+**
+** Parameters:
+** none.
+**
+** Returns:
+** none.
+**
+** Side Effects:
+** Arranges that signals are held.
+*/
+
+holdsigs()
+{
+}
+ /*
+** RLSESIGS -- arrange to release all signals
+**
+** This undoes the effect of holdsigs.
+**
+** Parameters:
+** none.
+**
+** Returns:
+** none.
+**
+** Side Effects:
+** Arranges that signals are released.
+*/
+
+rlsesigs()
+{
+}
+ /*
+** INIT_MD -- do machine dependent initializations
+**
+** Systems that have global modes that should be set should do
+** them here rather than in main.
+*/
+
+#ifdef _AUX_SOURCE
+# include <compat.h>
+#endif
+
+init_md(argc, argv)
+ int argc;
+ char **argv;
+{
+#ifdef _AUX_SOURCE
+ setcompat(getcompat() | COMPAT_BSDPROT);
+#endif
+}
+ /*
+** GETLA -- get the current load average
+**
+** This code stolen from la.c.
+**
+** Parameters:
+** none.
+**
+** Returns:
+** The current load average as an integer.
+**
+** Side Effects:
+** none.
+*/
+
+/* try to guess what style of load average we have */
+#define LA_ZERO 1 /* always return load average as zero */
+#define LA_INT 2 /* read kmem for avenrun; interpret as long */
+#define LA_FLOAT 3 /* read kmem for avenrun; interpret as float */
+#define LA_SUBR 4 /* call getloadavg */
+#define LA_MACH 5 /* MACH load averages (as on NeXT boxes) */
+#define LA_SHORT 6 /* read kmem for avenrun; interpret as short */
+#define LA_PROCSTR 7 /* read string ("1.17") from /proc/loadavg */
+
+/* do guesses based on general OS type */
+#ifndef LA_TYPE
+# define LA_TYPE LA_ZERO
+#endif
+
+#if (LA_TYPE == LA_INT) || (LA_TYPE == LA_FLOAT) || (LA_TYPE == LA_SHORT)
+
+#include <nlist.h>
+
+#ifndef LA_AVENRUN
+# ifdef SYSTEM5
+# define LA_AVENRUN "avenrun"
+# else
+# define LA_AVENRUN "_avenrun"
+# endif
+#endif
+
+/* _PATH_UNIX should be defined in <paths.h> */
+#ifndef _PATH_UNIX
+# if defined(SYSTEM5)
+# define _PATH_UNIX "/unix"
+# else
+# define _PATH_UNIX "/vmunix"
+# endif
+#endif
+
+struct nlist Nl[] =
+{
+ { LA_AVENRUN },
+#define X_AVENRUN 0
+ { 0 },
+};
+
+#ifndef FSHIFT
+# if defined(unixpc)
+# define FSHIFT 5
+# endif
+
+# if defined(__alpha) || defined(IRIX)
+# define FSHIFT 10
+# endif
+#endif
+
+#ifndef FSHIFT
+# define FSHIFT 8
+#endif
+
+#ifndef FSCALE
+# define FSCALE (1 << FSHIFT)
+#endif
+
+getla()
+{
+ static int kmem = -1;
+#if LA_TYPE == LA_INT
+ long avenrun[3];
+#else
+# if LA_TYPE == LA_SHORT
+ short avenrun[3];
+# else
+ double avenrun[3];
+# endif
+#endif
+ extern off_t lseek();
+ extern int errno;
+
+ if (kmem < 0)
+ {
+ kmem = open("/dev/kmem", 0, 0);
+ if (kmem < 0)
+ {
+ if (tTd(3, 1))
+ printf("getla: open(/dev/kmem): %s\n",
+ errstring(errno));
+ return (-1);
+ }
+ (void) fcntl(kmem, F_SETFD, 1);
+ if (nlist(_PATH_UNIX, Nl) < 0)
+ {
+ if (tTd(3, 1))
+ printf("getla: nlist(%s): %s\n", _PATH_UNIX,
+ errstring(errno));
+ return (-1);
+ }
+ if (Nl[X_AVENRUN].n_value == 0)
+ {
+ if (tTd(3, 1))
+ printf("getla: nlist(%s, %s) ==> 0\n",
+ _PATH_UNIX, LA_AVENRUN);
+ return (-1);
+ }
+#ifdef IRIX
+ Nl[X_AVENRUN].n_value &= 0x7fffffff;
+#endif
+ }
+ if (tTd(3, 20))
+ printf("getla: symbol address = %#x\n", Nl[X_AVENRUN].n_value);
+ if (lseek(kmem, (off_t) Nl[X_AVENRUN].n_value, 0) == -1 ||
+ read(kmem, (char *) avenrun, sizeof(avenrun)) < sizeof(avenrun))
+ {
+ /* thank you Ian */
+ if (tTd(3, 1))
+ printf("getla: lseek or read: %s\n", errstring(errno));
+ return (-1);
+ }
+#if (LA_TYPE == LA_INT) || (LA_TYPE == LA_SHORT)
+ if (tTd(3, 5))
+ {
+ printf("getla: avenrun = %d", avenrun[0]);
+ if (tTd(3, 15))
+ printf(", %d, %d", avenrun[1], avenrun[2]);
+ printf("\n");
+ }
+ if (tTd(3, 1))
+ printf("getla: %d\n", (int) (avenrun[0] + FSCALE/2) >> FSHIFT);
+ return ((int) (avenrun[0] + FSCALE/2) >> FSHIFT);
+#else
+ if (tTd(3, 5))
+ {
+ printf("getla: avenrun = %g", avenrun[0]);
+ if (tTd(3, 15))
+ printf(", %g, %g", avenrun[1], avenrun[2]);
+ printf("\n");
+ }
+ if (tTd(3, 1))
+ printf("getla: %d\n", (int) (avenrun[0] +0.5));
+ return ((int) (avenrun[0] + 0.5));
+#endif
+}
+
+#else
+#if LA_TYPE == LA_SUBR
+
+#ifdef DGUX
+
+#include <sys/dg_sys_info.h>
+
+int getla()
+{
+ struct dg_sys_info_load_info load_info;
+
+ dg_sys_info((long *)&load_info,
+ DG_SYS_INFO_LOAD_INFO_TYPE, DG_SYS_INFO_LOAD_VERSION_0);
+
+ return((int) (load_info.one_minute + 0.5));
+}
+
+#else
+
+getla()
+{
+ double avenrun[3];
+
+ if (getloadavg(avenrun, sizeof(avenrun) / sizeof(avenrun[0])) < 0)
+ {
+ if (tTd(3, 1))
+ perror("getla: getloadavg failed:");
+ return (-1);
+ }
+ if (tTd(3, 1))
+ printf("getla: %d\n", (int) (avenrun[0] +0.5));
+ return ((int) (avenrun[0] + 0.5));
+}
+
+#endif /* DGUX */
+#else
+#if LA_TYPE == LA_MACH
+
+/*
+** This has been tested on NEXTSTEP release 2.1/3.X.
+*/
+
+#if defined(NX_CURRENT_COMPILER_RELEASE) && NX_CURRENT_COMPILER_RELEASE > NX_COMPILER_RELEASE_3_0
+# include <mach/mach.h>
+#else
+# include <mach.h>
+#endif
+
+getla()
+{
+ processor_set_t default_set;
+ kern_return_t error;
+ unsigned int info_count;
+ struct processor_set_basic_info info;
+ host_t host;
+
+ error = processor_set_default(host_self(), &default_set);
+ if (error != KERN_SUCCESS)
+ return -1;
+ info_count = PROCESSOR_SET_BASIC_INFO_COUNT;
+ if (processor_set_info(default_set, PROCESSOR_SET_BASIC_INFO,
+ &host, (processor_set_info_t)&info,
+ &info_count) != KERN_SUCCESS)
+ {
+ return -1;
+ }
+ return (int) (info.load_average + (LOAD_SCALE / 2)) / LOAD_SCALE;
+}
+
+
+#else
+#if LA_TYPE == LA_PROCSTR
+
+/*
+** Read /proc/loadavg for the load average. This is assumed to be
+** in a format like "0.15 0.12 0.06".
+**
+** Initially intended for Linux. This has been in the kernel
+** since at least 0.99.15.
+*/
+
+# ifndef _PATH_LOADAVG
+# define _PATH_LOADAVG "/proc/loadavg"
+# endif
+
+int
+getla()
+{
+ double avenrun;
+ register int result;
+ FILE *fp;
+
+ fp = fopen(_PATH_LOADAVG, "r");
+ if (fp == NULL)
+ {
+ if (tTd(3, 1))
+ printf("getla: fopen(%s): %s\n",
+ _PATH_LOADAVG, errstring(errno));
+ return -1;
+ }
+ result = fscanf(fp, "%lf", &avenrun);
+ fclose(fp);
+ if (result != 1)
+ {
+ if (tTd(3, 1))
+ printf("getla: fscanf() = %d: %s\n",
+ result, errstring(errno));
+ return -1;
+ }
+
+ if (tTd(3, 1))
+ printf("getla(): %.2f\n", avenrun);
+
+ return ((int) (avenrun + 0.5));
+}
+
+#else
+
+getla()
+{
+ if (tTd(3, 1))
+ printf("getla: ZERO\n");
+ return (0);
+}
+
+#endif
+#endif
+#endif
+#endif
+
+
+/*
+ * Copyright 1989 Massachusetts Institute of Technology
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of M.I.T. not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. M.I.T. makes no representations about the
+ * suitability of this software for any purpose. It is provided "as is"
+ * without express or implied warranty.
+ *
+ * M.I.T. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL M.I.T.
+ * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Authors: Many and varied...
+ */
+
+/* Non Apollo stuff removed by Don Lewis 11/15/93 */
+#ifndef lint
+static char rcsid[] = "@(#)$Id: getloadavg.c,v 1.16 1991/06/21 12:51:15 paul Exp $";
+#endif /* !lint */
+
+#ifdef apollo
+# undef volatile
+# include <apollo/base.h>
+
+/* ARGSUSED */
+int getloadavg( call_data )
+ caddr_t call_data; /* pointer to (double) return value */
+{
+ double *avenrun = (double *) call_data;
+ int i;
+ status_$t st;
+ long loadav[3];
+ proc1_$get_loadav(loadav, &st);
+ *avenrun = loadav[0] / (double) (1 << 16);
+ return(0);
+}
+# endif /* apollo */
+ /*
+** SHOULDQUEUE -- should this message be queued or sent?
+**
+** Compares the message cost to the load average to decide.
+**
+** Parameters:
+** pri -- the priority of the message in question.
+** ctime -- the message creation time.
+**
+** Returns:
+** TRUE -- if this message should be queued up for the
+** time being.
+** FALSE -- if the load is low enough to send this message.
+**
+** Side Effects:
+** none.
+*/
+
+bool
+shouldqueue(pri, ctime)
+ long pri;
+ time_t ctime;
+{
+ if (CurrentLA < QueueLA)
+ return (FALSE);
+ if (CurrentLA >= RefuseLA)
+ return (TRUE);
+ return (pri > (QueueFactor / (CurrentLA - QueueLA + 1)));
+}
+ /*
+** REFUSECONNECTIONS -- decide if connections should be refused
+**
+** Parameters:
+** none.
+**
+** Returns:
+** TRUE if incoming SMTP connections should be refused
+** (for now).
+** FALSE if we should accept new work.
+**
+** Side Effects:
+** none.
+*/
+
+bool
+refuseconnections()
+{
+#ifdef XLA
+ if (!xla_smtp_ok())
+ return TRUE;
+#endif
+
+ /* this is probably too simplistic */
+ return (CurrentLA >= RefuseLA);
+}
+ /*
+** SETPROCTITLE -- set process title for ps
+**
+** Parameters:
+** fmt -- a printf style format string.
+** a, b, c -- possible parameters to fmt.
+**
+** Returns:
+** none.
+**
+** Side Effects:
+** Clobbers argv of our main procedure so ps(1) will
+** display the title.
+*/
+
+#ifdef SETPROCTITLE
+# ifdef HASSETPROCTITLE
+ *** ERROR *** Cannot have both SETPROCTITLE and HASSETPROCTITLE defined
+# endif
+# ifdef __hpux
+# include <sys/pstat.h>
+# endif
+# ifdef BSD4_4
+# include <machine/vmparam.h>
+# include <sys/exec.h>
+# ifdef __bsdi__
+# undef PS_STRINGS /* BSDI 1.0 doesn't do PS_STRINGS as we expect */
+# define PROCTITLEPAD '\0'
+# endif
+# ifdef PS_STRINGS
+# define SETPROC_STATIC static
+# endif
+# endif
+# ifndef SETPROC_STATIC
+# define SETPROC_STATIC
+# endif
+#endif
+
+#ifndef PROCTITLEPAD
+# define PROCTITLEPAD ' '
+#endif
+
+#ifndef HASSETPROCTITLE
+
+/*VARARGS1*/
+#ifdef __STDC__
+setproctitle(char *fmt, ...)
+#else
+setproctitle(fmt, va_alist)
+ char *fmt;
+ va_dcl
+#endif
+{
+# ifdef SETPROCTITLE
+ register char *p;
+ register int i;
+ SETPROC_STATIC char buf[MAXLINE];
+ VA_LOCAL_DECL
+# ifdef __hpux
+ union pstun pst;
+# endif
+ extern char **Argv;
+ extern char *LastArgv;
+
+ p = buf;
+
+ /* print sendmail: heading for grep */
+ (void) strcpy(p, "sendmail: ");
+ p += strlen(p);
+
+ /* print the argument string */
+ VA_START(fmt);
+ (void) vsprintf(p, fmt, ap);
+ VA_END;
+
+ i = strlen(buf);
+
+# ifdef __hpux
+ pst.pst_command = buf;
+ pstat(PSTAT_SETCMD, pst, i, 0, 0);
+# else
+# ifdef PS_STRINGS
+ PS_STRINGS->ps_nargvstr = 1;
+ PS_STRINGS->ps_argvstr = buf;
+# else
+ if (i > LastArgv - Argv[0] - 2)
+ {
+ i = LastArgv - Argv[0] - 2;
+ buf[i] = '\0';
+ }
+ (void) strcpy(Argv[0], buf);
+ p = &Argv[0][i];
+ while (p < LastArgv)
+ *p++ = PROCTITLEPAD;
+# endif
+# endif
+# endif /* SETPROCTITLE */
+}
+
+#endif
+ /*
+** REAPCHILD -- pick up the body of my child, lest it become a zombie
+**
+** Parameters:
+** none.
+**
+** Returns:
+** none.
+**
+** Side Effects:
+** Picks up extant zombies.
+*/
+
+void
+reapchild()
+{
+ int olderrno = errno;
+# ifdef HASWAITPID
+ auto int status;
+ int count;
+ int pid;
+
+ count = 0;
+ while ((pid = waitpid(-1, &status, WNOHANG)) > 0)
+ {
+ if (count++ > 1000)
+ {
+#ifdef LOG
+ syslog(LOG_ALERT, "reapchild: waitpid loop: pid=%d, status=%x",
+ pid, status);
+#endif
+ break;
+ }
+ }
+# else
+# ifdef WNOHANG
+ union wait status;
+
+ while (wait3(&status, WNOHANG, (struct rusage *) NULL) > 0)
+ continue;
+# else /* WNOHANG */
+ auto int status;
+
+ while (wait(&status) > 0)
+ continue;
+# endif /* WNOHANG */
+# endif
+# ifdef SYS5SIGNALS
+ (void) setsignal(SIGCHLD, reapchild);
+# endif
+ errno = olderrno;
+}
+ /*
+** UNSETENV -- remove a variable from the environment
+**
+** Not needed on newer systems.
+**
+** Parameters:
+** name -- the string name of the environment variable to be
+** deleted from the current environment.
+**
+** Returns:
+** none.
+**
+** Globals:
+** environ -- a pointer to the current environment.
+**
+** Side Effects:
+** Modifies environ.
+*/
+
+#ifndef HASUNSETENV
+
+void
+unsetenv(name)
+ char *name;
+{
+ extern char **environ;
+ register char **pp;
+ int len = strlen(name);
+
+ for (pp = environ; *pp != NULL; pp++)
+ {
+ if (strncmp(name, *pp, len) == 0 &&
+ ((*pp)[len] == '=' || (*pp)[len] == '\0'))
+ break;
+ }
+
+ for (; *pp != NULL; pp++)
+ *pp = pp[1];
+}
+
+#endif
+ /*
+** GETDTABLESIZE -- return number of file descriptors
+**
+** Only on non-BSD systems
+**
+** Parameters:
+** none
+**
+** Returns:
+** size of file descriptor table
+**
+** Side Effects:
+** none
+*/
+
+#ifdef SOLARIS
+# include <sys/resource.h>
+#endif
+
+int
+getdtsize()
+{
+#ifdef RLIMIT_NOFILE
+ struct rlimit rl;
+
+ if (getrlimit(RLIMIT_NOFILE, &rl) >= 0)
+ return rl.rlim_cur;
+#endif
+
+# ifdef HASGETDTABLESIZE
+ return getdtablesize();
+# else
+# ifdef _SC_OPEN_MAX
+ return sysconf(_SC_OPEN_MAX);
+# else
+ return NOFILE;
+# endif
+# endif
+}
+ /*
+** UNAME -- get the UUCP name of this system.
+*/
+
+#ifndef HASUNAME
+
+int
+uname(name)
+ struct utsname *name;
+{
+ FILE *file;
+ char *n;
+
+ name->nodename[0] = '\0';
+
+ /* try /etc/whoami -- one line with the node name */
+ if ((file = fopen("/etc/whoami", "r")) != NULL)
+ {
+ (void) fgets(name->nodename, NODE_LENGTH + 1, file);
+ (void) fclose(file);
+ n = strchr(name->nodename, '\n');
+ if (n != NULL)
+ *n = '\0';
+ if (name->nodename[0] != '\0')
+ return (0);
+ }
+
+ /* try /usr/include/whoami.h -- has a #define somewhere */
+ if ((file = fopen("/usr/include/whoami.h", "r")) != NULL)
+ {
+ char buf[MAXLINE];
+
+ while (fgets(buf, MAXLINE, file) != NULL)
+ if (sscanf(buf, "#define sysname \"%*[^\"]\"",
+ NODE_LENGTH, name->nodename) > 0)
+ break;
+ (void) fclose(file);
+ if (name->nodename[0] != '\0')
+ return (0);
+ }
+
+#ifdef TRUST_POPEN
+ /*
+ ** Popen is known to have security holes.
+ */
+
+ /* try uuname -l to return local name */
+ if ((file = popen("uuname -l", "r")) != NULL)
+ {
+ (void) fgets(name, NODE_LENGTH + 1, file);
+ (void) pclose(file);
+ n = strchr(name, '\n');
+ if (n != NULL)
+ *n = '\0';
+ if (name->nodename[0] != '\0')
+ return (0);
+ }
+#endif
+
+ return (-1);
+}
+#endif /* HASUNAME */
+ /*
+** INITGROUPS -- initialize groups
+**
+** Stub implementation for System V style systems
+*/
+
+#ifndef HASINITGROUPS
+
+initgroups(name, basegid)
+ char *name;
+ int basegid;
+{
+ return 0;
+}
+
+#endif
+ /*
+** SETSID -- set session id (for non-POSIX systems)
+*/
+
+#ifndef HASSETSID
+
+pid_t
+setsid __P ((void))
+{
+#ifdef TIOCNOTTY
+ int fd;
+
+ fd = open("/dev/tty", O_RDWR, 0);
+ if (fd >= 0)
+ {
+ (void) ioctl(fd, (int) TIOCNOTTY, (char *) 0);
+ (void) close(fd);
+ }
+#endif /* TIOCNOTTY */
+# ifdef SYS5SETPGRP
+ return setpgrp();
+# else
+ return setpgid(0, getpid());
+# endif
+}
+
+#endif
+ /*
+** FSYNC -- dummy fsync
+*/
+
+#ifdef NEEDFSYNC
+
+fsync(fd)
+ int fd;
+{
+# ifdef O_SYNC
+ return fcntl(fd, F_SETFL, O_SYNC);
+# else
+ /* nothing we can do */
+ return 0;
+# endif
+}
+
+#endif
+ /*
+** DGUX_INET_ADDR -- inet_addr for DG/UX
+**
+** Data General DG/UX version of inet_addr returns a struct in_addr
+** instead of a long. This patches things.
+*/
+
+#ifdef DGUX
+
+#undef inet_addr
+
+long
+dgux_inet_addr(host)
+ char *host;
+{
+ struct in_addr haddr;
+
+ haddr = inet_addr(host);
+ return haddr.s_addr;
+}
+
+#endif
+ /*
+** GETOPT -- for old systems or systems with bogus implementations
+*/
+
+#ifdef NEEDGETOPT
+
+/*
+ * Copyright (c) 1985 Regents of the University of California.
+ * All rights reserved. The Berkeley software License Agreement
+ * specifies the terms and conditions for redistribution.
+ */
+
+
+/*
+** this version hacked to add `atend' flag to allow state machine
+** to reset if invoked by the program to scan args for a 2nd time
+*/
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)getopt.c 4.3 (Berkeley) 3/9/86";
+#endif /* LIBC_SCCS and not lint */
+
+#include <stdio.h>
+
+/*
+ * get option letter from argument vector
+ */
+#ifdef _CONVEX_SOURCE
+extern int optind, opterr;
+#else
+int opterr = 1; /* if error message should be printed */
+int optind = 1; /* index into parent argv vector */
+#endif
+int optopt; /* character checked for validity */
+char *optarg; /* argument associated with option */
+
+#define BADCH (int)'?'
+#define EMSG ""
+#define tell(s) if (opterr) {fputs(*nargv,stderr);fputs(s,stderr); \
+ fputc(optopt,stderr);fputc('\n',stderr);return(BADCH);}
+
+getopt(nargc,nargv,ostr)
+ int nargc;
+ char *const *nargv;
+ const char *ostr;
+{
+ static char *place = EMSG; /* option letter processing */
+ static char atend = 0;
+ register char *oli; /* option letter list index */
+
+ if (atend) {
+ atend = 0;
+ place = EMSG;
+ }
+ if(!*place) { /* update scanning pointer */
+ if (optind >= nargc || *(place = nargv[optind]) != '-' || !*++place) {
+ atend++;
+ return(EOF);
+ }
+ if (*place == '-') { /* found "--" */
+ ++optind;
+ atend++;
+ return(EOF);
+ }
+ } /* option letter okay? */
+ if ((optopt = (int)*place++) == (int)':' || !(oli = strchr(ostr,optopt))) {
+ if (!*place) ++optind;
+ tell(": illegal option -- ");
+ }
+ if (*++oli != ':') { /* don't need argument */
+ optarg = NULL;
+ if (!*place) ++optind;
+ }
+ else { /* need an argument */
+ if (*place) optarg = place; /* no white space */
+ else if (nargc <= ++optind) { /* no arg */
+ place = EMSG;
+ tell(": option requires an argument -- ");
+ }
+ else optarg = nargv[optind]; /* white space */
+ place = EMSG;
+ ++optind;
+ }
+ return(optopt); /* dump back option letter */
+}
+
+#endif
+ /*
+** VFPRINTF, VSPRINTF -- for old 4.3 BSD systems missing a real version
+*/
+
+#ifdef NEEDVPRINTF
+
+#define MAXARG 16
+
+vfprintf(fp, fmt, ap)
+ FILE * fp;
+ char * fmt;
+ char ** ap;
+{
+ char * bp[MAXARG];
+ int i = 0;
+
+ while (*ap && i < MAXARG)
+ bp[i++] = *ap++;
+ fprintf(fp, fmt, bp[0], bp[1], bp[2], bp[3],
+ bp[4], bp[5], bp[6], bp[7],
+ bp[8], bp[9], bp[10], bp[11],
+ bp[12], bp[13], bp[14], bp[15]);
+}
+
+vsprintf(s, fmt, ap)
+ char * s;
+ char * fmt;
+ char ** ap;
+{
+ char * bp[MAXARG];
+ int i = 0;
+
+ while (*ap && i < MAXARG)
+ bp[i++] = *ap++;
+ sprintf(s, fmt, bp[0], bp[1], bp[2], bp[3],
+ bp[4], bp[5], bp[6], bp[7],
+ bp[8], bp[9], bp[10], bp[11],
+ bp[12], bp[13], bp[14], bp[15]);
+}
+
+#endif
+ /*
+** USERSHELLOK -- tell if a user's shell is ok for unrestricted use
+**
+** Parameters:
+** shell -- the user's shell from /etc/passwd
+**
+** Returns:
+** TRUE -- if it is ok to use this for unrestricted access.
+** FALSE -- if the shell is restricted.
+*/
+
+#if !HASGETUSERSHELL
+
+# ifndef _PATH_SHELLS
+# define _PATH_SHELLS "/etc/shells"
+# endif
+
+char *DefaultUserShells[] =
+{
+ "/bin/sh",
+ "/usr/bin/sh",
+ "/bin/csh",
+ "/usr/bin/csh",
+#ifdef __hpux
+ "/bin/rsh",
+ "/bin/ksh",
+ "/bin/rksh",
+ "/bin/pam",
+ "/usr/bin/keysh",
+ "/bin/posix/sh",
+#endif
+ NULL
+};
+
+#endif
+
+#define WILDCARD_SHELL "/SENDMAIL/ANY/SHELL/"
+
+bool
+usershellok(shell)
+ char *shell;
+{
+#if HASGETUSERSHELL
+ register char *p;
+ extern char *getusershell();
+
+ setusershell();
+ while ((p = getusershell()) != NULL)
+ if (strcmp(p, shell) == 0 || strcmp(p, WILDCARD_SHELL) == 0)
+ break;
+ endusershell();
+ return p != NULL;
+#else
+ register FILE *shellf;
+ char buf[MAXLINE];
+
+ shellf = fopen(_PATH_SHELLS, "r");
+ if (shellf == NULL)
+ {
+ /* no /etc/shells; see if it is one of the std shells */
+ char **d;
+
+ for (d = DefaultUserShells; *d != NULL; d++)
+ {
+ if (strcmp(shell, *d) == 0)
+ return TRUE;
+ }
+ return FALSE;
+ }
+
+ while (fgets(buf, sizeof buf, shellf) != NULL)
+ {
+ register char *p, *q;
+
+ p = buf;
+ while (*p != '\0' && *p != '#' && *p != '/')
+ p++;
+ if (*p == '#' || *p == '\0')
+ continue;
+ q = p;
+ while (*p != '\0' && *p != '#' && !isspace(*p))
+ p++;
+ *p = '\0';
+ if (strcmp(shell, q) == 0 || strcmp(WILDCARD_SHELL, q) == 0)
+ {
+ fclose(shellf);
+ return TRUE;
+ }
+ }
+ fclose(shellf);
+ return FALSE;
+#endif
+}
+ /*
+** FREESPACE -- see how much free space is on the queue filesystem
+**
+** Only implemented if you have statfs.
+**
+** Parameters:
+** dir -- the directory in question.
+** bsize -- a variable into which the filesystem
+** block size is stored.
+**
+** Returns:
+** The number of bytes free on the queue filesystem.
+** -1 if the statfs call fails.
+**
+** Side effects:
+** Puts the filesystem block size into bsize.
+*/
+
+/* statfs types */
+#define SFS_NONE 0 /* no statfs implementation */
+#define SFS_USTAT 1 /* use ustat */
+#define SFS_4ARGS 2 /* use four-argument statfs call */
+#define SFS_VFS 3 /* use <sys/vfs.h> implementation */
+#define SFS_MOUNT 4 /* use <sys/mount.h> implementation */
+#define SFS_STATFS 5 /* use <sys/statfs.h> implementation */
+#define SFS_STATVFS 6 /* use <sys/statvfs.h> implementation */
+
+#ifndef SFS_TYPE
+# define SFS_TYPE SFS_NONE
+#endif
+
+#if SFS_TYPE == SFS_USTAT
+# include <ustat.h>
+#endif
+#if SFS_TYPE == SFS_4ARGS || SFS_TYPE == SFS_STATFS
+# include <sys/statfs.h>
+#endif
+#if SFS_TYPE == SFS_VFS
+# include <sys/vfs.h>
+#endif
+#if SFS_TYPE == SFS_MOUNT
+# include <sys/mount.h>
+#endif
+#if SFS_TYPE == SFS_STATVFS
+# include <sys/statvfs.h>
+#endif
+
+long
+freespace(dir, bsize)
+ char *dir;
+ long *bsize;
+{
+#if SFS_TYPE != SFS_NONE
+# if SFS_TYPE == SFS_USTAT
+ struct ustat fs;
+ struct stat statbuf;
+# define FSBLOCKSIZE DEV_BSIZE
+# define f_bavail f_tfree
+# else
+# if defined(ultrix)
+ struct fs_data fs;
+# define f_bavail fd_bfreen
+# define FSBLOCKSIZE fs.fd_bsize
+# else
+# if SFS_TYPE == SFS_STATVFS
+ struct statvfs fs;
+# define FSBLOCKSIZE fs.f_bsize
+# else
+ struct statfs fs;
+# define FSBLOCKSIZE fs.f_bsize
+# if defined(_SCO_unix_) || defined(IRIX) || defined(apollo)
+# define f_bavail f_bfree
+# endif
+# endif
+# endif
+# endif
+ extern int errno;
+
+# if SFS_TYPE == SFS_USTAT
+ if (stat(dir, &statbuf) == 0 && ustat(statbuf.st_dev, &fs) == 0)
+# else
+# if SFS_TYPE == SFS_4ARGS
+ if (statfs(dir, &fs, sizeof fs, 0) == 0)
+# else
+# if defined(ultrix)
+ if (statfs(dir, &fs) > 0)
+# else
+ if (statfs(dir, &fs) == 0)
+# endif
+# endif
+# endif
+ {
+ if (bsize != NULL)
+ *bsize = FSBLOCKSIZE;
+ return (fs.f_bavail);
+ }
+#endif
+ return (-1);
+}
+ /*
+** ENOUGHSPACE -- check to see if there is enough free space on the queue fs
+**
+** Only implemented if you have statfs.
+**
+** Parameters:
+** msize -- the size to check against. If zero, we don't yet
+** know how big the message will be, so just check for
+** a "reasonable" amount.
+**
+** Returns:
+** TRUE if there is enough space.
+** FALSE otherwise.
+*/
+
+bool
+enoughspace(msize)
+ long msize;
+{
+ long bfree, bsize;
+
+ if (MinBlocksFree <= 0 && msize <= 0)
+ {
+ if (tTd(4, 80))
+ printf("enoughspace: no threshold\n");
+ return TRUE;
+ }
+
+ if ((bfree = freespace(QueueDir, &bsize)) >= 0)
+ {
+ if (tTd(4, 80))
+ printf("enoughspace: bavail=%ld, need=%ld\n",
+ bfree, msize);
+
+ /* convert msize to block count */
+ msize = msize / bsize + 1;
+ if (MinBlocksFree >= 0)
+ msize += MinBlocksFree;
+
+ if (bfree < msize)
+ {
+#ifdef LOG
+ if (LogLevel > 0)
+ syslog(LOG_ALERT,
+ "%s: low on space (have %ld, %s needs %ld in %s)",
+ CurEnv->e_id, bfree,
+ CurHostName, msize, QueueDir);
+#endif
+ return FALSE;
+ }
+ }
+ else if (tTd(4, 80))
+ printf("enoughspace failure: min=%ld, need=%ld: %s\n",
+ MinBlocksFree, msize, errstring(errno));
+ return TRUE;
+}
+ /*
+** TRANSIENTERROR -- tell if an error code indicates a transient failure
+**
+** This looks at an errno value and tells if this is likely to
+** go away if retried later.
+**
+** Parameters:
+** err -- the errno code to classify.
+**
+** Returns:
+** TRUE if this is probably transient.
+** FALSE otherwise.
+*/
+
+bool
+transienterror(err)
+ int err;
+{
+ switch (err)
+ {
+ case EIO: /* I/O error */
+ case ENXIO: /* Device not configured */
+ case EAGAIN: /* Resource temporarily unavailable */
+ case ENOMEM: /* Cannot allocate memory */
+ case ENODEV: /* Operation not supported by device */
+ case ENFILE: /* Too many open files in system */
+ case EMFILE: /* Too many open files */
+ case ENOSPC: /* No space left on device */
+#ifdef ETIMEDOUT
+ case ETIMEDOUT: /* Connection timed out */
+#endif
+#ifdef ESTALE
+ case ESTALE: /* Stale NFS file handle */
+#endif
+#ifdef ENETDOWN
+ case ENETDOWN: /* Network is down */
+#endif
+#ifdef ENETUNREACH
+ case ENETUNREACH: /* Network is unreachable */
+#endif
+#ifdef ENETRESET
+ case ENETRESET: /* Network dropped connection on reset */
+#endif
+#ifdef ECONNABORTED
+ case ECONNABORTED: /* Software caused connection abort */
+#endif
+#ifdef ECONNRESET
+ case ECONNRESET: /* Connection reset by peer */
+#endif
+#ifdef ENOBUFS
+ case ENOBUFS: /* No buffer space available */
+#endif
+#ifdef ESHUTDOWN
+ case ESHUTDOWN: /* Can't send after socket shutdown */
+#endif
+#ifdef ECONNREFUSED
+ case ECONNREFUSED: /* Connection refused */
+#endif
+#ifdef EHOSTDOWN
+ case EHOSTDOWN: /* Host is down */
+#endif
+#ifdef EHOSTUNREACH
+ case EHOSTUNREACH: /* No route to host */
+#endif
+#ifdef EDQUOT
+ case EDQUOT: /* Disc quota exceeded */
+#endif
+#ifdef EPROCLIM
+ case EPROCLIM: /* Too many processes */
+#endif
+#ifdef EUSERS
+ case EUSERS: /* Too many users */
+#endif
+#ifdef EDEADLK
+ case EDEADLK: /* Resource deadlock avoided */
+#endif
+#ifdef EISCONN
+ case EISCONN: /* Socket already connected */
+#endif
+#ifdef EINPROGRESS
+ case EINPROGRESS: /* Operation now in progress */
+#endif
+#ifdef EALREADY
+ case EALREADY: /* Operation already in progress */
+#endif
+#ifdef EADDRINUSE
+ case EADDRINUSE: /* Address already in use */
+#endif
+#ifdef EADDRNOTAVAIL
+ case EADDRNOTAVAIL: /* Can't assign requested address */
+#endif
+#ifdef ETXTBSY
+ case ETXTBSY: /* (Apollo) file locked */
+#endif
+#if defined(ENOSR) && (!defined(ENOBUFS) || (ENOBUFS != ENOSR))
+ case ENOSR: /* Out of streams resources */
+#endif
+ return TRUE;
+ }
+
+ /* nope, must be permanent */
+ return FALSE;
+}
+ /*
+** LOCKFILE -- lock a file using flock or (shudder) fcntl locking
+**
+** Parameters:
+** fd -- the file descriptor of the file.
+** filename -- the file name (for error messages).
+** ext -- the filename extension.
+** type -- type of the lock. Bits can be:
+** LOCK_EX -- exclusive lock.
+** LOCK_NB -- non-blocking.
+**
+** Returns:
+** TRUE if the lock was acquired.
+** FALSE otherwise.
+*/
+
+bool
+lockfile(fd, filename, ext, type)
+ int fd;
+ char *filename;
+ char *ext;
+ int type;
+{
+# if !HASFLOCK
+ int action;
+ struct flock lfd;
+
+ if (ext == NULL)
+ ext = "";
+
+ bzero(&lfd, sizeof lfd);
+ if (bitset(LOCK_UN, type))
+ lfd.l_type = F_UNLCK;
+ else if (bitset(LOCK_EX, type))
+ lfd.l_type = F_WRLCK;
+ else
+ lfd.l_type = F_RDLCK;
+
+ if (bitset(LOCK_NB, type))
+ action = F_SETLK;
+ else
+ action = F_SETLKW;
+
+ if (tTd(55, 60))
+ printf("lockfile(%s%s, action=%d, type=%d): ",
+ filename, ext, action, lfd.l_type);
+
+ if (fcntl(fd, action, &lfd) >= 0)
+ {
+ if (tTd(55, 60))
+ printf("SUCCESS\n");
+ return TRUE;
+ }
+
+ if (tTd(55, 60))
+ printf("(%s) ", errstring(errno));
+
+ /*
+ ** On SunOS, if you are testing using -oQ/tmp/mqueue or
+ ** -oA/tmp/aliases or anything like that, and /tmp is mounted
+ ** as type "tmp" (that is, served from swap space), the
+ ** previous fcntl will fail with "Invalid argument" errors.
+ ** Since this is fairly common during testing, we will assume
+ ** that this indicates that the lock is successfully grabbed.
+ */
+
+ if (errno == EINVAL)
+ {
+ if (tTd(55, 60))
+ printf("SUCCESS\n");
+ return TRUE;
+ }
+
+ if (!bitset(LOCK_NB, type) || (errno != EACCES && errno != EAGAIN))
+ {
+ int omode = -1;
+# ifdef F_GETFL
+ int oerrno = errno;
+
+ (void) fcntl(fd, F_GETFL, &omode);
+ errno = oerrno;
+# endif
+ syserr("cannot lockf(%s%s, fd=%d, type=%o, omode=%o, euid=%d)",
+ filename, ext, fd, type, omode, geteuid());
+ }
+# else
+ if (ext == NULL)
+ ext = "";
+
+ if (tTd(55, 60))
+ printf("lockfile(%s%s, type=%o): ", filename, ext, type);
+
+ if (flock(fd, type) >= 0)
+ {
+ if (tTd(55, 60))
+ printf("SUCCESS\n");
+ return TRUE;
+ }
+
+ if (tTd(55, 60))
+ printf("(%s) ", errstring(errno));
+
+ if (!bitset(LOCK_NB, type) || errno != EWOULDBLOCK)
+ {
+ int omode = -1;
+# ifdef F_GETFL
+ int oerrno = errno;
+
+ (void) fcntl(fd, F_GETFL, &omode);
+ errno = oerrno;
+# endif
+ syserr("cannot flock(%s%s, fd=%d, type=%o, omode=%o, euid=%d)",
+ filename, ext, fd, type, omode, geteuid());
+ }
+# endif
+ if (tTd(55, 60))
+ printf("FAIL\n");
+ return FALSE;
+}
+ /*
+** CHOWNSAFE -- tell if chown is "safe" (executable only by root)
+**
+** Parameters:
+** fd -- the file descriptor to check.
+**
+** Returns:
+** TRUE -- if only root can chown the file to an arbitrary
+** user.
+** FALSE -- if an arbitrary user can give away a file.
+*/
+
+bool
+chownsafe(fd)
+ int fd;
+{
+#ifdef __hpux
+ char *s;
+ int tfd;
+ uid_t o_uid, o_euid;
+ gid_t o_gid, o_egid;
+ bool rval;
+ struct stat stbuf;
+
+ o_uid = getuid();
+ o_euid = geteuid();
+ o_gid = getgid();
+ o_egid = getegid();
+ fstat(fd, &stbuf);
+ setresuid(stbuf.st_uid, stbuf.st_uid, -1);
+ setresgid(stbuf.st_gid, stbuf.st_gid, -1);
+ s = tmpnam(NULL);
+ tfd = open(s, O_RDONLY|O_CREAT, 0600);
+ rval = fchown(tfd, DefUid, DefGid) != 0;
+ close(tfd);
+ unlink(s);
+ setreuid(o_uid, o_euid);
+ setresgid(o_gid, o_egid, -1);
+ return rval;
+#else
+# ifdef _POSIX_CHOWN_RESTRICTED
+# if _POSIX_CHOWN_RESTRICTED == -1
+ return FALSE;
+# else
+ return TRUE;
+# endif
+# else
+# ifdef _PC_CHOWN_RESTRICTED
+ return fpathconf(fd, _PC_CHOWN_RESTRICTED) > 0;
+# else
+# ifdef BSD
+ return TRUE;
+# else
+ return FALSE;
+# endif
+# endif
+# endif
+#endif
+}
+ /*
+** GETCFNAME -- return the name of the .cf file.
+**
+** Some systems (e.g., NeXT) determine this dynamically.
+*/
+
+char *
+getcfname()
+{
+ if (ConfFile != NULL)
+ return ConfFile;
+#ifdef NETINFO
+ {
+ extern char *ni_propval();
+ char *cflocation;
+
+ cflocation = ni_propval("/locations/sendmail", "sendmail.cf");
+ if (cflocation != NULL)
+ return cflocation;
+ }
+#endif
+ return _PATH_SENDMAILCF;
+}
+ /*
+** SETVENDOR -- process vendor code from V configuration line
+**
+** Parameters:
+** vendor -- string representation of vendor.
+**
+** Returns:
+** TRUE -- if ok.
+** FALSE -- if vendor code could not be processed.
+**
+** Side Effects:
+** It is reasonable to set mode flags here to tweak
+** processing in other parts of the code if necessary.
+** For example, if you are a vendor that uses $%y to
+** indicate YP lookups, you could enable that here.
+*/
+
+bool
+setvendor(vendor)
+ char *vendor;
+{
+ if (strcasecmp(vendor, "Berkeley") == 0)
+ return TRUE;
+
+ /* add vendor extensions here */
+
+ return FALSE;
+}
+ /*
+** STRTOL -- convert string to long integer
+**
+** For systems that don't have it in the C library.
+**
+** This is taken verbatim from the 4.4-Lite C library.
+*/
+
+#ifdef NEEDSTRTOL
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)strtol.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include <limits.h>
+
+/*
+ * Convert a string to a long integer.
+ *
+ * Ignores `locale' stuff. Assumes that the upper and lower case
+ * alphabets and digits are each contiguous.
+ */
+
+long
+strtol(nptr, endptr, base)
+ const char *nptr;
+ char **endptr;
+ register int base;
+{
+ register const char *s = nptr;
+ register unsigned long acc;
+ register int c;
+ register unsigned long cutoff;
+ register int neg = 0, any, cutlim;
+
+ /*
+ * Skip white space and pick up leading +/- sign if any.
+ * If base is 0, allow 0x for hex and 0 for octal, else
+ * assume decimal; if base is already 16, allow 0x.
+ */
+ do {
+ c = *s++;
+ } while (isspace(c));
+ if (c == '-') {
+ neg = 1;
+ c = *s++;
+ } else if (c == '+')
+ c = *s++;
+ if ((base == 0 || base == 16) &&
+ c == '0' && (*s == 'x' || *s == 'X')) {
+ c = s[1];
+ s += 2;
+ base = 16;
+ }
+ if (base == 0)
+ base = c == '0' ? 8 : 10;
+
+ /*
+ * Compute the cutoff value between legal numbers and illegal
+ * numbers. That is the largest legal value, divided by the
+ * base. An input number that is greater than this value, if
+ * followed by a legal input character, is too big. One that
+ * is equal to this value may be valid or not; the limit
+ * between valid and invalid numbers is then based on the last
+ * digit. For instance, if the range for longs is
+ * [-2147483648..2147483647] and the input base is 10,
+ * cutoff will be set to 214748364 and cutlim to either
+ * 7 (neg==0) or 8 (neg==1), meaning that if we have accumulated
+ * a value > 214748364, or equal but the next digit is > 7 (or 8),
+ * the number is too big, and we will return a range error.
+ *
+ * Set any if any `digits' consumed; make it negative to indicate
+ * overflow.
+ */
+ cutoff = neg ? -(unsigned long)LONG_MIN : LONG_MAX;
+ cutlim = cutoff % (unsigned long)base;
+ cutoff /= (unsigned long)base;
+ for (acc = 0, any = 0;; c = *s++) {
+ if (isdigit(c))
+ c -= '0';
+ else if (isalpha(c))
+ c -= isupper(c) ? 'A' - 10 : 'a' - 10;
+ else
+ break;
+ if (c >= base)
+ break;
+ if (any < 0 || acc > cutoff || acc == cutoff && c > cutlim)
+ any = -1;
+ else {
+ any = 1;
+ acc *= base;
+ acc += c;
+ }
+ }
+ if (any < 0) {
+ acc = neg ? LONG_MIN : LONG_MAX;
+ errno = ERANGE;
+ } else if (neg)
+ acc = -acc;
+ if (endptr != 0)
+ *endptr = (char *)(any ? s - 1 : nptr);
+ return (acc);
+}
+
+#endif
+ /*
+** SOLARIS_GETHOSTBY{NAME,ADDR} -- compatibility routines for gethostbyXXX
+**
+** Solaris versions prior through 2.3 don't properly deliver a
+** canonical h_name field. This tries to work around it.
+*/
+
+#ifdef SOLARIS
+
+struct hostent *
+solaris_gethostbyname(name)
+ const char *name;
+{
+# ifdef SOLARIS_2_3
+ static struct hostent hp;
+ static char buf[1000];
+ extern struct hostent *_switch_gethostbyname_r();
+
+ return _switch_gethostbyname_r(name, &hp, buf, sizeof(buf), &h_errno);
+# else
+ extern struct hostent *__switch_gethostbyname();
+
+ return __switch_gethostbyname(name);
+# endif
+}
+
+struct hostent *
+solaris_gethostbyaddr(addr, len, type)
+ const char *addr;
+ int len;
+ int type;
+{
+# ifdef SOLARIS_2_3
+ static struct hostent hp;
+ static char buf[1000];
+ extern struct hostent *_switch_gethostbyaddr_r();
+
+ return _switch_gethostbyaddr_r(addr, len, type, &hp, buf, sizeof(buf), &h_errno);
+# else
+ extern struct hostent *__switch_gethostbyaddr();
+
+ return __switch_gethostbyaddr(addr, len, type);
+# endif
+}
+
+#endif
+ /*
+** NI_PROPVAL -- netinfo property value lookup routine
+**
+** Parameters:
+** directory -- the Netinfo directory name.
+** propname -- the Netinfo property name.
+**
+** Returns:
+** NULL -- if:
+** 1. the directory is not found
+** 2. the property name is not found
+** 3. the property contains multiple values
+** 4. some error occured
+** else -- the location of the config file.
+**
+** Notes:
+** Caller should free the return value of ni_proval
+*/
+
+#ifdef NETINFO
+
+# include <netinfo/ni.h>
+
+# define LOCAL_NETINFO_DOMAIN "."
+# define PARENT_NETINFO_DOMAIN ".."
+# define MAX_NI_LEVELS 256
+
+char *
+ni_propval(directory, propname)
+ char *directory;
+ char *propname;
+{
+ char *propval = NULL;
+ int i;
+ void *ni = NULL;
+ void *lastni = NULL;
+ ni_status nis;
+ ni_id nid;
+ ni_namelist ninl;
+
+ /*
+ ** If the passed directory and property name are found
+ ** in one of netinfo domains we need to search (starting
+ ** from the local domain moving all the way back to the
+ ** root domain) set propval to the property's value
+ ** and return it.
+ */
+
+ for (i = 0; i < MAX_NI_LEVELS; ++i)
+ {
+ if (i == 0)
+ {
+ nis = ni_open(NULL, LOCAL_NETINFO_DOMAIN, &ni);
+ }
+ else
+ {
+ if (lastni != NULL)
+ ni_free(lastni);
+ lastni = ni;
+ nis = ni_open(lastni, PARENT_NETINFO_DOMAIN, &ni);
+ }
+
+ /*
+ ** Don't bother if we didn't get a handle on a
+ ** proper domain. This is not necessarily an error.
+ ** We would get a positive ni_status if, for instance
+ ** we never found the directory or property and tried
+ ** to open the parent of the root domain!
+ */
+
+ if (nis != 0)
+ break;
+
+ /*
+ ** Find the path to the server information.
+ */
+
+ if (ni_pathsearch(ni, &nid, directory) != 0)
+ continue;
+
+ /*
+ ** Find "host" information.
+ */
+
+ if (ni_lookupprop(ni, &nid, propname, &ninl) != 0)
+ continue;
+
+ /*
+ ** If there's only one name in
+ ** the list, assume we've got
+ ** what we want.
+ */
+
+ if (ninl.ni_namelist_len == 1)
+ {
+ propval = ni_name_dup(ninl.ni_namelist_val[0]);
+ break;
+ }
+ }
+
+ /*
+ ** Clean up.
+ */
+
+ if (ni != NULL)
+ ni_free(ni);
+ if (lastni != NULL && ni != lastni)
+ ni_free(lastni);
+
+ return propval;
+}
+
+#endif /* NETINFO */
+ /*
+** HARD_SYSLOG -- call syslog repeatedly until it works
+**
+** Needed on HP-UX, which apparently doesn't guarantee that
+** syslog succeeds during interrupt handlers.
+*/
+
+#ifdef __hpux
+
+# define MAXSYSLOGTRIES 100
+# undef syslog
+
+# ifdef __STDC__
+hard_syslog(int pri, char *msg, ...)
+# else
+hard_syslog(pri, msg, va_alist)
+ int pri;
+ char *msg;
+ va_dcl
+# endif
+{
+ int i;
+ char buf[SYSLOG_BUFSIZE * 2];
+ VA_LOCAL_DECL;
+
+ VA_START(msg);
+ vsprintf(buf, msg, ap);
+ VA_END;
+
+ for (i = MAXSYSLOGTRIES; --i >= 0 && syslog(pri, "%s", buf) < 0; )
+ continue;
+}
+
+#endif
diff --git a/usr.sbin/sendmail/src/conf.h b/usr.sbin/sendmail/src/conf.h
new file mode 100644
index 0000000..0f02692
--- /dev/null
+++ b/usr.sbin/sendmail/src/conf.h
@@ -0,0 +1,1191 @@
+/*
+ * Copyright (c) 1983 Eric P. Allman
+ * Copyright (c) 1988, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)conf.h 8.104 (Berkeley) 4/17/94
+ */
+
+/*
+** CONF.H -- All user-configurable parameters for sendmail
+*/
+
+# include <sys/param.h>
+# include <sys/types.h>
+# include <sys/stat.h>
+# include <sys/file.h>
+# include <sys/wait.h>
+# include <fcntl.h>
+# include <signal.h>
+
+/**********************************************************************
+** Table sizes, etc....
+** There shouldn't be much need to change these....
+**********************************************************************/
+
+# define MAXLINE 2048 /* max line length */
+# define MAXNAME 256 /* max length of a name */
+# define MAXPV 40 /* max # of parms to mailers */
+# define MAXATOM 200 /* max atoms per address */
+# define MAXMAILERS 25 /* maximum mailers known to system */
+# define MAXRWSETS 100 /* max # of sets of rewriting rules */
+# define MAXPRIORITIES 25 /* max values for Precedence: field */
+# define MAXMXHOSTS 20 /* max # of MX records */
+# define SMTPLINELIM 990 /* maximum SMTP line length */
+# define MAXKEY 128 /* maximum size of a database key */
+# define MEMCHUNKSIZE 1024 /* chunk size for memory allocation */
+# define MAXUSERENVIRON 100 /* max envars saved, must be >= 3 */
+# define MAXALIASDB 12 /* max # of alias databases */
+
+# ifndef QUEUESIZE
+# define QUEUESIZE 1000 /* max # of jobs per queue run */
+# endif
+
+/**********************************************************************
+** Compilation options.
+**
+** #define these if they are available; comment them out otherwise.
+**********************************************************************/
+
+# define LOG 1 /* enable logging */
+# define UGLYUUCP 1 /* output ugly UUCP From lines */
+# define NETUNIX 1 /* include unix domain support */
+# define NETINET 1 /* include internet support */
+# define SETPROCTITLE 1 /* munge argv to display current status */
+# define MATCHGECOS 1 /* match user names from gecos field */
+# define XDEBUG 1 /* enable extended debugging */
+# ifdef NEWDB
+# define USERDB 1 /* look in user database (requires NEWDB) */
+# endif
+
+/**********************************************************************
+** 0/1 Compilation options.
+** #define these to 1 if they are available;
+** #define them to 0 otherwise.
+**********************************************************************/
+
+# ifndef NAMED_BIND
+# define NAMED_BIND 1 /* use Berkeley Internet Domain Server */
+# endif
+
+/*
+** Most systems have symbolic links today, so default them on. You
+** can turn them off by #undef'ing this below.
+*/
+
+# define HASLSTAT 1 /* has lstat(2) call */
+
+/*
+** General "standard C" defines.
+**
+** These may be undone later, to cope with systems that claim to
+** be Standard C but aren't. Gcc is the biggest offender -- it
+** doesn't realize that the library is part of the language.
+**
+** Life would be much easier if we could get rid of this sort
+** of bozo problems.
+*/
+
+#ifdef __STDC__
+# define HASSETVBUF 1 /* we have setvbuf(3) in libc */
+#endif
+
+/**********************************************************************
+** Operating system configuration.
+**
+** Unless you are porting to a new OS, you shouldn't have to
+** change these.
+**********************************************************************/
+
+/*
+** Per-Operating System defines
+*/
+
+
+/*
+** HP-UX -- tested for 8.07, 9.00, and 9.01.
+*/
+
+# ifdef __hpux
+/* avoid m_flags conflict between db.h & sys/sysmacros.h on HP 300 */
+# undef m_flags
+# define SYSTEM5 1 /* include all the System V defines */
+# define HASINITGROUPS 1 /* has initgroups(3) call */
+# define HASSETREUID 1 /* has setreuid(2) call */
+# define setreuid(r, e) setresuid(r, e, -1)
+# define LA_TYPE LA_FLOAT
+# define SFS_TYPE SFS_VFS /* use <sys/vfs.h> statfs() implementation */
+# define GIDSET_T gid_t
+# define _PATH_UNIX "/hp-ux"
+# ifndef _PATH_SENDMAILCF
+# define _PATH_SENDMAILCF "/usr/lib/sendmail.cf"
+# endif
+# ifndef IDENTPROTO
+# define IDENTPROTO 0 /* TCP/IP implementation is broken */
+# endif
+# ifndef HASGETUSERSHELL
+# define HASGETUSERSHELL 0 /* getusershell(3) causes core dumps */
+# endif
+# define syslog hard_syslog
+# ifdef __STDC__
+extern int syslog(int, char *, ...);
+# endif
+# endif
+
+
+/*
+** IBM AIX 3.x -- actually tested for 3.2.3
+*/
+
+# ifdef _AIX3
+# define HASINITGROUPS 1 /* has initgroups(3) call */
+# define HASUNAME 1 /* use System V uname(2) system call */
+# define HASGETUSERSHELL 0 /* does not have getusershell(3) call */
+# define FORK fork /* no vfork primitive available */
+# undef SETPROCTITLE /* setproctitle confuses AIX */
+# define SFS_TYPE SFS_STATFS /* use <sys/statfs.h> statfs() impl */
+# endif
+
+
+/*
+** Silicon Graphics IRIX
+**
+** Compiles on 4.0.1.
+*/
+
+# ifdef IRIX
+# define SYSTEM5 1 /* this is a System-V derived system */
+# define HASSETREUID 1 /* has setreuid(2) call */
+# define HASINITGROUPS 1 /* has initgroups(3) call */
+# define HASGETUSERSHELL 0 /* does not have getusershell(3) call */
+# define FORK fork /* no vfork primitive available */
+# define WAITUNION 1 /* use "union wait" as wait argument type */
+# define setpgid BSDsetpgrp
+# define GIDSET_T gid_t
+# define SFS_TYPE SFS_4ARGS /* four argument statfs() call */
+# define LA_TYPE LA_INT
+# endif
+
+
+/*
+** SunOS and Solaris
+**
+** Tested on SunOS 4.1.x (a.k.a. Solaris 1.1.x) and
+** Solaris 2.2 (a.k.a. SunOS 5.2).
+*/
+
+#if defined(sun) && !defined(BSD)
+
+# define HASINITGROUPS 1 /* has initgroups(3) call */
+# define HASUNAME 1 /* use System V uname(2) system call */
+# define HASGETUSERSHELL 1 /* DOES have getusershell(3) call in libc */
+# define LA_TYPE LA_INT
+
+# ifdef SOLARIS_2_3
+# define SOLARIS
+# endif
+
+# ifdef SOLARIS
+ /* Solaris 2.x (a.k.a. SunOS 5.x) */
+# ifndef __svr4__
+# define __svr4__ /* use all System V Releae 4 defines below */
+# endif
+# include <sys/time.h>
+# define gethostbyname solaris_gethostbyname /* get working version */
+# define gethostbyaddr solaris_gethostbyaddr /* get working version */
+# define GIDSET_T gid_t
+# ifndef _PATH_UNIX
+# define _PATH_UNIX "/kernel/unix"
+# endif
+# ifndef _PATH_SENDMAILCF
+# define _PATH_SENDMAILCF "/etc/mail/sendmail.cf"
+# endif
+# ifndef _PATH_SENDMAILPID
+# define _PATH_SENDMAILPID "/etc/mail/sendmail.pid"
+# endif
+# ifndef SYSLOG_BUFSIZE
+# define SYSLOG_BUFSIZE 1024 /* allow full size syslog buffer */
+# endif
+
+# else
+ /* SunOS 4.0.3 or 4.1.x */
+# define HASSETREUID 1 /* has setreuid(2) call */
+# ifndef HASFLOCK
+# define HASFLOCK 1 /* has flock(2) call */
+# endif
+# define SFS_TYPE SFS_VFS /* use <sys/vfs.h> statfs() implementation */
+# include <vfork.h>
+
+# ifdef SUNOS403
+ /* special tweaking for SunOS 4.0.3 */
+# include <malloc.h>
+# define SYS5SIGNALS 1 /* SysV signal semantics -- reset on each sig */
+# define WAITUNION 1 /* use "union wait" as wait argument type */
+# undef WIFEXITED
+# undef WEXITSTATUS
+# undef HASUNAME
+# define setpgid setpgrp
+typedef int pid_t;
+extern char *getenv();
+
+# else
+ /* 4.1.x specifics */
+# define HASSETSID 1 /* has Posix setsid(2) call */
+# define HASSETVBUF 1 /* we have setvbuf(3) in libc */
+
+# endif
+# endif
+#endif
+
+/*
+** DG/UX
+**
+** Tested on 5.4.2
+*/
+
+#ifdef DGUX
+# define SYSTEM5 1
+# define LA_TYPE LA_SUBR
+# define HASSETREUID 1 /* has setreuid(2) call */
+# define HASUNAME 1 /* use System V uname(2) system call */
+# define HASSETSID 1 /* has Posix setsid(2) call */
+# define HASINITGROUPS 1 /* has initgroups(3) call */
+# define HASGETUSERSHELL 0 /* does not have getusershell(3) */
+# ifndef IDENTPROTO
+# define IDENTPROTO 0 /* TCP/IP implementation is broken */
+# endif
+# undef SETPROCTITLE
+# define SFS_TYPE SFS_4ARGS /* four argument statfs() call */
+
+/* these include files must be included early on DG/UX */
+# include <netinet/in.h>
+# include <arpa/inet.h>
+
+# define inet_addr dgux_inet_addr
+extern long dgux_inet_addr();
+#endif
+
+
+/*
+** Digital Ultrix 4.2A or 4.3
+**
+** Apparently, fcntl locking is broken on 4.2A, in that locks are
+** not dropped when the process exits. This causes major problems,
+** so flock is the only alternative.
+*/
+
+#ifdef ultrix
+# define HASSETREUID 1 /* has setreuid(2) call */
+# define HASUNSETENV 1 /* has unsetenv(3) call */
+# define HASINITGROUPS 1 /* has initgroups(3) call */
+# define HASUNAME 1 /* use System V uname(2) system call */
+# ifndef HASFLOCK
+# define HASFLOCK 1 /* has flock(2) call */
+# endif
+# define HASGETUSERSHELL 0 /* does not have getusershell(3) call */
+# define BROKEN_RES_SEARCH 1 /* res_search(unknown) returns h_errno=0 */
+# ifdef vax
+# define LA_TYPE LA_FLOAT
+# else
+# define LA_TYPE LA_INT
+# define LA_AVENRUN "avenrun"
+# endif
+# define SFS_TYPE SFS_MOUNT /* use <sys/mount.h> statfs() impl */
+# ifndef IDENTPROTO
+# define IDENTPROTO 0 /* TCP/IP implementation is broken */
+# endif
+#endif
+
+
+/*
+** OSF/1 (tested on Alpha)
+*/
+
+#ifdef __osf__
+# define HASUNSETENV 1 /* has unsetenv(3) call */
+# define HASSETREUID 1 /* has setreuid(2) call */
+# define HASINITGROUPS 1 /* has initgroups(3) call */
+# ifndef HASFLOCK
+# define HASFLOCK 1 /* has flock(2) call */
+# endif
+# define LA_TYPE LA_INT
+# define SFS_TYPE SFS_MOUNT /* use <sys/mount.h> statfs() impl */
+# ifndef _PATH_SENDMAILPID
+# define _PATH_SENDMAILPID "/var/run/sendmail.pid"
+# endif
+#endif
+
+
+/*
+** NeXTstep
+*/
+
+#ifdef NeXT
+# define HASINITGROUPS 1 /* has initgroups(3) call */
+# ifndef HASFLOCK
+# define HASFLOCK 1 /* has flock(2) call */
+# endif
+# define NEEDGETOPT 1 /* need a replacement for getopt(3) */
+# define WAITUNION 1 /* use "union wait" as wait argument type */
+# define sleep sleepX
+# define setpgid setpgrp
+# ifndef LA_TYPE
+# define LA_TYPE LA_MACH
+# endif
+# define SFS_TYPE SFS_VFS /* use <sys/vfs.h> statfs() implementation */
+# ifndef _POSIX_SOURCE
+typedef int pid_t;
+# undef WEXITSTATUS
+# undef WIFEXITED
+# endif
+# ifndef _PATH_SENDMAILCF
+# define _PATH_SENDMAILCF "/etc/sendmail/sendmail.cf"
+# endif
+# ifndef _PATH_SENDMAILPID
+# define _PATH_SENDMAILPID "/etc/sendmail/sendmail.pid"
+# endif
+#endif
+
+
+/*
+** 4.4 BSD
+**
+** See also BSD defines.
+*/
+
+#ifdef BSD4_4
+# define HASUNSETENV 1 /* has unsetenv(3) call */
+# include <sys/cdefs.h>
+# define ERRLIST_PREDEFINED /* don't declare sys_errlist */
+# ifndef LA_TYPE
+# define LA_TYPE LA_SUBR
+# endif
+# define SFS_TYPE SFS_MOUNT /* use <sys/mount.h> statfs() impl */
+#endif
+
+
+/*
+** BSD/386 (all versions)
+** From Tony Sanders, BSDI
+*/
+
+#ifdef __bsdi__
+# define HASUNSETENV 1 /* has the unsetenv(3) call */
+# define HASSETSID 1 /* has the setsid(2) POSIX syscall */
+# include <sys/cdefs.h>
+# define ERRLIST_PREDEFINED /* don't declare sys_errlist */
+# define SFS_TYPE SFS_MOUNT /* use <sys/mount.h> statfs() impl */
+# ifndef LA_TYPE
+# define LA_TYPE LA_SUBR
+# endif
+# if defined(_BSDI_VERSION) && _BSDI_VERSION >= 199312
+ /* version 1.1 or later */
+# define HASSETPROCTITLE 1 /* setproctitle is in libc */
+# undef SETPROCTITLE /* so don't redefine it in conf.c */
+# else
+ /* version 1.0 or earlier */
+# ifndef OLD_NEWDB
+# define OLD_NEWDB 1 /* old version of newdb library */
+# endif
+# endif
+#endif
+
+
+
+/*
+** 386BSD / FreeBSD 1.0E / NetBSD (all architectures, all versions)
+**
+** 4.3BSD clone, closer to 4.4BSD
+**
+** See also BSD defines.
+*/
+
+#if defined(__386BSD__) || defined(__FreeBSD__) || defined(__NetBSD__)
+# define HASUNSETENV 1 /* has unsetenv(3) call */
+# define HASSETSID 1 /* has the setsid(2) POSIX syscall */
+# ifdef __NetBSD__
+# define HASUNAME 1 /* has uname(2) syscall */
+# endif
+# include <sys/cdefs.h>
+# define ERRLIST_PREDEFINED /* don't declare sys_errlist */
+# ifndef LA_TYPE
+# define LA_TYPE LA_SUBR
+# endif
+# define SFS_TYPE SFS_MOUNT /* use <sys/mount.h> statfs() impl */
+#endif
+
+
+/*
+** Mach386
+**
+** For mt Xinu's Mach386 system.
+*/
+
+#if defined(MACH) && defined(i386)
+# define MACH386 1
+# define HASUNSETENV 1 /* has unsetenv(3) call */
+# define HASINITGROUPS 1 /* has initgroups(3) call */
+# ifndef HASFLOCK
+# define HASFLOCK 1 /* has flock(2) call */
+# endif
+# define NEEDGETOPT 1 /* need a replacement for getopt(3) */
+# define NEEDSTRTOL 1 /* need the strtol() function */
+# define setpgid setpgrp
+# ifndef LA_TYPE
+# define LA_TYPE LA_FLOAT
+# endif
+# define SFS_TYPE SFS_VFS /* use <sys/vfs.h> statfs() implementation */
+# undef HASSETVBUF /* don't actually have setvbuf(3) */
+# undef WEXITSTATUS
+# undef WIFEXITED
+# ifndef _PATH_SENDMAILCF
+# define _PATH_SENDMAILCF "/usr/lib/sendmail.cf"
+# endif
+# ifndef _PATH_SENDMAILPID
+# define _PATH_SENDMAILPID "/etc/sendmail.pid"
+# endif
+#endif
+
+
+/*
+** 4.3 BSD -- this is for very old systems
+**
+** Should work for mt Xinu MORE/BSD and Mips UMIPS-BSD 2.1.
+**
+** You'll also have to install a new resolver library.
+** I don't guarantee that support for this environment is complete.
+*/
+
+#if defined(oldBSD43) || defined(MORE_BSD) || defined(umipsbsd)
+# define NEEDVPRINTF 1 /* need a replacement for vprintf(3) */
+# define NEEDGETOPT 1 /* need a replacement for getopt(3) */
+# define ARBPTR_T char *
+# define setpgid setpgrp
+# ifndef LA_TYPE
+# define LA_TYPE LA_FLOAT
+# endif
+# ifndef _PATH_SENDMAILCF
+# define _PATH_SENDMAILCF "/usr/lib/sendmail.cf"
+# endif
+# ifndef IDENTPROTO
+# define IDENTPROTO 0 /* TCP/IP implementation is broken */
+# endif
+# undef WEXITSTATUS
+# undef WIFEXITED
+typedef short pid_t;
+extern int errno;
+#endif
+
+
+/*
+** SCO Unix
+**
+** This includes two parts -- the first is for SCO Open Server 3.2v4
+** (contributed by Philippe Brand <phb@colombo.telesys-innov.fr>).
+** The second is, I believe, for an older version.
+*/
+
+#ifdef _SCO_unix_4_2
+# define _SCO_unix_
+# define HASSETREUID 1 /* has setreuid(2) call */
+# define NEEDFSYNC 1 /* needs the fsync(2) call stub */
+# define _PATH_UNIX "/unix"
+# ifndef _PATH_SENDMAILCF
+# define _PATH_SENDMAILCF "/usr/lib/sendmail.cf"
+# endif
+# ifndef _PATH_SENDMAILPID
+# define _PATH_SENDMAILPID "/etc/sendmail.pid"
+# endif
+#endif
+
+#ifdef _SCO_unix_
+# define SYSTEM5 1 /* include all the System V defines */
+# define SYS5SIGNALS 1 /* SysV signal semantics -- reset on each sig */
+# define HASGETUSERSHELL 0 /* does not have getusershell(3) call */
+# define FORK fork
+# define MAXPATHLEN PATHSIZE
+# define LA_TYPE LA_SHORT
+# define SFS_TYPE SFS_STATFS /* use <sys/statfs.h> statfs() impl */
+# undef NETUNIX /* no unix domain socket support */
+#endif
+
+
+/*
+** ConvexOS 11.0 and later
+**
+** "Todd C. Miller" <millert@mroe.cs.colorado.edu> claims this
+** works on 9.1 as well.
+*/
+
+#ifdef _CONVEX_SOURCE
+# define BSD 1 /* include all the BSD defines */
+# define HASUNAME 1 /* use System V uname(2) system call */
+# define HASSETSID 1 /* has POSIX setsid(2) call */
+# define NEEDGETOPT 1 /* need replacement for getopt(3) */
+# define LA_TYPE LA_FLOAT
+# define SFS_TYPE SFS_VFS /* use <sys/vfs.h> statfs() implementation */
+# ifndef _PATH_SENDMAILCF
+# define _PATH_SENDMAILCF "/usr/lib/sendmail.cf"
+# endif
+# ifndef S_IREAD
+# define S_IREAD _S_IREAD
+# define S_IWRITE _S_IWRITE
+# define S_IEXEC _S_IEXEC
+# define S_IFMT _S_IFMT
+# define S_IFCHR _S_IFCHR
+# define S_IFBLK _S_IFBLK
+# endif
+# ifndef IDENTPROTO
+# define IDENTPROTO 0 /* TCP/IP implementation is broken */
+# endif
+#endif
+
+
+/*
+** RISC/os 4.52
+**
+** Gives a ton of warning messages, but otherwise compiles.
+*/
+
+#ifdef RISCOS
+
+# define HASUNSETENV 1 /* has unsetenv(3) call */
+# ifndef HASFLOCK
+# define HASFLOCK 1 /* has flock(2) call */
+# endif
+# define WAITUNION 1 /* use "union wait" as wait argument type */
+# define NEEDGETOPT 1 /* need a replacement for getopt(3) */
+# define LA_TYPE LA_INT
+# define LA_AVENRUN "avenrun"
+# define _PATH_UNIX "/unix"
+# undef WIFEXITED
+
+# define setpgid setpgrp
+
+extern int errno;
+typedef int pid_t;
+#define SIGFUNC_DEFINED
+typedef int (*sigfunc_t)();
+extern char *getenv();
+extern void *malloc();
+
+#endif
+
+
+/*
+** Linux 0.99pl10 and above...
+**
+** Thanks to, in reverse order of contact:
+**
+** John Kennedy <warlock@csuchico.edu>
+** Florian La Roche <rzsfl@rz.uni-sb.de>
+** Karl London <karl@borg.demon.co.uk>
+**
+** Last compiled against: [03/02/94 @ 05:34 PM (Wednesday)]
+** sendmail 8.6.6.b9 named 4.9.2-931205-p1 db-1.73
+** gcc 2.5.8 libc.so.4.5.19
+** slackware 1.1.2 linux 0.99.15
+*/
+
+#ifdef __linux__
+# define BSD 1 /* include BSD defines */
+# define NEEDGETOPT 1 /* need a replacement for getopt(3) */
+# define HASUNAME 1 /* use System V uname(2) system call */
+# define HASUNSETENV 1 /* has unsetenv(3) call */
+# define ERRLIST_PREDEFINED /* don't declare sys_errlist */
+# define GIDSET_T gid_t /* from <linux/types.h> */
+# ifndef LA_TYPE
+# define LA_TYPE LA_PROCSTR
+# endif
+# define SFS_TYPE SFS_VFS /* use <sys/vfs.h> statfs() impl */
+# include <sys/sysmacros.h>
+# undef atol /* wounded in <stdlib.h> */
+#endif
+
+
+/*
+** DELL SVR4 Issue 2.2, and others
+** From Kimmo Suominen <kim@grendel.lut.fi>
+**
+** It's on #ifdef DELL_SVR4 because Solaris also gets __svr4__
+** defined, and the definitions conflict.
+**
+** Peter Wemm <peter@perth.DIALix.oz.au> claims that the setreuid
+** trick works on DELL 2.2 (SVR4.0/386 version 4.0) and ESIX 4.0.3A
+** (SVR4.0/386 version 3.0).
+*/
+
+#ifdef DELL_SVR4
+ /* no changes necessary */
+ /* see general __svr4__ defines below */
+#endif
+
+
+/*
+** Apple A/UX 3.0
+*/
+
+#ifdef _AUX_SOURCE
+# include <sys/sysmacros.h>
+# define BSD /* has BSD routines */
+# define HASUNAME 1 /* use System V uname(2) system call */
+# define HASSETVBUF 1 /* we have setvbuf(3) in libc */
+# define SIGFUNC_DEFINED /* sigfunc_t already defined */
+# ifndef IDENTPROTO
+# define IDENTPROTO 0 /* TCP/IP implementation is broken */
+# endif
+# define FORK fork
+# ifndef _PATH_SENDMAILCF
+# define _PATH_SENDMAILCF "/usr/lib/sendmail.cf"
+# endif
+# ifndef LA_TYPE
+# define LA_TYPE LA_ZERO
+# endif
+# define SFS_TYPE SFS_VFS /* use <sys/vfs.h> statfs() implementation */
+# undef WIFEXITED
+# undef WEXITSTATUS
+#endif
+
+
+/*
+** Encore UMAX V
+**
+** Not extensively tested.
+*/
+
+#ifdef UMAXV
+# include <limits.h>
+# define HASUNAME 1 /* use System V uname(2) system call */
+# define HASSETVBUF 1 /* we have setvbuf(3) in libc */
+# define HASINITGROUPS 1 /* has initgroups(3) call */
+# define HASGETUSERSHELL 0 /* does not have getusershell(3) call */
+# define SYS5SIGNALS 1 /* SysV signal semantics -- reset on each sig */
+# define SYS5SETPGRP 1 /* use System V setpgrp(2) syscall */
+# define FORK fork /* no vfork(2) primitive available */
+# define SFS_TYPE SFS_4ARGS /* four argument statfs() call */
+# define MAXPATHLEN PATH_MAX
+extern struct passwd *getpwent(), *getpwnam(), *getpwuid();
+extern struct group *getgrent(), *getgrnam(), *getgrgid();
+# undef WIFEXITED
+# undef WEXITSTATUS
+#endif
+
+
+/*
+** Stardent Titan 3000 running TitanOS 4.2.
+**
+** Must be compiled in "cc -43" mode.
+**
+** From Kate Hedstrom <kate@ahab.rutgers.edu>.
+**
+** Note the tweaking below after the BSD defines are set.
+*/
+
+#ifdef titan
+# define setpgid setpgrp
+typedef int pid_t;
+# undef WIFEXITED
+# undef WEXITSTATUS
+#endif
+
+
+/*
+** Sequent DYNIX 3.2.0
+**
+** From Jim Davis <jdavis@cs.arizona.edu>.
+*/
+
+#ifdef sequent
+
+# define BSD 1
+# define HASUNSETENV 1
+# define BSD4_3 1 /* to get signal() in conf.c */
+# define WAITUNION 1
+# define LA_TYPE LA_FLOAT
+# ifdef _POSIX_VERSION
+# undef _POSIX_VERSION /* set in <unistd.h> */
+# endif
+# undef HASSETVBUF /* don't actually have setvbuf(3) */
+# define setpgid setpgrp
+
+/* Have to redefine WIFEXITED to take an int, to work with waitfor() */
+# undef WIFEXITED
+# define WIFEXITED(s) (((union wait*)&(s))->w_stopval != WSTOPPED && \
+ ((union wait*)&(s))->w_termsig == 0)
+# define WEXITSTATUS(s) (((union wait*)&(s))->w_retcode)
+typedef int pid_t;
+# define isgraph(c) (isprint(c) && (c != ' '))
+
+# ifndef IDENTPROTO
+# define IDENTPROTO 0 /* TCP/IP implementation is broken */
+# endif
+
+# ifndef _PATH_UNIX
+# define _PATH_UNIX "/dynix"
+# endif
+# ifndef _PATH_SENDMAILCF
+# define _PATH_SENDMAILCF "/usr/lib/sendmail.cf"
+# endif
+
+#endif
+
+
+/*
+** Sequent DYNIX/ptx v2.0 (and higher)
+**
+** For DYNIX/ptx v1.x, undefine HASSETREUID.
+**
+** From Tim Wright <timw@sequent.com>.
+*/
+
+#ifdef _SEQUENT_
+# define SYSTEM5 1 /* include all the System V defines */
+# define HASSETSID 1 /* has POSIX setsid(2) call */
+# define HASINITGROUPS 1 /* has initgroups(3) call */
+# define HASSETREUID 1 /* has setreuid(2) call */
+# define HASGETUSERSHELL 0 /* does not have getusershell(3) call */
+# define GIDSET_T gid_t
+# define LA_TYPE LA_INT
+# define SFS_TYPE SFS_STATFS /* use <sys/statfs.h> statfs() impl */
+# undef SETPROCTITLE
+# ifndef IDENTPROTO
+# define IDENTPROTO 0 /* TCP/IP implementation is broken */
+# endif
+# ifndef _PATH_SENDMAILCF
+# define _PATH_SENDMAILCF "/usr/lib/sendmail.cf"
+# endif
+# ifndef _PATH_SENDMAILPID
+# define _PATH_SENDMAILPID "/etc/sendmail.pid"
+# endif
+#endif
+
+
+/*
+** Cray Unicos
+**
+** Ported by David L. Kensiski, Sterling Sofware <kensiski@nas.nasa.gov>
+*/
+
+#ifdef UNICOS
+# define SYSTEM5 1 /* include all the System V defines */
+# define SYS5SIGNALS 1 /* SysV signal semantics -- reset on each sig */
+# define MAXPATHLEN PATHSIZE
+# define LA_TYPE LA_ZERO
+# define SFS_TYPE SFS_4ARGS /* four argument statfs() call */
+#endif
+
+
+/*
+** Apollo DomainOS
+**
+** From Todd Martin <tmartint@tus.ssi1.com> & Don Lewis <gdonl@gv.ssi1.com>
+**
+** 15 Jan 1994
+**
+*/
+
+#ifdef apollo
+# define HASSETREUID 1 /* has setreuid(2) call */
+# define HASINITGROUPS 1 /* has initgroups(2) call */
+# undef SETPROCTITLE
+# define LA_TYPE LA_SUBR /* use getloadavg.c */
+# define SFS_TYPE SFS_4ARGS /* four argument statfs() call */
+# ifndef _PATH_SENDMAILCF
+# define _PATH_SENDMAILCF "/usr/lib/sendmail.cf"
+# endif
+# ifndef _PATH_SENDMAILPID
+# define _PATH_SENDMAILPID "/etc/sendmail.pid"
+# endif
+# undef S_IFSOCK /* S_IFSOCK and S_IFIFO are the same */
+# undef S_IFIFO
+# define S_IFIFO 0010000
+# ifndef IDENTPROTO
+# define IDENTPROTO 0 /* TCP/IP implementation is broken */
+# endif
+#endif
+
+
+/*
+** UnixWare
+**
+** From Evan Champion <evanc@spatial.synapse.org>.
+*/
+
+#ifdef UNIXWARE
+# define SYSTEM5 1
+# ifndef HASGETUSERSHELL
+# define HASGETUSERSHELL 0 /* does not have getusershell(3) call */
+# endif
+# define GIDSET_T int
+# define SLEEP_T int
+# define SFS_TYPE SFS_STATVFS
+# define LA_TYPE LA_ZERO
+# undef WIFEXITED
+# undef WEXITSTATUS
+# define _PATH_UNIX "/unix"
+# ifndef _PATH_SENDMAILCF
+# define _PATH_SENDMAILCF "/usr/ucblib/sendmail.cf"
+# endif
+# ifndef _PATH_SENDMAILPID
+# define _PATH_SENDMAILPID "/usr/ucblib/sendmail.pid"
+# endif
+# define SYSLOG_BUFSIZE 128
+#endif
+
+
+/*
+** Intergraph CLIX 3.1
+**
+** From Paul Southworth <pauls@locust.cic.net>
+*/
+
+#ifdef CLIX
+# define SYSTEM5 1 /* looks like System V */
+# ifndef HASGETUSERSHELL
+# define HASGETUSERSHELL 0 /* does not have getusershell(3) call */
+# endif
+# define DEV_BSIZE 512 /* device block size not defined */
+# define GIDSET_T gid_t
+# undef LOG /* syslog not available */
+# define NEEDFSYNC 1 /* no fsync in system library */
+# define GETSHORT _getshort
+#endif
+
+
+/*
+** NCR 3000 Series (SysVr4)
+**
+** From From: Kevin Darcy <kevin@tech.mis.cfc.com>.
+*/
+
+#ifdef NCR3000
+# define __svr4__
+# undef BSD
+# define LA_AVENRUN "avenrun"
+#endif
+
+
+
+
+
+/**********************************************************************
+** End of Per-Operating System defines
+**********************************************************************/
+
+/**********************************************************************
+** More general defines
+**********************************************************************/
+
+/* general BSD defines */
+#ifdef BSD
+# define HASGETDTABLESIZE 1 /* has getdtablesize(2) call */
+# define HASSETREUID 1 /* has setreuid(2) call */
+# define HASINITGROUPS 1 /* has initgroups(2) call */
+# ifndef HASFLOCK
+# define HASFLOCK 1 /* has flock(2) call */
+# endif
+#endif
+
+/* general System V Release 4 defines */
+#ifdef __svr4__
+# define SYSTEM5 1
+# define HASSETREUID 1 /* has seteuid(2) call & working saved uids */
+# ifndef HASGETUSERSHELL
+# define HASGETUSERSHELL 0 /* does not have getusershell(3) call */
+# endif
+# define setreuid(r, e) seteuid(e)
+
+# ifndef _PATH_UNIX
+# define _PATH_UNIX "/unix"
+# endif
+# ifndef _PATH_SENDMAILCF
+# define _PATH_SENDMAILCF "/usr/ucblib/sendmail.cf"
+# endif
+# ifndef _PATH_SENDMAILPID
+# define _PATH_SENDMAILPID "/usr/ucblib/sendmail.pid"
+# endif
+# ifndef SYSLOG_BUFSIZE
+# define SYSLOG_BUFSIZE 128
+# endif
+#endif
+
+/* general System V defines */
+#ifdef SYSTEM5
+# include <sys/sysmacros.h>
+# define HASUNAME 1 /* use System V uname(2) system call */
+# define SYS5SETPGRP 1 /* use System V setpgrp(2) syscall */
+# define HASSETVBUF 1 /* we have setvbuf(3) in libc */
+# ifndef LA_TYPE
+# define LA_TYPE LA_INT /* assume integer load average */
+# endif
+# ifndef SFS_TYPE
+# define SFS_TYPE SFS_USTAT /* use System V ustat(2) syscall */
+# endif
+# define bcopy(s, d, l) (memmove((d), (s), (l)))
+# define bzero(d, l) (memset((d), '\0', (l)))
+# define bcmp(s, d, l) (memcmp((s), (d), (l)))
+#endif
+
+/* general POSIX defines */
+#ifdef _POSIX_VERSION
+# define HASSETSID 1 /* has Posix setsid(2) call */
+# define HASWAITPID 1 /* has Posix waitpid(2) call */
+#endif
+
+/*
+** If no type for argument two of getgroups call is defined, assume
+** it's an integer -- unfortunately, there seem to be several choices
+** here.
+*/
+
+#ifndef GIDSET_T
+# define GIDSET_T int
+#endif
+
+/*
+** Tweaking for systems that (for example) claim to be BSD but
+** don't have all the standard BSD routines (boo hiss).
+*/
+
+#ifdef titan
+# undef HASINITGROUPS /* doesn't have initgroups(3) call */
+#endif
+
+
+/*
+** Due to a "feature" in some operating systems such as Ultrix 4.3 and
+** HPUX 8.0, if you receive a "No route to host" message (ICMP message
+** ICMP_UNREACH_HOST) on _any_ connection, all connections to that host
+** are closed. Some firewalls return this error if you try to connect
+** to the IDENT port (113), so you can't receive email from these hosts
+** on these systems. The firewall really should use a more specific
+** message such as ICMP_UNREACH_PROTOCOL or _PORT or _NET_PROHIB. If
+** not explicitly set to zero above, default it on.
+*/
+
+#ifndef IDENTPROTO
+# define IDENTPROTO 1 /* use IDENT proto (RFC 1413) */
+#endif
+
+#ifndef HASGETUSERSHELL
+# define HASGETUSERSHELL 1 /* libc has getusershell(3) call */
+#endif
+
+#ifndef HASFLOCK
+# define HASFLOCK 0 /* assume no flock(2) support */
+#endif
+
+#ifndef OLD_NEWDB
+# define OLD_NEWDB 0 /* assume newer version of newdb */
+#endif
+
+
+/**********************************************************************
+** Remaining definitions should never have to be changed. They are
+** primarily to provide back compatibility for older systems -- for
+** example, it includes some POSIX compatibility definitions
+**********************************************************************/
+
+/* System 5 compatibility */
+#ifndef S_ISREG
+# define S_ISREG(foo) ((foo & S_IFMT) == S_IFREG)
+#endif
+#if !defined(S_ISLNK) && defined(S_IFLNK)
+# define S_ISLNK(foo) ((foo & S_IFMT) == S_IFLNK)
+#endif
+#ifndef S_IWGRP
+#define S_IWGRP 020
+#endif
+#ifndef S_IWOTH
+#define S_IWOTH 002
+#endif
+
+/*
+** Older systems don't have this error code -- it should be in
+** /usr/include/sysexits.h.
+*/
+
+# ifndef EX_CONFIG
+# define EX_CONFIG 78 /* configuration error */
+# endif
+
+/* pseudo-code used in server SMTP */
+# define EX_QUIT 22 /* drop out of server immediately */
+
+
+/*
+** These are used in a few cases where we need some special
+** error codes, but where the system doesn't provide something
+** reasonable. They are printed in errstring.
+*/
+
+#ifndef E_PSEUDOBASE
+# define E_PSEUDOBASE 256
+#endif
+
+#define EOPENTIMEOUT (E_PSEUDOBASE + 0) /* timeout on open */
+#define E_DNSBASE (E_PSEUDOBASE + 20) /* base for DNS h_errno */
+
+/* type of arbitrary pointer */
+#ifndef ARBPTR_T
+# define ARBPTR_T void *
+#endif
+
+#ifndef __P
+# include "cdefs.h"
+#endif
+
+/*
+** Do some required dependencies
+*/
+
+#if defined(NETINET) || defined(NETISO)
+# define SMTP 1 /* enable user and server SMTP */
+# define QUEUE 1 /* enable queueing */
+# define DAEMON 1 /* include the daemon (requires IPC & SMTP) */
+#endif
+
+
+/*
+** Arrange to use either varargs or stdargs
+*/
+
+# ifdef __STDC__
+
+# include <stdarg.h>
+
+# define VA_LOCAL_DECL va_list ap;
+# define VA_START(f) va_start(ap, f)
+# define VA_END va_end(ap)
+
+# else
+
+# include <varargs.h>
+
+# define VA_LOCAL_DECL va_list ap;
+# define VA_START(f) va_start(ap)
+# define VA_END va_end(ap)
+
+# endif
+
+#ifdef HASUNAME
+# include <sys/utsname.h>
+# ifdef newstr
+# undef newstr
+# endif
+#else /* ! HASUNAME */
+# define NODE_LENGTH 32
+struct utsname
+{
+ char nodename[NODE_LENGTH+1];
+};
+#endif /* HASUNAME */
+
+#if !defined(MAXHOSTNAMELEN) && !defined(_SCO_unix_)
+# define MAXHOSTNAMELEN 256
+#endif
+
+#if !defined(SIGCHLD) && defined(SIGCLD)
+# define SIGCHLD SIGCLD
+#endif
+
+#ifndef STDIN_FILENO
+#define STDIN_FILENO 0
+#endif
+
+#ifndef STDOUT_FILENO
+#define STDOUT_FILENO 1
+#endif
+
+#ifndef STDERR_FILENO
+#define STDERR_FILENO 2
+#endif
+
+#ifndef LOCK_SH
+# define LOCK_SH 0x01 /* shared lock */
+# define LOCK_EX 0x02 /* exclusive lock */
+# define LOCK_NB 0x04 /* non-blocking lock */
+# define LOCK_UN 0x08 /* unlock */
+#endif
+
+#ifndef SIG_ERR
+# define SIG_ERR ((void (*)()) -1)
+#endif
+
+#ifndef WEXITSTATUS
+# define WEXITSTATUS(st) (((st) >> 8) & 0377)
+#endif
+#ifndef WIFEXITED
+# define WIFEXITED(st) (((st) & 0377) == 0)
+#endif
+
+#ifndef SIGFUNC_DEFINED
+typedef void (*sigfunc_t) __P((int));
+#endif
+
+/* size of syslog buffer */
+#ifndef SYSLOG_BUFSIZE
+# define SYSLOG_BUFSIZE 1024
+#endif
+
+/*
+** Size of tobuf (deliver.c)
+** Tweak this to match your syslog implementation. It will have to
+** allow for the extra information printed.
+*/
+
+#ifndef TOBUFSIZE
+# if (SYSLOG_BUFSIZE) > 512
+# define TOBUFSIZE (SYSLOG_BUFSIZE - 256)
+# else
+# define TOBUFSIZE 256
+# endif
+#endif
+
+/*
+** Size of prescan buffer.
+** Despite comments in the _sendmail_ book, this probably should
+** not be changed; there are some hard-to-define dependencies.
+*/
+
+# define PSBUFSIZE (MAXNAME + MAXATOM) /* size of prescan buffer */
+/* fork routine -- set above using #ifdef _osname_ or in Makefile */
+# ifndef FORK
+# define FORK vfork /* function to call to fork mailer */
+# endif
+
+/*
+** If we are going to link scanf anyway, use it in readcf
+*/
+
+#if !defined(HASUNAME) && !defined(SCANF)
+# define SCANF 1
+#endif
diff --git a/usr.sbin/sendmail/src/convtime.c b/usr.sbin/sendmail/src/convtime.c
new file mode 100644
index 0000000..5cb5e49
--- /dev/null
+++ b/usr.sbin/sendmail/src/convtime.c
@@ -0,0 +1,197 @@
+/*
+ * Copyright (c) 1983 Eric P. Allman
+ * Copyright (c) 1988, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)convtime.c 8.1 (Berkeley) 6/7/93";
+#endif /* not lint */
+
+# include <ctype.h>
+# include "useful.h"
+
+/*
+** CONVTIME -- convert time
+**
+** Takes a time as an ascii string with a trailing character
+** giving units:
+** s -- seconds
+** m -- minutes
+** h -- hours
+** d -- days (default)
+** w -- weeks
+** For example, "3d12h" is three and a half days.
+**
+** Parameters:
+** p -- pointer to ascii time.
+** units -- default units if none specified.
+**
+** Returns:
+** time in seconds.
+**
+** Side Effects:
+** none.
+*/
+
+time_t
+convtime(p, units)
+ char *p;
+ char units;
+{
+ register time_t t, r;
+ register char c;
+
+ r = 0;
+ while (*p != '\0')
+ {
+ t = 0;
+ while ((c = *p++) != '\0' && isascii(c) && isdigit(c))
+ t = t * 10 + (c - '0');
+ if (c == '\0')
+ {
+ c = units;
+ p--;
+ }
+ switch (c)
+ {
+ case 'w': /* weeks */
+ t *= 7;
+
+ case 'd': /* days */
+ default:
+ t *= 24;
+
+ case 'h': /* hours */
+ t *= 60;
+
+ case 'm': /* minutes */
+ t *= 60;
+
+ case 's': /* seconds */
+ break;
+ }
+ r += t;
+ }
+
+ return (r);
+}
+ /*
+** PINTVL -- produce printable version of a time interval
+**
+** Parameters:
+** intvl -- the interval to be converted
+** brief -- if TRUE, print this in an extremely compact form
+** (basically used for logging).
+**
+** Returns:
+** A pointer to a string version of intvl suitable for
+** printing or framing.
+**
+** Side Effects:
+** none.
+**
+** Warning:
+** The string returned is in a static buffer.
+*/
+
+# define PLURAL(n) ((n) == 1 ? "" : "s")
+
+char *
+pintvl(intvl, brief)
+ time_t intvl;
+ bool brief;
+{
+ static char buf[256];
+ register char *p;
+ int wk, dy, hr, mi, se;
+
+ if (intvl == 0 && !brief)
+ return ("zero seconds");
+
+ /* decode the interval into weeks, days, hours, minutes, seconds */
+ se = intvl % 60;
+ intvl /= 60;
+ mi = intvl % 60;
+ intvl /= 60;
+ hr = intvl % 24;
+ intvl /= 24;
+ if (brief)
+ dy = intvl;
+ else
+ {
+ dy = intvl % 7;
+ intvl /= 7;
+ wk = intvl;
+ }
+
+ /* now turn it into a sexy form */
+ p = buf;
+ if (brief)
+ {
+ if (dy > 0)
+ {
+ (void) sprintf(p, "%d+", dy);
+ p += strlen(p);
+ }
+ (void) sprintf(p, "%02d:%02d:%02d", hr, mi, se);
+ return (buf);
+ }
+
+ /* use the verbose form */
+ if (wk > 0)
+ {
+ (void) sprintf(p, ", %d week%s", wk, PLURAL(wk));
+ p += strlen(p);
+ }
+ if (dy > 0)
+ {
+ (void) sprintf(p, ", %d day%s", dy, PLURAL(dy));
+ p += strlen(p);
+ }
+ if (hr > 0)
+ {
+ (void) sprintf(p, ", %d hour%s", hr, PLURAL(hr));
+ p += strlen(p);
+ }
+ if (mi > 0)
+ {
+ (void) sprintf(p, ", %d minute%s", mi, PLURAL(mi));
+ p += strlen(p);
+ }
+ if (se > 0)
+ {
+ (void) sprintf(p, ", %d second%s", se, PLURAL(se));
+ p += strlen(p);
+ }
+
+ return (buf + 2);
+}
diff --git a/usr.sbin/sendmail/src/daemon.c b/usr.sbin/sendmail/src/daemon.c
new file mode 100644
index 0000000..293438b
--- /dev/null
+++ b/usr.sbin/sendmail/src/daemon.c
@@ -0,0 +1,1547 @@
+/*
+ * Copyright (c) 1983 Eric P. Allman
+ * Copyright (c) 1988, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <errno.h>
+#include "sendmail.h"
+
+#ifndef lint
+#ifdef DAEMON
+static char sccsid[] = "@(#)daemon.c 8.48 (Berkeley) 4/18/94 (with daemon mode)";
+#else
+static char sccsid[] = "@(#)daemon.c 8.48 (Berkeley) 4/18/94 (without daemon mode)";
+#endif
+#endif /* not lint */
+
+#ifdef DAEMON
+
+# include <netdb.h>
+# include <arpa/inet.h>
+
+#if NAMED_BIND
+# include <arpa/nameser.h>
+# include <resolv.h>
+#endif
+
+/*
+** DAEMON.C -- routines to use when running as a daemon.
+**
+** This entire file is highly dependent on the 4.2 BSD
+** interprocess communication primitives. No attempt has
+** been made to make this file portable to Version 7,
+** Version 6, MPX files, etc. If you should try such a
+** thing yourself, I recommend chucking the entire file
+** and starting from scratch. Basic semantics are:
+**
+** getrequests()
+** Opens a port and initiates a connection.
+** Returns in a child. Must set InChannel and
+** OutChannel appropriately.
+** clrdaemon()
+** Close any open files associated with getting
+** the connection; this is used when running the queue,
+** etc., to avoid having extra file descriptors during
+** the queue run and to avoid confusing the network
+** code (if it cares).
+** makeconnection(host, port, outfile, infile, usesecureport)
+** Make a connection to the named host on the given
+** port. Set *outfile and *infile to the files
+** appropriate for communication. Returns zero on
+** success, else an exit status describing the
+** error.
+** host_map_lookup(map, hbuf, avp, pstat)
+** Convert the entry in hbuf into a canonical form.
+*/
+ /*
+** GETREQUESTS -- open mail IPC port and get requests.
+**
+** Parameters:
+** none.
+**
+** Returns:
+** none.
+**
+** Side Effects:
+** Waits until some interesting activity occurs. When
+** it does, a child is created to process it, and the
+** parent waits for completion. Return from this
+** routine is always in the child. The file pointers
+** "InChannel" and "OutChannel" should be set to point
+** to the communication channel.
+*/
+
+int DaemonSocket = -1; /* fd describing socket */
+SOCKADDR DaemonAddr; /* socket for incoming */
+int ListenQueueSize = 10; /* size of listen queue */
+int TcpRcvBufferSize = 0; /* size of TCP receive buffer */
+int TcpSndBufferSize = 0; /* size of TCP send buffer */
+
+getrequests()
+{
+ int t;
+ bool refusingconnections = TRUE;
+ FILE *pidf;
+ int socksize;
+#ifdef XDEBUG
+ bool j_has_dot;
+#endif
+ extern void reapchild();
+
+ /*
+ ** Set up the address for the mailer.
+ */
+
+ if (DaemonAddr.sin.sin_family == 0)
+ DaemonAddr.sin.sin_family = AF_INET;
+ if (DaemonAddr.sin.sin_addr.s_addr == 0)
+ DaemonAddr.sin.sin_addr.s_addr = INADDR_ANY;
+ if (DaemonAddr.sin.sin_port == 0)
+ {
+ register struct servent *sp;
+
+ sp = getservbyname("smtp", "tcp");
+ if (sp == NULL)
+ {
+ syserr("554 service \"smtp\" unknown");
+ DaemonAddr.sin.sin_port = htons(25);
+ }
+ else
+ DaemonAddr.sin.sin_port = sp->s_port;
+ }
+
+ /*
+ ** Try to actually open the connection.
+ */
+
+ if (tTd(15, 1))
+ printf("getrequests: port 0x%x\n", DaemonAddr.sin.sin_port);
+
+ /* get a socket for the SMTP connection */
+ socksize = opendaemonsocket(TRUE);
+
+ (void) setsignal(SIGCHLD, reapchild);
+
+ /* write the pid to the log file for posterity */
+ pidf = fopen(PidFile, "w");
+ if (pidf != NULL)
+ {
+ extern char *CommandLineArgs;
+
+ /* write the process id on line 1 */
+ fprintf(pidf, "%d\n", getpid());
+
+ /* line 2 contains all command line flags */
+ fprintf(pidf, "%s\n", CommandLineArgs);
+
+ /* flush and close */
+ fclose(pidf);
+ }
+
+#ifdef XDEBUG
+ {
+ char jbuf[MAXHOSTNAMELEN];
+
+ expand("\201j", jbuf, &jbuf[sizeof jbuf - 1], CurEnv);
+ j_has_dot = strchr(jbuf, '.') != NULL;
+ }
+#endif
+
+ if (tTd(15, 1))
+ printf("getrequests: %d\n", DaemonSocket);
+
+ for (;;)
+ {
+ register int pid;
+ auto int lotherend;
+ extern bool refuseconnections();
+
+ /* see if we are rejecting connections */
+ CurrentLA = getla();
+ if (refuseconnections())
+ {
+ if (DaemonSocket >= 0)
+ {
+ /* close socket so peer will fail quickly */
+ (void) close(DaemonSocket);
+ DaemonSocket = -1;
+ }
+ refusingconnections = TRUE;
+ setproctitle("rejecting connections: load average: %d",
+ CurrentLA);
+ sleep(15);
+ continue;
+ }
+
+ if (refusingconnections)
+ {
+ /* start listening again */
+ (void) opendaemonsocket(FALSE);
+ setproctitle("accepting connections");
+ refusingconnections = FALSE;
+ }
+
+#ifdef XDEBUG
+ /* check for disaster */
+ {
+ register STAB *s;
+ char jbuf[MAXHOSTNAMELEN];
+
+ expand("\201j", jbuf, &jbuf[sizeof jbuf - 1], CurEnv);
+ if ((s = stab(jbuf, ST_CLASS, ST_FIND)) == NULL ||
+ !bitnset('w', s->s_class))
+ {
+ dumpstate("daemon lost $j");
+ syslog(LOG_ALERT, "daemon process doesn't have $j in $=w; see syslog");
+ abort();
+ }
+ else if (j_has_dot && strchr(jbuf, '.') == NULL)
+ {
+ dumpstate("daemon $j lost dot");
+ syslog(LOG_ALERT, "daemon process $j lost dot; see syslog");
+ abort();
+ }
+ }
+#endif
+
+ /* wait for a connection */
+ do
+ {
+ errno = 0;
+ lotherend = socksize;
+ t = accept(DaemonSocket,
+ (struct sockaddr *)&RealHostAddr, &lotherend);
+ } while (t < 0 && errno == EINTR);
+ if (t < 0)
+ {
+ syserr("getrequests: accept");
+ sleep(5);
+ continue;
+ }
+
+ /*
+ ** Create a subprocess to process the mail.
+ */
+
+ if (tTd(15, 2))
+ printf("getrequests: forking (fd = %d)\n", t);
+
+ pid = fork();
+ if (pid < 0)
+ {
+ syserr("daemon: cannot fork");
+ sleep(10);
+ (void) close(t);
+ continue;
+ }
+
+ if (pid == 0)
+ {
+ char *p;
+ extern char *hostnamebyanyaddr();
+
+ /*
+ ** CHILD -- return to caller.
+ ** Collect verified idea of sending host.
+ ** Verify calling user id if possible here.
+ */
+
+ (void) setsignal(SIGCHLD, SIG_DFL);
+ DisConnected = FALSE;
+
+ setproctitle("startup with %s",
+ anynet_ntoa(&RealHostAddr));
+
+ /* determine host name */
+ p = hostnamebyanyaddr(&RealHostAddr);
+ RealHostName = newstr(p);
+ setproctitle("startup with %s", p);
+
+#ifdef LOG
+ if (LogLevel > 11)
+ {
+ /* log connection information */
+ syslog(LOG_INFO, "connect from %s (%s)",
+ RealHostName, anynet_ntoa(&RealHostAddr));
+ }
+#endif
+
+ (void) close(DaemonSocket);
+ if ((InChannel = fdopen(t, "r")) == NULL ||
+ (t = dup(t)) < 0 ||
+ (OutChannel = fdopen(t, "w")) == NULL)
+ {
+ syserr("cannot open SMTP server channel, fd=%d", t);
+ exit(0);
+ }
+
+ /* should we check for illegal connection here? XXX */
+#ifdef XLA
+ if (!xla_host_ok(RealHostName))
+ {
+ message("421 Too many SMTP sessions for this host");
+ exit(0);
+ }
+#endif
+
+ if (tTd(15, 2))
+ printf("getreq: returning\n");
+ return;
+ }
+
+ /* close the port so that others will hang (for a while) */
+ (void) close(t);
+ }
+ /*NOTREACHED*/
+}
+ /*
+** OPENDAEMONSOCKET -- open the SMTP socket
+**
+** Deals with setting all appropriate options. DaemonAddr must
+** be set up in advance.
+**
+** Parameters:
+** firsttime -- set if this is the initial open.
+**
+** Returns:
+** Size in bytes of the daemon socket addr.
+**
+** Side Effects:
+** Leaves DaemonSocket set to the open socket.
+** Exits if the socket cannot be created.
+*/
+
+#define MAXOPENTRIES 10 /* maximum number of tries to open connection */
+
+int
+opendaemonsocket(firsttime)
+ bool firsttime;
+{
+ int on = 1;
+ int socksize;
+ int ntries = 0;
+ int saveerrno;
+
+ if (tTd(15, 2))
+ printf("opendaemonsocket()\n");
+
+ do
+ {
+ if (ntries > 0)
+ sleep(5);
+ if (firsttime || DaemonSocket < 0)
+ {
+ DaemonSocket = socket(DaemonAddr.sa.sa_family, SOCK_STREAM, 0);
+ if (DaemonSocket < 0)
+ {
+ /* probably another daemon already */
+ saveerrno = errno;
+ syserr("opendaemonsocket: can't create server SMTP socket");
+ severe:
+# ifdef LOG
+ if (LogLevel > 0)
+ syslog(LOG_ALERT, "problem creating SMTP socket");
+# endif /* LOG */
+ DaemonSocket = -1;
+ continue;
+ }
+
+ /* turn on network debugging? */
+ if (tTd(15, 101))
+ (void) setsockopt(DaemonSocket, SOL_SOCKET,
+ SO_DEBUG, (char *)&on,
+ sizeof on);
+
+ (void) setsockopt(DaemonSocket, SOL_SOCKET,
+ SO_REUSEADDR, (char *)&on, sizeof on);
+ (void) setsockopt(DaemonSocket, SOL_SOCKET,
+ SO_KEEPALIVE, (char *)&on, sizeof on);
+
+#ifdef SO_RCVBUF
+ if (TcpRcvBufferSize > 0)
+ {
+ if (setsockopt(DaemonSocket, SOL_SOCKET,
+ SO_RCVBUF,
+ (char *) &TcpRcvBufferSize,
+ sizeof(TcpRcvBufferSize)) < 0)
+ syserr("getrequests: setsockopt(SO_RCVBUF)");
+ }
+#endif
+
+ switch (DaemonAddr.sa.sa_family)
+ {
+# ifdef NETINET
+ case AF_INET:
+ socksize = sizeof DaemonAddr.sin;
+ break;
+# endif
+
+# ifdef NETISO
+ case AF_ISO:
+ socksize = sizeof DaemonAddr.siso;
+ break;
+# endif
+
+ default:
+ socksize = sizeof DaemonAddr;
+ break;
+ }
+
+ if (bind(DaemonSocket, &DaemonAddr.sa, socksize) < 0)
+ {
+ saveerrno = errno;
+ syserr("getrequests: cannot bind");
+ (void) close(DaemonSocket);
+ goto severe;
+ }
+ }
+ if (!firsttime && listen(DaemonSocket, ListenQueueSize) < 0)
+ {
+ saveerrno = errno;
+ syserr("getrequests: cannot listen");
+ (void) close(DaemonSocket);
+ goto severe;
+ }
+ return socksize;
+ } while (ntries++ < MAXOPENTRIES && transienterror(saveerrno));
+ finis();
+}
+ /*
+** CLRDAEMON -- reset the daemon connection
+**
+** Parameters:
+** none.
+**
+** Returns:
+** none.
+**
+** Side Effects:
+** releases any resources used by the passive daemon.
+*/
+
+clrdaemon()
+{
+ if (DaemonSocket >= 0)
+ (void) close(DaemonSocket);
+ DaemonSocket = -1;
+}
+ /*
+** SETDAEMONOPTIONS -- set options for running the daemon
+**
+** Parameters:
+** p -- the options line.
+**
+** Returns:
+** none.
+*/
+
+setdaemonoptions(p)
+ register char *p;
+{
+ if (DaemonAddr.sa.sa_family == AF_UNSPEC)
+ DaemonAddr.sa.sa_family = AF_INET;
+
+ while (p != NULL)
+ {
+ register char *f;
+ register char *v;
+
+ while (isascii(*p) && isspace(*p))
+ p++;
+ if (*p == '\0')
+ break;
+ f = p;
+ p = strchr(p, ',');
+ if (p != NULL)
+ *p++ = '\0';
+ v = strchr(f, '=');
+ if (v == NULL)
+ continue;
+ while (isascii(*++v) && isspace(*v))
+ continue;
+
+ switch (*f)
+ {
+ case 'F': /* address family */
+ if (isascii(*v) && isdigit(*v))
+ DaemonAddr.sa.sa_family = atoi(v);
+#ifdef NETINET
+ else if (strcasecmp(v, "inet") == 0)
+ DaemonAddr.sa.sa_family = AF_INET;
+#endif
+#ifdef NETISO
+ else if (strcasecmp(v, "iso") == 0)
+ DaemonAddr.sa.sa_family = AF_ISO;
+#endif
+#ifdef NETNS
+ else if (strcasecmp(v, "ns") == 0)
+ DaemonAddr.sa.sa_family = AF_NS;
+#endif
+#ifdef NETX25
+ else if (strcasecmp(v, "x.25") == 0)
+ DaemonAddr.sa.sa_family = AF_CCITT;
+#endif
+ else
+ syserr("554 Unknown address family %s in Family=option", v);
+ break;
+
+ case 'A': /* address */
+ switch (DaemonAddr.sa.sa_family)
+ {
+#ifdef NETINET
+ case AF_INET:
+ if (isascii(*v) && isdigit(*v))
+ DaemonAddr.sin.sin_addr.s_addr = inet_network(v);
+ else
+ {
+ register struct netent *np;
+
+ np = getnetbyname(v);
+ if (np == NULL)
+ syserr("554 network \"%s\" unknown", v);
+ else
+ DaemonAddr.sin.sin_addr.s_addr = np->n_net;
+ }
+ break;
+#endif
+
+ default:
+ syserr("554 Address= option unsupported for family %d",
+ DaemonAddr.sa.sa_family);
+ break;
+ }
+ break;
+
+ case 'P': /* port */
+ switch (DaemonAddr.sa.sa_family)
+ {
+ short port;
+
+#ifdef NETINET
+ case AF_INET:
+ if (isascii(*v) && isdigit(*v))
+ DaemonAddr.sin.sin_port = htons(atoi(v));
+ else
+ {
+ register struct servent *sp;
+
+ sp = getservbyname(v, "tcp");
+ if (sp == NULL)
+ syserr("554 service \"%s\" unknown", v);
+ else
+ DaemonAddr.sin.sin_port = sp->s_port;
+ }
+ break;
+#endif
+
+#ifdef NETISO
+ case AF_ISO:
+ /* assume two byte transport selector */
+ if (isascii(*v) && isdigit(*v))
+ port = htons(atoi(v));
+ else
+ {
+ register struct servent *sp;
+
+ sp = getservbyname(v, "tcp");
+ if (sp == NULL)
+ syserr("554 service \"%s\" unknown", v);
+ else
+ port = sp->s_port;
+ }
+ bcopy((char *) &port, TSEL(&DaemonAddr.siso), 2);
+ break;
+#endif
+
+ default:
+ syserr("554 Port= option unsupported for family %d",
+ DaemonAddr.sa.sa_family);
+ break;
+ }
+ break;
+
+ case 'L': /* listen queue size */
+ ListenQueueSize = atoi(v);
+ break;
+
+ case 'S': /* send buffer size */
+ TcpSndBufferSize = atoi(v);
+ break;
+
+ case 'R': /* receive buffer size */
+ TcpRcvBufferSize = atoi(v);
+ break;
+ }
+ }
+}
+ /*
+** MAKECONNECTION -- make a connection to an SMTP socket on another machine.
+**
+** Parameters:
+** host -- the name of the host.
+** port -- the port number to connect to.
+** mci -- a pointer to the mail connection information
+** structure to be filled in.
+** usesecureport -- if set, use a low numbered (reserved)
+** port to provide some rudimentary authentication.
+**
+** Returns:
+** An exit code telling whether the connection could be
+** made and if not why not.
+**
+** Side Effects:
+** none.
+*/
+
+SOCKADDR CurHostAddr; /* address of current host */
+
+int
+makeconnection(host, port, mci, usesecureport)
+ char *host;
+ u_short port;
+ register MCI *mci;
+ bool usesecureport;
+{
+ register int i, s;
+ register struct hostent *hp = (struct hostent *)NULL;
+ SOCKADDR addr;
+ int sav_errno;
+ int addrlen;
+#if NAMED_BIND
+ extern int h_errno;
+#endif
+
+ /*
+ ** Set up the address for the mailer.
+ ** Accept "[a.b.c.d]" syntax for host name.
+ */
+
+#if NAMED_BIND
+ h_errno = 0;
+#endif
+ errno = 0;
+ bzero(&CurHostAddr, sizeof CurHostAddr);
+ SmtpPhase = mci->mci_phase = "initial connection";
+ CurHostName = host;
+
+ if (host[0] == '[')
+ {
+ long hid;
+ register char *p = strchr(host, ']');
+
+ if (p != NULL)
+ {
+ *p = '\0';
+#ifdef NETINET
+ hid = inet_addr(&host[1]);
+ if (hid == -1)
+#endif
+ {
+ /* try it as a host name (avoid MX lookup) */
+ hp = gethostbyname(&host[1]);
+ if (hp == NULL && p[-1] == '.')
+ {
+ p[-1] = '\0';
+ hp = gethostbyname(&host[1]);
+ p[-1] = '.';
+ }
+ *p = ']';
+ goto gothostent;
+ }
+ *p = ']';
+ }
+ if (p == NULL)
+ {
+ usrerr("553 Invalid numeric domain spec \"%s\"", host);
+ return (EX_NOHOST);
+ }
+#ifdef NETINET
+ addr.sin.sin_family = AF_INET; /*XXX*/
+ addr.sin.sin_addr.s_addr = hid;
+#endif
+ }
+ else
+ {
+ register char *p = &host[strlen(host) - 1];
+
+ hp = gethostbyname(host);
+ if (hp == NULL && *p == '.')
+ {
+ *p = '\0';
+ hp = gethostbyname(host);
+ *p = '.';
+ }
+gothostent:
+ if (hp == NULL)
+ {
+#if NAMED_BIND
+ if (errno == ETIMEDOUT || h_errno == TRY_AGAIN)
+ return (EX_TEMPFAIL);
+
+ /* if name server is specified, assume temp fail */
+ if (errno == ECONNREFUSED && UseNameServer)
+ return (EX_TEMPFAIL);
+#endif
+ return (EX_NOHOST);
+ }
+ addr.sa.sa_family = hp->h_addrtype;
+ switch (hp->h_addrtype)
+ {
+#ifdef NETINET
+ case AF_INET:
+ bcopy(hp->h_addr,
+ &addr.sin.sin_addr,
+ sizeof addr.sin.sin_addr);
+ break;
+#endif
+
+ default:
+ bcopy(hp->h_addr,
+ addr.sa.sa_data,
+ hp->h_length);
+ break;
+ }
+ i = 1;
+ }
+
+ /*
+ ** Determine the port number.
+ */
+
+ if (port != 0)
+ port = htons(port);
+ else
+ {
+ register struct servent *sp = getservbyname("smtp", "tcp");
+
+ if (sp == NULL)
+ {
+ syserr("554 makeconnection: service \"smtp\" unknown");
+ port = htons(25);
+ }
+ else
+ port = sp->s_port;
+ }
+
+ switch (addr.sa.sa_family)
+ {
+#ifdef NETINET
+ case AF_INET:
+ addr.sin.sin_port = port;
+ addrlen = sizeof (struct sockaddr_in);
+ break;
+#endif
+
+#ifdef NETISO
+ case AF_ISO:
+ /* assume two byte transport selector */
+ bcopy((char *) &port, TSEL((struct sockaddr_iso *) &addr), 2);
+ addrlen = sizeof (struct sockaddr_iso);
+ break;
+#endif
+
+ default:
+ syserr("Can't connect to address family %d", addr.sa.sa_family);
+ return (EX_NOHOST);
+ }
+
+ /*
+ ** Try to actually open the connection.
+ */
+
+#ifdef XLA
+ /* if too many connections, don't bother trying */
+ if (!xla_noqueue_ok(host))
+ return EX_TEMPFAIL;
+#endif
+
+ for (;;)
+ {
+ if (tTd(16, 1))
+ printf("makeconnection (%s [%s])\n",
+ host, anynet_ntoa(&addr));
+
+ /* save for logging */
+ CurHostAddr = addr;
+
+ if (usesecureport)
+ {
+ int rport = IPPORT_RESERVED - 1;
+
+ s = rresvport(&rport);
+ }
+ else
+ {
+ s = socket(AF_INET, SOCK_STREAM, 0);
+ }
+ if (s < 0)
+ {
+ sav_errno = errno;
+ syserr("makeconnection: no socket");
+ goto failure;
+ }
+
+#ifdef SO_SNDBUF
+ if (TcpSndBufferSize > 0)
+ {
+ if (setsockopt(s, SOL_SOCKET, SO_SNDBUF,
+ (char *) &TcpSndBufferSize,
+ sizeof(TcpSndBufferSize)) < 0)
+ syserr("makeconnection: setsockopt(SO_SNDBUF)");
+ }
+#endif
+
+ if (tTd(16, 1))
+ printf("makeconnection: fd=%d\n", s);
+
+ /* turn on network debugging? */
+ if (tTd(16, 101))
+ {
+ int on = 1;
+ (void) setsockopt(s, SOL_SOCKET, SO_DEBUG,
+ (char *)&on, sizeof on);
+ }
+ if (CurEnv->e_xfp != NULL)
+ (void) fflush(CurEnv->e_xfp); /* for debugging */
+ errno = 0; /* for debugging */
+ if (connect(s, (struct sockaddr *) &addr, addrlen) >= 0)
+ break;
+
+ /* couldn't connect.... figure out why */
+ sav_errno = errno;
+ (void) close(s);
+ if (hp && hp->h_addr_list[i])
+ {
+ if (tTd(16, 1))
+ printf("Connect failed (%s); trying new address....\n",
+ errstring(sav_errno));
+ switch (addr.sa.sa_family)
+ {
+#ifdef NETINET
+ case AF_INET:
+ bcopy(hp->h_addr_list[i++],
+ &addr.sin.sin_addr,
+ sizeof addr.sin.sin_addr);
+ break;
+#endif
+
+ default:
+ bcopy(hp->h_addr_list[i++],
+ addr.sa.sa_data,
+ hp->h_length);
+ break;
+ }
+ continue;
+ }
+
+ /* failure, decide if temporary or not */
+ failure:
+#ifdef XLA
+ xla_host_end(host);
+#endif
+ if (transienterror(sav_errno))
+ return EX_TEMPFAIL;
+ else
+ {
+ message("%s", errstring(sav_errno));
+ return (EX_UNAVAILABLE);
+ }
+ }
+
+ /* connection ok, put it into canonical form */
+ if ((mci->mci_out = fdopen(s, "w")) == NULL ||
+ (s = dup(s)) < 0 ||
+ (mci->mci_in = fdopen(s, "r")) == NULL)
+ {
+ syserr("cannot open SMTP client channel, fd=%d", s);
+ return EX_TEMPFAIL;
+ }
+
+ return (EX_OK);
+}
+ /*
+** MYHOSTNAME -- return the name of this host.
+**
+** Parameters:
+** hostbuf -- a place to return the name of this host.
+** size -- the size of hostbuf.
+**
+** Returns:
+** A list of aliases for this host.
+**
+** Side Effects:
+** Adds numeric codes to $=w.
+*/
+
+char **
+myhostname(hostbuf, size)
+ char hostbuf[];
+ int size;
+{
+ register struct hostent *hp;
+ extern struct hostent *gethostbyname();
+
+ if (gethostname(hostbuf, size) < 0)
+ {
+ (void) strcpy(hostbuf, "localhost");
+ }
+ hp = gethostbyname(hostbuf);
+ if (hp == NULL)
+ {
+ syserr("!My host name (%s) does not seem to exist!", hostbuf);
+ }
+ (void) strncpy(hostbuf, hp->h_name, size - 1);
+ hostbuf[size - 1] = '\0';
+
+#if NAMED_BIND
+ /* if still no dot, try DNS directly (i.e., avoid NIS problems) */
+ if (strchr(hostbuf, '.') == NULL)
+ {
+ extern bool getcanonname();
+ extern int h_errno;
+
+ /* try twice in case name server not yet started up */
+ if (!getcanonname(hostbuf, size, TRUE) &&
+ UseNameServer &&
+ (h_errno != TRY_AGAIN ||
+ (sleep(30), !getcanonname(hostbuf, size, TRUE))))
+ {
+ errno = h_errno + E_DNSBASE;
+ syserr("!My host name (%s) not known to DNS",
+ hostbuf);
+ }
+ }
+#endif
+
+ if (hp->h_addrtype == AF_INET && hp->h_length == 4)
+ {
+ register int i;
+
+ for (i = 0; hp->h_addr_list[i] != NULL; i++)
+ {
+ char ipbuf[100];
+
+ sprintf(ipbuf, "[%s]",
+ inet_ntoa(*((struct in_addr *) hp->h_addr_list[i])));
+ setclass('w', ipbuf);
+ }
+ }
+
+ return (hp->h_aliases);
+}
+ /*
+** GETAUTHINFO -- get the real host name asociated with a file descriptor
+**
+** Uses RFC1413 protocol to try to get info from the other end.
+**
+** Parameters:
+** fd -- the descriptor
+**
+** Returns:
+** The user@host information associated with this descriptor.
+*/
+
+#if IDENTPROTO
+
+static jmp_buf CtxAuthTimeout;
+
+static
+authtimeout()
+{
+ longjmp(CtxAuthTimeout, 1);
+}
+
+#endif
+
+char *
+getauthinfo(fd)
+ int fd;
+{
+ int falen;
+ register char *p;
+#if IDENTPROTO
+ SOCKADDR la;
+ int lalen;
+ register struct servent *sp;
+ int s;
+ int i;
+ EVENT *ev;
+#endif
+ static char hbuf[MAXNAME * 2 + 2];
+ extern char *hostnamebyanyaddr();
+ extern char RealUserName[]; /* main.c */
+
+ falen = sizeof RealHostAddr;
+ if (getpeername(fd, &RealHostAddr.sa, &falen) < 0 || falen <= 0 ||
+ RealHostAddr.sa.sa_family == 0)
+ {
+ (void) sprintf(hbuf, "%s@localhost", RealUserName);
+ if (tTd(9, 1))
+ printf("getauthinfo: %s\n", hbuf);
+ return hbuf;
+ }
+
+ if (RealHostName == NULL)
+ {
+ /* translate that to a host name */
+ RealHostName = newstr(hostnamebyanyaddr(&RealHostAddr));
+ }
+
+#if IDENTPROTO
+ if (TimeOuts.to_ident == 0)
+ goto noident;
+
+ lalen = sizeof la;
+ if (RealHostAddr.sa.sa_family != AF_INET ||
+ getsockname(fd, &la.sa, &lalen) < 0 || lalen <= 0 ||
+ la.sa.sa_family != AF_INET)
+ {
+ /* no ident info */
+ goto noident;
+ }
+
+ /* create ident query */
+ (void) sprintf(hbuf, "%d,%d\r\n",
+ ntohs(RealHostAddr.sin.sin_port), ntohs(la.sin.sin_port));
+
+ /* create local address */
+ la.sin.sin_port = 0;
+
+ /* create foreign address */
+ sp = getservbyname("auth", "tcp");
+ if (sp != NULL)
+ RealHostAddr.sin.sin_port = sp->s_port;
+ else
+ RealHostAddr.sin.sin_port = htons(113);
+
+ s = -1;
+ if (setjmp(CtxAuthTimeout) != 0)
+ {
+ if (s >= 0)
+ (void) close(s);
+ goto noident;
+ }
+
+ /* put a timeout around the whole thing */
+ ev = setevent(TimeOuts.to_ident, authtimeout, 0);
+
+ /* connect to foreign IDENT server using same address as SMTP socket */
+ s = socket(AF_INET, SOCK_STREAM, 0);
+ if (s < 0)
+ {
+ clrevent(ev);
+ goto noident;
+ }
+ if (bind(s, &la.sa, sizeof la.sin) < 0 ||
+ connect(s, &RealHostAddr.sa, sizeof RealHostAddr.sin) < 0)
+ {
+ goto closeident;
+ }
+
+ if (tTd(9, 10))
+ printf("getauthinfo: sent %s", hbuf);
+
+ /* send query */
+ if (write(s, hbuf, strlen(hbuf)) < 0)
+ goto closeident;
+
+ /* get result */
+ i = read(s, hbuf, sizeof hbuf);
+ (void) close(s);
+ clrevent(ev);
+ if (i <= 0)
+ goto noident;
+ if (hbuf[--i] == '\n' && hbuf[--i] == '\r')
+ i--;
+ hbuf[++i] = '\0';
+
+ if (tTd(9, 3))
+ printf("getauthinfo: got %s\n", hbuf);
+
+ /* parse result */
+ p = strchr(hbuf, ':');
+ if (p == NULL)
+ {
+ /* malformed response */
+ goto noident;
+ }
+ while (isascii(*++p) && isspace(*p))
+ continue;
+ if (strncasecmp(p, "userid", 6) != 0)
+ {
+ /* presumably an error string */
+ goto noident;
+ }
+ p += 6;
+ while (isascii(*p) && isspace(*p))
+ p++;
+ if (*p++ != ':')
+ {
+ /* either useridxx or malformed response */
+ goto noident;
+ }
+
+ /* p now points to the OSTYPE field */
+ p = strchr(p, ':');
+ if (p == NULL)
+ {
+ /* malformed response */
+ goto noident;
+ }
+
+ /* 1413 says don't do this -- but it's broken otherwise */
+ while (isascii(*++p) && isspace(*p))
+ continue;
+
+ /* p now points to the authenticated name */
+ (void) sprintf(hbuf, "%s@%s",
+ p, RealHostName == NULL ? "localhost" : RealHostName);
+ goto finish;
+
+closeident:
+ (void) close(s);
+ clrevent(ev);
+
+#endif /* IDENTPROTO */
+
+noident:
+ if (RealHostName == NULL)
+ {
+ if (tTd(9, 1))
+ printf("getauthinfo: NULL\n");
+ return NULL;
+ }
+ (void) strcpy(hbuf, RealHostName);
+
+finish:
+ if (RealHostName != NULL && RealHostName[0] != '[')
+ {
+ p = &hbuf[strlen(hbuf)];
+ (void) sprintf(p, " [%s]", anynet_ntoa(&RealHostAddr));
+ }
+ if (tTd(9, 1))
+ printf("getauthinfo: %s\n", hbuf);
+ return hbuf;
+}
+ /*
+** HOST_MAP_LOOKUP -- turn a hostname into canonical form
+**
+** Parameters:
+** map -- a pointer to this map (unused).
+** name -- the (presumably unqualified) hostname.
+** av -- unused -- for compatibility with other mapping
+** functions.
+** statp -- an exit status (out parameter) -- set to
+** EX_TEMPFAIL if the name server is unavailable.
+**
+** Returns:
+** The mapping, if found.
+** NULL if no mapping found.
+**
+** Side Effects:
+** Looks up the host specified in hbuf. If it is not
+** the canonical name for that host, return the canonical
+** name.
+*/
+
+char *
+host_map_lookup(map, name, av, statp)
+ MAP *map;
+ char *name;
+ char **av;
+ int *statp;
+{
+ register struct hostent *hp;
+ u_long in_addr;
+ char *cp;
+ int i;
+ register STAB *s;
+ char hbuf[MAXNAME];
+ extern struct hostent *gethostbyaddr();
+#if NAMED_BIND
+ extern int h_errno;
+#endif
+
+ /*
+ ** See if we have already looked up this name. If so, just
+ ** return it.
+ */
+
+ s = stab(name, ST_NAMECANON, ST_ENTER);
+ if (bitset(NCF_VALID, s->s_namecanon.nc_flags))
+ {
+ if (tTd(9, 1))
+ printf("host_map_lookup(%s) => CACHE %s\n",
+ name, s->s_namecanon.nc_cname);
+ errno = s->s_namecanon.nc_errno;
+#if NAMED_BIND
+ h_errno = s->s_namecanon.nc_herrno;
+#endif
+ *statp = s->s_namecanon.nc_stat;
+ if (CurEnv->e_message == NULL && *statp == EX_TEMPFAIL)
+ {
+ sprintf(hbuf, "%s: Name server timeout",
+ shortenstring(name, 33));
+ CurEnv->e_message = newstr(hbuf);
+ }
+ return s->s_namecanon.nc_cname;
+ }
+
+ /*
+ ** If first character is a bracket, then it is an address
+ ** lookup. Address is copied into a temporary buffer to
+ ** strip the brackets and to preserve name if address is
+ ** unknown.
+ */
+
+ if (*name != '[')
+ {
+ extern bool getcanonname();
+
+ if (tTd(9, 1))
+ printf("host_map_lookup(%s) => ", name);
+ s->s_namecanon.nc_flags |= NCF_VALID; /* will be soon */
+ (void) strcpy(hbuf, name);
+ if (getcanonname(hbuf, sizeof hbuf - 1, TRUE))
+ {
+ if (tTd(9, 1))
+ printf("%s\n", hbuf);
+ cp = map_rewrite(map, hbuf, strlen(hbuf), av);
+ s->s_namecanon.nc_cname = newstr(cp);
+ return cp;
+ }
+ else
+ {
+ register struct hostent *hp;
+
+ s->s_namecanon.nc_errno = errno;
+#if NAMED_BIND
+ s->s_namecanon.nc_herrno = h_errno;
+ if (tTd(9, 1))
+ printf("FAIL (%d)\n", h_errno);
+ switch (h_errno)
+ {
+ case TRY_AGAIN:
+ if (UseNameServer)
+ {
+ sprintf(hbuf, "%s: Name server timeout",
+ shortenstring(name, 33));
+ message("%s", hbuf);
+ if (CurEnv->e_message == NULL)
+ CurEnv->e_message = newstr(hbuf);
+ }
+ *statp = EX_TEMPFAIL;
+ break;
+
+ case HOST_NOT_FOUND:
+ *statp = EX_NOHOST;
+ break;
+
+ case NO_RECOVERY:
+ *statp = EX_SOFTWARE;
+ break;
+
+ default:
+ *statp = EX_UNAVAILABLE;
+ break;
+ }
+#else
+ if (tTd(9, 1))
+ printf("FAIL\n");
+ *statp = EX_NOHOST;
+#endif
+ s->s_namecanon.nc_stat = *statp;
+ if (*statp != EX_TEMPFAIL || UseNameServer)
+ return NULL;
+
+ /*
+ ** Try to look it up in /etc/hosts
+ */
+
+ hp = gethostbyname(name);
+ if (hp == NULL)
+ {
+ /* no dice there either */
+ s->s_namecanon.nc_stat = *statp = EX_NOHOST;
+ return NULL;
+ }
+
+ s->s_namecanon.nc_stat = *statp = EX_OK;
+ cp = map_rewrite(map, hp->h_name, strlen(hp->h_name), av);
+ s->s_namecanon.nc_cname = newstr(cp);
+ return cp;
+ }
+ }
+ if ((cp = strchr(name, ']')) == NULL)
+ return (NULL);
+ *cp = '\0';
+ in_addr = inet_addr(&name[1]);
+
+ /* nope -- ask the name server */
+ hp = gethostbyaddr((char *)&in_addr, sizeof(struct in_addr), AF_INET);
+ s->s_namecanon.nc_errno = errno;
+#if NAMED_BIND
+ s->s_namecanon.nc_herrno = h_errno;
+#endif
+ s->s_namecanon.nc_flags |= NCF_VALID; /* will be soon */
+ if (hp == NULL)
+ {
+ s->s_namecanon.nc_stat = *statp = EX_NOHOST;
+ return (NULL);
+ }
+
+ /* found a match -- copy out */
+ cp = map_rewrite(map, hp->h_name, strlen(hp->h_name), av);
+ s->s_namecanon.nc_stat = *statp = EX_OK;
+ s->s_namecanon.nc_cname = newstr(cp);
+ return cp;
+}
+ /*
+** ANYNET_NTOA -- convert a network address to printable form.
+**
+** Parameters:
+** sap -- a pointer to a sockaddr structure.
+**
+** Returns:
+** A printable version of that sockaddr.
+*/
+
+char *
+anynet_ntoa(sap)
+ register SOCKADDR *sap;
+{
+ register char *bp;
+ register char *ap;
+ int l;
+ static char buf[100];
+
+ /* check for null/zero family */
+ if (sap == NULL)
+ return "NULLADDR";
+ if (sap->sa.sa_family == 0)
+ return "0";
+
+ switch (sap->sa.sa_family)
+ {
+#ifdef MAYBENEXTRELEASE /*** UNTESTED *** UNTESTED *** UNTESTED ***/
+#ifdef NETUNIX
+ case AF_UNIX:
+ if (sap->sunix.sun_path[0] != '\0')
+ sprintf(buf, "[UNIX: %.64s]", sap->sunix.sun_path);
+ else
+ sprintf(buf, "[UNIX: localhost]");
+ return buf;
+#endif
+#endif
+
+#ifdef NETINET
+ case AF_INET:
+ return inet_ntoa(((struct sockaddr_in *) sap)->sin_addr);
+#endif
+
+ default:
+ /* this case is only to ensure syntactic correctness */
+ break;
+ }
+
+ /* unknown family -- just dump bytes */
+ (void) sprintf(buf, "Family %d: ", sap->sa.sa_family);
+ bp = &buf[strlen(buf)];
+ ap = sap->sa.sa_data;
+ for (l = sizeof sap->sa.sa_data; --l >= 0; )
+ {
+ (void) sprintf(bp, "%02x:", *ap++ & 0377);
+ bp += 3;
+ }
+ *--bp = '\0';
+ return buf;
+}
+ /*
+** HOSTNAMEBYANYADDR -- return name of host based on address
+**
+** Parameters:
+** sap -- SOCKADDR pointer
+**
+** Returns:
+** text representation of host name.
+**
+** Side Effects:
+** none.
+*/
+
+char *
+hostnamebyanyaddr(sap)
+ register SOCKADDR *sap;
+{
+ register struct hostent *hp;
+ int saveretry;
+
+#if NAMED_BIND
+ /* shorten name server timeout to avoid higher level timeouts */
+ saveretry = _res.retry;
+ _res.retry = 3;
+#endif /* NAMED_BIND */
+
+ switch (sap->sa.sa_family)
+ {
+#ifdef NETINET
+ case AF_INET:
+ hp = gethostbyaddr((char *) &sap->sin.sin_addr,
+ sizeof sap->sin.sin_addr,
+ AF_INET);
+ break;
+#endif
+
+#ifdef NETISO
+ case AF_ISO:
+ hp = gethostbyaddr((char *) &sap->siso.siso_addr,
+ sizeof sap->siso.siso_addr,
+ AF_ISO);
+ break;
+#endif
+
+#ifdef MAYBENEXTRELEASE /*** UNTESTED *** UNTESTED *** UNTESTED ***/
+ case AF_UNIX:
+ hp = NULL;
+ break;
+#endif
+
+ default:
+ hp = gethostbyaddr(sap->sa.sa_data,
+ sizeof sap->sa.sa_data,
+ sap->sa.sa_family);
+ break;
+ }
+
+#if NAMED_BIND
+ _res.retry = saveretry;
+#endif /* NAMED_BIND */
+
+ if (hp != NULL)
+ return hp->h_name;
+ else
+ {
+ /* produce a dotted quad */
+ static char buf[512];
+
+ (void) sprintf(buf, "[%s]", anynet_ntoa(sap));
+ return buf;
+ }
+}
+
+# else /* DAEMON */
+/* code for systems without sophisticated networking */
+
+/*
+** MYHOSTNAME -- stub version for case of no daemon code.
+**
+** Can't convert to upper case here because might be a UUCP name.
+**
+** Mark, you can change this to be anything you want......
+*/
+
+char **
+myhostname(hostbuf, size)
+ char hostbuf[];
+ int size;
+{
+ register FILE *f;
+
+ hostbuf[0] = '\0';
+ f = fopen("/usr/include/whoami", "r");
+ if (f != NULL)
+ {
+ (void) fgets(hostbuf, size, f);
+ fixcrlf(hostbuf, TRUE);
+ (void) fclose(f);
+ }
+ return (NULL);
+}
+ /*
+** GETAUTHINFO -- get the real host name asociated with a file descriptor
+**
+** Parameters:
+** fd -- the descriptor
+**
+** Returns:
+** The host name associated with this descriptor, if it can
+** be determined.
+** NULL otherwise.
+**
+** Side Effects:
+** none
+*/
+
+char *
+getauthinfo(fd)
+ int fd;
+{
+ return NULL;
+}
+ /*
+** MAPHOSTNAME -- turn a hostname into canonical form
+**
+** Parameters:
+** map -- a pointer to the database map.
+** name -- a buffer containing a hostname.
+** avp -- a pointer to a (cf file defined) argument vector.
+** statp -- an exit status (out parameter).
+**
+** Returns:
+** mapped host name
+** FALSE otherwise.
+**
+** Side Effects:
+** Looks up the host specified in name. If it is not
+** the canonical name for that host, replace it with
+** the canonical name. If the name is unknown, or it
+** is already the canonical name, leave it unchanged.
+*/
+
+/*ARGSUSED*/
+char *
+host_map_lookup(map, name, avp, statp)
+ MAP *map;
+ char *name;
+ char **avp;
+ char *statp;
+{
+ register struct hostent *hp;
+
+ hp = gethostbyname(name);
+ if (hp != NULL)
+ return hp->h_name;
+ *statp = EX_NOHOST;
+ return NULL;
+}
+
+#endif /* DAEMON */
diff --git a/usr.sbin/sendmail/src/deliver.c b/usr.sbin/sendmail/src/deliver.c
new file mode 100644
index 0000000..4266122
--- /dev/null
+++ b/usr.sbin/sendmail/src/deliver.c
@@ -0,0 +1,2409 @@
+/*
+ * Copyright (c) 1983 Eric P. Allman
+ * Copyright (c) 1988, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)deliver.c 8.82 (Berkeley) 4/18/94";
+#endif /* not lint */
+
+#include "sendmail.h"
+#include <netdb.h>
+#include <errno.h>
+#if NAMED_BIND
+#include <arpa/nameser.h>
+#include <resolv.h>
+
+extern int h_errno;
+#endif
+
+extern char SmtpError[];
+
+/*
+** SENDALL -- actually send all the messages.
+**
+** Parameters:
+** e -- the envelope to send.
+** mode -- the delivery mode to use. If SM_DEFAULT, use
+** the current e->e_sendmode.
+**
+** Returns:
+** none.
+**
+** Side Effects:
+** Scans the send lists and sends everything it finds.
+** Delivers any appropriate error messages.
+** If we are running in a non-interactive mode, takes the
+** appropriate action.
+*/
+
+sendall(e, mode)
+ ENVELOPE *e;
+ char mode;
+{
+ register ADDRESS *q;
+ char *owner;
+ int otherowners;
+ register ENVELOPE *ee;
+ ENVELOPE *splitenv = NULL;
+ bool announcequeueup;
+
+ /*
+ ** If we have had global, fatal errors, don't bother sending
+ ** the message at all if we are in SMTP mode. Local errors
+ ** (e.g., a single address failing) will still cause the other
+ ** addresses to be sent.
+ */
+
+ if (bitset(EF_FATALERRS, e->e_flags) &&
+ (OpMode == MD_SMTP || OpMode == MD_DAEMON))
+ {
+ e->e_flags |= EF_CLRQUEUE;
+ return;
+ }
+
+ /* determine actual delivery mode */
+ CurrentLA = getla();
+ if (mode == SM_DEFAULT)
+ {
+ mode = e->e_sendmode;
+ if (mode != SM_VERIFY &&
+ shouldqueue(e->e_msgpriority, e->e_ctime))
+ mode = SM_QUEUE;
+ announcequeueup = mode == SM_QUEUE;
+ }
+ else
+ announcequeueup = FALSE;
+
+ if (tTd(13, 1))
+ {
+ printf("\n===== SENDALL: mode %c, id %s, e_from ",
+ mode, e->e_id);
+ printaddr(&e->e_from, FALSE);
+ printf("sendqueue:\n");
+ printaddr(e->e_sendqueue, TRUE);
+ }
+
+ /*
+ ** Do any preprocessing necessary for the mode we are running.
+ ** Check to make sure the hop count is reasonable.
+ ** Delete sends to the sender in mailing lists.
+ */
+
+ CurEnv = e;
+
+ if (e->e_hopcount > MaxHopCount)
+ {
+ errno = 0;
+ e->e_flags |= EF_FATALERRS|EF_PM_NOTIFY|EF_CLRQUEUE;
+ syserr("554 too many hops %d (%d max): from %s via %s, to %s",
+ e->e_hopcount, MaxHopCount, e->e_from.q_paddr,
+ RealHostName == NULL ? "localhost" : RealHostName,
+ e->e_sendqueue->q_paddr);
+ return;
+ }
+
+ /*
+ ** Do sender deletion.
+ **
+ ** If the sender has the QQUEUEUP flag set, skip this.
+ ** This can happen if the name server is hosed when you
+ ** are trying to send mail. The result is that the sender
+ ** is instantiated in the queue as a recipient.
+ */
+
+ if (!bitset(EF_METOO, e->e_flags) &&
+ !bitset(QQUEUEUP, e->e_from.q_flags))
+ {
+ if (tTd(13, 5))
+ {
+ printf("sendall: QDONTSEND ");
+ printaddr(&e->e_from, FALSE);
+ }
+ e->e_from.q_flags |= QDONTSEND;
+ (void) recipient(&e->e_from, &e->e_sendqueue, e);
+ }
+
+ /*
+ ** Handle alias owners.
+ **
+ ** We scan up the q_alias chain looking for owners.
+ ** We discard owners that are the same as the return path.
+ */
+
+ for (q = e->e_sendqueue; q != NULL; q = q->q_next)
+ {
+ register struct address *a;
+
+ for (a = q; a != NULL && a->q_owner == NULL; a = a->q_alias)
+ continue;
+ if (a != NULL)
+ q->q_owner = a->q_owner;
+
+ if (q->q_owner != NULL &&
+ !bitset(QDONTSEND, q->q_flags) &&
+ strcmp(q->q_owner, e->e_from.q_paddr) == 0)
+ q->q_owner = NULL;
+ }
+
+ owner = "";
+ otherowners = 1;
+ while (owner != NULL && otherowners > 0)
+ {
+ owner = NULL;
+ otherowners = 0;
+
+ for (q = e->e_sendqueue; q != NULL; q = q->q_next)
+ {
+ if (bitset(QDONTSEND, q->q_flags))
+ continue;
+
+ if (q->q_owner != NULL)
+ {
+ if (owner == NULL)
+ owner = q->q_owner;
+ else if (owner != q->q_owner)
+ {
+ if (strcmp(owner, q->q_owner) == 0)
+ {
+ /* make future comparisons cheap */
+ q->q_owner = owner;
+ }
+ else
+ {
+ otherowners++;
+ }
+ owner = q->q_owner;
+ }
+ }
+ else
+ {
+ otherowners++;
+ }
+ }
+
+ if (owner != NULL && otherowners > 0)
+ {
+ extern HDR *copyheader();
+ extern ADDRESS *copyqueue();
+
+ /*
+ ** Split this envelope into two.
+ */
+
+ ee = (ENVELOPE *) xalloc(sizeof(ENVELOPE));
+ *ee = *e;
+ ee->e_id = NULL;
+ (void) queuename(ee, '\0');
+
+ if (tTd(13, 1))
+ printf("sendall: split %s into %s\n",
+ e->e_id, ee->e_id);
+
+ ee->e_header = copyheader(e->e_header);
+ ee->e_sendqueue = copyqueue(e->e_sendqueue);
+ ee->e_errorqueue = copyqueue(e->e_errorqueue);
+ ee->e_flags = e->e_flags & ~(EF_INQUEUE|EF_CLRQUEUE|EF_FATALERRS|EF_SENDRECEIPT);
+ ee->e_flags |= EF_NORECEIPT;
+ setsender(owner, ee, NULL, TRUE);
+ if (tTd(13, 5))
+ {
+ printf("sendall(split): QDONTSEND ");
+ printaddr(&ee->e_from, FALSE);
+ }
+ ee->e_from.q_flags |= QDONTSEND;
+ ee->e_dfp = NULL;
+ ee->e_xfp = NULL;
+ ee->e_df = NULL;
+ ee->e_errormode = EM_MAIL;
+ ee->e_sibling = splitenv;
+ splitenv = ee;
+
+ for (q = e->e_sendqueue; q != NULL; q = q->q_next)
+ if (q->q_owner == owner)
+ {
+ q->q_flags |= QDONTSEND;
+ q->q_flags &= ~QQUEUEUP;
+ }
+ for (q = ee->e_sendqueue; q != NULL; q = q->q_next)
+ if (q->q_owner != owner)
+ {
+ q->q_flags |= QDONTSEND;
+ q->q_flags &= ~QQUEUEUP;
+ }
+
+ if (e->e_df != NULL && mode != SM_VERIFY)
+ {
+ ee->e_dfp = NULL;
+ ee->e_df = queuename(ee, 'd');
+ ee->e_df = newstr(ee->e_df);
+ if (link(e->e_df, ee->e_df) < 0)
+ {
+ syserr("sendall: link(%s, %s)",
+ e->e_df, ee->e_df);
+ }
+ }
+#ifdef LOG
+ if (LogLevel > 4)
+ syslog(LOG_INFO, "%s: clone %s, owner=%s",
+ ee->e_id, e->e_id, owner);
+#endif
+ }
+ }
+
+ if (owner != NULL)
+ {
+ setsender(owner, e, NULL, TRUE);
+ if (tTd(13, 5))
+ {
+ printf("sendall(owner): QDONTSEND ");
+ printaddr(&e->e_from, FALSE);
+ }
+ e->e_from.q_flags |= QDONTSEND;
+ e->e_errormode = EM_MAIL;
+ e->e_flags |= EF_NORECEIPT;
+ }
+
+# ifdef QUEUE
+ if ((mode == SM_QUEUE || mode == SM_FORK ||
+ (mode != SM_VERIFY && SuperSafe)) &&
+ !bitset(EF_INQUEUE, e->e_flags))
+ {
+ /* be sure everything is instantiated in the queue */
+ queueup(e, TRUE, announcequeueup);
+ for (ee = splitenv; ee != NULL; ee = ee->e_sibling)
+ queueup(ee, TRUE, announcequeueup);
+ }
+#endif /* QUEUE */
+
+ if (splitenv != NULL)
+ {
+ if (tTd(13, 1))
+ {
+ printf("\nsendall: Split queue; remaining queue:\n");
+ printaddr(e->e_sendqueue, TRUE);
+ }
+
+ for (ee = splitenv; ee != NULL; ee = ee->e_sibling)
+ {
+ CurEnv = ee;
+ if (mode != SM_VERIFY)
+ openxscript(ee);
+ sendenvelope(ee, mode);
+ dropenvelope(ee);
+ }
+
+ CurEnv = e;
+ }
+ sendenvelope(e, mode);
+}
+
+sendenvelope(e, mode)
+ register ENVELOPE *e;
+ char mode;
+{
+ bool oldverbose;
+ int pid;
+ register ADDRESS *q;
+ char *qf;
+ char *id;
+
+ /*
+ ** If we have had global, fatal errors, don't bother sending
+ ** the message at all if we are in SMTP mode. Local errors
+ ** (e.g., a single address failing) will still cause the other
+ ** addresses to be sent.
+ */
+
+ if (bitset(EF_FATALERRS, e->e_flags) &&
+ (OpMode == MD_SMTP || OpMode == MD_DAEMON))
+ {
+ e->e_flags |= EF_CLRQUEUE;
+ return;
+ }
+
+ oldverbose = Verbose;
+ switch (mode)
+ {
+ case SM_VERIFY:
+ Verbose = TRUE;
+ break;
+
+ case SM_QUEUE:
+ queueonly:
+ e->e_flags |= EF_INQUEUE|EF_KEEPQUEUE;
+ return;
+
+ case SM_FORK:
+ if (e->e_xfp != NULL)
+ (void) fflush(e->e_xfp);
+
+# if !HASFLOCK
+ /*
+ ** Since fcntl locking has the interesting semantic that
+ ** the lock is owned by a process, not by an open file
+ ** descriptor, we have to flush this to the queue, and
+ ** then restart from scratch in the child.
+ */
+
+ /* save id for future use */
+ id = e->e_id;
+
+ /* now drop the envelope in the parent */
+ e->e_flags |= EF_INQUEUE|EF_KEEPQUEUE;
+ dropenvelope(e);
+
+ /* and reacquire in the child */
+ (void) dowork(id, TRUE, FALSE, e);
+
+ return;
+
+# else /* HASFLOCK */
+
+ pid = fork();
+ if (pid < 0)
+ {
+ goto queueonly;
+ }
+ else if (pid > 0)
+ {
+ /* be sure we leave the temp files to our child */
+ /* can't call unlockqueue to avoid unlink of xfp */
+ if (e->e_lockfp != NULL)
+ (void) xfclose(e->e_lockfp, "sendenvelope", "lockfp");
+ e->e_lockfp = NULL;
+
+ /* close any random open files in the envelope */
+ closexscript(e);
+ if (e->e_dfp != NULL)
+ (void) xfclose(e->e_dfp, "sendenvelope", e->e_df);
+ e->e_dfp = NULL;
+ e->e_id = e->e_df = NULL;
+
+ /* catch intermediate zombie */
+ (void) waitfor(pid);
+ return;
+ }
+
+ /* double fork to avoid zombies */
+ pid = fork();
+ if (pid > 0)
+ exit(EX_OK);
+
+ /* be sure we are immune from the terminal */
+ disconnect(1, e);
+
+ /* prevent parent from waiting if there was an error */
+ if (pid < 0)
+ {
+ e->e_flags |= EF_INQUEUE|EF_KEEPQUEUE;
+ finis();
+ }
+
+ /*
+ ** Close any cached connections.
+ **
+ ** We don't send the QUIT protocol because the parent
+ ** still knows about the connection.
+ **
+ ** This should only happen when delivering an error
+ ** message.
+ */
+
+ mci_flush(FALSE, NULL);
+
+# endif /* HASFLOCK */
+
+ break;
+ }
+
+ /*
+ ** Run through the list and send everything.
+ **
+ ** Set EF_GLOBALERRS so that error messages during delivery
+ ** result in returned mail.
+ */
+
+ e->e_nsent = 0;
+ e->e_flags |= EF_GLOBALERRS;
+
+ /* now run through the queue */
+ for (q = e->e_sendqueue; q != NULL; q = q->q_next)
+ {
+#ifdef XDEBUG
+ char wbuf[MAXNAME + 20];
+
+ (void) sprintf(wbuf, "sendall(%s)", q->q_paddr);
+ checkfd012(wbuf);
+#endif
+ if (mode == SM_VERIFY)
+ {
+ e->e_to = q->q_paddr;
+ if (!bitset(QDONTSEND|QBADADDR, q->q_flags))
+ {
+ if (q->q_host != NULL && q->q_host[0] != '\0')
+ message("deliverable: mailer %s, host %s, user %s",
+ q->q_mailer->m_name,
+ q->q_host,
+ q->q_user);
+ else
+ message("deliverable: mailer %s, user %s",
+ q->q_mailer->m_name,
+ q->q_user);
+ }
+ }
+ else if (!bitset(QDONTSEND|QBADADDR, q->q_flags))
+ {
+# ifdef QUEUE
+ /*
+ ** Checkpoint the send list every few addresses
+ */
+
+ if (e->e_nsent >= CheckpointInterval)
+ {
+ queueup(e, TRUE, FALSE);
+ e->e_nsent = 0;
+ }
+# endif /* QUEUE */
+ (void) deliver(e, q);
+ }
+ }
+ Verbose = oldverbose;
+
+#ifdef XDEBUG
+ checkfd012("end of sendenvelope");
+#endif
+
+ if (mode == SM_FORK)
+ finis();
+}
+ /*
+** DOFORK -- do a fork, retrying a couple of times on failure.
+**
+** This MUST be a macro, since after a vfork we are running
+** two processes on the same stack!!!
+**
+** Parameters:
+** none.
+**
+** Returns:
+** From a macro??? You've got to be kidding!
+**
+** Side Effects:
+** Modifies the ==> LOCAL <== variable 'pid', leaving:
+** pid of child in parent, zero in child.
+** -1 on unrecoverable error.
+**
+** Notes:
+** I'm awfully sorry this looks so awful. That's
+** vfork for you.....
+*/
+
+# define NFORKTRIES 5
+
+# ifndef FORK
+# define FORK fork
+# endif
+
+# define DOFORK(fORKfN) \
+{\
+ register int i;\
+\
+ for (i = NFORKTRIES; --i >= 0; )\
+ {\
+ pid = fORKfN();\
+ if (pid >= 0)\
+ break;\
+ if (i > 0)\
+ sleep((unsigned) NFORKTRIES - i);\
+ }\
+}
+ /*
+** DOFORK -- simple fork interface to DOFORK.
+**
+** Parameters:
+** none.
+**
+** Returns:
+** pid of child in parent.
+** zero in child.
+** -1 on error.
+**
+** Side Effects:
+** returns twice, once in parent and once in child.
+*/
+
+dofork()
+{
+ register int pid;
+
+ DOFORK(fork);
+ return (pid);
+}
+ /*
+** DELIVER -- Deliver a message to a list of addresses.
+**
+** This routine delivers to everyone on the same host as the
+** user on the head of the list. It is clever about mailers
+** that don't handle multiple users. It is NOT guaranteed
+** that it will deliver to all these addresses however -- so
+** deliver should be called once for each address on the
+** list.
+**
+** Parameters:
+** e -- the envelope to deliver.
+** firstto -- head of the address list to deliver to.
+**
+** Returns:
+** zero -- successfully delivered.
+** else -- some failure, see ExitStat for more info.
+**
+** Side Effects:
+** The standard input is passed off to someone.
+*/
+
+deliver(e, firstto)
+ register ENVELOPE *e;
+ ADDRESS *firstto;
+{
+ char *host; /* host being sent to */
+ char *user; /* user being sent to */
+ char **pvp;
+ register char **mvp;
+ register char *p;
+ register MAILER *m; /* mailer for this recipient */
+ ADDRESS *ctladdr;
+ register MCI *mci;
+ register ADDRESS *to = firstto;
+ bool clever = FALSE; /* running user smtp to this mailer */
+ ADDRESS *tochain = NULL; /* chain of users in this mailer call */
+ int rcode; /* response code */
+ char *firstsig; /* signature of firstto */
+ int pid;
+ char *curhost;
+ int mpvect[2];
+ int rpvect[2];
+ char *pv[MAXPV+1];
+ char tobuf[TOBUFSIZE]; /* text line of to people */
+ char buf[MAXNAME];
+ char rpathbuf[MAXNAME]; /* translated return path */
+ extern int checkcompat();
+
+ errno = 0;
+ if (bitset(QDONTSEND|QBADADDR|QQUEUEUP, to->q_flags))
+ return (0);
+
+#if NAMED_BIND
+ /* unless interactive, try twice, over a minute */
+ if (OpMode == MD_DAEMON || OpMode == MD_SMTP)
+ {
+ _res.retrans = 30;
+ _res.retry = 2;
+ }
+#endif
+
+ m = to->q_mailer;
+ host = to->q_host;
+ CurEnv = e; /* just in case */
+ e->e_statmsg = NULL;
+ SmtpError[0] = '\0';
+
+ if (tTd(10, 1))
+ printf("\n--deliver, id=%s, mailer=%s, host=`%s', first user=`%s'\n",
+ e->e_id, m->m_name, host, to->q_user);
+ if (tTd(10, 100))
+ printopenfds(FALSE);
+
+ /*
+ ** If this mailer is expensive, and if we don't want to make
+ ** connections now, just mark these addresses and return.
+ ** This is useful if we want to batch connections to
+ ** reduce load. This will cause the messages to be
+ ** queued up, and a daemon will come along to send the
+ ** messages later.
+ ** This should be on a per-mailer basis.
+ */
+
+ if (NoConnect && bitnset(M_EXPENSIVE, m->m_flags) && !Verbose)
+ {
+ for (; to != NULL; to = to->q_next)
+ {
+ if (bitset(QDONTSEND|QBADADDR|QQUEUEUP, to->q_flags) ||
+ to->q_mailer != m)
+ continue;
+ to->q_flags |= QQUEUEUP;
+ e->e_to = to->q_paddr;
+ message("queued");
+ if (LogLevel > 8)
+ logdelivery(m, NULL, "queued", NULL, e);
+ }
+ e->e_to = NULL;
+ return (0);
+ }
+
+ /*
+ ** Do initial argv setup.
+ ** Insert the mailer name. Notice that $x expansion is
+ ** NOT done on the mailer name. Then, if the mailer has
+ ** a picky -f flag, we insert it as appropriate. This
+ ** code does not check for 'pv' overflow; this places a
+ ** manifest lower limit of 4 for MAXPV.
+ ** The from address rewrite is expected to make
+ ** the address relative to the other end.
+ */
+
+ /* rewrite from address, using rewriting rules */
+ rcode = EX_OK;
+ (void) strcpy(rpathbuf, remotename(e->e_from.q_paddr, m,
+ RF_SENDERADDR|RF_CANONICAL,
+ &rcode, e));
+ define('g', rpathbuf, e); /* translated return path */
+ define('h', host, e); /* to host */
+ Errors = 0;
+ pvp = pv;
+ *pvp++ = m->m_argv[0];
+
+ /* insert -f or -r flag as appropriate */
+ if (FromFlag && (bitnset(M_FOPT, m->m_flags) || bitnset(M_ROPT, m->m_flags)))
+ {
+ if (bitnset(M_FOPT, m->m_flags))
+ *pvp++ = "-f";
+ else
+ *pvp++ = "-r";
+ *pvp++ = newstr(rpathbuf);
+ }
+
+ /*
+ ** Append the other fixed parts of the argv. These run
+ ** up to the first entry containing "$u". There can only
+ ** be one of these, and there are only a few more slots
+ ** in the pv after it.
+ */
+
+ for (mvp = m->m_argv; (p = *++mvp) != NULL; )
+ {
+ /* can't use strchr here because of sign extension problems */
+ while (*p != '\0')
+ {
+ if ((*p++ & 0377) == MACROEXPAND)
+ {
+ if (*p == 'u')
+ break;
+ }
+ }
+
+ if (*p != '\0')
+ break;
+
+ /* this entry is safe -- go ahead and process it */
+ expand(*mvp, buf, &buf[sizeof buf - 1], e);
+ *pvp++ = newstr(buf);
+ if (pvp >= &pv[MAXPV - 3])
+ {
+ syserr("554 Too many parameters to %s before $u", pv[0]);
+ return (-1);
+ }
+ }
+
+ /*
+ ** If we have no substitution for the user name in the argument
+ ** list, we know that we must supply the names otherwise -- and
+ ** SMTP is the answer!!
+ */
+
+ if (*mvp == NULL)
+ {
+ /* running SMTP */
+# ifdef SMTP
+ clever = TRUE;
+ *pvp = NULL;
+# else /* SMTP */
+ /* oops! we don't implement SMTP */
+ syserr("554 SMTP style mailer not implemented");
+ return (EX_SOFTWARE);
+# endif /* SMTP */
+ }
+
+ /*
+ ** At this point *mvp points to the argument with $u. We
+ ** run through our address list and append all the addresses
+ ** we can. If we run out of space, do not fret! We can
+ ** always send another copy later.
+ */
+
+ tobuf[0] = '\0';
+ e->e_to = tobuf;
+ ctladdr = NULL;
+ firstsig = hostsignature(firstto->q_mailer, firstto->q_host, e);
+ for (; to != NULL; to = to->q_next)
+ {
+ /* avoid sending multiple recipients to dumb mailers */
+ if (tobuf[0] != '\0' && !bitnset(M_MUSER, m->m_flags))
+ break;
+
+ /* if already sent or not for this host, don't send */
+ if (bitset(QDONTSEND|QBADADDR|QQUEUEUP, to->q_flags) ||
+ to->q_mailer != firstto->q_mailer ||
+ strcmp(hostsignature(to->q_mailer, to->q_host, e), firstsig) != 0)
+ continue;
+
+ /* avoid overflowing tobuf */
+ if (sizeof tobuf < (strlen(to->q_paddr) + strlen(tobuf) + 2))
+ break;
+
+ if (tTd(10, 1))
+ {
+ printf("\nsend to ");
+ printaddr(to, FALSE);
+ }
+
+ /* compute effective uid/gid when sending */
+ /* XXX perhaps this should be to->q_mailer != LocalMailer ?? */
+ /* XXX perhaps it should be a mailer flag? */
+ if (to->q_mailer == ProgMailer || to->q_mailer == FileMailer)
+ ctladdr = getctladdr(to);
+
+ user = to->q_user;
+ e->e_to = to->q_paddr;
+ if (tTd(10, 5))
+ {
+ printf("deliver: QDONTSEND ");
+ printaddr(to, FALSE);
+ }
+ to->q_flags |= QDONTSEND;
+
+ /*
+ ** Check to see that these people are allowed to
+ ** talk to each other.
+ */
+
+ if (m->m_maxsize != 0 && e->e_msgsize > m->m_maxsize)
+ {
+ NoReturn = TRUE;
+ usrerr("552 Message is too large; %ld bytes max", m->m_maxsize);
+ giveresponse(EX_UNAVAILABLE, m, NULL, ctladdr, e);
+ continue;
+ }
+ rcode = checkcompat(to, e);
+ if (rcode != EX_OK)
+ {
+ markfailure(e, to, rcode);
+ giveresponse(rcode, m, NULL, ctladdr, e);
+ continue;
+ }
+
+ /*
+ ** Strip quote bits from names if the mailer is dumb
+ ** about them.
+ */
+
+ if (bitnset(M_STRIPQ, m->m_flags))
+ {
+ stripquotes(user);
+ stripquotes(host);
+ }
+
+ /* hack attack -- delivermail compatibility */
+ if (m == ProgMailer && *user == '|')
+ user++;
+
+ /*
+ ** If an error message has already been given, don't
+ ** bother to send to this address.
+ **
+ ** >>>>>>>>>> This clause assumes that the local mailer
+ ** >> NOTE >> cannot do any further aliasing; that
+ ** >>>>>>>>>> function is subsumed by sendmail.
+ */
+
+ if (bitset(QBADADDR|QQUEUEUP, to->q_flags))
+ continue;
+
+ /* save statistics.... */
+ markstats(e, to);
+
+ /*
+ ** See if this user name is "special".
+ ** If the user name has a slash in it, assume that this
+ ** is a file -- send it off without further ado. Note
+ ** that this type of addresses is not processed along
+ ** with the others, so we fudge on the To person.
+ */
+
+ if (m == FileMailer)
+ {
+ rcode = mailfile(user, ctladdr, e);
+ giveresponse(rcode, m, NULL, ctladdr, e);
+ if (rcode == EX_OK)
+ to->q_flags |= QSENT;
+ continue;
+ }
+
+ /*
+ ** Address is verified -- add this user to mailer
+ ** argv, and add it to the print list of recipients.
+ */
+
+ /* link together the chain of recipients */
+ to->q_tchain = tochain;
+ tochain = to;
+
+ /* create list of users for error messages */
+ (void) strcat(tobuf, ",");
+ (void) strcat(tobuf, to->q_paddr);
+ define('u', user, e); /* to user */
+ p = to->q_home;
+ if (p == NULL && ctladdr != NULL)
+ p = ctladdr->q_home;
+ define('z', p, e); /* user's home */
+
+ /*
+ ** Expand out this user into argument list.
+ */
+
+ if (!clever)
+ {
+ expand(*mvp, buf, &buf[sizeof buf - 1], e);
+ *pvp++ = newstr(buf);
+ if (pvp >= &pv[MAXPV - 2])
+ {
+ /* allow some space for trailing parms */
+ break;
+ }
+ }
+ }
+
+ /* see if any addresses still exist */
+ if (tobuf[0] == '\0')
+ {
+ define('g', (char *) NULL, e);
+ return (0);
+ }
+
+ /* print out messages as full list */
+ e->e_to = tobuf + 1;
+
+ /*
+ ** Fill out any parameters after the $u parameter.
+ */
+
+ while (!clever && *++mvp != NULL)
+ {
+ expand(*mvp, buf, &buf[sizeof buf - 1], e);
+ *pvp++ = newstr(buf);
+ if (pvp >= &pv[MAXPV])
+ syserr("554 deliver: pv overflow after $u for %s", pv[0]);
+ }
+ *pvp++ = NULL;
+
+ /*
+ ** Call the mailer.
+ ** The argument vector gets built, pipes
+ ** are created as necessary, and we fork & exec as
+ ** appropriate.
+ ** If we are running SMTP, we just need to clean up.
+ */
+
+ /*XXX this seems a bit wierd */
+ if (ctladdr == NULL && m != ProgMailer &&
+ bitset(QGOODUID, e->e_from.q_flags))
+ ctladdr = &e->e_from;
+
+#if NAMED_BIND
+ if (ConfigLevel < 2)
+ _res.options &= ~(RES_DEFNAMES | RES_DNSRCH); /* XXX */
+#endif
+
+ if (tTd(11, 1))
+ {
+ printf("openmailer:");
+ printav(pv);
+ }
+ errno = 0;
+
+ CurHostName = m->m_mailer;
+
+ /*
+ ** Deal with the special case of mail handled through an IPC
+ ** connection.
+ ** In this case we don't actually fork. We must be
+ ** running SMTP for this to work. We will return a
+ ** zero pid to indicate that we are running IPC.
+ ** We also handle a debug version that just talks to stdin/out.
+ */
+
+ curhost = NULL;
+ SmtpPhase = NULL;
+ mci = NULL;
+
+#ifdef XDEBUG
+ {
+ char wbuf[MAXLINE];
+
+ /* make absolutely certain 0, 1, and 2 are in use */
+ sprintf(wbuf, "%s... openmailer(%s)", e->e_to, m->m_name);
+ checkfd012(wbuf);
+ }
+#endif
+
+ /* check for Local Person Communication -- not for mortals!!! */
+ if (strcmp(m->m_mailer, "[LPC]") == 0)
+ {
+ mci = (MCI *) xalloc(sizeof *mci);
+ bzero((char *) mci, sizeof *mci);
+ mci->mci_in = stdin;
+ mci->mci_out = stdout;
+ mci->mci_state = clever ? MCIS_OPENING : MCIS_OPEN;
+ mci->mci_mailer = m;
+ }
+ else if (strcmp(m->m_mailer, "[IPC]") == 0 ||
+ strcmp(m->m_mailer, "[TCP]") == 0)
+ {
+#ifdef DAEMON
+ register int i;
+ register u_short port;
+
+ if (pv[0] == NULL || pv[1] == NULL || pv[1][0] == '\0')
+ {
+ syserr("null host name for %s mailer", m->m_mailer);
+ rcode = EX_CONFIG;
+ goto give_up;
+ }
+
+ CurHostName = pv[1];
+ curhost = hostsignature(m, pv[1], e);
+
+ if (curhost == NULL || curhost[0] == '\0')
+ {
+ syserr("null host signature for %s", pv[1]);
+ rcode = EX_OSERR;
+ goto give_up;
+ }
+
+ if (!clever)
+ {
+ syserr("554 non-clever IPC");
+ rcode = EX_CONFIG;
+ goto give_up;
+ }
+ if (pv[2] != NULL)
+ port = atoi(pv[2]);
+ else
+ port = 0;
+tryhost:
+ while (*curhost != '\0')
+ {
+ register char *p;
+ static char hostbuf[MAXNAME];
+
+ /* pull the next host from the signature */
+ p = strchr(curhost, ':');
+ if (p == NULL)
+ p = &curhost[strlen(curhost)];
+ if (p == curhost)
+ {
+ syserr("deliver: null host name in signature");
+ curhost++;
+ continue;
+ }
+ strncpy(hostbuf, curhost, p - curhost);
+ hostbuf[p - curhost] = '\0';
+ if (*p != '\0')
+ p++;
+ curhost = p;
+
+ /* see if we already know that this host is fried */
+ CurHostName = hostbuf;
+ mci = mci_get(hostbuf, m);
+ if (mci->mci_state != MCIS_CLOSED)
+ {
+ if (tTd(11, 1))
+ {
+ printf("openmailer: ");
+ mci_dump(mci, FALSE);
+ }
+ CurHostName = mci->mci_host;
+ break;
+ }
+ mci->mci_mailer = m;
+ if (mci->mci_exitstat != EX_OK)
+ continue;
+
+ /* try the connection */
+ setproctitle("%s %s: %s", e->e_id, hostbuf, "user open");
+ message("Connecting to %s (%s)...",
+ hostbuf, m->m_name);
+ i = makeconnection(hostbuf, port, mci,
+ bitnset(M_SECURE_PORT, m->m_flags));
+ mci->mci_exitstat = i;
+ mci->mci_errno = errno;
+#if NAMED_BIND
+ mci->mci_herrno = h_errno;
+#endif
+ if (i == EX_OK)
+ {
+ mci->mci_state = MCIS_OPENING;
+ mci_cache(mci);
+ if (TrafficLogFile != NULL)
+ fprintf(TrafficLogFile, "%05d == CONNECT %s\n",
+ getpid(), hostbuf);
+ break;
+ }
+ else if (tTd(11, 1))
+ printf("openmailer: makeconnection => stat=%d, errno=%d\n",
+ i, errno);
+
+ /* enter status of this host */
+ setstat(i);
+
+ /* should print some message here for -v mode */
+ }
+ if (mci == NULL)
+ {
+ syserr("deliver: no host name");
+ rcode = EX_OSERR;
+ goto give_up;
+ }
+ mci->mci_pid = 0;
+#else /* no DAEMON */
+ syserr("554 openmailer: no IPC");
+ if (tTd(11, 1))
+ printf("openmailer: NULL\n");
+ rcode = EX_UNAVAILABLE;
+ goto give_up;
+#endif /* DAEMON */
+ }
+ else
+ {
+ if (TrafficLogFile != NULL)
+ {
+ char **av;
+
+ fprintf(TrafficLogFile, "%05d === EXEC", getpid());
+ for (av = pv; *av != NULL; av++)
+ fprintf(TrafficLogFile, " %s", *av);
+ fprintf(TrafficLogFile, "\n");
+ }
+
+ /* create a pipe to shove the mail through */
+ if (pipe(mpvect) < 0)
+ {
+ syserr("%s... openmailer(%s): pipe (to mailer)",
+ e->e_to, m->m_name);
+ if (tTd(11, 1))
+ printf("openmailer: NULL\n");
+ rcode = EX_OSERR;
+ goto give_up;
+ }
+
+ /* if this mailer speaks smtp, create a return pipe */
+ if (clever && pipe(rpvect) < 0)
+ {
+ syserr("%s... openmailer(%s): pipe (from mailer)",
+ e->e_to, m->m_name);
+ (void) close(mpvect[0]);
+ (void) close(mpvect[1]);
+ if (tTd(11, 1))
+ printf("openmailer: NULL\n");
+ rcode = EX_OSERR;
+ goto give_up;
+ }
+
+ /*
+ ** Actually fork the mailer process.
+ ** DOFORK is clever about retrying.
+ **
+ ** Dispose of SIGCHLD signal catchers that may be laying
+ ** around so that endmail will get it.
+ */
+
+ if (e->e_xfp != NULL)
+ (void) fflush(e->e_xfp); /* for debugging */
+ (void) fflush(stdout);
+# ifdef SIGCHLD
+ (void) setsignal(SIGCHLD, SIG_DFL);
+# endif /* SIGCHLD */
+ DOFORK(FORK);
+ /* pid is set by DOFORK */
+ if (pid < 0)
+ {
+ /* failure */
+ syserr("%s... openmailer(%s): cannot fork",
+ e->e_to, m->m_name);
+ (void) close(mpvect[0]);
+ (void) close(mpvect[1]);
+ if (clever)
+ {
+ (void) close(rpvect[0]);
+ (void) close(rpvect[1]);
+ }
+ if (tTd(11, 1))
+ printf("openmailer: NULL\n");
+ rcode = EX_OSERR;
+ goto give_up;
+ }
+ else if (pid == 0)
+ {
+ int i;
+ int saveerrno;
+ char **ep;
+ char *env[MAXUSERENVIRON];
+ extern char **environ;
+ extern int DtableSize;
+
+ /* child -- set up input & exec mailer */
+ (void) setsignal(SIGINT, SIG_IGN);
+ (void) setsignal(SIGHUP, SIG_IGN);
+ (void) setsignal(SIGTERM, SIG_DFL);
+
+ /* reset user and group */
+ if (!bitnset(M_RESTR, m->m_flags))
+ {
+ if (ctladdr == NULL || ctladdr->q_uid == 0)
+ {
+ (void) initgroups(DefUser, DefGid);
+ (void) setgid(DefGid);
+ (void) setuid(DefUid);
+ }
+ else
+ {
+ (void) initgroups(ctladdr->q_ruser?
+ ctladdr->q_ruser: ctladdr->q_user,
+ ctladdr->q_gid);
+ (void) setgid(ctladdr->q_gid);
+ (void) setuid(ctladdr->q_uid);
+ }
+ }
+
+ if (tTd(11, 2))
+ printf("openmailer: running as r/euid=%d/%d\n",
+ getuid(), geteuid());
+
+ /* move into some "safe" directory */
+ if (m->m_execdir != NULL)
+ {
+ char *p, *q;
+ char buf[MAXLINE];
+
+ for (p = m->m_execdir; p != NULL; p = q)
+ {
+ q = strchr(p, ':');
+ if (q != NULL)
+ *q = '\0';
+ expand(p, buf, &buf[sizeof buf] - 1, e);
+ if (q != NULL)
+ *q++ = ':';
+ if (tTd(11, 20))
+ printf("openmailer: trydir %s\n",
+ buf);
+ if (buf[0] != '\0' && chdir(buf) >= 0)
+ break;
+ }
+ }
+
+ /* arrange to filter std & diag output of command */
+ if (clever)
+ {
+ (void) close(rpvect[0]);
+ if (dup2(rpvect[1], STDOUT_FILENO) < 0)
+ {
+ syserr("%s... openmailer(%s): cannot dup pipe %d for stdout",
+ e->e_to, m->m_name, rpvect[1]);
+ _exit(EX_OSERR);
+ }
+ (void) close(rpvect[1]);
+ }
+ else if (OpMode == MD_SMTP || OpMode == MD_DAEMON ||
+ HoldErrs || DisConnected)
+ {
+ /* put mailer output in transcript */
+ if (dup2(fileno(e->e_xfp), STDOUT_FILENO) < 0)
+ {
+ syserr("%s... openmailer(%s): cannot dup xscript %d for stdout",
+ e->e_to, m->m_name,
+ fileno(e->e_xfp));
+ _exit(EX_OSERR);
+ }
+ }
+ if (dup2(STDOUT_FILENO, STDERR_FILENO) < 0)
+ {
+ syserr("%s... openmailer(%s): cannot dup stdout for stderr",
+ e->e_to, m->m_name);
+ _exit(EX_OSERR);
+ }
+
+ /* arrange to get standard input */
+ (void) close(mpvect[1]);
+ if (dup2(mpvect[0], STDIN_FILENO) < 0)
+ {
+ syserr("%s... openmailer(%s): cannot dup pipe %d for stdin",
+ e->e_to, m->m_name, mpvect[0]);
+ _exit(EX_OSERR);
+ }
+ (void) close(mpvect[0]);
+
+ /* arrange for all the files to be closed */
+ for (i = 3; i < DtableSize; i++)
+ {
+ register int j;
+
+ if ((j = fcntl(i, F_GETFD, 0)) != -1)
+ (void) fcntl(i, F_SETFD, j | 1);
+ }
+
+ /*
+ ** Set up the mailer environment
+ ** TZ is timezone information.
+ ** SYSTYPE is Apollo software sys type (required).
+ ** ISP is Apollo hardware system type (required).
+ */
+
+ i = 0;
+ env[i++] = "AGENT=sendmail";
+ for (ep = environ; *ep != NULL; ep++)
+ {
+ if (strncmp(*ep, "TZ=", 3) == 0 ||
+ strncmp(*ep, "ISP=", 4) == 0 ||
+ strncmp(*ep, "SYSTYPE=", 8) == 0)
+ env[i++] = *ep;
+ }
+ env[i++] = NULL;
+
+ /* run disconnected from terminal */
+ (void) setsid();
+
+ /* try to execute the mailer */
+ execve(m->m_mailer, pv, env);
+ saveerrno = errno;
+ syserr("Cannot exec %s", m->m_mailer);
+ if (m == LocalMailer || transienterror(saveerrno))
+ _exit(EX_OSERR);
+ _exit(EX_UNAVAILABLE);
+ }
+
+ /*
+ ** Set up return value.
+ */
+
+ mci = (MCI *) xalloc(sizeof *mci);
+ bzero((char *) mci, sizeof *mci);
+ mci->mci_mailer = m;
+ mci->mci_state = clever ? MCIS_OPENING : MCIS_OPEN;
+ mci->mci_pid = pid;
+ (void) close(mpvect[0]);
+ mci->mci_out = fdopen(mpvect[1], "w");
+ if (mci->mci_out == NULL)
+ {
+ syserr("deliver: cannot create mailer output channel, fd=%d",
+ mpvect[1]);
+ (void) close(mpvect[1]);
+ if (clever)
+ {
+ (void) close(rpvect[0]);
+ (void) close(rpvect[1]);
+ }
+ rcode = EX_OSERR;
+ goto give_up;
+ }
+ if (clever)
+ {
+ (void) close(rpvect[1]);
+ mci->mci_in = fdopen(rpvect[0], "r");
+ if (mci->mci_in == NULL)
+ {
+ syserr("deliver: cannot create mailer input channel, fd=%d",
+ mpvect[1]);
+ (void) close(rpvect[0]);
+ fclose(mci->mci_out);
+ mci->mci_out = NULL;
+ rcode = EX_OSERR;
+ goto give_up;
+ }
+ }
+ else
+ {
+ mci->mci_flags |= MCIF_TEMP;
+ mci->mci_in = NULL;
+ }
+ }
+
+ /*
+ ** If we are in SMTP opening state, send initial protocol.
+ */
+
+ if (clever && mci->mci_state != MCIS_CLOSED)
+ {
+ smtpinit(m, mci, e);
+ }
+ if (tTd(11, 1))
+ {
+ printf("openmailer: ");
+ mci_dump(mci, FALSE);
+ }
+
+ if (mci->mci_state != MCIS_OPEN)
+ {
+ /* couldn't open the mailer */
+ rcode = mci->mci_exitstat;
+ errno = mci->mci_errno;
+#if NAMED_BIND
+ h_errno = mci->mci_herrno;
+#endif
+ if (rcode == EX_OK)
+ {
+ /* shouldn't happen */
+ syserr("554 deliver: rcode=%d, mci_state=%d, sig=%s",
+ rcode, mci->mci_state, firstsig);
+ rcode = EX_SOFTWARE;
+ }
+ else if (rcode == EX_TEMPFAIL && curhost != NULL && *curhost != '\0')
+ {
+ /* try next MX site */
+ goto tryhost;
+ }
+ }
+ else if (!clever)
+ {
+ /*
+ ** Format and send message.
+ */
+
+ putfromline(mci, e);
+ (*e->e_puthdr)(mci, e);
+ putline("\n", mci);
+ (*e->e_putbody)(mci, e, NULL);
+
+ /* get the exit status */
+ rcode = endmailer(mci, e, pv);
+ }
+ else
+#ifdef SMTP
+ {
+ /*
+ ** Send the MAIL FROM: protocol
+ */
+
+ rcode = smtpmailfrom(m, mci, e);
+ if (rcode == EX_OK)
+ {
+ register char *t = tobuf;
+ register int i;
+
+ /* send the recipient list */
+ tobuf[0] = '\0';
+ for (to = tochain; to != NULL; to = to->q_tchain)
+ {
+ e->e_to = to->q_paddr;
+ if ((i = smtprcpt(to, m, mci, e)) != EX_OK)
+ {
+ markfailure(e, to, i);
+ giveresponse(i, m, mci, ctladdr, e);
+ }
+ else
+ {
+ *t++ = ',';
+ for (p = to->q_paddr; *p; *t++ = *p++)
+ continue;
+ *t = '\0';
+ }
+ }
+
+ /* now send the data */
+ if (tobuf[0] == '\0')
+ {
+ rcode = EX_OK;
+ e->e_to = NULL;
+ if (bitset(MCIF_CACHED, mci->mci_flags))
+ smtprset(m, mci, e);
+ }
+ else
+ {
+ e->e_to = tobuf + 1;
+ rcode = smtpdata(m, mci, e);
+ }
+
+ /* now close the connection */
+ if (!bitset(MCIF_CACHED, mci->mci_flags))
+ smtpquit(m, mci, e);
+ }
+ if (rcode != EX_OK && curhost != NULL && *curhost != '\0')
+ {
+ /* try next MX site */
+ goto tryhost;
+ }
+ }
+#else /* not SMTP */
+ {
+ syserr("554 deliver: need SMTP compiled to use clever mailer");
+ rcode = EX_CONFIG;
+ goto give_up;
+ }
+#endif /* SMTP */
+#if NAMED_BIND
+ if (ConfigLevel < 2)
+ _res.options |= RES_DEFNAMES | RES_DNSRCH; /* XXX */
+#endif
+
+ /* arrange a return receipt if requested */
+ if (rcode == EX_OK && e->e_receiptto != NULL &&
+ bitnset(M_LOCALMAILER, m->m_flags))
+ {
+ e->e_flags |= EF_SENDRECEIPT;
+ /* do we want to send back more info? */
+ }
+
+ /*
+ ** Do final status disposal.
+ ** We check for something in tobuf for the SMTP case.
+ ** If we got a temporary failure, arrange to queue the
+ ** addressees.
+ */
+
+ give_up:
+ if (tobuf[0] != '\0')
+ giveresponse(rcode, m, mci, ctladdr, e);
+ for (to = tochain; to != NULL; to = to->q_tchain)
+ {
+ if (rcode != EX_OK)
+ markfailure(e, to, rcode);
+ else
+ {
+ to->q_flags |= QSENT;
+ e->e_nsent++;
+ if (e->e_receiptto != NULL &&
+ bitnset(M_LOCALMAILER, m->m_flags))
+ {
+ fprintf(e->e_xfp, "%s... Successfully delivered\n",
+ to->q_paddr);
+ }
+ }
+ }
+
+ /*
+ ** Restore state and return.
+ */
+
+#ifdef XDEBUG
+ {
+ char wbuf[MAXLINE];
+
+ /* make absolutely certain 0, 1, and 2 are in use */
+ sprintf(wbuf, "%s... end of deliver(%s)",
+ e->e_to == NULL ? "NO-TO-LIST" : e->e_to,
+ m->m_name);
+ checkfd012(wbuf);
+ }
+#endif
+
+ errno = 0;
+ define('g', (char *) NULL, e);
+ return (rcode);
+}
+ /*
+** MARKFAILURE -- mark a failure on a specific address.
+**
+** Parameters:
+** e -- the envelope we are sending.
+** q -- the address to mark.
+** rcode -- the code signifying the particular failure.
+**
+** Returns:
+** none.
+**
+** Side Effects:
+** marks the address (and possibly the envelope) with the
+** failure so that an error will be returned or
+** the message will be queued, as appropriate.
+*/
+
+markfailure(e, q, rcode)
+ register ENVELOPE *e;
+ register ADDRESS *q;
+ int rcode;
+{
+ char buf[MAXLINE];
+
+ switch (rcode)
+ {
+ case EX_OK:
+ break;
+
+ case EX_TEMPFAIL:
+ case EX_IOERR:
+ case EX_OSERR:
+ q->q_flags |= QQUEUEUP;
+ break;
+
+ default:
+ q->q_flags |= QBADADDR;
+ break;
+ }
+}
+ /*
+** ENDMAILER -- Wait for mailer to terminate.
+**
+** We should never get fatal errors (e.g., segmentation
+** violation), so we report those specially. For other
+** errors, we choose a status message (into statmsg),
+** and if it represents an error, we print it.
+**
+** Parameters:
+** pid -- pid of mailer.
+** e -- the current envelope.
+** pv -- the parameter vector that invoked the mailer
+** (for error messages).
+**
+** Returns:
+** exit code of mailer.
+**
+** Side Effects:
+** none.
+*/
+
+endmailer(mci, e, pv)
+ register MCI *mci;
+ register ENVELOPE *e;
+ char **pv;
+{
+ int st;
+
+ /* close any connections */
+ if (mci->mci_in != NULL)
+ (void) xfclose(mci->mci_in, mci->mci_mailer->m_name, "mci_in");
+ if (mci->mci_out != NULL)
+ (void) xfclose(mci->mci_out, mci->mci_mailer->m_name, "mci_out");
+ mci->mci_in = mci->mci_out = NULL;
+ mci->mci_state = MCIS_CLOSED;
+
+ /* in the IPC case there is nothing to wait for */
+ if (mci->mci_pid == 0)
+ return (EX_OK);
+
+ /* wait for the mailer process to die and collect status */
+ st = waitfor(mci->mci_pid);
+ if (st == -1)
+ {
+ syserr("endmailer %s: wait", pv[0]);
+ return (EX_SOFTWARE);
+ }
+
+ if (WIFEXITED(st))
+ {
+ /* normal death -- return status */
+ return (WEXITSTATUS(st));
+ }
+
+ /* it died a horrid death */
+ syserr("451 mailer %s died with signal %o",
+ mci->mci_mailer->m_name, st);
+
+ /* log the arguments */
+ if (pv != NULL && e->e_xfp != NULL)
+ {
+ register char **av;
+
+ fprintf(e->e_xfp, "Arguments:");
+ for (av = pv; *av != NULL; av++)
+ fprintf(e->e_xfp, " %s", *av);
+ fprintf(e->e_xfp, "\n");
+ }
+
+ ExitStat = EX_TEMPFAIL;
+ return (EX_TEMPFAIL);
+}
+ /*
+** GIVERESPONSE -- Interpret an error response from a mailer
+**
+** Parameters:
+** stat -- the status code from the mailer (high byte
+** only; core dumps must have been taken care of
+** already).
+** m -- the mailer info for this mailer.
+** mci -- the mailer connection info -- can be NULL if the
+** response is given before the connection is made.
+** ctladdr -- the controlling address for the recipient
+** address(es).
+** e -- the current envelope.
+**
+** Returns:
+** none.
+**
+** Side Effects:
+** Errors may be incremented.
+** ExitStat may be set.
+*/
+
+giveresponse(stat, m, mci, ctladdr, e)
+ int stat;
+ register MAILER *m;
+ register MCI *mci;
+ ADDRESS *ctladdr;
+ ENVELOPE *e;
+{
+ register const char *statmsg;
+ extern char *SysExMsg[];
+ register int i;
+ extern int N_SysEx;
+ char buf[MAXLINE];
+
+ /*
+ ** Compute status message from code.
+ */
+
+ i = stat - EX__BASE;
+ if (stat == 0)
+ {
+ statmsg = "250 Sent";
+ if (e->e_statmsg != NULL)
+ {
+ (void) sprintf(buf, "%s (%s)", statmsg, e->e_statmsg);
+ statmsg = buf;
+ }
+ }
+ else if (i < 0 || i > N_SysEx)
+ {
+ (void) sprintf(buf, "554 unknown mailer error %d", stat);
+ stat = EX_UNAVAILABLE;
+ statmsg = buf;
+ }
+ else if (stat == EX_TEMPFAIL)
+ {
+ (void) strcpy(buf, SysExMsg[i] + 1);
+#if NAMED_BIND
+ if (h_errno == TRY_AGAIN)
+ statmsg = errstring(h_errno+E_DNSBASE);
+ else
+#endif
+ {
+ if (errno != 0)
+ statmsg = errstring(errno);
+ else
+ {
+#ifdef SMTP
+ statmsg = SmtpError;
+#else /* SMTP */
+ statmsg = NULL;
+#endif /* SMTP */
+ }
+ }
+ if (statmsg != NULL && statmsg[0] != '\0')
+ {
+ (void) strcat(buf, ": ");
+ (void) strcat(buf, statmsg);
+ }
+ statmsg = buf;
+ }
+#if NAMED_BIND
+ else if (stat == EX_NOHOST && h_errno != 0)
+ {
+ statmsg = errstring(h_errno + E_DNSBASE);
+ (void) sprintf(buf, "%s (%s)", SysExMsg[i], statmsg);
+ statmsg = buf;
+ }
+#endif
+ else
+ {
+ statmsg = SysExMsg[i];
+ if (*statmsg++ == ':')
+ {
+ (void) sprintf(buf, "%s: %s", statmsg, errstring(errno));
+ statmsg = buf;
+ }
+ }
+
+ /*
+ ** Print the message as appropriate
+ */
+
+ if (stat == EX_OK || stat == EX_TEMPFAIL)
+ {
+ extern char MsgBuf[];
+
+ message("%s", &statmsg[4]);
+ if (stat == EX_TEMPFAIL && e->e_xfp != NULL)
+ fprintf(e->e_xfp, "%s\n", &MsgBuf[4]);
+ }
+ else
+ {
+ Errors++;
+ usrerr(statmsg, errstring(errno));
+ }
+
+ /*
+ ** Final cleanup.
+ ** Log a record of the transaction. Compute the new
+ ** ExitStat -- if we already had an error, stick with
+ ** that.
+ */
+
+ if (LogLevel > ((stat == EX_TEMPFAIL) ? 8 : (stat == EX_OK) ? 7 : 6))
+ logdelivery(m, mci, &statmsg[4], ctladdr, e);
+
+ if (tTd(11, 2))
+ printf("giveresponse: stat=%d, e->e_message=%s\n",
+ stat, e->e_message);
+
+ if (stat != EX_TEMPFAIL)
+ setstat(stat);
+ if (stat != EX_OK && (stat != EX_TEMPFAIL || e->e_message == NULL))
+ {
+ if (e->e_message != NULL)
+ free(e->e_message);
+ e->e_message = newstr(&statmsg[4]);
+ }
+ errno = 0;
+#if NAMED_BIND
+ h_errno = 0;
+#endif
+}
+ /*
+** LOGDELIVERY -- log the delivery in the system log
+**
+** Care is taken to avoid logging lines that are too long, because
+** some versions of syslog have an unfortunate proclivity for core
+** dumping. This is a hack, to be sure, that is at best empirical.
+**
+** Parameters:
+** m -- the mailer info. Can be NULL for initial queue.
+** mci -- the mailer connection info -- can be NULL if the
+** log is occuring when no connection is active.
+** stat -- the message to print for the status.
+** ctladdr -- the controlling address for the to list.
+** e -- the current envelope.
+**
+** Returns:
+** none
+**
+** Side Effects:
+** none
+*/
+
+logdelivery(m, mci, stat, ctladdr, e)
+ MAILER *m;
+ register MCI *mci;
+ char *stat;
+ ADDRESS *ctladdr;
+ register ENVELOPE *e;
+{
+# ifdef LOG
+ register char *bp;
+ register char *p;
+ int l;
+ char buf[512];
+
+# if (SYSLOG_BUFSIZE) >= 256
+ bp = buf;
+ if (ctladdr != NULL)
+ {
+ strcpy(bp, ", ctladdr=");
+ strcat(bp, shortenstring(ctladdr->q_paddr, 83));
+ bp += strlen(bp);
+ if (bitset(QGOODUID, ctladdr->q_flags))
+ {
+ (void) sprintf(bp, " (%d/%d)",
+ ctladdr->q_uid, ctladdr->q_gid);
+ bp += strlen(bp);
+ }
+ }
+
+ (void) sprintf(bp, ", delay=%s", pintvl(curtime() - e->e_ctime, TRUE));
+ bp += strlen(bp);
+
+ if (m != NULL)
+ {
+ (void) strcpy(bp, ", mailer=");
+ (void) strcat(bp, m->m_name);
+ bp += strlen(bp);
+ }
+
+ if (mci != NULL && mci->mci_host != NULL)
+ {
+# ifdef DAEMON
+ extern SOCKADDR CurHostAddr;
+# endif
+
+ (void) strcpy(bp, ", relay=");
+ (void) strcat(bp, mci->mci_host);
+
+# ifdef DAEMON
+ (void) strcat(bp, " [");
+ (void) strcat(bp, anynet_ntoa(&CurHostAddr));
+ (void) strcat(bp, "]");
+# endif
+ }
+ else if (strcmp(stat, "queued") != 0)
+ {
+ char *p = macvalue('h', e);
+
+ if (p != NULL && p[0] != '\0')
+ {
+ (void) strcpy(bp, ", relay=");
+ (void) strcat(bp, p);
+ }
+ }
+ bp += strlen(bp);
+
+#define STATLEN (((SYSLOG_BUFSIZE) - 100) / 4)
+#if (STATLEN) < 63
+# undef STATLEN
+# define STATLEN 63
+#endif
+#if (STATLEN) > 203
+# undef STATLEN
+# define STATLEN 203
+#endif
+
+ if ((bp - buf) > (sizeof buf - ((STATLEN) + 20)))
+ {
+ /* desperation move -- truncate data */
+ bp = buf + sizeof buf - ((STATLEN) + 17);
+ strcpy(bp, "...");
+ bp += 3;
+ }
+
+ (void) strcpy(bp, ", stat=");
+ bp += strlen(bp);
+
+ (void) strcpy(bp, shortenstring(stat, (STATLEN)));
+
+ l = SYSLOG_BUFSIZE - 100 - strlen(buf);
+ p = e->e_to;
+ while (strlen(p) >= l)
+ {
+ register char *q = strchr(p + l, ',');
+
+ if (q == NULL)
+ break;
+ syslog(LOG_INFO, "%s: to=%.*s [more]%s",
+ e->e_id, ++q - p, p, buf);
+ p = q;
+ }
+ syslog(LOG_INFO, "%s: to=%s%s", e->e_id, p, buf);
+
+# else /* we have a very short log buffer size */
+
+ l = SYSLOG_BUFSIZE - 85;
+ p = e->e_to;
+ while (strlen(p) >= l)
+ {
+ register char *q = strchr(p + l, ',');
+
+ if (q == NULL)
+ break;
+ syslog(LOG_INFO, "%s: to=%.*s [more]",
+ e->e_id, ++q - p, p);
+ p = q;
+ }
+ syslog(LOG_INFO, "%s: to=%s", e->e_id, p);
+
+ if (ctladdr != NULL)
+ {
+ bp = buf;
+ strcpy(buf, "ctladdr=");
+ bp += strlen(buf);
+ strcpy(bp, shortenstring(ctladdr->q_paddr, 83));
+ bp += strlen(buf);
+ if (bitset(QGOODUID, ctladdr->q_flags))
+ {
+ (void) sprintf(bp, " (%d/%d)",
+ ctladdr->q_uid, ctladdr->q_gid);
+ bp += strlen(bp);
+ }
+ syslog(LOG_INFO, "%s: %s", e->e_id, buf);
+ }
+ bp = buf;
+ sprintf(bp, "delay=%s", pintvl(curtime() - e->e_ctime, TRUE));
+ bp += strlen(bp);
+
+ if (m != NULL)
+ {
+ sprintf(bp, ", mailer=%s", m->m_name);
+ bp += strlen(bp);
+ }
+ syslog(LOG_INFO, "%s: %s", e->e_id, buf);
+
+ buf[0] = '\0';
+ if (mci != NULL && mci->mci_host != NULL)
+ {
+# ifdef DAEMON
+ extern SOCKADDR CurHostAddr;
+# endif
+
+ sprintf(buf, "relay=%s", mci->mci_host);
+
+# ifdef DAEMON
+ (void) strcat(buf, " [");
+ (void) strcat(buf, anynet_ntoa(&CurHostAddr));
+ (void) strcat(buf, "]");
+# endif
+ }
+ else if (strcmp(stat, "queued") != 0)
+ {
+ char *p = macvalue('h', e);
+
+ if (p != NULL && p[0] != '\0')
+ sprintf(buf, "relay=%s", p);
+ }
+ if (buf[0] != '\0')
+ syslog(LOG_INFO, "%s: %s", e->e_id, buf);
+
+ syslog(LOG_INFO, "%s: stat=%s", e->e_id, shortenstring(stat, 63));
+# endif /* short log buffer */
+# endif /* LOG */
+}
+ /*
+** PUTFROMLINE -- output a UNIX-style from line (or whatever)
+**
+** This can be made an arbitrary message separator by changing $l
+**
+** One of the ugliest hacks seen by human eyes is contained herein:
+** UUCP wants those stupid "remote from <host>" lines. Why oh why
+** does a well-meaning programmer such as myself have to deal with
+** this kind of antique garbage????
+**
+** Parameters:
+** mci -- the connection information.
+** e -- the envelope.
+**
+** Returns:
+** none
+**
+** Side Effects:
+** outputs some text to fp.
+*/
+
+putfromline(mci, e)
+ register MCI *mci;
+ ENVELOPE *e;
+{
+ char *template = "\201l\n";
+ char buf[MAXLINE];
+
+ if (bitnset(M_NHDR, mci->mci_mailer->m_flags))
+ return;
+
+# ifdef UGLYUUCP
+ if (bitnset(M_UGLYUUCP, mci->mci_mailer->m_flags))
+ {
+ char *bang;
+ char xbuf[MAXLINE];
+
+ expand("\201g", buf, &buf[sizeof buf - 1], e);
+ bang = strchr(buf, '!');
+ if (bang == NULL)
+ {
+ errno = 0;
+ syserr("554 No ! in UUCP From address! (%s given)", buf);
+ }
+ else
+ {
+ *bang++ = '\0';
+ (void) sprintf(xbuf, "From %s \201d remote from %s\n", bang, buf);
+ template = xbuf;
+ }
+ }
+# endif /* UGLYUUCP */
+ expand(template, buf, &buf[sizeof buf - 1], e);
+ putline(buf, mci);
+}
+ /*
+** PUTBODY -- put the body of a message.
+**
+** Parameters:
+** mci -- the connection information.
+** e -- the envelope to put out.
+** separator -- if non-NULL, a message separator that must
+** not be permitted in the resulting message.
+**
+** Returns:
+** none.
+**
+** Side Effects:
+** The message is written onto fp.
+*/
+
+putbody(mci, e, separator)
+ register MCI *mci;
+ register ENVELOPE *e;
+ char *separator;
+{
+ char buf[MAXLINE];
+
+ /*
+ ** Output the body of the message
+ */
+
+ if (e->e_dfp == NULL)
+ {
+ if (e->e_df != NULL)
+ {
+ e->e_dfp = fopen(e->e_df, "r");
+ if (e->e_dfp == NULL)
+ syserr("putbody: Cannot open %s for %s from %s",
+ e->e_df, e->e_to, e->e_from.q_paddr);
+ }
+ else
+ putline("<<< No Message Collected >>>", mci);
+ }
+ if (e->e_dfp != NULL)
+ {
+ rewind(e->e_dfp);
+ while (!ferror(mci->mci_out) && fgets(buf, sizeof buf, e->e_dfp) != NULL)
+ {
+ if (buf[0] == 'F' &&
+ bitnset(M_ESCFROM, mci->mci_mailer->m_flags) &&
+ strncmp(buf, "From ", 5) == 0)
+ (void) putc('>', mci->mci_out);
+ if (buf[0] == '-' && buf[1] == '-' && separator != NULL)
+ {
+ /* possible separator */
+ int sl = strlen(separator);
+
+ if (strncmp(&buf[2], separator, sl) == 0)
+ (void) putc(' ', mci->mci_out);
+ }
+ putline(buf, mci);
+ }
+
+ if (ferror(e->e_dfp))
+ {
+ syserr("putbody: %s: read error", e->e_df);
+ ExitStat = EX_IOERR;
+ }
+ }
+
+ /* some mailers want extra blank line at end of message */
+ if (bitnset(M_BLANKEND, mci->mci_mailer->m_flags) &&
+ buf[0] != '\0' && buf[0] != '\n')
+ putline("", mci);
+
+ (void) fflush(mci->mci_out);
+ if (ferror(mci->mci_out) && errno != EPIPE)
+ {
+ syserr("putbody: write error");
+ ExitStat = EX_IOERR;
+ }
+ errno = 0;
+}
+ /*
+** MAILFILE -- Send a message to a file.
+**
+** If the file has the setuid/setgid bits set, but NO execute
+** bits, sendmail will try to become the owner of that file
+** rather than the real user. Obviously, this only works if
+** sendmail runs as root.
+**
+** This could be done as a subordinate mailer, except that it
+** is used implicitly to save messages in ~/dead.letter. We
+** view this as being sufficiently important as to include it
+** here. For example, if the system is dying, we shouldn't have
+** to create another process plus some pipes to save the message.
+**
+** Parameters:
+** filename -- the name of the file to send to.
+** ctladdr -- the controlling address header -- includes
+** the userid/groupid to be when sending.
+**
+** Returns:
+** The exit code associated with the operation.
+**
+** Side Effects:
+** none.
+*/
+
+mailfile(filename, ctladdr, e)
+ char *filename;
+ ADDRESS *ctladdr;
+ register ENVELOPE *e;
+{
+ register FILE *f;
+ register int pid;
+ int mode;
+
+ if (tTd(11, 1))
+ {
+ printf("mailfile %s\n ctladdr=", filename);
+ printaddr(ctladdr, FALSE);
+ }
+
+ if (e->e_xfp != NULL)
+ fflush(e->e_xfp);
+
+ /*
+ ** Fork so we can change permissions here.
+ ** Note that we MUST use fork, not vfork, because of
+ ** the complications of calling subroutines, etc.
+ */
+
+ DOFORK(fork);
+
+ if (pid < 0)
+ return (EX_OSERR);
+ else if (pid == 0)
+ {
+ /* child -- actually write to file */
+ struct stat stb;
+ MCI mcibuf;
+
+ (void) setsignal(SIGINT, SIG_DFL);
+ (void) setsignal(SIGHUP, SIG_DFL);
+ (void) setsignal(SIGTERM, SIG_DFL);
+ (void) umask(OldUmask);
+
+ if (stat(filename, &stb) < 0)
+ stb.st_mode = FileMode;
+ mode = stb.st_mode;
+
+ /* limit the errors to those actually caused in the child */
+ errno = 0;
+ ExitStat = EX_OK;
+
+ if (bitset(0111, stb.st_mode))
+ exit(EX_CANTCREAT);
+ if (ctladdr != NULL)
+ {
+ /* ignore setuid and setgid bits */
+ mode &= ~(S_ISGID|S_ISUID);
+ }
+
+ /* we have to open the dfile BEFORE setuid */
+ if (e->e_dfp == NULL && e->e_df != NULL)
+ {
+ e->e_dfp = fopen(e->e_df, "r");
+ if (e->e_dfp == NULL)
+ {
+ syserr("mailfile: Cannot open %s for %s from %s",
+ e->e_df, e->e_to, e->e_from.q_paddr);
+ }
+ }
+
+ if (!bitset(S_ISGID, mode) || setgid(stb.st_gid) < 0)
+ {
+ if (ctladdr == NULL || ctladdr->q_uid == 0)
+ {
+ (void) initgroups(DefUser, DefGid);
+ }
+ else
+ {
+ (void) initgroups(ctladdr->q_ruser ?
+ ctladdr->q_ruser : ctladdr->q_user,
+ ctladdr->q_gid);
+ }
+ }
+ if (!bitset(S_ISUID, mode) || setuid(stb.st_uid) < 0)
+ {
+ if (ctladdr == NULL || ctladdr->q_uid == 0)
+ (void) setuid(DefUid);
+ else
+ (void) setuid(ctladdr->q_uid);
+ }
+ FileName = filename;
+ LineNumber = 0;
+ f = dfopen(filename, O_WRONLY|O_CREAT|O_APPEND, FileMode);
+ if (f == NULL)
+ {
+ message("554 cannot open: %s", errstring(errno));
+ exit(EX_CANTCREAT);
+ }
+
+ bzero(&mcibuf, sizeof mcibuf);
+ mcibuf.mci_mailer = FileMailer;
+ mcibuf.mci_out = f;
+ if (bitnset(M_7BITS, FileMailer->m_flags))
+ mcibuf.mci_flags |= MCIF_7BIT;
+
+ putfromline(&mcibuf, e);
+ (*e->e_puthdr)(&mcibuf, e);
+ putline("\n", &mcibuf);
+ (*e->e_putbody)(&mcibuf, e, NULL);
+ putline("\n", &mcibuf);
+ if (ferror(f))
+ {
+ message("451 I/O error: %s", errstring(errno));
+ setstat(EX_IOERR);
+ }
+ (void) xfclose(f, "mailfile", filename);
+ (void) fflush(stdout);
+
+ /* reset ISUID & ISGID bits for paranoid systems */
+ (void) chmod(filename, (int) stb.st_mode);
+ exit(ExitStat);
+ /*NOTREACHED*/
+ }
+ else
+ {
+ /* parent -- wait for exit status */
+ int st;
+
+ st = waitfor(pid);
+ if (WIFEXITED(st))
+ return (WEXITSTATUS(st));
+ else
+ {
+ syserr("child died on signal %d", st);
+ return (EX_UNAVAILABLE);
+ }
+ /*NOTREACHED*/
+ }
+}
+ /*
+** HOSTSIGNATURE -- return the "signature" for a host.
+**
+** The signature describes how we are going to send this -- it
+** can be just the hostname (for non-Internet hosts) or can be
+** an ordered list of MX hosts.
+**
+** Parameters:
+** m -- the mailer describing this host.
+** host -- the host name.
+** e -- the current envelope.
+**
+** Returns:
+** The signature for this host.
+**
+** Side Effects:
+** Can tweak the symbol table.
+*/
+
+char *
+hostsignature(m, host, e)
+ register MAILER *m;
+ char *host;
+ ENVELOPE *e;
+{
+ register char *p;
+ register STAB *s;
+ int i;
+ int len;
+#if NAMED_BIND
+ int nmx;
+ auto int rcode;
+ char *hp;
+ char *endp;
+ int oldoptions;
+ char *mxhosts[MAXMXHOSTS + 1];
+#endif
+
+ /*
+ ** Check to see if this uses IPC -- if not, it can't have MX records.
+ */
+
+ p = m->m_mailer;
+ if (strcmp(p, "[IPC]") != 0 && strcmp(p, "[TCP]") != 0)
+ {
+ /* just an ordinary mailer */
+ return host;
+ }
+
+ /*
+ ** Look it up in the symbol table.
+ */
+
+ s = stab(host, ST_HOSTSIG, ST_ENTER);
+ if (s->s_hostsig != NULL)
+ return s->s_hostsig;
+
+ /*
+ ** Not already there -- create a signature.
+ */
+
+#if NAMED_BIND
+ if (ConfigLevel < 2)
+ {
+ oldoptions = _res.options;
+ _res.options &= ~(RES_DEFNAMES | RES_DNSRCH); /* XXX */
+ }
+
+ for (hp = host; hp != NULL; hp = endp)
+ {
+ endp = strchr(hp, ':');
+ if (endp != NULL)
+ *endp = '\0';
+
+ nmx = getmxrr(hp, mxhosts, TRUE, &rcode);
+
+ if (nmx <= 0)
+ {
+ register MCI *mci;
+
+ /* update the connection info for this host */
+ mci = mci_get(hp, m);
+ mci->mci_exitstat = rcode;
+ mci->mci_errno = errno;
+#if NAMED_BIND
+ mci->mci_herrno = h_errno;
+#endif
+
+ /* and return the original host name as the signature */
+ nmx = 1;
+ mxhosts[0] = hp;
+ }
+
+ len = 0;
+ for (i = 0; i < nmx; i++)
+ {
+ len += strlen(mxhosts[i]) + 1;
+ }
+ if (s->s_hostsig != NULL)
+ len += strlen(s->s_hostsig) + 1;
+ p = xalloc(len);
+ if (s->s_hostsig != NULL)
+ {
+ (void) strcpy(p, s->s_hostsig);
+ free(s->s_hostsig);
+ s->s_hostsig = p;
+ p += strlen(p);
+ *p++ = ':';
+ }
+ else
+ s->s_hostsig = p;
+ for (i = 0; i < nmx; i++)
+ {
+ if (i != 0)
+ *p++ = ':';
+ strcpy(p, mxhosts[i]);
+ p += strlen(p);
+ }
+ if (endp != NULL)
+ *endp++ = ':';
+ }
+ makelower(s->s_hostsig);
+ if (ConfigLevel < 2)
+ _res.options = oldoptions;
+#else
+ /* not using BIND -- the signature is just the host name */
+ s->s_hostsig = host;
+#endif
+ if (tTd(17, 1))
+ printf("hostsignature(%s) = %s\n", host, s->s_hostsig);
+ return s->s_hostsig;
+}
diff --git a/usr.sbin/sendmail/src/domain.c b/usr.sbin/sendmail/src/domain.c
new file mode 100644
index 0000000..48109fe
--- /dev/null
+++ b/usr.sbin/sendmail/src/domain.c
@@ -0,0 +1,769 @@
+/*
+ * Copyright (c) 1986 Eric P. Allman
+ * Copyright (c) 1988, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "sendmail.h"
+
+#ifndef lint
+#if NAMED_BIND
+static char sccsid[] = "@(#)domain.c 8.19 (Berkeley) 3/11/94 (with name server)";
+#else
+static char sccsid[] = "@(#)domain.c 8.19 (Berkeley) 3/11/94 (without name server)";
+#endif
+#endif /* not lint */
+
+#if NAMED_BIND
+
+#include <errno.h>
+#include <arpa/nameser.h>
+#include <resolv.h>
+#include <netdb.h>
+
+typedef union
+{
+ HEADER qb1;
+ char qb2[PACKETSZ];
+} querybuf;
+
+static char MXHostBuf[MAXMXHOSTS*PACKETSZ];
+
+#ifndef MAXDNSRCH
+#define MAXDNSRCH 6 /* number of possible domains to search */
+#endif
+
+#ifndef MAX
+#define MAX(a, b) ((a) > (b) ? (a) : (b))
+#endif
+
+#ifndef NO_DATA
+# define NO_DATA NO_ADDRESS
+#endif
+
+#ifndef HEADERSZ
+# define HEADERSZ sizeof(HEADER)
+#endif
+
+/* don't use sizeof because sizeof(long) is different on 64-bit machines */
+#define SHORTSIZE 2 /* size of a short (really, must be 2) */
+#define LONGSIZE 4 /* size of a long (really, must be 4) */
+
+#define MAXCNAMEDEPTH 10 /* maximum depth of CNAME recursion */
+ /*
+** GETMXRR -- get MX resource records for a domain
+**
+** Parameters:
+** host -- the name of the host to MX.
+** mxhosts -- a pointer to a return buffer of MX records.
+** droplocalhost -- If TRUE, all MX records less preferred
+** than the local host (as determined by $=w) will
+** be discarded.
+** rcode -- a pointer to an EX_ status code.
+**
+** Returns:
+** The number of MX records found.
+** -1 if there is an internal failure.
+** If no MX records are found, mxhosts[0] is set to host
+** and 1 is returned.
+*/
+
+getmxrr(host, mxhosts, droplocalhost, rcode)
+ char *host;
+ char **mxhosts;
+ bool droplocalhost;
+ int *rcode;
+{
+ extern int h_errno;
+ register u_char *eom, *cp;
+ register int i, j, n;
+ int nmx = 0;
+ register char *bp;
+ HEADER *hp;
+ querybuf answer;
+ int ancount, qdcount, buflen;
+ bool seenlocal = FALSE;
+ u_short pref, localpref, type;
+ char *fallbackMX = FallBackMX;
+ static bool firsttime = TRUE;
+ STAB *st;
+ bool trycanon = FALSE;
+ u_short prefer[MAXMXHOSTS];
+ int weight[MAXMXHOSTS];
+ extern bool getcanonname();
+
+ if (tTd(8, 2))
+ printf("getmxrr(%s, droplocalhost=%d)\n", host, droplocalhost);
+
+ if (fallbackMX != NULL)
+ {
+ if (firsttime && res_query(FallBackMX, C_IN, T_A,
+ (char *) &answer, sizeof answer) < 0)
+ {
+ /* this entry is bogus */
+ fallbackMX = FallBackMX = NULL;
+ }
+ else if (droplocalhost &&
+ (st = stab(fallbackMX, ST_CLASS, ST_FIND)) != NULL &&
+ bitnset('w', st->s_class))
+ {
+ /* don't use fallback for this pass */
+ fallbackMX = NULL;
+ }
+ firsttime = FALSE;
+ }
+
+ /* efficiency hack -- numeric or non-MX lookups */
+ if (host[0] == '[')
+ goto punt;
+
+ errno = 0;
+ n = res_search(host, C_IN, T_MX, (char *)&answer, sizeof(answer));
+ if (n < 0)
+ {
+ if (tTd(8, 1))
+ printf("getmxrr: res_search(%s) failed (errno=%d, h_errno=%d)\n",
+ (host == NULL) ? "<NULL>" : host, errno, h_errno);
+ switch (h_errno)
+ {
+ case NO_DATA:
+ trycanon = TRUE;
+ /* fall through */
+
+ case NO_RECOVERY:
+ /* no MX data on this host */
+ goto punt;
+
+ case HOST_NOT_FOUND:
+#ifdef BROKEN_RES_SEARCH
+ /* Ultrix resolver returns failure w/ h_errno=0 */
+ case 0:
+#endif
+ /* the host just doesn't exist */
+ *rcode = EX_NOHOST;
+
+ if (!UseNameServer)
+ {
+ /* might exist in /etc/hosts */
+ goto punt;
+ }
+ break;
+
+ case TRY_AGAIN:
+ /* couldn't connect to the name server */
+ if (!UseNameServer && errno == ECONNREFUSED)
+ goto punt;
+
+ /* it might come up later; better queue it up */
+ *rcode = EX_TEMPFAIL;
+ break;
+
+ default:
+ syserr("getmxrr: res_search (%s) failed with impossible h_errno (%d)\n",
+ host, h_errno);
+ *rcode = EX_OSERR;
+ break;
+ }
+
+ /* irreconcilable differences */
+ return (-1);
+ }
+
+ /* find first satisfactory answer */
+ hp = (HEADER *)&answer;
+ cp = (u_char *)&answer + HEADERSZ;
+ eom = (u_char *)&answer + n;
+ for (qdcount = ntohs(hp->qdcount); qdcount--; cp += n + QFIXEDSZ)
+ if ((n = dn_skipname(cp, eom)) < 0)
+ goto punt;
+ buflen = sizeof(MXHostBuf) - 1;
+ bp = MXHostBuf;
+ ancount = ntohs(hp->ancount);
+ while (--ancount >= 0 && cp < eom && nmx < MAXMXHOSTS - 1)
+ {
+ if ((n = dn_expand((u_char *)&answer,
+ eom, cp, (u_char *)bp, buflen)) < 0)
+ break;
+ cp += n;
+ GETSHORT(type, cp);
+ cp += SHORTSIZE + LONGSIZE;
+ GETSHORT(n, cp);
+ if (type != T_MX)
+ {
+ if (tTd(8, 8) || _res.options & RES_DEBUG)
+ printf("unexpected answer type %d, size %d\n",
+ type, n);
+ cp += n;
+ continue;
+ }
+ GETSHORT(pref, cp);
+ if ((n = dn_expand((u_char *)&answer, eom, cp,
+ (u_char *)bp, buflen)) < 0)
+ break;
+ cp += n;
+ if (droplocalhost &&
+ (st = stab(bp, ST_CLASS, ST_FIND)) != NULL &&
+ bitnset('w', st->s_class))
+ {
+ if (tTd(8, 3))
+ printf("found localhost (%s) in MX list, pref=%d\n",
+ bp, pref);
+ if (!seenlocal || pref < localpref)
+ localpref = pref;
+ seenlocal = TRUE;
+ continue;
+ }
+ weight[nmx] = mxrand(bp);
+ prefer[nmx] = pref;
+ mxhosts[nmx++] = bp;
+ n = strlen(bp);
+ bp += n;
+ if (bp[-1] != '.')
+ {
+ *bp++ = '.';
+ n++;
+ }
+ *bp++ = '\0';
+ buflen -= n + 1;
+ }
+
+ /* sort the records */
+ for (i = 0; i < nmx; i++)
+ {
+ for (j = i + 1; j < nmx; j++)
+ {
+ if (prefer[i] > prefer[j] ||
+ (prefer[i] == prefer[j] && weight[i] > weight[j]))
+ {
+ register int temp;
+ register char *temp1;
+
+ temp = prefer[i];
+ prefer[i] = prefer[j];
+ prefer[j] = temp;
+ temp1 = mxhosts[i];
+ mxhosts[i] = mxhosts[j];
+ mxhosts[j] = temp1;
+ temp = weight[i];
+ weight[i] = weight[j];
+ weight[j] = temp;
+ }
+ }
+ if (seenlocal && prefer[i] >= localpref)
+ {
+ /* truncate higher preference part of list */
+ nmx = i;
+ }
+ }
+
+ if (nmx == 0)
+ {
+punt:
+ if (seenlocal &&
+ (!TryNullMXList || gethostbyname(host) == NULL))
+ {
+ /*
+ ** If we have deleted all MX entries, this is
+ ** an error -- we should NEVER send to a host that
+ ** has an MX, and this should have been caught
+ ** earlier in the config file.
+ **
+ ** Some sites prefer to go ahead and try the
+ ** A record anyway; that case is handled by
+ ** setting TryNullMXList. I believe this is a
+ ** bad idea, but it's up to you....
+ */
+
+ *rcode = EX_CONFIG;
+ syserr("MX list for %s points back to %s",
+ host, MyHostName);
+ return -1;
+ }
+ strcpy(MXHostBuf, host);
+ mxhosts[0] = MXHostBuf;
+ if (host[0] == '[')
+ {
+ register char *p;
+
+ /* this may be an MX suppression-style address */
+ p = strchr(MXHostBuf, ']');
+ if (p != NULL)
+ {
+ *p = '\0';
+ if (inet_addr(&MXHostBuf[1]) != -1)
+ *p = ']';
+ else
+ {
+ trycanon = TRUE;
+ mxhosts[0]++;
+ }
+ }
+ }
+ if (trycanon &&
+ getcanonname(mxhosts[0], sizeof MXHostBuf - 2, FALSE))
+ {
+ bp = &MXHostBuf[strlen(MXHostBuf)];
+ if (bp[-1] != '.')
+ {
+ *bp++ = '.';
+ *bp = '\0';
+ }
+ }
+ nmx = 1;
+ }
+
+ /* if we have a default lowest preference, include that */
+ if (fallbackMX != NULL && !seenlocal)
+ mxhosts[nmx++] = fallbackMX;
+
+ return (nmx);
+}
+ /*
+** MXRAND -- create a randomizer for equal MX preferences
+**
+** If two MX hosts have equal preferences we want to randomize
+** the selection. But in order for signatures to be the same,
+** we need to randomize the same way each time. This function
+** computes a pseudo-random hash function from the host name.
+**
+** Parameters:
+** host -- the name of the host.
+**
+** Returns:
+** A random but repeatable value based on the host name.
+**
+** Side Effects:
+** none.
+*/
+
+mxrand(host)
+ register char *host;
+{
+ int hfunc;
+ static unsigned int seed;
+
+ if (seed == 0)
+ {
+ seed = (int) curtime() & 0xffff;
+ if (seed == 0)
+ seed++;
+ }
+
+ if (tTd(17, 9))
+ printf("mxrand(%s)", host);
+
+ hfunc = seed;
+ while (*host != '\0')
+ {
+ int c = *host++;
+
+ if (isascii(c) && isupper(c))
+ c = tolower(c);
+ hfunc = ((hfunc << 1) ^ c) % 2003;
+ }
+
+ hfunc &= 0xff;
+
+ if (tTd(17, 9))
+ printf(" = %d\n", hfunc);
+ return hfunc;
+}
+ /*
+** GETCANONNAME -- get the canonical name for named host
+**
+** This algorithm tries to be smart about wildcard MX records.
+** This is hard to do because DNS doesn't tell is if we matched
+** against a wildcard or a specific MX.
+**
+** We always prefer A & CNAME records, since these are presumed
+** to be specific.
+**
+** If we match an MX in one pass and lose it in the next, we use
+** the old one. For example, consider an MX matching *.FOO.BAR.COM.
+** A hostname bletch.foo.bar.com will match against this MX, but
+** will stop matching when we try bletch.bar.com -- so we know
+** that bletch.foo.bar.com must have been right. This fails if
+** there was also an MX record matching *.BAR.COM, but there are
+** some things that just can't be fixed.
+**
+** Parameters:
+** host -- a buffer containing the name of the host.
+** This is a value-result parameter.
+** hbsize -- the size of the host buffer.
+** trymx -- if set, try MX records as well as A and CNAME.
+**
+** Returns:
+** TRUE -- if the host matched.
+** FALSE -- otherwise.
+*/
+
+bool
+getcanonname(host, hbsize, trymx)
+ char *host;
+ int hbsize;
+ bool trymx;
+{
+ extern int h_errno;
+ register u_char *eom, *ap;
+ register char *cp;
+ register int n;
+ HEADER *hp;
+ querybuf answer;
+ int ancount, qdcount;
+ int ret;
+ char **domain;
+ int type;
+ char **dp;
+ char *mxmatch;
+ bool amatch;
+ bool gotmx;
+ int qtype;
+ int loopcnt;
+ char *xp;
+ char nbuf[MAX(PACKETSZ, MAXDNAME*2+2)];
+ char *searchlist[MAXDNSRCH+2];
+ extern char *gethostalias();
+
+ if (tTd(8, 2))
+ printf("getcanonname(%s)\n", host);
+
+ if ((_res.options & RES_INIT) == 0 && res_init() == -1)
+ return (FALSE);
+
+ /*
+ ** Initialize domain search list. If there is at least one
+ ** dot in the name, search the unmodified name first so we
+ ** find "vse.CS" in Czechoslovakia instead of in the local
+ ** domain (e.g., vse.CS.Berkeley.EDU).
+ **
+ ** Older versions of the resolver could create this
+ ** list by tearing apart the host name.
+ */
+
+ loopcnt = 0;
+cnameloop:
+ for (cp = host, n = 0; *cp; cp++)
+ if (*cp == '.')
+ n++;
+
+ if (n == 0 && (xp = gethostalias(host)) != NULL)
+ {
+ if (loopcnt++ > MAXCNAMEDEPTH)
+ {
+ syserr("loop in ${HOSTALIASES} file");
+ }
+ else
+ {
+ strncpy(host, xp, hbsize);
+ host[hbsize - 1] = '\0';
+ goto cnameloop;
+ }
+ }
+
+ dp = searchlist;
+ if (n > 0)
+ *dp++ = "";
+ if (n >= 0 && *--cp != '.' && bitset(RES_DNSRCH, _res.options))
+ {
+ for (domain = _res.dnsrch; *domain != NULL; )
+ *dp++ = *domain++;
+ }
+ else if (n == 0 && bitset(RES_DEFNAMES, _res.options))
+ {
+ *dp++ = _res.defdname;
+ }
+ else if (*cp == '.')
+ {
+ *cp = '\0';
+ }
+ *dp = NULL;
+
+ /*
+ ** Now run through the search list for the name in question.
+ */
+
+ mxmatch = NULL;
+ qtype = T_ANY;
+
+ for (dp = searchlist; *dp != NULL; )
+ {
+ if (qtype == T_ANY)
+ gotmx = FALSE;
+ if (tTd(8, 5))
+ printf("getcanonname: trying %s.%s (%s)\n", host, *dp,
+ qtype == T_ANY ? "ANY" : qtype == T_A ? "A" :
+ qtype == T_MX ? "MX" : "???");
+ ret = res_querydomain(host, *dp, C_IN, qtype,
+ &answer, sizeof(answer));
+ if (ret <= 0)
+ {
+ if (tTd(8, 7))
+ printf("\tNO: errno=%d, h_errno=%d\n",
+ errno, h_errno);
+
+ if (errno == ECONNREFUSED || h_errno == TRY_AGAIN)
+ {
+ /* the name server seems to be down */
+ h_errno = TRY_AGAIN;
+ return FALSE;
+ }
+
+ if (h_errno != HOST_NOT_FOUND)
+ {
+ /* might have another type of interest */
+ if (qtype == T_ANY)
+ {
+ qtype = T_A;
+ continue;
+ }
+ else if (qtype == T_A && !gotmx && trymx)
+ {
+ qtype = T_MX;
+ continue;
+ }
+ }
+
+ if (mxmatch != NULL)
+ {
+ /* we matched before -- use that one */
+ break;
+ }
+
+ /* otherwise, try the next name */
+ dp++;
+ qtype = T_ANY;
+ continue;
+ }
+ else if (tTd(8, 7))
+ printf("\tYES\n");
+
+ /*
+ ** This might be a bogus match. Search for A or
+ ** CNAME records. If we don't have a matching
+ ** wild card MX record, we will accept MX as well.
+ */
+
+ hp = (HEADER *) &answer;
+ ap = (u_char *) &answer + HEADERSZ;
+ eom = (u_char *) &answer + ret;
+
+ /* skip question part of response -- we know what we asked */
+ for (qdcount = ntohs(hp->qdcount); qdcount--; ap += ret + QFIXEDSZ)
+ {
+ if ((ret = dn_skipname(ap, eom)) < 0)
+ {
+ if (tTd(8, 20))
+ printf("qdcount failure (%d)\n",
+ ntohs(hp->qdcount));
+ return FALSE; /* ???XXX??? */
+ }
+ }
+
+ amatch = FALSE;
+ for (ancount = ntohs(hp->ancount); --ancount >= 0 && ap < eom; ap += n)
+ {
+ n = dn_expand((u_char *) &answer, eom, ap,
+ (u_char *) nbuf, sizeof nbuf);
+ if (n < 0)
+ break;
+ ap += n;
+ GETSHORT(type, ap);
+ ap += SHORTSIZE + LONGSIZE;
+ GETSHORT(n, ap);
+ switch (type)
+ {
+ case T_MX:
+ gotmx = TRUE;
+ if (**dp != '\0')
+ {
+ /* got a match -- save that info */
+ if (trymx && mxmatch == NULL)
+ mxmatch = *dp;
+ continue;
+ }
+
+ /* exact MX matches are as good as an A match */
+ /* fall through */
+
+ case T_A:
+ /* good show */
+ amatch = TRUE;
+
+ /* continue in case a CNAME also exists */
+ continue;
+
+ case T_CNAME:
+ if (loopcnt++ > MAXCNAMEDEPTH)
+ {
+ /*XXX should notify postmaster XXX*/
+ message("DNS failure: CNAME loop for %s",
+ host);
+ if (CurEnv->e_message == NULL)
+ {
+ char ebuf[MAXLINE];
+
+ sprintf(ebuf, "Deferred: DNS failure: CNAME loop for %s",
+ host);
+ CurEnv->e_message = newstr(ebuf);
+ }
+ h_errno = NO_RECOVERY;
+ return FALSE;
+ }
+
+ /* value points at name */
+ if ((ret = dn_expand((u_char *)&answer,
+ eom, ap, (u_char *)nbuf, sizeof(nbuf))) < 0)
+ break;
+ (void)strncpy(host, nbuf, hbsize); /* XXX */
+ host[hbsize - 1] = '\0';
+
+ /*
+ ** RFC 1034 section 3.6 specifies that CNAME
+ ** should point at the canonical name -- but
+ ** urges software to try again anyway.
+ */
+
+ goto cnameloop;
+
+ default:
+ /* not a record of interest */
+ continue;
+ }
+ }
+
+ if (amatch)
+ {
+ /* got an A record and no CNAME */
+ mxmatch = *dp;
+ break;
+ }
+
+ /*
+ ** If this was a T_ANY query, we may have the info but
+ ** need an explicit query. Try T_A, then T_MX.
+ */
+
+ if (qtype == T_ANY)
+ qtype = T_A;
+ else if (qtype == T_A && !gotmx && trymx)
+ qtype = T_MX;
+ else
+ {
+ /* really nothing in this domain; try the next */
+ qtype = T_ANY;
+ dp++;
+ }
+ }
+
+ if (mxmatch == NULL)
+ return FALSE;
+
+ /* create matching name and return */
+ (void) sprintf(nbuf, "%.*s%s%.*s", MAXDNAME, host,
+ *mxmatch == '\0' ? "" : ".",
+ MAXDNAME, mxmatch);
+ strncpy(host, nbuf, hbsize);
+ host[hbsize - 1] = '\0';
+ return TRUE;
+}
+
+
+char *
+gethostalias(host)
+ char *host;
+{
+ char *fname;
+ FILE *fp;
+ register char *p;
+ char buf[MAXLINE];
+ static char hbuf[MAXDNAME];
+
+ fname = getenv("HOSTALIASES");
+ if (fname == NULL || (fp = fopen(fname, "r")) == NULL)
+ return NULL;
+ while (fgets(buf, sizeof buf, fp) != NULL)
+ {
+ for (p = buf; p != '\0' && !(isascii(*p) && isspace(*p)); p++)
+ continue;
+ if (*p == 0)
+ {
+ /* syntax error */
+ continue;
+ }
+ *p++ = '\0';
+ if (strcasecmp(buf, host) == 0)
+ break;
+ }
+
+ if (feof(fp))
+ {
+ /* no match */
+ fclose(fp);
+ return NULL;
+ }
+
+ /* got a match; extract the equivalent name */
+ while (*p != '\0' && isascii(*p) && isspace(*p))
+ p++;
+ host = p;
+ while (*p != '\0' && !(isascii(*p) && isspace(*p)))
+ p++;
+ *p = '\0';
+ strncpy(hbuf, host, sizeof hbuf - 1);
+ hbuf[sizeof hbuf - 1] = '\0';
+ return hbuf;
+}
+
+
+#else /* not NAMED_BIND */
+
+#include <netdb.h>
+
+bool
+getcanonname(host, hbsize, trymx)
+ char *host;
+ int hbsize;
+ bool trymx;
+{
+ struct hostent *hp;
+
+ hp = gethostbyname(host);
+ if (hp == NULL)
+ return (FALSE);
+
+ if (strlen(hp->h_name) >= hbsize)
+ return (FALSE);
+
+ (void) strcpy(host, hp->h_name);
+ return (TRUE);
+}
+
+#endif /* not NAMED_BIND */
diff --git a/usr.sbin/sendmail/src/envelope.c b/usr.sbin/sendmail/src/envelope.c
new file mode 100644
index 0000000..3a2314c
--- /dev/null
+++ b/usr.sbin/sendmail/src/envelope.c
@@ -0,0 +1,777 @@
+/*
+ * Copyright (c) 1983 Eric P. Allman
+ * Copyright (c) 1988, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)envelope.c 8.34 (Berkeley) 4/14/94";
+#endif /* not lint */
+
+#include "sendmail.h"
+#include <pwd.h>
+
+/*
+** NEWENVELOPE -- allocate a new envelope
+**
+** Supports inheritance.
+**
+** Parameters:
+** e -- the new envelope to fill in.
+** parent -- the envelope to be the parent of e.
+**
+** Returns:
+** e.
+**
+** Side Effects:
+** none.
+*/
+
+ENVELOPE *
+newenvelope(e, parent)
+ register ENVELOPE *e;
+ register ENVELOPE *parent;
+{
+ extern putheader(), putbody();
+ extern ENVELOPE BlankEnvelope;
+
+ if (e == parent && e->e_parent != NULL)
+ parent = e->e_parent;
+ clearenvelope(e, TRUE);
+ if (e == CurEnv)
+ bcopy((char *) &NullAddress, (char *) &e->e_from, sizeof e->e_from);
+ else
+ bcopy((char *) &CurEnv->e_from, (char *) &e->e_from, sizeof e->e_from);
+ e->e_parent = parent;
+ e->e_ctime = curtime();
+ if (parent != NULL)
+ e->e_msgpriority = parent->e_msgsize;
+ e->e_puthdr = putheader;
+ e->e_putbody = putbody;
+ if (CurEnv->e_xfp != NULL)
+ (void) fflush(CurEnv->e_xfp);
+
+ return (e);
+}
+ /*
+** DROPENVELOPE -- deallocate an envelope.
+**
+** Parameters:
+** e -- the envelope to deallocate.
+**
+** Returns:
+** none.
+**
+** Side Effects:
+** housekeeping necessary to dispose of an envelope.
+** Unlocks this queue file.
+*/
+
+void
+dropenvelope(e)
+ register ENVELOPE *e;
+{
+ bool queueit = FALSE;
+ bool saveit = bitset(EF_FATALERRS, e->e_flags);
+ register ADDRESS *q;
+ char *id = e->e_id;
+ char buf[MAXLINE];
+
+ if (tTd(50, 1))
+ {
+ printf("dropenvelope %x: id=", e);
+ xputs(e->e_id);
+ printf(", flags=0x%x\n", e->e_flags);
+ if (tTd(50, 10))
+ {
+ printf("sendq=");
+ printaddr(e->e_sendqueue, TRUE);
+ }
+ }
+
+ /* we must have an id to remove disk files */
+ if (id == NULL)
+ return;
+
+#ifdef LOG
+ if (LogLevel > 4 && bitset(EF_LOGSENDER, e->e_flags))
+ logsender(e, NULL);
+ if (LogLevel > 84)
+ syslog(LOG_DEBUG, "dropenvelope, id=%s, flags=0x%x, pid=%d",
+ id, e->e_flags, getpid());
+#endif /* LOG */
+ e->e_flags &= ~EF_LOGSENDER;
+
+ /* post statistics */
+ poststats(StatFile);
+
+ /*
+ ** Extract state information from dregs of send list.
+ */
+
+ e->e_flags &= ~EF_QUEUERUN;
+ for (q = e->e_sendqueue; q != NULL; q = q->q_next)
+ {
+ if (bitset(QQUEUEUP, q->q_flags))
+ queueit = TRUE;
+ if (!bitset(QDONTSEND, q->q_flags) &&
+ bitset(QBADADDR, q->q_flags))
+ {
+ if (q->q_owner == NULL &&
+ strcmp(e->e_from.q_paddr, "<>") != 0)
+ (void) sendtolist(e->e_from.q_paddr, NULL,
+ &e->e_errorqueue, e);
+ }
+ }
+
+ /*
+ ** See if the message timed out.
+ */
+
+ if (!queueit)
+ /* nothing to do */ ;
+ else if (curtime() > e->e_ctime + TimeOuts.to_q_return)
+ {
+ (void) sprintf(buf, "Cannot send message for %s",
+ pintvl(TimeOuts.to_q_return, FALSE));
+ if (e->e_message != NULL)
+ free(e->e_message);
+ e->e_message = newstr(buf);
+ message(buf);
+ e->e_flags |= EF_CLRQUEUE;
+ saveit = TRUE;
+ fprintf(e->e_xfp, "Message could not be delivered for %s\n",
+ pintvl(TimeOuts.to_q_return, FALSE));
+ fprintf(e->e_xfp, "Message will be deleted from queue\n");
+ for (q = e->e_sendqueue; q != NULL; q = q->q_next)
+ {
+ if (bitset(QQUEUEUP, q->q_flags))
+ q->q_flags |= QBADADDR;
+ }
+ }
+ else if (TimeOuts.to_q_warning > 0 &&
+ curtime() > e->e_ctime + TimeOuts.to_q_warning)
+ {
+ if (!bitset(EF_WARNING|EF_RESPONSE, e->e_flags) &&
+ e->e_class >= 0 &&
+ strcmp(e->e_from.q_paddr, "<>") != 0)
+ {
+ (void) sprintf(buf,
+ "warning: cannot send message for %s",
+ pintvl(TimeOuts.to_q_warning, FALSE));
+ if (e->e_message != NULL)
+ free(e->e_message);
+ e->e_message = newstr(buf);
+ message(buf);
+ e->e_flags |= EF_WARNING;
+ saveit = TRUE;
+ }
+ fprintf(e->e_xfp,
+ "Warning: message still undelivered after %s\n",
+ pintvl(TimeOuts.to_q_warning, FALSE));
+ fprintf(e->e_xfp, "Will keep trying until message is %s old\n",
+ pintvl(TimeOuts.to_q_return, FALSE));
+ for (q = e->e_sendqueue; q != NULL; q = q->q_next)
+ {
+ if (bitset(QQUEUEUP, q->q_flags))
+ q->q_flags |= QREPORT;
+ }
+ }
+
+ /*
+ ** Send back return receipts as requested.
+ */
+
+ if (e->e_receiptto != NULL && bitset(EF_SENDRECEIPT, e->e_flags)
+ && !bitset(PRIV_NORECEIPTS, PrivacyFlags))
+ {
+ auto ADDRESS *rlist = NULL;
+
+ (void) sendtolist(e->e_receiptto, NULLADDR, &rlist, e);
+ (void) returntosender("Return receipt", rlist, FALSE, e);
+ e->e_flags &= ~EF_SENDRECEIPT;
+ }
+
+ /*
+ ** Arrange to send error messages if there are fatal errors.
+ */
+
+ if (saveit && e->e_errormode != EM_QUIET)
+ savemail(e);
+
+ /*
+ ** Arrange to send warning messages to postmaster as requested.
+ */
+
+ if (bitset(EF_PM_NOTIFY, e->e_flags) && PostMasterCopy != NULL &&
+ !bitset(EF_RESPONSE, e->e_flags) && e->e_class >= 0)
+ {
+ auto ADDRESS *rlist = NULL;
+
+ (void) sendtolist(PostMasterCopy, NULLADDR, &rlist, e);
+ (void) returntosender(e->e_message, rlist, FALSE, e);
+ }
+
+ /*
+ ** Instantiate or deinstantiate the queue.
+ */
+
+ if ((!queueit && !bitset(EF_KEEPQUEUE, e->e_flags)) ||
+ bitset(EF_CLRQUEUE, e->e_flags))
+ {
+ if (tTd(50, 1))
+ printf("\n===== Dropping [dq]f%s =====\n\n", e->e_id);
+ if (e->e_df != NULL)
+ xunlink(e->e_df);
+ xunlink(queuename(e, 'q'));
+
+#ifdef LOG
+ if (LogLevel > 10)
+ syslog(LOG_INFO, "%s: done", id);
+#endif
+ }
+ else if (queueit || !bitset(EF_INQUEUE, e->e_flags))
+ {
+#ifdef QUEUE
+ queueup(e, bitset(EF_KEEPQUEUE, e->e_flags), FALSE);
+#else /* QUEUE */
+ syserr("554 dropenvelope: queueup");
+#endif /* QUEUE */
+ }
+
+ /* now unlock the job */
+ closexscript(e);
+ unlockqueue(e);
+
+ /* make sure that this envelope is marked unused */
+ if (e->e_dfp != NULL)
+ (void) xfclose(e->e_dfp, "dropenvelope", e->e_df);
+ e->e_dfp = NULL;
+ e->e_id = e->e_df = NULL;
+}
+ /*
+** CLEARENVELOPE -- clear an envelope without unlocking
+**
+** This is normally used by a child process to get a clean
+** envelope without disturbing the parent.
+**
+** Parameters:
+** e -- the envelope to clear.
+** fullclear - if set, the current envelope is total
+** garbage and should be ignored; otherwise,
+** release any resources it may indicate.
+**
+** Returns:
+** none.
+**
+** Side Effects:
+** Closes files associated with the envelope.
+** Marks the envelope as unallocated.
+*/
+
+void
+clearenvelope(e, fullclear)
+ register ENVELOPE *e;
+ bool fullclear;
+{
+ register HDR *bh;
+ register HDR **nhp;
+ extern ENVELOPE BlankEnvelope;
+
+ if (!fullclear)
+ {
+ /* clear out any file information */
+ if (e->e_xfp != NULL)
+ (void) xfclose(e->e_xfp, "clearenvelope xfp", e->e_id);
+ if (e->e_dfp != NULL)
+ (void) xfclose(e->e_dfp, "clearenvelope dfp", e->e_df);
+ e->e_xfp = e->e_dfp = NULL;
+ }
+
+ /* now clear out the data */
+ STRUCTCOPY(BlankEnvelope, *e);
+ if (Verbose)
+ e->e_sendmode = SM_DELIVER;
+ bh = BlankEnvelope.e_header;
+ nhp = &e->e_header;
+ while (bh != NULL)
+ {
+ *nhp = (HDR *) xalloc(sizeof *bh);
+ bcopy((char *) bh, (char *) *nhp, sizeof *bh);
+ bh = bh->h_link;
+ nhp = &(*nhp)->h_link;
+ }
+}
+ /*
+** INITSYS -- initialize instantiation of system
+**
+** In Daemon mode, this is done in the child.
+**
+** Parameters:
+** none.
+**
+** Returns:
+** none.
+**
+** Side Effects:
+** Initializes the system macros, some global variables,
+** etc. In particular, the current time in various
+** forms is set.
+*/
+
+void
+initsys(e)
+ register ENVELOPE *e;
+{
+ char cbuf[5]; /* holds hop count */
+ char pbuf[10]; /* holds pid */
+#ifdef TTYNAME
+ static char ybuf[60]; /* holds tty id */
+ register char *p;
+#endif /* TTYNAME */
+ extern char *ttyname();
+ extern void settime();
+ extern char Version[];
+
+ /*
+ ** Give this envelope a reality.
+ ** I.e., an id, a transcript, and a creation time.
+ */
+
+ openxscript(e);
+ e->e_ctime = curtime();
+
+ /*
+ ** Set OutChannel to something useful if stdout isn't it.
+ ** This arranges that any extra stuff the mailer produces
+ ** gets sent back to the user on error (because it is
+ ** tucked away in the transcript).
+ */
+
+ if (OpMode == MD_DAEMON && bitset(EF_QUEUERUN, e->e_flags) &&
+ e->e_xfp != NULL)
+ OutChannel = e->e_xfp;
+
+ /*
+ ** Set up some basic system macros.
+ */
+
+ /* process id */
+ (void) sprintf(pbuf, "%d", getpid());
+ define('p', newstr(pbuf), e);
+
+ /* hop count */
+ (void) sprintf(cbuf, "%d", e->e_hopcount);
+ define('c', newstr(cbuf), e);
+
+ /* time as integer, unix time, arpa time */
+ settime(e);
+
+#ifdef TTYNAME
+ /* tty name */
+ if (macvalue('y', e) == NULL)
+ {
+ p = ttyname(2);
+ if (p != NULL)
+ {
+ if (strrchr(p, '/') != NULL)
+ p = strrchr(p, '/') + 1;
+ (void) strcpy(ybuf, p);
+ define('y', ybuf, e);
+ }
+ }
+#endif /* TTYNAME */
+}
+ /*
+** SETTIME -- set the current time.
+**
+** Parameters:
+** none.
+**
+** Returns:
+** none.
+**
+** Side Effects:
+** Sets the various time macros -- $a, $b, $d, $t.
+*/
+
+void
+settime(e)
+ register ENVELOPE *e;
+{
+ register char *p;
+ auto time_t now;
+ char tbuf[20]; /* holds "current" time */
+ char dbuf[30]; /* holds ctime(tbuf) */
+ register struct tm *tm;
+ extern char *arpadate();
+ extern struct tm *gmtime();
+
+ now = curtime();
+ tm = gmtime(&now);
+ (void) sprintf(tbuf, "%04d%02d%02d%02d%02d", tm->tm_year + 1900,
+ tm->tm_mon+1, tm->tm_mday, tm->tm_hour, tm->tm_min);
+ define('t', newstr(tbuf), e);
+ (void) strcpy(dbuf, ctime(&now));
+ p = strchr(dbuf, '\n');
+ if (p != NULL)
+ *p = '\0';
+ define('d', newstr(dbuf), e);
+ p = arpadate(dbuf);
+ p = newstr(p);
+ if (macvalue('a', e) == NULL)
+ define('a', p, e);
+ define('b', p, e);
+}
+ /*
+** OPENXSCRIPT -- Open transcript file
+**
+** Creates a transcript file for possible eventual mailing or
+** sending back.
+**
+** Parameters:
+** e -- the envelope to create the transcript in/for.
+**
+** Returns:
+** none
+**
+** Side Effects:
+** Creates the transcript file.
+*/
+
+#ifndef O_APPEND
+#define O_APPEND 0
+#endif
+
+void
+openxscript(e)
+ register ENVELOPE *e;
+{
+ register char *p;
+ int fd;
+
+ if (e->e_xfp != NULL)
+ return;
+ p = queuename(e, 'x');
+ fd = open(p, O_WRONLY|O_CREAT|O_APPEND, 0644);
+ if (fd < 0)
+ {
+ syserr("Can't create transcript file %s", p);
+ fd = open("/dev/null", O_WRONLY, 0644);
+ if (fd < 0)
+ syserr("!Can't open /dev/null");
+ }
+ e->e_xfp = fdopen(fd, "w");
+ if (e->e_xfp == NULL)
+ {
+ syserr("!Can't create transcript stream %s", p);
+ }
+ if (tTd(46, 9))
+ {
+ printf("openxscript(%s):\n ", p);
+ dumpfd(fileno(e->e_xfp), TRUE, FALSE);
+ }
+}
+ /*
+** CLOSEXSCRIPT -- close the transcript file.
+**
+** Parameters:
+** e -- the envelope containing the transcript to close.
+**
+** Returns:
+** none.
+**
+** Side Effects:
+** none.
+*/
+
+void
+closexscript(e)
+ register ENVELOPE *e;
+{
+ if (e->e_xfp == NULL)
+ return;
+ (void) xfclose(e->e_xfp, "closexscript", e->e_id);
+ e->e_xfp = NULL;
+}
+ /*
+** SETSENDER -- set the person who this message is from
+**
+** Under certain circumstances allow the user to say who
+** s/he is (using -f or -r). These are:
+** 1. The user's uid is zero (root).
+** 2. The user's login name is in an approved list (typically
+** from a network server).
+** 3. The address the user is trying to claim has a
+** "!" character in it (since #2 doesn't do it for
+** us if we are dialing out for UUCP).
+** A better check to replace #3 would be if the
+** effective uid is "UUCP" -- this would require me
+** to rewrite getpwent to "grab" uucp as it went by,
+** make getname more nasty, do another passwd file
+** scan, or compile the UID of "UUCP" into the code,
+** all of which are reprehensible.
+**
+** Assuming all of these fail, we figure out something
+** ourselves.
+**
+** Parameters:
+** from -- the person we would like to believe this message
+** is from, as specified on the command line.
+** e -- the envelope in which we would like the sender set.
+** delimptr -- if non-NULL, set to the location of the
+** trailing delimiter.
+** internal -- set if this address is coming from an internal
+** source such as an owner alias.
+**
+** Returns:
+** none.
+**
+** Side Effects:
+** sets sendmail's notion of who the from person is.
+*/
+
+void
+setsender(from, e, delimptr, internal)
+ char *from;
+ register ENVELOPE *e;
+ char **delimptr;
+ bool internal;
+{
+ register char **pvp;
+ char *realname = NULL;
+ register struct passwd *pw;
+ char delimchar;
+ char *bp;
+ char buf[MAXNAME + 2];
+ char pvpbuf[PSBUFSIZE];
+ extern struct passwd *getpwnam();
+ extern char *FullName;
+
+ if (tTd(45, 1))
+ printf("setsender(%s)\n", from == NULL ? "" : from);
+
+ /*
+ ** Figure out the real user executing us.
+ ** Username can return errno != 0 on non-errors.
+ */
+
+ if (bitset(EF_QUEUERUN, e->e_flags) || OpMode == MD_SMTP ||
+ OpMode == MD_ARPAFTP || OpMode == MD_DAEMON)
+ realname = from;
+ if (realname == NULL || realname[0] == '\0')
+ realname = username();
+
+ if (ConfigLevel < 2)
+ SuprErrs = TRUE;
+
+ delimchar = internal ? '\0' : ' ';
+ e->e_from.q_flags = QBADADDR;
+ if (from == NULL ||
+ parseaddr(from, &e->e_from, RF_COPYALL|RF_SENDERADDR,
+ delimchar, delimptr, e) == NULL ||
+ bitset(QBADADDR, e->e_from.q_flags) ||
+ e->e_from.q_mailer == ProgMailer ||
+ e->e_from.q_mailer == FileMailer ||
+ e->e_from.q_mailer == InclMailer)
+ {
+ /* log garbage addresses for traceback */
+# ifdef LOG
+ if (from != NULL && LogLevel > 2)
+ {
+ char *p;
+ char ebuf[MAXNAME * 2 + 2];
+
+ p = macvalue('_', e);
+ if (p == NULL)
+ {
+ char *host = RealHostName;
+ if (host == NULL)
+ host = MyHostName;
+ (void) sprintf(ebuf, "%s@%s", realname, host);
+ p = ebuf;
+ }
+ syslog(LOG_NOTICE,
+ "setsender: %s: invalid or unparseable, received from %s",
+ shortenstring(from, 83), p);
+ }
+# endif /* LOG */
+ if (from != NULL)
+ {
+ if (!bitset(QBADADDR, e->e_from.q_flags))
+ {
+ /* it was a bogus mailer in the from addr */
+ usrerr("553 Invalid sender address");
+ }
+ SuprErrs = TRUE;
+ }
+ if (from == realname ||
+ parseaddr(from = newstr(realname), &e->e_from,
+ RF_COPYALL|RF_SENDERADDR, ' ', NULL, e) == NULL)
+ {
+ char nbuf[100];
+
+ SuprErrs = TRUE;
+ expand("\201n", nbuf, &nbuf[sizeof nbuf], e);
+ if (parseaddr(from = newstr(nbuf), &e->e_from,
+ RF_COPYALL, ' ', NULL, e) == NULL &&
+ parseaddr(from = "postmaster", &e->e_from,
+ RF_COPYALL, ' ', NULL, e) == NULL)
+ syserr("553 setsender: can't even parse postmaster!");
+ }
+ }
+ else
+ FromFlag = TRUE;
+ e->e_from.q_flags |= QDONTSEND;
+ if (tTd(45, 5))
+ {
+ printf("setsender: QDONTSEND ");
+ printaddr(&e->e_from, FALSE);
+ }
+ SuprErrs = FALSE;
+
+ pvp = NULL;
+ if (e->e_from.q_mailer == LocalMailer)
+ {
+# ifdef USERDB
+ register char *p;
+ extern char *udbsender();
+# endif
+
+ if (!internal)
+ {
+ /* if the user has given fullname already, don't redefine */
+ if (FullName == NULL)
+ FullName = macvalue('x', e);
+ if (FullName != NULL && FullName[0] == '\0')
+ FullName = NULL;
+
+# ifdef USERDB
+ p = udbsender(e->e_from.q_user);
+
+ if (p != NULL)
+ {
+ /*
+ ** We have an alternate address for the sender
+ */
+
+ pvp = prescan(p, '\0', pvpbuf, sizeof pvpbuf, NULL);
+ }
+# endif /* USERDB */
+ }
+
+ if ((pw = getpwnam(e->e_from.q_user)) != NULL)
+ {
+ /*
+ ** Process passwd file entry.
+ */
+
+ /* extract home directory */
+ if (strcmp(pw->pw_dir, "/") == 0)
+ e->e_from.q_home = newstr("");
+ else
+ e->e_from.q_home = newstr(pw->pw_dir);
+ define('z', e->e_from.q_home, e);
+
+ /* extract user and group id */
+ e->e_from.q_uid = pw->pw_uid;
+ e->e_from.q_gid = pw->pw_gid;
+ e->e_from.q_flags |= QGOODUID;
+
+ /* extract full name from passwd file */
+ if (FullName == NULL && pw->pw_gecos != NULL &&
+ strcmp(pw->pw_name, e->e_from.q_user) == 0 &&
+ !internal)
+ {
+ buildfname(pw->pw_gecos, e->e_from.q_user, buf);
+ if (buf[0] != '\0')
+ FullName = newstr(buf);
+ }
+ }
+ if (FullName != NULL && !internal)
+ define('x', FullName, e);
+ }
+ else if (!internal && OpMode != MD_DAEMON)
+ {
+ if (e->e_from.q_home == NULL)
+ {
+ e->e_from.q_home = getenv("HOME");
+ if (e->e_from.q_home != NULL &&
+ strcmp(e->e_from.q_home, "/") == 0)
+ e->e_from.q_home++;
+ }
+ e->e_from.q_uid = RealUid;
+ e->e_from.q_gid = RealGid;
+ e->e_from.q_flags |= QGOODUID;
+ }
+
+ /*
+ ** Rewrite the from person to dispose of possible implicit
+ ** links in the net.
+ */
+
+ if (pvp == NULL)
+ pvp = prescan(from, delimchar, pvpbuf, sizeof pvpbuf, NULL);
+ if (pvp == NULL)
+ {
+ /* don't need to give error -- prescan did that already */
+# ifdef LOG
+ if (LogLevel > 2)
+ syslog(LOG_NOTICE, "cannot prescan from (%s)", from);
+# endif
+ finis();
+ }
+ (void) rewrite(pvp, 3, 0, e);
+ (void) rewrite(pvp, 1, 0, e);
+ (void) rewrite(pvp, 4, 0, e);
+ bp = buf + 1;
+ cataddr(pvp, NULL, bp, sizeof buf - 2, '\0');
+ if (*bp == '@')
+ {
+ /* heuristic: route-addr: add angle brackets */
+ strcat(bp, ">");
+ *--bp = '<';
+ }
+ e->e_sender = newstr(bp);
+ define('f', e->e_sender, e);
+
+ /* save the domain spec if this mailer wants it */
+ if (e->e_from.q_mailer != NULL &&
+ bitnset(M_CANONICAL, e->e_from.q_mailer->m_flags))
+ {
+ extern char **copyplist();
+
+ while (*pvp != NULL && strcmp(*pvp, "@") != 0)
+ pvp++;
+ if (*pvp != NULL)
+ e->e_fromdomain = copyplist(pvp, TRUE);
+ }
+}
diff --git a/usr.sbin/sendmail/src/err.c b/usr.sbin/sendmail/src/err.c
new file mode 100644
index 0000000..c6a87e9
--- /dev/null
+++ b/usr.sbin/sendmail/src/err.c
@@ -0,0 +1,561 @@
+/*
+ * Copyright (c) 1983 Eric P. Allman
+ * Copyright (c) 1988, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)err.c 8.27 (Berkeley) 4/18/94";
+#endif /* not lint */
+
+# include "sendmail.h"
+# include <errno.h>
+# include <netdb.h>
+# include <pwd.h>
+
+/*
+** SYSERR -- Print error message.
+**
+** Prints an error message via printf to the diagnostic
+** output. If LOG is defined, it logs it also.
+**
+** If the first character of the syserr message is `!' it will
+** log this as an ALERT message and exit immediately. This can
+** leave queue files in an indeterminate state, so it should not
+** be used lightly.
+**
+** Parameters:
+** f -- the format string
+** a, b, c, d, e -- parameters
+**
+** Returns:
+** none
+** Through TopFrame if QuickAbort is set.
+**
+** Side Effects:
+** increments Errors.
+** sets ExitStat.
+*/
+
+char MsgBuf[BUFSIZ*2]; /* text of most recent message */
+
+static void fmtmsg();
+
+#if NAMED_BIND && !defined(NO_DATA)
+# define NO_DATA NO_ADDRESS
+#endif
+
+void
+/*VARARGS1*/
+#ifdef __STDC__
+syserr(const char *fmt, ...)
+#else
+syserr(fmt, va_alist)
+ const char *fmt;
+ va_dcl
+#endif
+{
+ register char *p;
+ int olderrno = errno;
+ bool panic;
+#ifdef LOG
+ char *uname;
+ struct passwd *pw;
+ char ubuf[80];
+#endif
+ VA_LOCAL_DECL
+
+ panic = *fmt == '!';
+ if (panic)
+ fmt++;
+
+ /* format and output the error message */
+ if (olderrno == 0)
+ p = "554";
+ else
+ p = "451";
+ VA_START(fmt);
+ fmtmsg(MsgBuf, (char *) NULL, p, olderrno, fmt, ap);
+ VA_END;
+ puterrmsg(MsgBuf);
+
+ /* determine exit status if not already set */
+ if (ExitStat == EX_OK)
+ {
+ if (olderrno == 0)
+ ExitStat = EX_SOFTWARE;
+ else
+ ExitStat = EX_OSERR;
+ if (tTd(54, 1))
+ printf("syserr: ExitStat = %d\n", ExitStat);
+ }
+
+# ifdef LOG
+ pw = getpwuid(getuid());
+ if (pw != NULL)
+ uname = pw->pw_name;
+ else
+ {
+ uname = ubuf;
+ sprintf(ubuf, "UID%d", getuid());
+ }
+
+ if (LogLevel > 0)
+ syslog(panic ? LOG_ALERT : LOG_CRIT, "%s: SYSERR(%s): %s",
+ CurEnv->e_id == NULL ? "NOQUEUE" : CurEnv->e_id,
+ uname, &MsgBuf[4]);
+# endif /* LOG */
+ if (olderrno == EMFILE)
+ {
+ printopenfds(TRUE);
+ mci_dump_all(TRUE);
+ }
+ if (panic)
+ {
+#ifdef XLA
+ xla_all_end();
+#endif
+ exit(EX_OSERR);
+ }
+ errno = 0;
+ if (QuickAbort)
+ longjmp(TopFrame, 2);
+}
+ /*
+** USRERR -- Signal user error.
+**
+** This is much like syserr except it is for user errors.
+**
+** Parameters:
+** fmt, a, b, c, d -- printf strings
+**
+** Returns:
+** none
+** Through TopFrame if QuickAbort is set.
+**
+** Side Effects:
+** increments Errors.
+*/
+
+/*VARARGS1*/
+void
+#ifdef __STDC__
+usrerr(const char *fmt, ...)
+#else
+usrerr(fmt, va_alist)
+ const char *fmt;
+ va_dcl
+#endif
+{
+ VA_LOCAL_DECL
+
+ if (SuprErrs)
+ return;
+
+ VA_START(fmt);
+ fmtmsg(MsgBuf, CurEnv->e_to, "501", 0, fmt, ap);
+ VA_END;
+ puterrmsg(MsgBuf);
+
+# ifdef LOG
+ if (LogLevel > 3 && LogUsrErrs)
+ syslog(LOG_NOTICE, "%s: %s",
+ CurEnv->e_id == NULL ? "NOQUEUE" : CurEnv->e_id,
+ &MsgBuf[4]);
+# endif /* LOG */
+
+ if (QuickAbort)
+ longjmp(TopFrame, 1);
+}
+ /*
+** MESSAGE -- print message (not necessarily an error)
+**
+** Parameters:
+** msg -- the message (printf fmt) -- it can begin with
+** an SMTP reply code. If not, 050 is assumed.
+** a, b, c, d, e -- printf arguments
+**
+** Returns:
+** none
+**
+** Side Effects:
+** none.
+*/
+
+/*VARARGS2*/
+void
+#ifdef __STDC__
+message(const char *msg, ...)
+#else
+message(msg, va_alist)
+ const char *msg;
+ va_dcl
+#endif
+{
+ VA_LOCAL_DECL
+
+ errno = 0;
+ VA_START(msg);
+ fmtmsg(MsgBuf, CurEnv->e_to, "050", 0, msg, ap);
+ VA_END;
+ putoutmsg(MsgBuf, FALSE);
+}
+ /*
+** NMESSAGE -- print message (not necessarily an error)
+**
+** Just like "message" except it never puts the to... tag on.
+**
+** Parameters:
+** num -- the default ARPANET error number (in ascii)
+** msg -- the message (printf fmt) -- if it begins
+** with three digits, this number overrides num.
+** a, b, c, d, e -- printf arguments
+**
+** Returns:
+** none
+**
+** Side Effects:
+** none.
+*/
+
+/*VARARGS2*/
+void
+#ifdef __STDC__
+nmessage(const char *msg, ...)
+#else
+nmessage(msg, va_alist)
+ const char *msg;
+ va_dcl
+#endif
+{
+ VA_LOCAL_DECL
+
+ errno = 0;
+ VA_START(msg);
+ fmtmsg(MsgBuf, (char *) NULL, "050", 0, msg, ap);
+ VA_END;
+ putoutmsg(MsgBuf, FALSE);
+}
+ /*
+** PUTOUTMSG -- output error message to transcript and channel
+**
+** Parameters:
+** msg -- message to output (in SMTP format).
+** holdmsg -- if TRUE, don't output a copy of the message to
+** our output channel.
+**
+** Returns:
+** none.
+**
+** Side Effects:
+** Outputs msg to the transcript.
+** If appropriate, outputs it to the channel.
+** Deletes SMTP reply code number as appropriate.
+*/
+
+putoutmsg(msg, holdmsg)
+ char *msg;
+ bool holdmsg;
+{
+ /* display for debugging */
+ if (tTd(54, 8))
+ printf("--- %s%s\n", msg, holdmsg ? " (held)" : "");
+
+ /* output to transcript if serious */
+ if (CurEnv->e_xfp != NULL && strchr("456", msg[0]) != NULL)
+ fprintf(CurEnv->e_xfp, "%s\n", msg);
+
+ /* output to channel if appropriate */
+ if (holdmsg || (!Verbose && msg[0] == '0'))
+ return;
+
+ /* map warnings to something SMTP can handle */
+ if (msg[0] == '6')
+ msg[0] = '5';
+
+ (void) fflush(stdout);
+
+ /* if DisConnected, OutChannel now points to the transcript */
+ if (!DisConnected &&
+ (OpMode == MD_SMTP || OpMode == MD_DAEMON || OpMode == MD_ARPAFTP))
+ fprintf(OutChannel, "%s\r\n", msg);
+ else
+ fprintf(OutChannel, "%s\n", &msg[4]);
+ if (TrafficLogFile != NULL)
+ fprintf(TrafficLogFile, "%05d >>> %s\n", getpid(),
+ (OpMode == MD_SMTP || OpMode == MD_DAEMON) ? msg : &msg[4]);
+ if (msg[3] == ' ')
+ (void) fflush(OutChannel);
+ if (!ferror(OutChannel) || DisConnected)
+ return;
+
+ /*
+ ** Error on output -- if reporting lost channel, just ignore it.
+ ** Also, ignore errors from QUIT response (221 message) -- some
+ ** rude servers don't read result.
+ */
+
+ if (feof(InChannel) || ferror(InChannel) || strncmp(msg, "221", 3) == 0)
+ return;
+
+ /* can't call syserr, 'cause we are using MsgBuf */
+ HoldErrs = TRUE;
+#ifdef LOG
+ if (LogLevel > 0)
+ syslog(LOG_CRIT,
+ "%s: SYSERR: putoutmsg (%s): error on output channel sending \"%s\": %s",
+ CurEnv->e_id == NULL ? "NOQUEUE" : CurEnv->e_id,
+ CurHostName == NULL ? "NO-HOST" : CurHostName,
+ msg, errstring(errno));
+#endif
+}
+ /*
+** PUTERRMSG -- like putoutmsg, but does special processing for error messages
+**
+** Parameters:
+** msg -- the message to output.
+**
+** Returns:
+** none.
+**
+** Side Effects:
+** Sets the fatal error bit in the envelope as appropriate.
+*/
+
+puterrmsg(msg)
+ char *msg;
+{
+ char msgcode = msg[0];
+
+ /* output the message as usual */
+ putoutmsg(msg, HoldErrs);
+
+ /* signal the error */
+ Errors++;
+ if (msgcode == '6')
+ {
+ /* notify the postmaster */
+ CurEnv->e_flags |= EF_PM_NOTIFY;
+ }
+ else if (msgcode == '5' && bitset(EF_GLOBALERRS, CurEnv->e_flags))
+ {
+ /* mark long-term fatal errors */
+ CurEnv->e_flags |= EF_FATALERRS;
+ }
+}
+ /*
+** FMTMSG -- format a message into buffer.
+**
+** Parameters:
+** eb -- error buffer to get result.
+** to -- the recipient tag for this message.
+** num -- arpanet error number.
+** en -- the error number to display.
+** fmt -- format of string.
+** a, b, c, d, e -- arguments.
+**
+** Returns:
+** none.
+**
+** Side Effects:
+** none.
+*/
+
+static void
+fmtmsg(eb, to, num, eno, fmt, ap)
+ register char *eb;
+ char *to;
+ char *num;
+ int eno;
+ char *fmt;
+ va_list ap;
+{
+ char del;
+ char *meb;
+
+ /* output the reply code */
+ if (isdigit(fmt[0]) && isdigit(fmt[1]) && isdigit(fmt[2]))
+ {
+ num = fmt;
+ fmt += 4;
+ }
+ if (num[3] == '-')
+ del = '-';
+ else
+ del = ' ';
+ (void) sprintf(eb, "%3.3s%c", num, del);
+ eb += 4;
+
+ /* output the file name and line number */
+ if (FileName != NULL)
+ {
+ (void) sprintf(eb, "%s: line %d: ", FileName, LineNumber);
+ eb += strlen(eb);
+ }
+
+ /* output the "to" person */
+ if (to != NULL && to[0] != '\0')
+ {
+ (void) sprintf(eb, "%s... ", shortenstring(to, 203));
+ while (*eb != '\0')
+ *eb++ &= 0177;
+ }
+
+ meb = eb;
+
+ /* output the message */
+ (void) vsprintf(eb, fmt, ap);
+ while (*eb != '\0')
+ *eb++ &= 0177;
+
+ /* output the error code, if any */
+ if (eno != 0)
+ {
+ (void) sprintf(eb, ": %s", errstring(eno));
+ eb += strlen(eb);
+ }
+
+ if (num[0] == '5' || (CurEnv->e_message == NULL && num[0] == '4'))
+ {
+ if (CurEnv->e_message != NULL)
+ free(CurEnv->e_message);
+ CurEnv->e_message = newstr(meb);
+ }
+}
+ /*
+** ERRSTRING -- return string description of error code
+**
+** Parameters:
+** errnum -- the error number to translate
+**
+** Returns:
+** A string description of errnum.
+**
+** Side Effects:
+** none.
+*/
+
+const char *
+errstring(errnum)
+ int errnum;
+{
+ char *dnsmsg;
+ static char buf[MAXLINE];
+# ifndef ERRLIST_PREDEFINED
+ extern char *sys_errlist[];
+ extern int sys_nerr;
+# endif
+# ifdef SMTP
+ extern char *SmtpPhase;
+# endif /* SMTP */
+
+ /*
+ ** Handle special network error codes.
+ **
+ ** These are 4.2/4.3bsd specific; they should be in daemon.c.
+ */
+
+ dnsmsg = NULL;
+ switch (errnum)
+ {
+# if defined(DAEMON) && defined(ETIMEDOUT)
+ case ETIMEDOUT:
+ case ECONNRESET:
+ (void) strcpy(buf, sys_errlist[errnum]);
+ if (SmtpPhase != NULL)
+ {
+ (void) strcat(buf, " during ");
+ (void) strcat(buf, SmtpPhase);
+ }
+ if (CurHostName != NULL)
+ {
+ (void) strcat(buf, " with ");
+ (void) strcat(buf, CurHostName);
+ }
+ return (buf);
+
+ case EHOSTDOWN:
+ if (CurHostName == NULL)
+ break;
+ (void) sprintf(buf, "Host %s is down", CurHostName);
+ return (buf);
+
+ case ECONNREFUSED:
+ if (CurHostName == NULL)
+ break;
+ (void) sprintf(buf, "Connection refused by %s", CurHostName);
+ return (buf);
+# endif
+
+ case EOPENTIMEOUT:
+ return "Timeout on file open";
+
+# if NAMED_BIND
+ case HOST_NOT_FOUND + E_DNSBASE:
+ dnsmsg = "host not found";
+ break;
+
+ case TRY_AGAIN + E_DNSBASE:
+ dnsmsg = "host name lookup failure";
+ break;
+
+ case NO_RECOVERY + E_DNSBASE:
+ dnsmsg = "non-recoverable error";
+ break;
+
+ case NO_DATA + E_DNSBASE:
+ dnsmsg = "no data known";
+ break;
+# endif
+
+ case EPERM:
+ /* SunOS gives "Not owner" -- this is the POSIX message */
+ return "Operation not permitted";
+ }
+
+ if (dnsmsg != NULL)
+ {
+ (void) strcpy(buf, "Name server: ");
+ if (CurHostName != NULL)
+ {
+ (void) strcat(buf, CurHostName);
+ (void) strcat(buf, ": ");
+ }
+ (void) strcat(buf, dnsmsg);
+ return buf;
+ }
+
+ if (errnum > 0 && errnum < sys_nerr)
+ return (sys_errlist[errnum]);
+
+ (void) sprintf(buf, "Error %d", errnum);
+ return (buf);
+}
diff --git a/usr.sbin/sendmail/src/headers.c b/usr.sbin/sendmail/src/headers.c
new file mode 100644
index 0000000..8493e79c
--- /dev/null
+++ b/usr.sbin/sendmail/src/headers.c
@@ -0,0 +1,1192 @@
+/*
+ * Copyright (c) 1983 Eric P. Allman
+ * Copyright (c) 1988, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)headers.c 8.32 (Berkeley) 4/14/94";
+#endif /* not lint */
+
+# include <errno.h>
+# include "sendmail.h"
+
+/*
+** CHOMPHEADER -- process and save a header line.
+**
+** Called by collect and by readcf to deal with header lines.
+**
+** Parameters:
+** line -- header as a text line.
+** def -- if set, this is a default value.
+** e -- the envelope including this header.
+**
+** Returns:
+** flags for this header.
+**
+** Side Effects:
+** The header is saved on the header list.
+** Contents of 'line' are destroyed.
+*/
+
+chompheader(line, def, e)
+ char *line;
+ bool def;
+ register ENVELOPE *e;
+{
+ register char *p;
+ register HDR *h;
+ HDR **hp;
+ char *fname;
+ char *fvalue;
+ struct hdrinfo *hi;
+ bool cond = FALSE;
+ BITMAP mopts;
+ char buf[MAXNAME];
+
+ if (tTd(31, 6))
+ printf("chompheader: %s\n", line);
+
+ /* strip off options */
+ clrbitmap(mopts);
+ p = line;
+ if (*p == '?')
+ {
+ /* have some */
+ register char *q = strchr(p + 1, *p);
+
+ if (q != NULL)
+ {
+ *q++ = '\0';
+ while (*++p != '\0')
+ setbitn(*p, mopts);
+ p = q;
+ }
+ else
+ usrerr("553 header syntax error, line \"%s\"", line);
+ cond = TRUE;
+ }
+
+ /* find canonical name */
+ fname = p;
+ while (isascii(*p) && isgraph(*p) && *p != ':')
+ p++;
+ fvalue = p;
+ while (isascii(*p) && isspace(*p))
+ p++;
+ if (*p++ != ':' || fname == fvalue)
+ {
+ syserr("553 header syntax error, line \"%s\"", line);
+ return (0);
+ }
+ *fvalue = '\0';
+ fvalue = p;
+
+ /* strip field value on front */
+ if (*fvalue == ' ')
+ fvalue++;
+
+ /* see if it is a known type */
+ for (hi = HdrInfo; hi->hi_field != NULL; hi++)
+ {
+ if (strcasecmp(hi->hi_field, fname) == 0)
+ break;
+ }
+
+ if (tTd(31, 9))
+ {
+ if (hi->hi_field == NULL)
+ printf("no header match\n");
+ else
+ printf("header match, hi_flags=%o\n", hi->hi_flags);
+ }
+
+ /* see if this is a resent message */
+ if (!def && bitset(H_RESENT, hi->hi_flags))
+ e->e_flags |= EF_RESENT;
+
+ /* if this means "end of header" quit now */
+ if (bitset(H_EOH, hi->hi_flags))
+ return (hi->hi_flags);
+
+ /*
+ ** Drop explicit From: if same as what we would generate.
+ ** This is to make MH (which doesn't always give a full name)
+ ** insert the full name information in all circumstances.
+ */
+
+ p = "resent-from";
+ if (!bitset(EF_RESENT, e->e_flags))
+ p += 7;
+ if (!def && !bitset(EF_QUEUERUN, e->e_flags) && strcasecmp(fname, p) == 0)
+ {
+ if (tTd(31, 2))
+ {
+ printf("comparing header from (%s) against default (%s or %s)\n",
+ fvalue, e->e_from.q_paddr, e->e_from.q_user);
+ }
+ if (e->e_from.q_paddr != NULL &&
+ (strcmp(fvalue, e->e_from.q_paddr) == 0 ||
+ strcmp(fvalue, e->e_from.q_user) == 0))
+ return (hi->hi_flags);
+#ifdef MAYBENEXTRELEASE /* XXX UNTESTED XXX UNTESTED XXX UNTESTED XXX */
+#ifdef USERDB
+ else
+ {
+ auto ADDRESS a;
+ char *fancy;
+ bool oldSuprErrs = SuprErrs;
+ extern char *crackaddr();
+ extern char *udbsender();
+
+ /*
+ ** Try doing USERDB rewriting even on fully commented
+ ** names; this saves the "comment" information (such
+ ** as full name) and rewrites the electronic part.
+ **
+ ** XXX This code doesn't belong here -- parsing should
+ ** XXX not be done during collect() phase because
+ ** XXX error messages can confuse the SMTP phase.
+ ** XXX Setting SuprErrs is a crude hack around this
+ ** XXX problem.
+ */
+
+ if (OpMode == MD_SMTP || OpMode == MD_ARPAFTP)
+ SuprErrs = TRUE;
+ fancy = crackaddr(fvalue);
+ if (parseaddr(fvalue, &a, RF_COPYNONE, '\0', NULL, e) != NULL &&
+ a.q_mailer == LocalMailer &&
+ (p = udbsender(a.q_user)) != NULL)
+ {
+ char *oldg = macvalue('g', e);
+
+ define('g', p, e);
+ expand(fancy, buf, &buf[sizeof buf], e);
+ define('g', oldg, e);
+ fvalue = buf;
+ }
+ SuprErrs = oldSuprErrs;
+ }
+#endif
+#endif
+ }
+
+ /* delete default value for this header */
+ for (hp = &e->e_header; (h = *hp) != NULL; hp = &h->h_link)
+ {
+ if (strcasecmp(fname, h->h_field) == 0 &&
+ bitset(H_DEFAULT, h->h_flags) &&
+ !bitset(H_FORCE, h->h_flags))
+ h->h_value = NULL;
+ }
+
+ /* create a new node */
+ h = (HDR *) xalloc(sizeof *h);
+ h->h_field = newstr(fname);
+ h->h_value = newstr(fvalue);
+ h->h_link = NULL;
+ bcopy((char *) mopts, (char *) h->h_mflags, sizeof mopts);
+ *hp = h;
+ h->h_flags = hi->hi_flags;
+ if (def)
+ h->h_flags |= H_DEFAULT;
+ if (cond)
+ h->h_flags |= H_CHECK;
+
+ /* hack to see if this is a new format message */
+ if (!def && bitset(H_RCPT|H_FROM, h->h_flags) &&
+ (strchr(fvalue, ',') != NULL || strchr(fvalue, '(') != NULL ||
+ strchr(fvalue, '<') != NULL || strchr(fvalue, ';') != NULL))
+ {
+ e->e_flags &= ~EF_OLDSTYLE;
+ }
+
+ return (h->h_flags);
+}
+ /*
+** ADDHEADER -- add a header entry to the end of the queue.
+**
+** This bypasses the special checking of chompheader.
+**
+** Parameters:
+** field -- the name of the header field.
+** value -- the value of the field.
+** e -- the envelope to add them to.
+**
+** Returns:
+** none.
+**
+** Side Effects:
+** adds the field on the list of headers for this envelope.
+*/
+
+addheader(field, value, e)
+ char *field;
+ char *value;
+ ENVELOPE *e;
+{
+ register HDR *h;
+ register struct hdrinfo *hi;
+ HDR **hp;
+
+ /* find info struct */
+ for (hi = HdrInfo; hi->hi_field != NULL; hi++)
+ {
+ if (strcasecmp(field, hi->hi_field) == 0)
+ break;
+ }
+
+ /* find current place in list -- keep back pointer? */
+ for (hp = &e->e_header; (h = *hp) != NULL; hp = &h->h_link)
+ {
+ if (strcasecmp(field, h->h_field) == 0)
+ break;
+ }
+
+ /* allocate space for new header */
+ h = (HDR *) xalloc(sizeof *h);
+ h->h_field = field;
+ h->h_value = newstr(value);
+ h->h_link = *hp;
+ h->h_flags = hi->hi_flags | H_DEFAULT;
+ clrbitmap(h->h_mflags);
+ *hp = h;
+}
+ /*
+** HVALUE -- return value of a header.
+**
+** Only "real" fields (i.e., ones that have not been supplied
+** as a default) are used.
+**
+** Parameters:
+** field -- the field name.
+** e -- the envelope containing the header.
+**
+** Returns:
+** pointer to the value part.
+** NULL if not found.
+**
+** Side Effects:
+** none.
+*/
+
+char *
+hvalue(field, e)
+ char *field;
+ register ENVELOPE *e;
+{
+ register HDR *h;
+
+ for (h = e->e_header; h != NULL; h = h->h_link)
+ {
+ if (!bitset(H_DEFAULT, h->h_flags) &&
+ strcasecmp(h->h_field, field) == 0)
+ return (h->h_value);
+ }
+ return (NULL);
+}
+ /*
+** ISHEADER -- predicate telling if argument is a header.
+**
+** A line is a header if it has a single word followed by
+** optional white space followed by a colon.
+**
+** Parameters:
+** s -- string to check for possible headerness.
+**
+** Returns:
+** TRUE if s is a header.
+** FALSE otherwise.
+**
+** Side Effects:
+** none.
+*/
+
+bool
+isheader(s)
+ register char *s;
+{
+ while (*s > ' ' && *s != ':' && *s != '\0')
+ s++;
+
+ /* following technically violates RFC822 */
+ while (isascii(*s) && isspace(*s))
+ s++;
+
+ return (*s == ':');
+}
+ /*
+** EATHEADER -- run through the stored header and extract info.
+**
+** Parameters:
+** e -- the envelope to process.
+** full -- if set, do full processing (e.g., compute
+** message priority).
+**
+** Returns:
+** none.
+**
+** Side Effects:
+** Sets a bunch of global variables from information
+** in the collected header.
+** Aborts the message if the hop count is exceeded.
+*/
+
+eatheader(e, full)
+ register ENVELOPE *e;
+ bool full;
+{
+ register HDR *h;
+ register char *p;
+ int hopcnt = 0;
+ char *msgid;
+ char buf[MAXLINE];
+
+ /*
+ ** Set up macros for possible expansion in headers.
+ */
+
+ define('f', e->e_sender, e);
+ define('g', e->e_sender, e);
+ if (e->e_origrcpt != NULL && *e->e_origrcpt != '\0')
+ define('u', e->e_origrcpt, e);
+ else
+ define('u', NULL, e);
+
+ /* full name of from person */
+ p = hvalue("full-name", e);
+ if (p != NULL)
+ define('x', p, e);
+
+ if (tTd(32, 1))
+ printf("----- collected header -----\n");
+ msgid = "<none>";
+ for (h = e->e_header; h != NULL; h = h->h_link)
+ {
+ if (h->h_value == NULL)
+ {
+ if (tTd(32, 1))
+ printf("%s: <NULL>\n", h->h_field);
+ continue;
+ }
+
+ /* do early binding */
+ if (bitset(H_DEFAULT, h->h_flags))
+ {
+ expand(h->h_value, buf, &buf[sizeof buf], e);
+ if (buf[0] != '\0')
+ {
+ h->h_value = newstr(buf);
+ h->h_flags &= ~H_DEFAULT;
+ }
+ }
+
+ if (tTd(32, 1))
+ {
+ printf("%s: ", h->h_field);
+ xputs(h->h_value);
+ printf("\n");
+ }
+
+ /* count the number of times it has been processed */
+ if (bitset(H_TRACE, h->h_flags))
+ hopcnt++;
+
+ /* send to this person if we so desire */
+ if (GrabTo && bitset(H_RCPT, h->h_flags) &&
+ !bitset(H_DEFAULT, h->h_flags) &&
+ (!bitset(EF_RESENT, e->e_flags) || bitset(H_RESENT, h->h_flags)))
+ {
+ int saveflags = e->e_flags;
+
+ (void) sendtolist(h->h_value, NULLADDR,
+ &e->e_sendqueue, e);
+
+ /* delete fatal errors generated by this address */
+ if (!GrabTo && !bitset(EF_FATALERRS, saveflags))
+ e->e_flags &= ~EF_FATALERRS;
+ }
+
+ /* save the message-id for logging */
+ if (full && strcasecmp(h->h_field, "message-id") == 0)
+ {
+ msgid = h->h_value;
+ while (isascii(*msgid) && isspace(*msgid))
+ msgid++;
+ }
+
+ /* see if this is a return-receipt header */
+ if (bitset(H_RECEIPTTO, h->h_flags))
+ e->e_receiptto = h->h_value;
+
+ /* see if this is an errors-to header */
+ if (UseErrorsTo && bitset(H_ERRORSTO, h->h_flags))
+ (void) sendtolist(h->h_value, NULLADDR,
+ &e->e_errorqueue, e);
+ }
+ if (tTd(32, 1))
+ printf("----------------------------\n");
+
+ /* if we are just verifying (that is, sendmail -t -bv), drop out now */
+ if (OpMode == MD_VERIFY)
+ return;
+
+ /* store hop count */
+ if (hopcnt > e->e_hopcount)
+ e->e_hopcount = hopcnt;
+
+ /* message priority */
+ p = hvalue("precedence", e);
+ if (p != NULL)
+ e->e_class = priencode(p);
+ if (full)
+ e->e_msgpriority = e->e_msgsize
+ - e->e_class * WkClassFact
+ + e->e_nrcpts * WkRecipFact;
+
+ /* date message originated */
+ p = hvalue("posted-date", e);
+ if (p == NULL)
+ p = hvalue("date", e);
+ if (p != NULL)
+ define('a', p, e);
+
+ /*
+ ** From person in antiquated ARPANET mode
+ ** required by UK Grey Book e-mail gateways (sigh)
+ */
+
+ if (OpMode == MD_ARPAFTP)
+ {
+ register struct hdrinfo *hi;
+
+ for (hi = HdrInfo; hi->hi_field != NULL; hi++)
+ {
+ if (bitset(H_FROM, hi->hi_flags) &&
+ (!bitset(H_RESENT, hi->hi_flags) ||
+ bitset(EF_RESENT, e->e_flags)) &&
+ (p = hvalue(hi->hi_field, e)) != NULL)
+ break;
+ }
+ if (hi->hi_field != NULL)
+ {
+ if (tTd(32, 2))
+ printf("eatheader: setsender(*%s == %s)\n",
+ hi->hi_field, p);
+ setsender(p, e, NULL, TRUE);
+ }
+ }
+
+ /*
+ ** Log collection information.
+ */
+
+# ifdef LOG
+ if (full && LogLevel > 4)
+ logsender(e, msgid);
+# endif /* LOG */
+ e->e_flags &= ~EF_LOGSENDER;
+}
+ /*
+** LOGSENDER -- log sender information
+**
+** Parameters:
+** e -- the envelope to log
+** msgid -- the message id
+**
+** Returns:
+** none
+*/
+
+logsender(e, msgid)
+ register ENVELOPE *e;
+ char *msgid;
+{
+# ifdef LOG
+ char *name;
+ register char *sbp;
+ register char *p;
+ char hbuf[MAXNAME];
+ char sbuf[MAXLINE];
+
+ if (bitset(EF_RESPONSE, e->e_flags))
+ name = "[RESPONSE]";
+ else if ((name = macvalue('_', e)) != NULL)
+ ;
+ else if (RealHostName == NULL)
+ name = "localhost";
+ else if (RealHostName[0] == '[')
+ name = RealHostName;
+ else
+ {
+ name = hbuf;
+ (void) sprintf(hbuf, "%.80s", RealHostName);
+ if (RealHostAddr.sa.sa_family != 0)
+ {
+ p = &hbuf[strlen(hbuf)];
+ (void) sprintf(p, " (%s)",
+ anynet_ntoa(&RealHostAddr));
+ }
+ }
+
+ /* some versions of syslog only take 5 printf args */
+# if (SYSLOG_BUFSIZE) >= 256
+ sbp = sbuf;
+ sprintf(sbp, "from=%.200s, size=%ld, class=%d, pri=%ld, nrcpts=%d",
+ e->e_from.q_paddr, e->e_msgsize, e->e_class,
+ e->e_msgpriority, e->e_nrcpts);
+ sbp += strlen(sbp);
+ if (msgid != NULL)
+ {
+ sprintf(sbp, ", msgid=%.100s", msgid);
+ sbp += strlen(sbp);
+ }
+ if (e->e_bodytype != NULL)
+ {
+ (void) sprintf(sbp, ", bodytype=%.20s", e->e_bodytype);
+ sbp += strlen(sbp);
+ }
+ p = macvalue('r', e);
+ if (p != NULL)
+ (void) sprintf(sbp, ", proto=%.20s", p);
+ syslog(LOG_INFO, "%s: %s, relay=%s",
+ e->e_id, sbuf, name);
+
+# else /* short syslog buffer */
+
+ syslog(LOG_INFO, "%s: from=%s",
+ e->e_id, shortenstring(e->e_from.q_paddr, 83));
+ syslog(LOG_INFO, "%s: size=%ld, class=%ld, pri=%ld, nrcpts=%d",
+ e->e_id, e->e_msgsize, e->e_class,
+ e->e_msgpriority, e->e_nrcpts);
+ if (msgid != NULL)
+ syslog(LOG_INFO, "%s: msgid=%s", e->e_id, msgid);
+ sbp = sbuf;
+ sprintf(sbp, "%s:", e->e_id);
+ sbp += strlen(sbp);
+ if (e->e_bodytype != NULL)
+ {
+ sprintf(sbp, " bodytype=%s,", e->e_bodytype);
+ sbp += strlen(sbp);
+ }
+ p = macvalue('r', e);
+ if (p != NULL)
+ {
+ sprintf(sbp, " proto=%s,", p);
+ sbp += strlen(sbp);
+ }
+ syslog(LOG_INFO, "%s relay=%s", sbuf, name);
+# endif
+# endif
+}
+ /*
+** PRIENCODE -- encode external priority names into internal values.
+**
+** Parameters:
+** p -- priority in ascii.
+**
+** Returns:
+** priority as a numeric level.
+**
+** Side Effects:
+** none.
+*/
+
+priencode(p)
+ char *p;
+{
+ register int i;
+
+ for (i = 0; i < NumPriorities; i++)
+ {
+ if (!strcasecmp(p, Priorities[i].pri_name))
+ return (Priorities[i].pri_val);
+ }
+
+ /* unknown priority */
+ return (0);
+}
+ /*
+** CRACKADDR -- parse an address and turn it into a macro
+**
+** This doesn't actually parse the address -- it just extracts
+** it and replaces it with "$g". The parse is totally ad hoc
+** and isn't even guaranteed to leave something syntactically
+** identical to what it started with. However, it does leave
+** something semantically identical.
+**
+** This algorithm has been cleaned up to handle a wider range
+** of cases -- notably quoted and backslash escaped strings.
+** This modification makes it substantially better at preserving
+** the original syntax.
+**
+** Parameters:
+** addr -- the address to be cracked.
+**
+** Returns:
+** a pointer to the new version.
+**
+** Side Effects:
+** none.
+**
+** Warning:
+** The return value is saved in local storage and should
+** be copied if it is to be reused.
+*/
+
+char *
+crackaddr(addr)
+ register char *addr;
+{
+ register char *p;
+ register char c;
+ int cmtlev;
+ int realcmtlev;
+ int anglelev, realanglelev;
+ int copylev;
+ bool qmode;
+ bool realqmode;
+ bool skipping;
+ bool putgmac = FALSE;
+ bool quoteit = FALSE;
+ bool gotangle = FALSE;
+ register char *bp;
+ char *buflim;
+ static char buf[MAXNAME];
+
+ if (tTd(33, 1))
+ printf("crackaddr(%s)\n", addr);
+
+ /* strip leading spaces */
+ while (*addr != '\0' && isascii(*addr) && isspace(*addr))
+ addr++;
+
+ /*
+ ** Start by assuming we have no angle brackets. This will be
+ ** adjusted later if we find them.
+ */
+
+ bp = buf;
+ buflim = &buf[sizeof buf - 5];
+ p = addr;
+ copylev = anglelev = realanglelev = cmtlev = realcmtlev = 0;
+ qmode = realqmode = FALSE;
+
+ while ((c = *p++) != '\0')
+ {
+ /*
+ ** If the buffer is overful, go into a special "skipping"
+ ** mode that tries to keep legal syntax but doesn't actually
+ ** output things.
+ */
+
+ skipping = bp >= buflim;
+
+ if (copylev > 0 && !skipping)
+ *bp++ = c;
+
+ /* check for backslash escapes */
+ if (c == '\\')
+ {
+ /* arrange to quote the address */
+ if (cmtlev <= 0 && !qmode)
+ quoteit = TRUE;
+
+ if ((c = *p++) == '\0')
+ {
+ /* too far */
+ p--;
+ goto putg;
+ }
+ if (copylev > 0 && !skipping)
+ *bp++ = c;
+ goto putg;
+ }
+
+ /* check for quoted strings */
+ if (c == '"' && cmtlev <= 0)
+ {
+ qmode = !qmode;
+ if (copylev > 0 && !skipping)
+ realqmode = !realqmode;
+ continue;
+ }
+ if (qmode)
+ goto putg;
+
+ /* check for comments */
+ if (c == '(')
+ {
+ cmtlev++;
+
+ /* allow space for closing paren */
+ if (!skipping)
+ {
+ buflim--;
+ realcmtlev++;
+ if (copylev++ <= 0)
+ {
+ *bp++ = ' ';
+ *bp++ = c;
+ }
+ }
+ }
+ if (cmtlev > 0)
+ {
+ if (c == ')')
+ {
+ cmtlev--;
+ copylev--;
+ if (!skipping)
+ {
+ realcmtlev--;
+ buflim++;
+ }
+ }
+ continue;
+ }
+ else if (c == ')')
+ {
+ /* syntax error: unmatched ) */
+ if (copylev > 0 && !skipping)
+ bp--;
+ }
+
+ /* check for characters that may have to be quoted */
+ if (strchr(".'@,;:\\()[]", c) != NULL)
+ {
+ /*
+ ** If these occur as the phrase part of a <>
+ ** construct, but are not inside of () or already
+ ** quoted, they will have to be quoted. Note that
+ ** now (but don't actually do the quoting).
+ */
+
+ if (cmtlev <= 0 && !qmode)
+ quoteit = TRUE;
+ }
+
+ /* check for angle brackets */
+ if (c == '<')
+ {
+ register char *q;
+
+ /* assume first of two angles is bogus */
+ if (gotangle)
+ quoteit = TRUE;
+ gotangle = TRUE;
+
+ /* oops -- have to change our mind */
+ anglelev = 1;
+ if (!skipping)
+ realanglelev = 1;
+
+ bp = buf;
+ if (quoteit)
+ {
+ *bp++ = '"';
+
+ /* back up over the '<' and any spaces */
+ --p;
+ while (isascii(*--p) && isspace(*p))
+ continue;
+ p++;
+ }
+ for (q = addr; q < p; )
+ {
+ c = *q++;
+ if (bp < buflim)
+ {
+ if (quoteit && c == '"')
+ *bp++ = '\\';
+ *bp++ = c;
+ }
+ }
+ if (quoteit)
+ {
+ if (bp == &buf[1])
+ bp--;
+ else
+ *bp++ = '"';
+ while ((c = *p++) != '<')
+ {
+ if (bp < buflim)
+ *bp++ = c;
+ }
+ *bp++ = c;
+ }
+ copylev = 0;
+ putgmac = quoteit = FALSE;
+ continue;
+ }
+
+ if (c == '>')
+ {
+ if (anglelev > 0)
+ {
+ anglelev--;
+ if (!skipping)
+ {
+ realanglelev--;
+ buflim++;
+ }
+ }
+ else if (!skipping)
+ {
+ /* syntax error: unmatched > */
+ if (copylev > 0)
+ bp--;
+ quoteit = TRUE;
+ continue;
+ }
+ if (copylev++ <= 0)
+ *bp++ = c;
+ continue;
+ }
+
+ /* must be a real address character */
+ putg:
+ if (copylev <= 0 && !putgmac)
+ {
+ *bp++ = MACROEXPAND;
+ *bp++ = 'g';
+ putgmac = TRUE;
+ }
+ }
+
+ /* repair any syntactic damage */
+ if (realqmode)
+ *bp++ = '"';
+ while (realcmtlev-- > 0)
+ *bp++ = ')';
+ while (realanglelev-- > 0)
+ *bp++ = '>';
+ *bp++ = '\0';
+
+ if (tTd(33, 1))
+ printf("crackaddr=>`%s'\n", buf);
+
+ return (buf);
+}
+ /*
+** PUTHEADER -- put the header part of a message from the in-core copy
+**
+** Parameters:
+** mci -- the connection information.
+** e -- envelope to use.
+**
+** Returns:
+** none.
+**
+** Side Effects:
+** none.
+*/
+
+/*
+ * Macro for fast max (not available in e.g. DG/UX, 386/ix).
+ */
+#ifndef MAX
+# define MAX(a,b) (((a)>(b))?(a):(b))
+#endif
+
+putheader(mci, e)
+ register MCI *mci;
+ register ENVELOPE *e;
+{
+ char buf[MAX(MAXLINE,BUFSIZ)];
+ register HDR *h;
+ char obuf[MAXLINE];
+
+ if (tTd(34, 1))
+ printf("--- putheader, mailer = %s ---\n",
+ mci->mci_mailer->m_name);
+
+ for (h = e->e_header; h != NULL; h = h->h_link)
+ {
+ register char *p;
+ extern bool bitintersect();
+
+ if (tTd(34, 11))
+ {
+ printf(" %s: ", h->h_field);
+ xputs(h->h_value);
+ }
+
+ if (bitset(H_CHECK|H_ACHECK, h->h_flags) &&
+ !bitintersect(h->h_mflags, mci->mci_mailer->m_flags))
+ {
+ if (tTd(34, 11))
+ printf(" (skipped)\n");
+ continue;
+ }
+
+ /* handle Resent-... headers specially */
+ if (bitset(H_RESENT, h->h_flags) && !bitset(EF_RESENT, e->e_flags))
+ {
+ if (tTd(34, 11))
+ printf(" (skipped (resent))\n");
+ continue;
+ }
+
+ /* suppress return receipts if requested */
+ if (bitset(H_RECEIPTTO, h->h_flags) &&
+ bitset(EF_NORECEIPT, e->e_flags))
+ {
+ if (tTd(34, 11))
+ printf(" (skipped (receipt))\n");
+ continue;
+ }
+
+ /* macro expand value if generated internally */
+ p = h->h_value;
+ if (bitset(H_DEFAULT, h->h_flags))
+ {
+ expand(p, buf, &buf[sizeof buf], e);
+ p = buf;
+ if (p == NULL || *p == '\0')
+ {
+ if (tTd(34, 11))
+ printf(" (skipped -- null value)\n");
+ continue;
+ }
+ }
+
+ if (tTd(34, 11))
+ printf("\n");
+
+ if (bitset(H_FROM|H_RCPT, h->h_flags))
+ {
+ /* address field */
+ bool oldstyle = bitset(EF_OLDSTYLE, e->e_flags);
+
+ if (bitset(H_FROM, h->h_flags))
+ oldstyle = FALSE;
+ commaize(h, p, oldstyle, mci, e);
+ }
+ else
+ {
+ /* vanilla header line */
+ register char *nlp;
+
+ (void) sprintf(obuf, "%s: ", h->h_field);
+ while ((nlp = strchr(p, '\n')) != NULL)
+ {
+ *nlp = '\0';
+ (void) strcat(obuf, p);
+ *nlp = '\n';
+ putline(obuf, mci);
+ p = ++nlp;
+ obuf[0] = '\0';
+ }
+ (void) strcat(obuf, p);
+ putline(obuf, mci);
+ }
+ }
+}
+ /*
+** COMMAIZE -- output a header field, making a comma-translated list.
+**
+** Parameters:
+** h -- the header field to output.
+** p -- the value to put in it.
+** oldstyle -- TRUE if this is an old style header.
+** mci -- the connection information.
+** e -- the envelope containing the message.
+**
+** Returns:
+** none.
+**
+** Side Effects:
+** outputs "p" to file "fp".
+*/
+
+void
+commaize(h, p, oldstyle, mci, e)
+ register HDR *h;
+ register char *p;
+ bool oldstyle;
+ register MCI *mci;
+ register ENVELOPE *e;
+{
+ register char *obp;
+ int opos;
+ int omax;
+ bool firstone = TRUE;
+ char obuf[MAXLINE + 3];
+
+ /*
+ ** Output the address list translated by the
+ ** mailer and with commas.
+ */
+
+ if (tTd(14, 2))
+ printf("commaize(%s: %s)\n", h->h_field, p);
+
+ obp = obuf;
+ (void) sprintf(obp, "%s: ", h->h_field);
+ opos = strlen(h->h_field) + 2;
+ obp += opos;
+ omax = mci->mci_mailer->m_linelimit - 2;
+ if (omax < 0 || omax > 78)
+ omax = 78;
+
+ /*
+ ** Run through the list of values.
+ */
+
+ while (*p != '\0')
+ {
+ register char *name;
+ register int c;
+ char savechar;
+ int flags;
+ auto int stat;
+
+ /*
+ ** Find the end of the name. New style names
+ ** end with a comma, old style names end with
+ ** a space character. However, spaces do not
+ ** necessarily delimit an old-style name -- at
+ ** signs mean keep going.
+ */
+
+ /* find end of name */
+ while ((isascii(*p) && isspace(*p)) || *p == ',')
+ p++;
+ name = p;
+ for (;;)
+ {
+ auto char *oldp;
+ char pvpbuf[PSBUFSIZE];
+
+ (void) prescan(p, oldstyle ? ' ' : ',', pvpbuf,
+ sizeof pvpbuf, &oldp);
+ p = oldp;
+
+ /* look to see if we have an at sign */
+ while (*p != '\0' && isascii(*p) && isspace(*p))
+ p++;
+
+ if (*p != '@')
+ {
+ p = oldp;
+ break;
+ }
+ p += *p == '@' ? 1 : 2;
+ while (*p != '\0' && isascii(*p) && isspace(*p))
+ p++;
+ }
+ /* at the end of one complete name */
+
+ /* strip off trailing white space */
+ while (p >= name &&
+ ((isascii(*p) && isspace(*p)) || *p == ',' || *p == '\0'))
+ p--;
+ if (++p == name)
+ continue;
+ savechar = *p;
+ *p = '\0';
+
+ /* translate the name to be relative */
+ flags = RF_HEADERADDR|RF_ADDDOMAIN;
+ if (bitset(H_FROM, h->h_flags))
+ flags |= RF_SENDERADDR;
+ stat = EX_OK;
+ name = remotename(name, mci->mci_mailer, flags, &stat, e);
+ if (*name == '\0')
+ {
+ *p = savechar;
+ continue;
+ }
+
+ /* output the name with nice formatting */
+ opos += strlen(name);
+ if (!firstone)
+ opos += 2;
+ if (opos > omax && !firstone)
+ {
+ (void) strcpy(obp, ",\n");
+ putline(obuf, mci);
+ obp = obuf;
+ (void) strcpy(obp, " ");
+ opos = strlen(obp);
+ obp += opos;
+ opos += strlen(name);
+ }
+ else if (!firstone)
+ {
+ (void) strcpy(obp, ", ");
+ obp += 2;
+ }
+
+ while ((c = *name++) != '\0' && obp < &obuf[MAXLINE])
+ *obp++ = c;
+ firstone = FALSE;
+ *p = savechar;
+ }
+ (void) strcpy(obp, "\n");
+ putline(obuf, mci);
+}
+ /*
+** COPYHEADER -- copy header list
+**
+** This routine is the equivalent of newstr for header lists
+**
+** Parameters:
+** header -- list of header structures to copy.
+**
+** Returns:
+** a copy of 'header'.
+**
+** Side Effects:
+** none.
+*/
+
+HDR *
+copyheader(header)
+ register HDR *header;
+{
+ register HDR *newhdr;
+ HDR *ret;
+ register HDR **tail = &ret;
+
+ while (header != NULL)
+ {
+ newhdr = (HDR *) xalloc(sizeof(HDR));
+ STRUCTCOPY(*header, *newhdr);
+ *tail = newhdr;
+ tail = &newhdr->h_link;
+ header = header->h_link;
+ }
+ *tail = NULL;
+
+ return ret;
+}
diff --git a/usr.sbin/sendmail/src/macro.c b/usr.sbin/sendmail/src/macro.c
new file mode 100644
index 0000000..8a8a90b
--- /dev/null
+++ b/usr.sbin/sendmail/src/macro.c
@@ -0,0 +1,279 @@
+/*
+ * Copyright (c) 1983 Eric P. Allman
+ * Copyright (c) 1988, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)macro.c 8.3 (Berkeley) 2/7/94";
+#endif /* not lint */
+
+# include "sendmail.h"
+
+/*
+** EXPAND -- macro expand a string using $x escapes.
+**
+** Parameters:
+** s -- the string to expand.
+** buf -- the place to put the expansion.
+** buflim -- the buffer limit, i.e., the address
+** of the last usable position in buf.
+** e -- envelope in which to work.
+**
+** Returns:
+** none.
+**
+** Side Effects:
+** none.
+*/
+
+void
+expand(s, buf, buflim, e)
+ register char *s;
+ register char *buf;
+ char *buflim;
+ register ENVELOPE *e;
+{
+ register char *xp;
+ register char *q;
+ bool skipping; /* set if conditionally skipping output */
+ bool recurse = FALSE; /* set if recursion required */
+ int i;
+ int iflev; /* if nesting level */
+ char xbuf[BUFSIZ];
+
+ if (tTd(35, 24))
+ {
+ printf("expand(");
+ xputs(s);
+ printf(")\n");
+ }
+
+ skipping = FALSE;
+ iflev = 0;
+ if (s == NULL)
+ s = "";
+ for (xp = xbuf; *s != '\0'; s++)
+ {
+ int c;
+
+ /*
+ ** Check for non-ordinary (special?) character.
+ ** 'q' will be the interpolated quantity.
+ */
+
+ q = NULL;
+ c = *s;
+ switch (c & 0377)
+ {
+ case CONDIF: /* see if var set */
+ c = *++s;
+ if (skipping)
+ iflev++;
+ else
+ skipping = macvalue(c, e) == NULL;
+ continue;
+
+ case CONDELSE: /* change state of skipping */
+ if (iflev == 0)
+ skipping = !skipping;
+ continue;
+
+ case CONDFI: /* stop skipping */
+ if (iflev == 0)
+ skipping = FALSE;
+ if (skipping)
+ iflev--;
+ continue;
+
+ case MACROEXPAND: /* macro interpolation */
+ c = *++s & 0177;
+ if (c != '\0')
+ q = macvalue(c, e);
+ else
+ {
+ s--;
+ q = NULL;
+ }
+ if (q == NULL)
+ continue;
+ break;
+ }
+
+ /*
+ ** Interpolate q or output one character
+ */
+
+ if (skipping || xp >= &xbuf[sizeof xbuf])
+ continue;
+ if (q == NULL)
+ *xp++ = c;
+ else
+ {
+ /* copy to end of q or max space remaining in buf */
+ while ((c = *q++) != '\0' && xp < &xbuf[sizeof xbuf - 1])
+ {
+ /* check for any sendmail metacharacters */
+ if ((c & 0340) == 0200)
+ recurse = TRUE;
+ *xp++ = c;
+ }
+ }
+ }
+ *xp = '\0';
+
+ if (tTd(35, 24))
+ {
+ printf("expand ==> ");
+ xputs(xbuf);
+ printf("\n");
+ }
+
+ /* recurse as appropriate */
+ if (recurse)
+ {
+ expand(xbuf, buf, buflim, e);
+ return;
+ }
+
+ /* copy results out */
+ i = buflim - buf - 1;
+ if (i > xp - xbuf)
+ i = xp - xbuf;
+ bcopy(xbuf, buf, i);
+ buf[i] = '\0';
+}
+ /*
+** DEFINE -- define a macro.
+**
+** this would be better done using a #define macro.
+**
+** Parameters:
+** n -- the macro name.
+** v -- the macro value.
+** e -- the envelope to store the definition in.
+**
+** Returns:
+** none.
+**
+** Side Effects:
+** e->e_macro[n] is defined.
+**
+** Notes:
+** There is one macro for each ASCII character,
+** although they are not all used. The currently
+** defined macros are:
+**
+** $a date in ARPANET format (preferring the Date: line
+** of the message)
+** $b the current date (as opposed to the date as found
+** the message) in ARPANET format
+** $c hop count
+** $d (current) date in UNIX (ctime) format
+** $e the SMTP entry message+
+** $f raw from address
+** $g translated from address
+** $h to host
+** $i queue id
+** $j official SMTP hostname, used in messages+
+** $k UUCP node name
+** $l UNIX-style from line+
+** $m The domain part of our full name.
+** $n name of sendmail ("MAILER-DAEMON" on local
+** net typically)+
+** $o delimiters ("operators") for address tokens+
+** $p my process id in decimal
+** $q the string that becomes an address -- this is
+** normally used to combine $g & $x.
+** $r protocol used to talk to sender
+** $s sender's host name
+** $t the current time in seconds since 1/1/1970
+** $u to user
+** $v version number of sendmail
+** $w our host name (if it can be determined)
+** $x signature (full name) of from person
+** $y the tty id of our terminal
+** $z home directory of to person
+** $_ RFC1413 authenticated sender address
+**
+** Macros marked with + must be defined in the
+** configuration file and are used internally, but
+** are not set.
+**
+** There are also some macros that can be used
+** arbitrarily to make the configuration file
+** cleaner. In general all upper-case letters
+** are available.
+*/
+
+void
+define(n, v, e)
+ int n;
+ char *v;
+ register ENVELOPE *e;
+{
+ if (tTd(35, 9))
+ {
+ printf("define(%c as ", n);
+ xputs(v);
+ printf(")\n");
+ }
+ e->e_macro[n & 0177] = v;
+}
+ /*
+** MACVALUE -- return uninterpreted value of a macro.
+**
+** Parameters:
+** n -- the name of the macro.
+**
+** Returns:
+** The value of n.
+**
+** Side Effects:
+** none.
+*/
+
+char *
+macvalue(n, e)
+ int n;
+ register ENVELOPE *e;
+{
+ n &= 0177;
+ while (e != NULL)
+ {
+ register char *p = e->e_macro[n];
+
+ if (p != NULL)
+ return (p);
+ e = e->e_parent;
+ }
+ return (NULL);
+}
diff --git a/usr.sbin/sendmail/src/mailq.1 b/usr.sbin/sendmail/src/mailq.1
new file mode 100644
index 0000000..f7b9da4
--- /dev/null
+++ b/usr.sbin/sendmail/src/mailq.1
@@ -0,0 +1,88 @@
+.\" Copyright (c) 1985, 1990, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)mailq.1 8.4 (Berkeley) 2/22/94
+.\"
+.Dd February 22, 1994
+.Dt MAILQ 1
+.Os BSD 4
+.Sh NAME
+.Nm mailq
+.Nd print the mail queue
+.Sh SYNOPSIS
+.Nm mailq
+.Op Fl v
+.Sh DESCRIPTION
+.Nm Mailq
+prints a summary of the mail messages queued for future delivery.
+.Pp
+The first line printed for each message
+shows the internal identifier used on this host
+for the message,
+the size of the message in bytes,
+the date and time the message was accepted into the queue,
+and the envelope sender of the message.
+The second line shows the error message that caused this message
+to be retained in the queue;
+it will not be present if the message is being processed
+for the first time.
+The following lines show message recipients,
+one per line.
+.Pp
+.Nm Mailq
+is identical to
+.Dq Li "sendmail -bp" .
+.Pp
+The options are as follows:
+.Bl -tag -width Ds
+.It Fl v
+Print verbose information.
+This adds the priority of the message and
+a single character indicator (``+'' or blank)
+indicating whether a warning message has been sent
+on the first line of the message.
+Additionally, extra lines may be intermixed with the recipients
+indicating the ``controlling user'' information;
+this shows who will own any programs that are executed
+on behalf of this message
+and the name of the alias this command expanded from, if any.
+.El
+.Pp
+The
+.Nm mailq
+utility exits 0 on success, and >0 if an error occurs.
+.Sh SEE ALSO
+.Xr sendmail 8
+.Sh HISTORY
+The
+.Nm mailq
+command appeared in
+.Bx 4.0 .
diff --git a/usr.sbin/sendmail/src/mailstats.h b/usr.sbin/sendmail/src/mailstats.h
new file mode 100644
index 0000000..0164d91
--- /dev/null
+++ b/usr.sbin/sendmail/src/mailstats.h
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 1983 Eric P. Allman
+ * Copyright (c) 1988, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)mailstats.h 8.1 (Berkeley) 6/7/93
+ */
+
+/*
+** Statistics structure.
+*/
+
+struct statistics
+{
+ time_t stat_itime; /* file initialization time */
+ short stat_size; /* size of this structure */
+ long stat_nf[MAXMAILERS]; /* # msgs from each mailer */
+ long stat_bf[MAXMAILERS]; /* kbytes from each mailer */
+ long stat_nt[MAXMAILERS]; /* # msgs to each mailer */
+ long stat_bt[MAXMAILERS]; /* kbytes to each mailer */
+};
diff --git a/usr.sbin/sendmail/src/main.c b/usr.sbin/sendmail/src/main.c
new file mode 100644
index 0000000..e2af9df
--- /dev/null
+++ b/usr.sbin/sendmail/src/main.c
@@ -0,0 +1,1479 @@
+/*
+ * Copyright (c) 1983 Eric P. Allman
+ * Copyright (c) 1988, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char copyright[] =
+"@(#) Copyright (c) 1988, 1993\n\
+ The Regents of the University of California. All rights reserved.\n";
+#endif /* not lint */
+
+#ifndef lint
+static char sccsid[] = "@(#)main.c 8.55 (Berkeley) 4/15/94";
+#endif /* not lint */
+
+#define _DEFINE
+
+#include "sendmail.h"
+#if NAMED_BIND
+#include <arpa/nameser.h>
+#include <resolv.h>
+#endif
+#include <pwd.h>
+
+# ifdef lint
+char edata, end;
+# endif /* lint */
+
+/*
+** SENDMAIL -- Post mail to a set of destinations.
+**
+** This is the basic mail router. All user mail programs should
+** call this routine to actually deliver mail. Sendmail in
+** turn calls a bunch of mail servers that do the real work of
+** delivering the mail.
+**
+** Sendmail is driven by tables read in from /usr/lib/sendmail.cf
+** (read by readcf.c). Some more static configuration info,
+** including some code that you may want to tailor for your
+** installation, is in conf.c. You may also want to touch
+** daemon.c (if you have some other IPC mechanism), acct.c
+** (to change your accounting), names.c (to adjust the name
+** server mechanism).
+**
+** Usage:
+** /usr/lib/sendmail [flags] addr ...
+**
+** See the associated documentation for details.
+**
+** Author:
+** Eric Allman, UCB/INGRES (until 10/81)
+** Britton-Lee, Inc., purveyors of fine
+** database computers (from 11/81)
+** Now back at UCB at the Mammoth project.
+** The support of the INGRES Project and Britton-Lee is
+** gratefully acknowledged. Britton-Lee in
+** particular had absolutely nothing to gain from
+** my involvement in this project.
+*/
+
+
+int NextMailer; /* "free" index into Mailer struct */
+char *FullName; /* sender's full name */
+ENVELOPE BlankEnvelope; /* a "blank" envelope */
+ENVELOPE MainEnvelope; /* the envelope around the basic letter */
+ADDRESS NullAddress = /* a null address */
+ { "", "", NULL, "" };
+char *UserEnviron[MAXUSERENVIRON + 2];
+ /* saved user environment */
+char RealUserName[256]; /* the actual user id on this host */
+char *CommandLineArgs; /* command line args for pid file */
+bool Warn_Q_option = FALSE; /* warn about Q option use */
+
+/*
+** Pointers for setproctitle.
+** This allows "ps" listings to give more useful information.
+*/
+
+# ifdef SETPROCTITLE
+char **Argv = NULL; /* pointer to argument vector */
+char *LastArgv = NULL; /* end of argv */
+# endif /* SETPROCTITLE */
+
+static void obsolete();
+
+#ifdef DAEMON
+#ifndef SMTP
+ERROR %%%% Cannot have daemon mode without SMTP %%%% ERROR
+#endif /* SMTP */
+#endif /* DAEMON */
+
+#define MAXCONFIGLEVEL 5 /* highest config version level known */
+
+main(argc, argv, envp)
+ int argc;
+ char **argv;
+ char **envp;
+{
+ register char *p;
+ char **av;
+ extern int finis();
+ extern char Version[];
+ char *ep, *from;
+ typedef int (*fnptr)();
+ STAB *st;
+ register int i;
+ int j;
+ bool queuemode = FALSE; /* process queue requests */
+ bool safecf = TRUE;
+ bool warn_C_flag = FALSE;
+ char warn_f_flag = '\0';
+ static bool reenter = FALSE;
+ char *argv0 = argv[0];
+ struct passwd *pw;
+ struct stat stb;
+ char jbuf[MAXHOSTNAMELEN]; /* holds MyHostName */
+ extern int DtableSize;
+ extern int optind;
+ extern time_t convtime();
+ extern putheader(), putbody();
+ extern void intsig();
+ extern char **myhostname();
+ extern char *arpadate();
+ extern char *getauthinfo();
+ extern char *getcfname();
+ extern char *optarg;
+ extern char **environ;
+ extern void sigusr1();
+
+ /*
+ ** Check to see if we reentered.
+ ** This would normally happen if e_putheader or e_putbody
+ ** were NULL when invoked.
+ */
+
+ if (reenter)
+ {
+ syserr("main: reentered!");
+ abort();
+ }
+ reenter = TRUE;
+
+ /* do machine-dependent initializations */
+ init_md(argc, argv);
+
+ /* arrange to dump state on signal */
+#ifdef SIGUSR1
+ setsignal(SIGUSR1, sigusr1);
+#endif
+
+ /* in 4.4BSD, the table can be huge; impose a reasonable limit */
+ DtableSize = getdtsize();
+ if (DtableSize > 256)
+ DtableSize = 256;
+
+ /*
+ ** Be sure we have enough file descriptors.
+ ** But also be sure that 0, 1, & 2 are open.
+ */
+
+ i = open("/dev/null", O_RDWR, 0);
+ if (fstat(STDIN_FILENO, &stb) < 0 && errno != EOPNOTSUPP)
+ (void) dup2(i, STDIN_FILENO);
+ if (fstat(STDOUT_FILENO, &stb) < 0 && errno != EOPNOTSUPP)
+ (void) dup2(i, STDOUT_FILENO);
+ if (fstat(STDERR_FILENO, &stb) < 0 && errno != EOPNOTSUPP)
+ (void) dup2(i, STDERR_FILENO);
+ if (i != STDIN_FILENO && i != STDOUT_FILENO && i != STDERR_FILENO)
+ (void) close(i);
+
+ i = DtableSize;
+ while (--i > 0)
+ {
+ if (i != STDIN_FILENO && i != STDOUT_FILENO && i != STDERR_FILENO)
+ (void) close(i);
+ }
+ errno = 0;
+
+#ifdef LOG
+# ifdef LOG_MAIL
+ openlog("sendmail", LOG_PID, LOG_MAIL);
+# else
+ openlog("sendmail", LOG_PID);
+# endif
+#endif
+
+ /* set up the blank envelope */
+ BlankEnvelope.e_puthdr = putheader;
+ BlankEnvelope.e_putbody = putbody;
+ BlankEnvelope.e_xfp = NULL;
+ STRUCTCOPY(NullAddress, BlankEnvelope.e_from);
+ CurEnv = &BlankEnvelope;
+ STRUCTCOPY(NullAddress, MainEnvelope.e_from);
+
+ /*
+ ** Set default values for variables.
+ ** These cannot be in initialized data space.
+ */
+
+ setdefaults(&BlankEnvelope);
+
+ RealUid = getuid();
+ RealGid = getgid();
+
+ pw = getpwuid(RealUid);
+ if (pw != NULL)
+ (void) strcpy(RealUserName, pw->pw_name);
+ else
+ (void) sprintf(RealUserName, "Unknown UID %d", RealUid);
+
+ /* save command line arguments */
+ i = 0;
+ for (av = argv; *av != NULL; )
+ i += strlen(*av++) + 1;
+ CommandLineArgs = xalloc(i);
+ p = CommandLineArgs;
+ for (av = argv; *av != NULL; )
+ {
+ if (av != argv)
+ *p++ = ' ';
+ strcpy(p, *av++);
+ p += strlen(p);
+ }
+
+ /* Handle any non-getoptable constructions. */
+ obsolete(argv);
+
+ /*
+ ** Do a quick prescan of the argument list.
+ */
+
+#if defined(__osf__) || defined(_AIX3)
+# define OPTIONS "B:b:C:cd:e:F:f:h:Iimno:p:q:r:sTtvX:x"
+#endif
+#if defined(ultrix)
+# define OPTIONS "B:b:C:cd:e:F:f:h:IiM:mno:p:q:r:sTtvX:"
+#endif
+#if defined(NeXT)
+# define OPTIONS "B:b:C:cd:e:F:f:h:IimnOo:p:q:r:sTtvX:"
+#endif
+#ifndef OPTIONS
+# define OPTIONS "B:b:C:cd:e:F:f:h:Iimno:p:q:r:sTtvX:"
+#endif
+ while ((j = getopt(argc, argv, OPTIONS)) != EOF)
+ {
+ switch (j)
+ {
+ case 'd':
+ tTsetup(tTdvect, sizeof tTdvect, "0-99.1");
+ tTflag(optarg);
+ setbuf(stdout, (char *) NULL);
+ printf("Version %s\n", Version);
+ break;
+ }
+ }
+
+ InChannel = stdin;
+ OutChannel = stdout;
+
+ /*
+ ** Move the environment so setproctitle can use the space at
+ ** the top of memory.
+ */
+
+ for (i = j = 0; j < MAXUSERENVIRON && (p = envp[i]) != NULL; i++)
+ {
+ if (strncmp(p, "FS=", 3) == 0 || strncmp(p, "LD_", 3) == 0)
+ continue;
+ UserEnviron[j++] = newstr(p);
+ }
+ UserEnviron[j] = NULL;
+ environ = UserEnviron;
+
+# ifdef SETPROCTITLE
+ /*
+ ** Save start and extent of argv for setproctitle.
+ */
+
+ Argv = argv;
+ if (i > 0)
+ LastArgv = envp[i - 1] + strlen(envp[i - 1]);
+ else
+ LastArgv = argv[argc - 1] + strlen(argv[argc - 1]);
+# endif /* SETPROCTITLE */
+
+ if (setsignal(SIGINT, SIG_IGN) != SIG_IGN)
+ (void) setsignal(SIGINT, intsig);
+ if (setsignal(SIGHUP, SIG_IGN) != SIG_IGN)
+ (void) setsignal(SIGHUP, intsig);
+ (void) setsignal(SIGTERM, intsig);
+ (void) setsignal(SIGPIPE, SIG_IGN);
+ OldUmask = umask(022);
+ OpMode = MD_DELIVER;
+ FullName = getenv("NAME");
+
+#if NAMED_BIND
+ if (tTd(8, 8))
+ _res.options |= RES_DEBUG;
+#endif
+
+ errno = 0;
+ from = NULL;
+
+ /* initialize some macros, etc. */
+ initmacros(CurEnv);
+
+ /* version */
+ define('v', Version, CurEnv);
+
+ /* hostname */
+ av = myhostname(jbuf, sizeof jbuf);
+ if (jbuf[0] != '\0')
+ {
+ struct utsname utsname;
+
+ if (tTd(0, 4))
+ printf("canonical name: %s\n", jbuf);
+ define('w', newstr(jbuf), CurEnv); /* must be new string */
+ define('j', newstr(jbuf), CurEnv);
+ setclass('w', jbuf);
+
+ p = strchr(jbuf, '.');
+ if (p != NULL)
+ {
+ if (p[1] != '\0')
+ {
+ define('m', newstr(&p[1]), CurEnv);
+ setclass('m', &p[1]);
+ }
+ while (p != NULL && strchr(&p[1], '.') != NULL)
+ {
+ *p = '\0';
+ setclass('w', jbuf);
+ *p++ = '.';
+ p = strchr(p, '.');
+ }
+ }
+
+ if (uname(&utsname) >= 0)
+ p = utsname.nodename;
+ else
+ {
+ if (tTd(0, 22))
+ printf("uname failed (%s)\n", errstring(errno));
+ makelower(jbuf);
+ p = jbuf;
+ }
+ if (tTd(0, 4))
+ printf("UUCP nodename: %s\n", p);
+ p = newstr(p);
+ define('k', p, CurEnv);
+ setclass('k', p);
+ setclass('w', p);
+ }
+ while (av != NULL && *av != NULL)
+ {
+ if (tTd(0, 4))
+ printf("\ta.k.a.: %s\n", *av);
+ setclass('w', *av++);
+ }
+
+ /* current time */
+ define('b', arpadate((char *) NULL), CurEnv);
+
+ /*
+ ** Find our real host name for future logging.
+ */
+
+ p = getauthinfo(STDIN_FILENO);
+ define('_', p, CurEnv);
+
+ /*
+ ** Crack argv.
+ */
+
+ av = argv;
+ p = strrchr(*av, '/');
+ if (p++ == NULL)
+ p = *av;
+ if (strcmp(p, "newaliases") == 0)
+ OpMode = MD_INITALIAS;
+ else if (strcmp(p, "mailq") == 0)
+ OpMode = MD_PRINT;
+ else if (strcmp(p, "smtpd") == 0)
+ OpMode = MD_DAEMON;
+
+ optind = 1;
+ while ((j = getopt(argc, argv, OPTIONS)) != EOF)
+ {
+ switch (j)
+ {
+ case 'b': /* operations mode */
+ switch (j = *optarg)
+ {
+ case MD_DAEMON:
+# ifdef DAEMON
+ if (RealUid != 0) {
+ usrerr("Permission denied");
+ exit (EX_USAGE);
+ }
+ (void) unsetenv("HOSTALIASES");
+# else
+ usrerr("Daemon mode not implemented");
+ ExitStat = EX_USAGE;
+ break;
+# endif /* DAEMON */
+ case MD_SMTP:
+# ifndef SMTP
+ usrerr("I don't speak SMTP");
+ ExitStat = EX_USAGE;
+ break;
+# endif /* SMTP */
+ case MD_DELIVER:
+ case MD_VERIFY:
+ case MD_TEST:
+ case MD_INITALIAS:
+ case MD_PRINT:
+#ifdef MAYBE_NEXT_RELEASE
+ case MD_ARPAFTP:
+#endif
+ OpMode = j;
+ break;
+
+ case MD_FREEZE:
+ usrerr("Frozen configurations unsupported");
+ ExitStat = EX_USAGE;
+ break;
+
+ default:
+ usrerr("Invalid operation mode %c", j);
+ ExitStat = EX_USAGE;
+ break;
+ }
+ break;
+
+ case 'B': /* body type */
+ CurEnv->e_bodytype = newstr(optarg);
+ break;
+
+ case 'C': /* select configuration file (already done) */
+ if (RealUid != 0)
+ warn_C_flag = TRUE;
+ ConfFile = optarg;
+ (void) setgid(RealGid);
+ (void) setuid(RealUid);
+ safecf = FALSE;
+ break;
+
+ case 'd': /* debugging -- already done */
+ break;
+
+ case 'f': /* from address */
+ case 'r': /* obsolete -f flag */
+ if (from != NULL)
+ {
+ usrerr("More than one \"from\" person");
+ ExitStat = EX_USAGE;
+ break;
+ }
+ from = newstr(optarg);
+ if (strcmp(RealUserName, from) != 0)
+ warn_f_flag = j;
+ break;
+
+ case 'F': /* set full name */
+ FullName = newstr(optarg);
+ break;
+
+ case 'h': /* hop count */
+ CurEnv->e_hopcount = strtol(optarg, &ep, 10);
+ if (*ep)
+ {
+ usrerr("Bad hop count (%s)", optarg);
+ ExitStat = EX_USAGE;
+ break;
+ }
+ break;
+
+ case 'n': /* don't alias */
+ NoAlias = TRUE;
+ break;
+
+ case 'o': /* set option */
+ setoption(*optarg, optarg + 1, FALSE, TRUE, CurEnv);
+ break;
+
+ case 'p': /* set protocol */
+ p = strchr(optarg, ':');
+ if (p != NULL)
+ *p++ = '\0';
+ if (*optarg != '\0')
+ define('r', newstr(optarg), CurEnv);
+ if (p != NULL && *p != '\0')
+ define('s', newstr(p), CurEnv);
+ break;
+
+ case 'q': /* run queue files at intervals */
+# ifdef QUEUE
+ (void) unsetenv("HOSTALIASES");
+ FullName = NULL;
+ queuemode = TRUE;
+ switch (optarg[0])
+ {
+ case 'I':
+ QueueLimitId = newstr(&optarg[1]);
+ break;
+
+ case 'R':
+ QueueLimitRecipient = newstr(&optarg[1]);
+ break;
+
+ case 'S':
+ QueueLimitSender = newstr(&optarg[1]);
+ break;
+
+ default:
+ QueueIntvl = convtime(optarg, 'm');
+ break;
+ }
+# else /* QUEUE */
+ usrerr("I don't know about queues");
+ ExitStat = EX_USAGE;
+# endif /* QUEUE */
+ break;
+
+ case 't': /* read recipients from message */
+ GrabTo = TRUE;
+ break;
+
+ case 'X': /* traffic log file */
+ setuid(RealUid);
+ TrafficLogFile = fopen(optarg, "a");
+ if (TrafficLogFile == NULL)
+ {
+ syserr("cannot open %s", optarg);
+ break;
+ }
+#ifdef HASSETVBUF
+ setvbuf(TrafficLogFile, NULL, _IOLBF, 0);
+#else
+ setlinebuf(TrafficLogFile);
+#endif
+ break;
+
+ /* compatibility flags */
+ case 'c': /* connect to non-local mailers */
+ case 'i': /* don't let dot stop me */
+ case 'm': /* send to me too */
+ case 'T': /* set timeout interval */
+ case 'v': /* give blow-by-blow description */
+ setoption(j, "T", FALSE, TRUE, CurEnv);
+ break;
+
+ case 'e': /* error message disposition */
+# if defined(ultrix)
+ case 'M': /* define macro */
+# endif
+ setoption(j, optarg, FALSE, TRUE, CurEnv);
+ break;
+
+ case 's': /* save From lines in headers */
+ setoption('f', "T", FALSE, TRUE, CurEnv);
+ break;
+
+# ifdef DBM
+ case 'I': /* initialize alias DBM file */
+ OpMode = MD_INITALIAS;
+ break;
+# endif /* DBM */
+
+# if defined(__osf__) || defined(_AIX3)
+ case 'x': /* random flag that OSF/1 & AIX mailx passes */
+ break;
+# endif
+# if defined(NeXT)
+ case 'O': /* random flag that NeXT Mail.app passes */
+ break;
+# endif
+
+ default:
+ ExitStat = EX_USAGE;
+ finis();
+ break;
+ }
+ }
+ av += optind;
+
+ /*
+ ** Do basic initialization.
+ ** Read system control file.
+ ** Extract special fields for local use.
+ */
+
+#ifdef XDEBUG
+ checkfd012("before readcf");
+#endif
+ readcf(getcfname(), safecf, CurEnv);
+
+ if (tTd(0, 1))
+ {
+ printf("SYSTEM IDENTITY (after readcf):");
+ printf("\n\t (short domain name) $w = ");
+ xputs(macvalue('w', CurEnv));
+ printf("\n\t(canonical domain name) $j = ");
+ xputs(macvalue('j', CurEnv));
+ printf("\n\t (subdomain name) $m = ");
+ xputs(macvalue('m', CurEnv));
+ printf("\n\t (node name) $k = ");
+ xputs(macvalue('k', CurEnv));
+ printf("\n");
+ }
+
+ /*
+ ** Process authorization warnings from command line.
+ */
+
+ if (warn_C_flag)
+ auth_warning(CurEnv, "Processed by %s with -C %s",
+ RealUserName, ConfFile);
+/*
+ if (warn_f_flag != '\0')
+ auth_warning(CurEnv, "%s set sender to %s using -%c",
+ RealUserName, from, warn_f_flag);
+*/
+ if (Warn_Q_option)
+ auth_warning(CurEnv, "Processed from queue %s", QueueDir);
+
+ /* Enforce use of local time (null string overrides this) */
+ if (TimeZoneSpec == NULL)
+ unsetenv("TZ");
+ else if (TimeZoneSpec[0] != '\0')
+ {
+ char **evp = UserEnviron;
+ char tzbuf[100];
+
+ strcpy(tzbuf, "TZ=");
+ strcpy(&tzbuf[3], TimeZoneSpec);
+
+ while (*evp != NULL && strncmp(*evp, "TZ=", 3) != 0)
+ evp++;
+ if (*evp == NULL)
+ {
+ *evp++ = newstr(tzbuf);
+ *evp = NULL;
+ }
+ else
+ *evp++ = newstr(tzbuf);
+ }
+
+ if (ConfigLevel > MAXCONFIGLEVEL)
+ {
+ syserr("Warning: .cf version level (%d) exceeds program functionality (%d)",
+ ConfigLevel, MAXCONFIGLEVEL);
+ }
+
+ if (MeToo)
+ BlankEnvelope.e_flags |= EF_METOO;
+
+# ifdef QUEUE
+ if (queuemode && RealUid != 0 && bitset(PRIV_RESTRICTQRUN, PrivacyFlags))
+ {
+ struct stat stbuf;
+
+ /* check to see if we own the queue directory */
+ if (stat(QueueDir, &stbuf) < 0)
+ syserr("main: cannot stat %s", QueueDir);
+ if (stbuf.st_uid != RealUid)
+ {
+ /* nope, really a botch */
+ usrerr("You do not have permission to process the queue");
+ exit (EX_NOPERM);
+ }
+ }
+# endif /* QUEUE */
+
+ switch (OpMode)
+ {
+ case MD_INITALIAS:
+ Verbose = TRUE;
+ break;
+
+ case MD_DAEMON:
+ /* remove things that don't make sense in daemon mode */
+ FullName = NULL;
+ break;
+ }
+
+ /* do heuristic mode adjustment */
+ if (Verbose)
+ {
+ /* turn off noconnect option */
+ setoption('c', "F", TRUE, FALSE, CurEnv);
+
+ /* turn on interactive delivery */
+ setoption('d', "", TRUE, FALSE, CurEnv);
+ }
+
+ if (ConfigLevel < 3)
+ {
+ UseErrorsTo = TRUE;
+ }
+
+ /* our name for SMTP codes */
+ expand("\201j", jbuf, &jbuf[sizeof jbuf - 1], CurEnv);
+ MyHostName = jbuf;
+
+ /* make certain that this name is part of the $=w class */
+ setclass('w', MyHostName);
+
+ /* the indices of built-in mailers */
+ st = stab("local", ST_MAILER, ST_FIND);
+ if (st == NULL)
+ syserr("No local mailer defined");
+ else
+ LocalMailer = st->s_mailer;
+
+ st = stab("prog", ST_MAILER, ST_FIND);
+ if (st == NULL)
+ syserr("No prog mailer defined");
+ else
+ ProgMailer = st->s_mailer;
+
+ st = stab("*file*", ST_MAILER, ST_FIND);
+ if (st == NULL)
+ syserr("No *file* mailer defined");
+ else
+ FileMailer = st->s_mailer;
+
+ st = stab("*include*", ST_MAILER, ST_FIND);
+ if (st == NULL)
+ syserr("No *include* mailer defined");
+ else
+ InclMailer = st->s_mailer;
+
+
+ /* operate in queue directory */
+ if (OpMode != MD_TEST && chdir(QueueDir) < 0)
+ {
+ syserr("cannot chdir(%s)", QueueDir);
+ ExitStat = EX_SOFTWARE;
+ }
+
+ /* if we've had errors so far, exit now */
+ if (ExitStat != EX_OK && OpMode != MD_TEST)
+ {
+ setuid(RealUid);
+ exit(ExitStat);
+ }
+
+#ifdef XDEBUG
+ checkfd012("before main() initmaps");
+#endif
+
+ /*
+ ** Do operation-mode-dependent initialization.
+ */
+
+ switch (OpMode)
+ {
+ case MD_PRINT:
+ /* print the queue */
+#ifdef QUEUE
+ dropenvelope(CurEnv);
+ printqueue();
+ setuid(RealUid);
+ exit(EX_OK);
+#else /* QUEUE */
+ usrerr("No queue to print");
+ finis();
+#endif /* QUEUE */
+
+ case MD_INITALIAS:
+ /* initialize alias database */
+ initmaps(TRUE, CurEnv);
+ setuid(RealUid);
+ exit(EX_OK);
+
+ case MD_DAEMON:
+ /* don't open alias database -- done in srvrsmtp */
+ break;
+
+ default:
+ /* open the alias database */
+ initmaps(FALSE, CurEnv);
+ break;
+ }
+
+ if (tTd(0, 15))
+ {
+ /* print configuration table (or at least part of it) */
+ printrules();
+ for (i = 0; i < MAXMAILERS; i++)
+ {
+ register struct mailer *m = Mailer[i];
+ int j;
+
+ if (m == NULL)
+ continue;
+ printf("mailer %d (%s): P=%s S=%d/%d R=%d/%d M=%ld F=", i, m->m_name,
+ m->m_mailer, m->m_se_rwset, m->m_sh_rwset,
+ m->m_re_rwset, m->m_rh_rwset, m->m_maxsize);
+ for (j = '\0'; j <= '\177'; j++)
+ if (bitnset(j, m->m_flags))
+ (void) putchar(j);
+ printf(" E=");
+ xputs(m->m_eol);
+ if (m->m_argv != NULL)
+ {
+ char **a = m->m_argv;
+
+ printf(" A=");
+ while (*a != NULL)
+ {
+ if (a != m->m_argv)
+ printf(" ");
+ xputs(*a++);
+ }
+ }
+ printf("\n");
+ }
+ }
+
+ /*
+ ** Switch to the main envelope.
+ */
+
+ CurEnv = newenvelope(&MainEnvelope, CurEnv);
+ MainEnvelope.e_flags = BlankEnvelope.e_flags;
+
+ /*
+ ** If test mode, read addresses from stdin and process.
+ */
+
+ if (OpMode == MD_TEST)
+ {
+ char buf[MAXLINE];
+
+ if (isatty(fileno(stdin)))
+ Verbose = TRUE;
+
+ if (Verbose)
+ {
+ printf("ADDRESS TEST MODE (ruleset 3 NOT automatically invoked)\n");
+ printf("Enter <ruleset> <address>\n");
+ }
+ for (;;)
+ {
+ register char **pvp;
+ char *q;
+ auto char *delimptr;
+ extern bool invalidaddr();
+ extern char *crackaddr();
+
+ if (Verbose)
+ printf("> ");
+ (void) fflush(stdout);
+ if (fgets(buf, sizeof buf, stdin) == NULL)
+ finis();
+ if (!Verbose)
+ printf("> %s", buf);
+ switch (buf[0])
+ {
+ case '#':
+ continue;
+
+#ifdef MAYBENEXTRELEASE
+ case 'C': /* try crackaddr */
+ q = crackaddr(&buf[1]);
+ xputs(q);
+ printf("\n");
+ continue;
+#endif
+ }
+
+ for (p = buf; isascii(*p) && isspace(*p); p++)
+ continue;
+ q = p;
+ while (*p != '\0' && !(isascii(*p) && isspace(*p)))
+ p++;
+ if (*p == '\0')
+ {
+ printf("No address!\n");
+ continue;
+ }
+ *p = '\0';
+ if (invalidaddr(p + 1, NULL))
+ continue;
+ do
+ {
+ char pvpbuf[PSBUFSIZE];
+
+ pvp = prescan(++p, ',', pvpbuf, sizeof pvpbuf,
+ &delimptr);
+ if (pvp == NULL)
+ continue;
+ p = q;
+ while (*p != '\0')
+ {
+ int stat;
+
+ stat = rewrite(pvp, atoi(p), 0, CurEnv);
+ if (stat != EX_OK)
+ printf("== Ruleset %s status %d\n",
+ p, stat);
+ while (*p != '\0' && *p++ != ',')
+ continue;
+ }
+ } while (*(p = delimptr) != '\0');
+ }
+ }
+
+# ifdef QUEUE
+ /*
+ ** If collecting stuff from the queue, go start doing that.
+ */
+
+ if (queuemode && OpMode != MD_DAEMON && QueueIntvl == 0)
+ {
+ runqueue(FALSE);
+ finis();
+ }
+# endif /* QUEUE */
+
+ /*
+ ** If a daemon, wait for a request.
+ ** getrequests will always return in a child.
+ ** If we should also be processing the queue, start
+ ** doing it in background.
+ ** We check for any errors that might have happened
+ ** during startup.
+ */
+
+ if (OpMode == MD_DAEMON || QueueIntvl != 0)
+ {
+ char dtype[200];
+
+ if (!tTd(0, 1))
+ {
+ /* put us in background */
+ i = fork();
+ if (i < 0)
+ syserr("daemon: cannot fork");
+ if (i != 0)
+ exit(0);
+
+ /* disconnect from our controlling tty */
+ disconnect(2, CurEnv);
+ }
+
+ dtype[0] = '\0';
+ if (OpMode == MD_DAEMON)
+ strcat(dtype, "+SMTP");
+ if (QueueIntvl != 0)
+ {
+ strcat(dtype, "+queueing@");
+ strcat(dtype, pintvl(QueueIntvl, TRUE));
+ }
+ if (tTd(0, 1))
+ strcat(dtype, "+debugging");
+
+#ifdef LOG
+ syslog(LOG_INFO, "starting daemon (%s): %s", Version, dtype + 1);
+#endif
+#ifdef XLA
+ xla_create_file();
+#endif
+
+# ifdef QUEUE
+ if (queuemode)
+ {
+ runqueue(TRUE);
+ if (OpMode != MD_DAEMON)
+ for (;;)
+ pause();
+ }
+# endif /* QUEUE */
+ dropenvelope(CurEnv);
+
+#ifdef DAEMON
+ getrequests();
+
+ /* at this point we are in a child: reset state */
+ (void) newenvelope(CurEnv, CurEnv);
+
+ /*
+ ** Get authentication data
+ */
+
+ p = getauthinfo(fileno(InChannel));
+ define('_', p, CurEnv);
+
+#endif /* DAEMON */
+ }
+
+# ifdef SMTP
+ /*
+ ** If running SMTP protocol, start collecting and executing
+ ** commands. This will never return.
+ */
+
+ if (OpMode == MD_SMTP || OpMode == MD_DAEMON)
+ smtp(CurEnv);
+# endif /* SMTP */
+
+ if (OpMode == MD_VERIFY)
+ {
+ CurEnv->e_sendmode = SM_VERIFY;
+ CurEnv->e_errormode = EM_QUIET;
+ }
+ else
+ {
+ /* interactive -- all errors are global */
+ CurEnv->e_flags |= EF_GLOBALERRS;
+ }
+
+ /*
+ ** Do basic system initialization and set the sender
+ */
+
+ initsys(CurEnv);
+ setsender(from, CurEnv, NULL, FALSE);
+ if (macvalue('s', CurEnv) == NULL)
+ define('s', RealHostName, CurEnv);
+
+ if (*av == NULL && !GrabTo)
+ {
+ CurEnv->e_flags |= EF_GLOBALERRS;
+ usrerr("Recipient names must be specified");
+
+ /* collect body for UUCP return */
+ if (OpMode != MD_VERIFY)
+ collect(FALSE, FALSE, CurEnv);
+ finis();
+ }
+
+ /*
+ ** Scan argv and deliver the message to everyone.
+ */
+
+ sendtoargv(av, CurEnv);
+
+ /* if we have had errors sofar, arrange a meaningful exit stat */
+ if (Errors > 0 && ExitStat == EX_OK)
+ ExitStat = EX_USAGE;
+
+ /*
+ ** Read the input mail.
+ */
+
+ CurEnv->e_to = NULL;
+ if (OpMode != MD_VERIFY || GrabTo)
+ {
+ CurEnv->e_flags |= EF_GLOBALERRS;
+ collect(FALSE, FALSE, CurEnv);
+ }
+ errno = 0;
+
+ if (tTd(1, 1))
+ printf("From person = \"%s\"\n", CurEnv->e_from.q_paddr);
+
+ /*
+ ** Actually send everything.
+ ** If verifying, just ack.
+ */
+
+ CurEnv->e_from.q_flags |= QDONTSEND;
+ if (tTd(1, 5))
+ {
+ printf("main: QDONTSEND ");
+ printaddr(&CurEnv->e_from, FALSE);
+ }
+ CurEnv->e_to = NULL;
+ sendall(CurEnv, SM_DEFAULT);
+
+ /*
+ ** All done.
+ ** Don't send return error message if in VERIFY mode.
+ */
+
+ finis();
+}
+ /*
+** FINIS -- Clean up and exit.
+**
+** Parameters:
+** none
+**
+** Returns:
+** never
+**
+** Side Effects:
+** exits sendmail
+*/
+
+finis()
+{
+ if (tTd(2, 1))
+ printf("\n====finis: stat %d e_flags %o, e_id=%s\n",
+ ExitStat, CurEnv->e_flags,
+ CurEnv->e_id == NULL ? "NOQUEUE" : CurEnv->e_id);
+ if (tTd(2, 9))
+ printopenfds(FALSE);
+
+ /* clean up temp files */
+ CurEnv->e_to = NULL;
+ dropenvelope(CurEnv);
+
+ /* flush any cached connections */
+ mci_flush(TRUE, NULL);
+
+# ifdef XLA
+ /* clean up extended load average stuff */
+ xla_all_end();
+# endif
+
+ /* and exit */
+# ifdef LOG
+ if (LogLevel > 78)
+ syslog(LOG_DEBUG, "finis, pid=%d", getpid());
+# endif /* LOG */
+ if (ExitStat == EX_TEMPFAIL)
+ ExitStat = EX_OK;
+
+ /* reset uid for process accounting */
+ setuid(RealUid);
+
+ exit(ExitStat);
+}
+ /*
+** INTSIG -- clean up on interrupt
+**
+** This just arranges to exit. It pessimises in that it
+** may resend a message.
+**
+** Parameters:
+** none.
+**
+** Returns:
+** none.
+**
+** Side Effects:
+** Unlocks the current job.
+*/
+
+void
+intsig()
+{
+ FileName = NULL;
+ unlockqueue(CurEnv);
+#ifdef XLA
+ xla_all_end();
+#endif
+
+ /* reset uid for process accounting */
+ setuid(RealUid);
+
+ exit(EX_OK);
+}
+ /*
+** INITMACROS -- initialize the macro system
+**
+** This just involves defining some macros that are actually
+** used internally as metasymbols to be themselves.
+**
+** Parameters:
+** none.
+**
+** Returns:
+** none.
+**
+** Side Effects:
+** initializes several macros to be themselves.
+*/
+
+struct metamac MetaMacros[] =
+{
+ /* LHS pattern matching characters */
+ '*', MATCHZANY, '+', MATCHANY, '-', MATCHONE,
+ '=', MATCHCLASS, '~', MATCHNCLASS,
+
+ /* these are RHS metasymbols */
+ '#', CANONNET, '@', CANONHOST, ':', CANONUSER,
+ '>', CALLSUBR,
+
+ /* the conditional operations */
+ '?', CONDIF, '|', CONDELSE, '.', CONDFI,
+
+ /* the hostname lookup characters */
+ '[', HOSTBEGIN, ']', HOSTEND,
+ '(', LOOKUPBEGIN, ')', LOOKUPEND,
+
+ /* miscellaneous control characters */
+ '&', MACRODEXPAND,
+
+ '\0'
+};
+
+initmacros(e)
+ register ENVELOPE *e;
+{
+ register struct metamac *m;
+ char buf[5];
+ register int c;
+
+ for (m = MetaMacros; m->metaname != '\0'; m++)
+ {
+ buf[0] = m->metaval;
+ buf[1] = '\0';
+ define(m->metaname, newstr(buf), e);
+ }
+ buf[0] = MATCHREPL;
+ buf[2] = '\0';
+ for (c = '0'; c <= '9'; c++)
+ {
+ buf[1] = c;
+ define(c, newstr(buf), e);
+ }
+
+ /* set defaults for some macros sendmail will use later */
+ define('e', "\201j Sendmail \201v ready at \201b", e);
+ define('l', "From \201g \201d", e);
+ define('n', "MAILER-DAEMON", e);
+ define('o', ".:@[]", e);
+ define('q', "<\201g>", e);
+}
+ /*
+** DISCONNECT -- remove our connection with any foreground process
+**
+** Parameters:
+** droplev -- how "deeply" we should drop the line.
+** 0 -- ignore signals, mail back errors, make sure
+** output goes to stdout.
+** 1 -- also, make stdout go to transcript.
+** 2 -- also, disconnect from controlling terminal
+** (only for daemon mode).
+** e -- the current envelope.
+**
+** Returns:
+** none
+**
+** Side Effects:
+** Trys to insure that we are immune to vagaries of
+** the controlling tty.
+*/
+
+disconnect(droplev, e)
+ int droplev;
+ register ENVELOPE *e;
+{
+ int fd;
+
+ if (tTd(52, 1))
+ printf("disconnect: In %d Out %d, e=%x\n",
+ fileno(InChannel), fileno(OutChannel), e);
+ if (tTd(52, 5))
+ {
+ printf("don't\n");
+ return;
+ }
+
+ /* be sure we don't get nasty signals */
+ (void) setsignal(SIGHUP, SIG_IGN);
+ (void) setsignal(SIGINT, SIG_IGN);
+ (void) setsignal(SIGQUIT, SIG_IGN);
+
+ /* we can't communicate with our caller, so.... */
+ HoldErrs = TRUE;
+ CurEnv->e_errormode = EM_MAIL;
+ Verbose = FALSE;
+ DisConnected = TRUE;
+
+ /* all input from /dev/null */
+ if (InChannel != stdin)
+ {
+ (void) fclose(InChannel);
+ InChannel = stdin;
+ }
+ (void) freopen("/dev/null", "r", stdin);
+
+ /* output to the transcript */
+ if (OutChannel != stdout)
+ {
+ (void) fclose(OutChannel);
+ OutChannel = stdout;
+ }
+ if (droplev > 0)
+ {
+ if (e->e_xfp == NULL)
+ fd = open("/dev/null", O_WRONLY, 0666);
+ else
+ fd = fileno(e->e_xfp);
+ (void) fflush(stdout);
+ dup2(fd, STDOUT_FILENO);
+ dup2(fd, STDERR_FILENO);
+ if (e->e_xfp == NULL)
+ close(fd);
+ }
+
+ /* drop our controlling TTY completely if possible */
+ if (droplev > 1)
+ {
+ (void) setsid();
+ errno = 0;
+ }
+
+#ifdef XDEBUG
+ checkfd012("disconnect");
+#endif
+
+# ifdef LOG
+ if (LogLevel > 71)
+ syslog(LOG_DEBUG, "in background, pid=%d", getpid());
+# endif /* LOG */
+
+ errno = 0;
+}
+
+static void
+obsolete(argv)
+ char *argv[];
+{
+ register char *ap;
+ register char *op;
+
+ while ((ap = *++argv) != NULL)
+ {
+ /* Return if "--" or not an option of any form. */
+ if (ap[0] != '-' || ap[1] == '-')
+ return;
+
+ /* skip over options that do have a value */
+ op = strchr(OPTIONS, ap[1]);
+ if (op != NULL && *++op == ':' && ap[2] == '\0' &&
+ ap[1] != 'd' && argv[1] != NULL && argv[1][0] != '-')
+ {
+ argv++;
+ continue;
+ }
+
+ /* If -C doesn't have an argument, use sendmail.cf. */
+#define __DEFPATH "sendmail.cf"
+ if (ap[1] == 'C' && ap[2] == '\0')
+ {
+ *argv = xalloc(sizeof(__DEFPATH) + 2);
+ argv[0][0] = '-';
+ argv[0][1] = 'C';
+ (void)strcpy(&argv[0][2], __DEFPATH);
+ }
+
+ /* If -q doesn't have an argument, run it once. */
+ if (ap[1] == 'q' && ap[2] == '\0')
+ *argv = "-q0";
+
+ /* if -d doesn't have an argument, use 0-99.1 */
+ if (ap[1] == 'd' && ap[2] == '\0')
+ *argv = "-d0-99.1";
+ }
+}
+ /*
+** AUTH_WARNING -- specify authorization warning
+**
+** Parameters:
+** e -- the current envelope.
+** msg -- the text of the message.
+** args -- arguments to the message.
+**
+** Returns:
+** none.
+*/
+
+void
+#ifdef __STDC__
+auth_warning(register ENVELOPE *e, const char *msg, ...)
+#else
+auth_warning(e, msg, va_alist)
+ register ENVELOPE *e;
+ const char *msg;
+ va_dcl
+#endif
+{
+ char buf[MAXLINE];
+ VA_LOCAL_DECL
+
+ if (bitset(PRIV_AUTHWARNINGS, PrivacyFlags))
+ {
+ register char *p;
+ static char hostbuf[48];
+ extern char **myhostname();
+
+ if (hostbuf[0] == '\0')
+ (void) myhostname(hostbuf, sizeof hostbuf);
+
+ (void) sprintf(buf, "%s: ", hostbuf);
+ p = &buf[strlen(buf)];
+ VA_START(msg);
+ vsprintf(p, msg, ap);
+ VA_END;
+ addheader("X-Authentication-Warning", buf, e);
+ }
+}
+ /*
+** DUMPSTATE -- dump state
+**
+** For debugging.
+*/
+
+void
+dumpstate(when)
+ char *when;
+{
+#ifdef LOG
+ register char *j = macvalue('j', CurEnv);
+ register STAB *s;
+
+ syslog(LOG_DEBUG, "--- dumping state on %s: $j = %s ---",
+ when,
+ j == NULL ? "<NULL>" : j);
+ if (j != NULL)
+ {
+ s = stab(j, ST_CLASS, ST_FIND);
+ if (s == NULL || !bitnset('w', s->s_class))
+ syslog(LOG_DEBUG, "*** $j not in $=w ***");
+ }
+ syslog(LOG_DEBUG, "--- open file descriptors: ---");
+ printopenfds(TRUE);
+ syslog(LOG_DEBUG, "--- connection cache: ---");
+ mci_dump_all(TRUE);
+ if (RewriteRules[89] != NULL)
+ {
+ int stat;
+ register char **pvp;
+ char *pv[MAXATOM + 1];
+
+ pv[0] = NULL;
+ stat = rewrite(pv, 89, 0, CurEnv);
+ syslog(LOG_DEBUG, "--- ruleset 89 returns stat %d, pv: ---",
+ stat);
+ for (pvp = pv; *pvp != NULL; pvp++)
+ syslog(LOG_DEBUG, "%s", *pvp);
+ }
+ syslog(LOG_DEBUG, "--- end of state dump ---");
+#endif
+}
+
+
+void
+sigusr1()
+{
+ dumpstate("user signal");
+}
diff --git a/usr.sbin/sendmail/src/makesendmail b/usr.sbin/sendmail/src/makesendmail
new file mode 100644
index 0000000..7c13db9
--- /dev/null
+++ b/usr.sbin/sendmail/src/makesendmail
@@ -0,0 +1,113 @@
+#!/bin/sh
+
+# Copyright (c) 1993 Eric P. Allman
+# Copyright (c) 1993 The Regents of the University of California.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+# 3. All advertising materials mentioning features or use of this software
+# must display the following acknowledgement:
+# This product includes software developed by the University of
+# California, Berkeley and its contributors.
+# 4. Neither the name of the University nor the names of its contributors
+# may be used to endorse or promote products derived from this software
+# without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+#
+# @(#)makesendmail 8.5 (Berkeley) 2/27/94
+#
+
+#
+# A quick-and-dirty script to compile sendmail in the presence of
+# multiple architectures and Makefiles.
+#
+
+# determine machine architecture
+arch=`uname -m`
+case $arch
+in
+ sun4*) arch=sun4;;
+
+ 9000/*) arch=`echo $arch | sed -e 's/9000.//' -e 's/..$/xx/'`;;
+esac
+
+# determine operating system type
+os=`uname -s`
+
+# determine operating system release
+rel=`uname -r`
+rbase=`echo $rel | sed 's/\..*//''`
+
+# now try to find a reasonable object directory
+if [ -r obj.$os.$arch.$rel ]; then
+ obj=obj.$os.$arch.$rel
+elif [ -r obj.$os.$arch.$rbase.x ]; then
+ obj=obj.$os.$arch.$rbase.x
+elif [ -r obj.$os.$rel ]; then
+ obj=obj.$os.$rel
+elif [ -r obj.$os.$rbase.x ]; then
+ obj=obj.$os.$rbase.x
+elif [ -r obj.$os.$arch ]; then
+ obj=obj.$os.$arch
+elif [ -r obj.$arch.$rel ]; then
+ obj=obj.$arch.$rel
+elif [ -r obj.$arch.$rbase.x ]; then
+ obj=obj.$arch.$rbase.x
+elif [ -r obj.$os ]; then
+ obj=obj.$os
+elif [ -r obj.$arch ]; then
+ obj=obj.$arch
+elif [ -r obj.$rel ]; then
+ obj=obj.$rel
+else
+ # no existing obj directory -- try to create one if Makefile found
+ obj=obj.$os.$arch.$rel
+ if [ -r Makefile.$os.$arch.$rel ]; then
+ makefile=Makefile.$os.$arch.$rel
+ elif [ -r Makefile.$os.$arch.$rbase.x ]; then
+ makefile=Makefile.$os.$arch.$rbase.x
+ elif [ -r Makefile.$os.$rel ]; then
+ makefile=Makefile.$os.$rel
+ elif [ -r Makefile.$os.$rbase.x ]; then
+ makefile=Makefile.$os.$rbase.x
+ elif [ -r Makefile.$os.$arch ]; then
+ makefile=Makefile.$os.$arch
+ elif [ -r Makefile.$arch.$rel ]; then
+ makefile=Makefile.$arch.$rel
+ elif [ -r Makefile.$arch.$rbase.x ]; then
+ makefile=Makefile.$arch.$rbase.x
+ elif [ -r Makefile.$os ]; then
+ makefile=Makefile.$os
+ elif [ -r Makefile.$arch ]; then
+ makefile=Makefile.$arch
+ elif [ -r Makefile.$rel ]; then
+ makefile=Makefile.$rel
+ else
+ echo "Cannot determine how to support $arch.$os.$rel"
+ exit 1
+ fi
+ echo "Creating $obj using $makefile"
+ mkdir $obj
+ (cd $obj; ln -s ../*.[ch158] ../sendmail.hf .; ln -s ../$makefile Makefile)
+fi
+echo "Making in $obj"
+cd $obj
+exec make -f Makefile $*
diff --git a/usr.sbin/sendmail/src/map.c b/usr.sbin/sendmail/src/map.c
new file mode 100644
index 0000000..01ba411
--- /dev/null
+++ b/usr.sbin/sendmail/src/map.c
@@ -0,0 +1,1339 @@
+/*
+ * Copyright (c) 1992 Eric P. Allman.
+ * Copyright (c) 1992, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)map.c 8.25 (Berkeley) 4/17/94";
+#endif /* not lint */
+
+#include "sendmail.h"
+
+#ifdef NDBM
+#include <ndbm.h>
+#endif
+#ifdef NEWDB
+#include <db.h>
+#endif
+#ifdef NIS
+#include <rpcsvc/ypclnt.h>
+#endif
+
+/*
+** MAP.C -- implementations for various map classes.
+**
+** Each map class implements a series of functions:
+**
+** bool map_parse(MAP *map, char *args)
+** Parse the arguments from the config file. Return TRUE
+** if they were ok, FALSE otherwise. Fill in map with the
+** values.
+**
+** char *map_lookup(MAP *map, char *key, char **args, int *pstat)
+** Look up the key in the given map. If found, do any
+** rewriting the map wants (including "args" if desired)
+** and return the value. Set *pstat to the appropriate status
+** on error and return NULL. Args will be NULL if called
+** from the alias routines, although this should probably
+** not be relied upon. It is suggested you call map_rewrite
+** to return the results -- it takes care of null termination
+** and uses a dynamically expanded buffer as needed.
+**
+** void map_store(MAP *map, char *key, char *value)
+** Store the key:value pair in the map.
+**
+** bool map_open(MAP *map, int mode)
+** Open the map for the indicated mode. Mode should
+** be either O_RDONLY or O_RDWR. Return TRUE if it
+** was opened successfully, FALSE otherwise. If the open
+** failed an the MF_OPTIONAL flag is not set, it should
+** also print an error. If the MF_ALIAS bit is set
+** and this map class understands the @:@ convention, it
+** should call aliaswait() before returning.
+**
+** void map_close(MAP *map)
+** Close the map.
+*/
+
+#define DBMMODE 0644
+
+extern bool aliaswait __P((MAP *, char *, int));
+ /*
+** MAP_PARSEARGS -- parse config line arguments for database lookup
+**
+** This is a generic version of the map_parse method.
+**
+** Parameters:
+** map -- the map being initialized.
+** ap -- a pointer to the args on the config line.
+**
+** Returns:
+** TRUE -- if everything parsed OK.
+** FALSE -- otherwise.
+**
+** Side Effects:
+** null terminates the filename; stores it in map
+*/
+
+bool
+map_parseargs(map, ap)
+ MAP *map;
+ char *ap;
+{
+ register char *p = ap;
+
+ map->map_mflags |= MF_TRY0NULL | MF_TRY1NULL;
+ for (;;)
+ {
+ while (isascii(*p) && isspace(*p))
+ p++;
+ if (*p != '-')
+ break;
+ switch (*++p)
+ {
+ case 'N':
+ map->map_mflags |= MF_INCLNULL;
+ map->map_mflags &= ~MF_TRY0NULL;
+ break;
+
+ case 'O':
+ map->map_mflags &= ~MF_TRY1NULL;
+ break;
+
+ case 'o':
+ map->map_mflags |= MF_OPTIONAL;
+ break;
+
+ case 'f':
+ map->map_mflags |= MF_NOFOLDCASE;
+ break;
+
+ case 'm':
+ map->map_mflags |= MF_MATCHONLY;
+ break;
+
+ case 'a':
+ map->map_app = ++p;
+ break;
+ }
+ while (*p != '\0' && !(isascii(*p) && isspace(*p)))
+ p++;
+ if (*p != '\0')
+ *p++ = '\0';
+ }
+ if (map->map_app != NULL)
+ map->map_app = newstr(map->map_app);
+
+ if (*p != '\0')
+ {
+ map->map_file = p;
+ while (*p != '\0' && !(isascii(*p) && isspace(*p)))
+ p++;
+ if (*p != '\0')
+ *p++ = '\0';
+ map->map_file = newstr(map->map_file);
+ }
+
+ while (*p != '\0' && isascii(*p) && isspace(*p))
+ p++;
+ if (*p != '\0')
+ map->map_rebuild = newstr(p);
+
+ if (map->map_file == NULL)
+ {
+ syserr("No file name for %s map %s",
+ map->map_class->map_cname, map->map_mname);
+ return FALSE;
+ }
+ return TRUE;
+}
+ /*
+** MAP_REWRITE -- rewrite a database key, interpolating %n indications.
+**
+** It also adds the map_app string. It can be used as a utility
+** in the map_lookup method.
+**
+** Parameters:
+** map -- the map that causes this.
+** s -- the string to rewrite, NOT necessarily null terminated.
+** slen -- the length of s.
+** av -- arguments to interpolate into buf.
+**
+** Returns:
+** Pointer to rewritten result.
+**
+** Side Effects:
+** none.
+*/
+
+struct rwbuf
+{
+ int rwb_len; /* size of buffer */
+ char *rwb_buf; /* ptr to buffer */
+};
+
+struct rwbuf RwBufs[2]; /* buffers for rewriting output */
+
+char *
+map_rewrite(map, s, slen, av)
+ register MAP *map;
+ register char *s;
+ int slen;
+ char **av;
+{
+ register char *bp;
+ register char c;
+ char **avp;
+ register char *ap;
+ register struct rwbuf *rwb;
+ int i;
+ int len;
+
+ if (tTd(39, 1))
+ {
+ printf("map_rewrite(%.*s), av =", slen, s);
+ if (av == NULL)
+ printf(" (nullv)");
+ else
+ {
+ for (avp = av; *avp != NULL; avp++)
+ printf("\n\t%s", *avp);
+ }
+ printf("\n");
+ }
+
+ rwb = RwBufs;
+ if (av == NULL)
+ rwb++;
+
+ /* count expected size of output (can safely overestimate) */
+ i = len = slen;
+ if (av != NULL)
+ {
+ bp = s;
+ for (i = slen; --i >= 0 && (c = *bp++) != 0; )
+ {
+ if (c != '%')
+ continue;
+ if (--i < 0)
+ break;
+ c = *bp++;
+ if (!(isascii(c) && isdigit(c)))
+ continue;
+ for (avp = av; --c >= '0' && *avp != NULL; avp++)
+ continue;
+ if (*avp == NULL)
+ continue;
+ len += strlen(*avp);
+ }
+ }
+ if (map->map_app != NULL)
+ len += strlen(map->map_app);
+ if (rwb->rwb_len < ++len)
+ {
+ /* need to malloc additional space */
+ rwb->rwb_len = len;
+ if (rwb->rwb_buf != NULL)
+ free(rwb->rwb_buf);
+ rwb->rwb_buf = xalloc(rwb->rwb_len);
+ }
+
+ bp = rwb->rwb_buf;
+ if (av == NULL)
+ {
+ bcopy(s, bp, slen);
+ bp += slen;
+ }
+ else
+ {
+ while (--slen >= 0 && (c = *s++) != '\0')
+ {
+ if (c != '%')
+ {
+ pushc:
+ *bp++ = c;
+ continue;
+ }
+ if (--slen < 0 || (c = *s++) == '\0')
+ c = '%';
+ if (c == '%')
+ goto pushc;
+ if (!(isascii(c) && isdigit(c)))
+ {
+ *bp++ = '%';
+ goto pushc;
+ }
+ for (avp = av; --c >= '0' && *avp != NULL; avp++)
+ continue;
+ if (*avp == NULL)
+ continue;
+
+ /* transliterate argument into output string */
+ for (ap = *avp; (c = *ap++) != '\0'; )
+ *bp++ = c;
+ }
+ }
+ if (map->map_app != NULL)
+ strcpy(bp, map->map_app);
+ else
+ *bp = '\0';
+ if (tTd(39, 1))
+ printf("map_rewrite => %s\n", rwb->rwb_buf);
+ return rwb->rwb_buf;
+}
+ /*
+** INITMAPS -- initialize for aliasing
+**
+** Parameters:
+** rebuild -- if TRUE, this rebuilds the cached versions.
+** e -- current envelope.
+**
+** Returns:
+** none.
+**
+** Side Effects:
+** initializes aliases:
+** if NDBM: opens the database.
+** if ~NDBM: reads the aliases into the symbol table.
+*/
+
+initmaps(rebuild, e)
+ bool rebuild;
+ register ENVELOPE *e;
+{
+ extern void map_init();
+
+#ifdef XDEBUG
+ checkfd012("entering initmaps");
+#endif
+ CurEnv = e;
+ if (rebuild)
+ {
+ stabapply(map_init, 1);
+ stabapply(map_init, 2);
+ }
+ else
+ {
+ stabapply(map_init, 0);
+ }
+#ifdef XDEBUG
+ checkfd012("exiting initmaps");
+#endif
+}
+
+void
+map_init(s, rebuild)
+ register STAB *s;
+ int rebuild;
+{
+ register MAP *map;
+
+ /* has to be a map */
+ if (s->s_type != ST_MAP)
+ return;
+
+ map = &s->s_map;
+ if (!bitset(MF_VALID, map->map_mflags))
+ return;
+
+ if (tTd(38, 2))
+ printf("map_init(%s:%s, %d)\n",
+ map->map_class->map_cname == NULL ? "NULL" :
+ map->map_class->map_cname,
+ map->map_file == NULL ? "NULL" : map->map_file,
+ rebuild);
+
+ if (rebuild == (bitset(MF_ALIAS, map->map_mflags) &&
+ bitset(MCF_REBUILDABLE, map->map_class->map_cflags) ? 1 : 2))
+ {
+ if (tTd(38, 3))
+ printf("\twrong pass\n");
+ return;
+ }
+
+ /* if already open, close it (for nested open) */
+ if (bitset(MF_OPEN, map->map_mflags))
+ {
+ map->map_class->map_close(map);
+ map->map_mflags &= ~(MF_OPEN|MF_WRITABLE);
+ }
+
+ if (rebuild == 2)
+ {
+ rebuildaliases(map, FALSE);
+ }
+ else
+ {
+ if (map->map_class->map_open(map, O_RDONLY))
+ {
+ if (tTd(38, 4))
+ printf("\t%s:%s: valid\n",
+ map->map_class->map_cname == NULL ? "NULL" :
+ map->map_class->map_cname,
+ map->map_file == NULL ? "NULL" :
+ map->map_file);
+ map->map_mflags |= MF_OPEN;
+ }
+ else if (tTd(38, 4))
+ printf("\t%s:%s: invalid: %s\n",
+ map->map_class->map_cname == NULL ? "NULL" :
+ map->map_class->map_cname,
+ map->map_file == NULL ? "NULL" :
+ map->map_file,
+ errstring(errno));
+ }
+}
+ /*
+** NDBM modules
+*/
+
+#ifdef NDBM
+
+/*
+** DBM_MAP_OPEN -- DBM-style map open
+*/
+
+bool
+ndbm_map_open(map, mode)
+ MAP *map;
+ int mode;
+{
+ register DBM *dbm;
+ struct stat st;
+
+ if (tTd(38, 2))
+ printf("ndbm_map_open(%s, %d)\n", map->map_file, mode);
+
+ if (mode == O_RDWR)
+ mode |= O_CREAT|O_TRUNC;
+
+ /* open the database */
+ dbm = dbm_open(map->map_file, mode, DBMMODE);
+ if (dbm == NULL)
+ {
+#ifdef MAYBENEXTRELEASE
+ if (aliaswait(map, ".pag", FALSE))
+ return TRUE;
+#endif
+ if (!bitset(MF_OPTIONAL, map->map_mflags))
+ syserr("Cannot open DBM database %s", map->map_file);
+ return FALSE;
+ }
+ map->map_db1 = (void *) dbm;
+ if (mode == O_RDONLY)
+ {
+ if (bitset(MF_ALIAS, map->map_mflags) &&
+ !aliaswait(map, ".pag", TRUE))
+ return FALSE;
+ }
+ else
+ {
+ int fd;
+
+ /* exclusive lock for duration of rebuild */
+ fd = dbm_dirfno((DBM *) map->map_db1);
+ if (fd >= 0 && !bitset(MF_LOCKED, map->map_mflags) &&
+ lockfile(fd, map->map_file, ".dir", LOCK_EX))
+ map->map_mflags |= MF_LOCKED;
+ }
+ if (fstat(dbm_dirfno((DBM *) map->map_db1), &st) >= 0)
+ map->map_mtime = st.st_mtime;
+ return TRUE;
+}
+
+
+/*
+** DBM_MAP_LOOKUP -- look up a datum in a DBM-type map
+*/
+
+char *
+ndbm_map_lookup(map, name, av, statp)
+ MAP *map;
+ char *name;
+ char **av;
+ int *statp;
+{
+ datum key, val;
+ int fd;
+ char keybuf[MAXNAME + 1];
+
+ if (tTd(38, 20))
+ printf("ndbm_map_lookup(%s)\n", name);
+
+ key.dptr = name;
+ key.dsize = strlen(name);
+ if (!bitset(MF_NOFOLDCASE, map->map_mflags))
+ {
+ if (key.dsize > sizeof keybuf - 1)
+ key.dsize = sizeof keybuf - 1;
+ bcopy(key.dptr, keybuf, key.dsize + 1);
+ makelower(keybuf);
+ key.dptr = keybuf;
+ }
+ fd = dbm_dirfno((DBM *) map->map_db1);
+ if (fd >= 0 && !bitset(MF_LOCKED, map->map_mflags))
+ (void) lockfile(fd, map->map_file, ".dir", LOCK_SH);
+ val.dptr = NULL;
+ if (bitset(MF_TRY0NULL, map->map_mflags))
+ {
+ val = dbm_fetch((DBM *) map->map_db1, key);
+ if (val.dptr != NULL)
+ map->map_mflags &= ~MF_TRY1NULL;
+ }
+ if (val.dptr == NULL && bitset(MF_TRY1NULL, map->map_mflags))
+ {
+ key.dsize++;
+ val = dbm_fetch((DBM *) map->map_db1, key);
+ if (val.dptr != NULL)
+ map->map_mflags &= ~MF_TRY0NULL;
+ }
+ if (fd >= 0 && !bitset(MF_LOCKED, map->map_mflags))
+ (void) lockfile(fd, map->map_file, ".dir", LOCK_UN);
+ if (val.dptr == NULL)
+ return NULL;
+ if (bitset(MF_MATCHONLY, map->map_mflags))
+ return map_rewrite(map, name, strlen(name), NULL);
+ else
+ return map_rewrite(map, val.dptr, val.dsize, av);
+}
+
+
+/*
+** DBM_MAP_STORE -- store a datum in the database
+*/
+
+void
+ndbm_map_store(map, lhs, rhs)
+ register MAP *map;
+ char *lhs;
+ char *rhs;
+{
+ datum key;
+ datum data;
+ int stat;
+
+ if (tTd(38, 12))
+ printf("ndbm_map_store(%s, %s)\n", lhs, rhs);
+
+ key.dsize = strlen(lhs);
+ key.dptr = lhs;
+
+ data.dsize = strlen(rhs);
+ data.dptr = rhs;
+
+ if (bitset(MF_INCLNULL, map->map_mflags))
+ {
+ key.dsize++;
+ data.dsize++;
+ }
+
+ stat = dbm_store((DBM *) map->map_db1, key, data, DBM_INSERT);
+ if (stat > 0)
+ {
+ usrerr("050 Warning: duplicate alias name %s", lhs);
+ stat = dbm_store((DBM *) map->map_db1, key, data, DBM_REPLACE);
+ }
+ if (stat != 0)
+ syserr("readaliases: dbm put (%s)", lhs);
+}
+
+
+/*
+** NDBM_MAP_CLOSE -- close the database
+*/
+
+void
+ndbm_map_close(map)
+ register MAP *map;
+{
+ if (tTd(38, 9))
+ printf("ndbm_map_close(%s, %x)\n", map->map_file, map->map_mflags);
+
+ if (bitset(MF_WRITABLE, map->map_mflags))
+ {
+#ifdef NIS
+ bool inclnull;
+ char buf[200];
+
+ inclnull = bitset(MF_INCLNULL, map->map_mflags);
+ map->map_mflags &= ~MF_INCLNULL;
+
+ (void) sprintf(buf, "%010ld", curtime());
+ ndbm_map_store(map, "YP_LAST_MODIFIED", buf);
+
+ (void) gethostname(buf, sizeof buf);
+ ndbm_map_store(map, "YP_MASTER_NAME", buf);
+
+ if (inclnull)
+ map->map_mflags |= MF_INCLNULL;
+#endif
+
+ /* write out the distinguished alias */
+ ndbm_map_store(map, "@", "@");
+ }
+ dbm_close((DBM *) map->map_db1);
+}
+
+#endif
+ /*
+** NEWDB (Hash and BTree) Modules
+*/
+
+#ifdef NEWDB
+
+/*
+** BT_MAP_OPEN, HASH_MAP_OPEN -- database open primitives.
+**
+** These do rather bizarre locking. If you can lock on open,
+** do that to avoid the condition of opening a database that
+** is being rebuilt. If you don't, we'll try to fake it, but
+** there will be a race condition. If opening for read-only,
+** we immediately release the lock to avoid freezing things up.
+** We really ought to hold the lock, but guarantee that we won't
+** be pokey about it. That's hard to do.
+*/
+
+bool
+bt_map_open(map, mode)
+ MAP *map;
+ int mode;
+{
+ DB *db;
+ int i;
+ int omode;
+ int fd;
+ struct stat st;
+ char buf[MAXNAME];
+
+ if (tTd(38, 2))
+ printf("bt_map_open(%s, %d)\n", map->map_file, mode);
+
+ omode = mode;
+ if (omode == O_RDWR)
+ {
+ omode |= O_CREAT|O_TRUNC;
+#if defined(O_EXLOCK) && HASFLOCK
+ omode |= O_EXLOCK;
+# if !OLD_NEWDB
+ }
+ else
+ {
+ omode |= O_SHLOCK;
+# endif
+#endif
+ }
+
+ (void) strcpy(buf, map->map_file);
+ i = strlen(buf);
+ if (i < 3 || strcmp(&buf[i - 3], ".db") != 0)
+ (void) strcat(buf, ".db");
+ db = dbopen(buf, omode, DBMMODE, DB_BTREE, NULL);
+ if (db == NULL)
+ {
+#ifdef MAYBENEXTRELEASE
+ if (aliaswait(map, ".db", FALSE))
+ return TRUE;
+#endif
+ if (!bitset(MF_OPTIONAL, map->map_mflags))
+ syserr("Cannot open BTREE database %s", map->map_file);
+ return FALSE;
+ }
+#if !OLD_NEWDB && HASFLOCK
+ fd = db->fd(db);
+# if !defined(O_EXLOCK)
+ if (mode == O_RDWR && fd >= 0)
+ {
+ if (lockfile(fd, map->map_file, ".db", LOCK_EX))
+ map->map_mflags |= MF_LOCKED;
+ }
+# else
+ if (mode == O_RDONLY && fd >= 0)
+ (void) lockfile(fd, map->map_file, ".db", LOCK_UN);
+ else
+ map->map_mflags |= MF_LOCKED;
+# endif
+#endif
+
+ /* try to make sure that at least the database header is on disk */
+ if (mode == O_RDWR)
+#if OLD_NEWDB
+ (void) db->sync(db);
+#else
+ (void) db->sync(db, 0);
+
+ if (fd >= 0 && fstat(fd, &st) >= 0)
+ map->map_mtime = st.st_mtime;
+#endif
+
+ map->map_db2 = (void *) db;
+ if (mode == O_RDONLY && bitset(MF_ALIAS, map->map_mflags))
+ if (!aliaswait(map, ".db", TRUE))
+ return FALSE;
+ return TRUE;
+}
+
+
+/*
+** HASH_MAP_INIT -- HASH-style map initialization
+*/
+
+bool
+hash_map_open(map, mode)
+ MAP *map;
+ int mode;
+{
+ DB *db;
+ int i;
+ int omode;
+ int fd;
+ struct stat st;
+ char buf[MAXNAME];
+
+ if (tTd(38, 2))
+ printf("hash_map_open(%s, %d)\n", map->map_file, mode);
+
+ omode = mode;
+ if (omode == O_RDWR)
+ {
+ omode |= O_CREAT|O_TRUNC;
+#if defined(O_EXLOCK) && HASFLOCK
+ omode |= O_EXLOCK;
+# if !OLD_NEWDB
+ }
+ else
+ {
+ omode |= O_SHLOCK;
+# endif
+#endif
+ }
+
+ (void) strcpy(buf, map->map_file);
+ i = strlen(buf);
+ if (i < 3 || strcmp(&buf[i - 3], ".db") != 0)
+ (void) strcat(buf, ".db");
+ db = dbopen(buf, omode, DBMMODE, DB_HASH, NULL);
+ if (db == NULL)
+ {
+#ifdef MAYBENEXTRELEASE
+ if (aliaswait(map, ".db", FALSE))
+ return TRUE;
+#endif
+ if (!bitset(MF_OPTIONAL, map->map_mflags))
+ syserr("Cannot open HASH database %s", map->map_file);
+ return FALSE;
+ }
+#if !OLD_NEWDB && HASFLOCK
+ fd = db->fd(db);
+# if !defined(O_EXLOCK)
+ if (mode == O_RDWR && fd >= 0)
+ {
+ if (lockfile(fd, map->map_file, ".db", LOCK_EX))
+ map->map_mflags |= MF_LOCKED;
+ }
+# else
+ if (mode == O_RDONLY && fd >= 0)
+ (void) lockfile(fd, map->map_file, ".db", LOCK_UN);
+ else
+ map->map_mflags |= MF_LOCKED;
+# endif
+#endif
+
+ /* try to make sure that at least the database header is on disk */
+ if (mode == O_RDWR)
+#if OLD_NEWDB
+ (void) db->sync(db);
+#else
+ (void) db->sync(db, 0);
+
+ if (fd >= 0 && fstat(fd, &st) >= 0)
+ map->map_mtime = st.st_mtime;
+#endif
+
+ map->map_db2 = (void *) db;
+ if (mode == O_RDONLY && bitset(MF_ALIAS, map->map_mflags))
+ if (!aliaswait(map, ".db", TRUE))
+ return FALSE;
+ return TRUE;
+}
+
+
+/*
+** DB_MAP_LOOKUP -- look up a datum in a BTREE- or HASH-type map
+*/
+
+char *
+db_map_lookup(map, name, av, statp)
+ MAP *map;
+ char *name;
+ char **av;
+ int *statp;
+{
+ DBT key, val;
+ register DB *db = (DB *) map->map_db2;
+ int st;
+ int saveerrno;
+ int fd;
+ char keybuf[MAXNAME + 1];
+
+ if (tTd(38, 20))
+ printf("db_map_lookup(%s)\n", name);
+
+ key.size = strlen(name);
+ if (key.size > sizeof keybuf - 1)
+ key.size = sizeof keybuf - 1;
+ key.data = keybuf;
+ bcopy(name, keybuf, key.size + 1);
+ if (!bitset(MF_NOFOLDCASE, map->map_mflags))
+ makelower(keybuf);
+#if !OLD_NEWDB
+ fd = db->fd(db);
+ if (fd >= 0 && !bitset(MF_LOCKED, map->map_mflags))
+ (void) lockfile(db->fd(db), map->map_file, ".db", LOCK_SH);
+#endif
+ st = 1;
+ if (bitset(MF_TRY0NULL, map->map_mflags))
+ {
+ st = db->get(db, &key, &val, 0);
+ if (st == 0)
+ map->map_mflags &= ~MF_TRY1NULL;
+ }
+ if (st != 0 && bitset(MF_TRY1NULL, map->map_mflags))
+ {
+ key.size++;
+ st = db->get(db, &key, &val, 0);
+ if (st == 0)
+ map->map_mflags &= ~MF_TRY0NULL;
+ }
+ saveerrno = errno;
+#if !OLD_NEWDB
+ if (fd >= 0 && !bitset(MF_LOCKED, map->map_mflags))
+ (void) lockfile(fd, map->map_file, ".db", LOCK_UN);
+#endif
+ if (st != 0)
+ {
+ errno = saveerrno;
+ if (st < 0)
+ syserr("db_map_lookup: get (%s)", name);
+ return NULL;
+ }
+ if (bitset(MF_MATCHONLY, map->map_mflags))
+ return map_rewrite(map, name, strlen(name), NULL);
+ else
+ return map_rewrite(map, val.data, val.size, av);
+}
+
+
+/*
+** DB_MAP_STORE -- store a datum in the NEWDB database
+*/
+
+void
+db_map_store(map, lhs, rhs)
+ register MAP *map;
+ char *lhs;
+ char *rhs;
+{
+ int stat;
+ DBT key;
+ DBT data;
+ register DB *db = map->map_db2;
+
+ if (tTd(38, 20))
+ printf("db_map_store(%s, %s)\n", lhs, rhs);
+
+ key.size = strlen(lhs);
+ key.data = lhs;
+
+ data.size = strlen(rhs);
+ data.data = rhs;
+
+ if (bitset(MF_INCLNULL, map->map_mflags))
+ {
+ key.size++;
+ data.size++;
+ }
+
+ stat = db->put(db, &key, &data, R_NOOVERWRITE);
+ if (stat > 0)
+ {
+ usrerr("050 Warning: duplicate alias name %s", lhs);
+ stat = db->put(db, &key, &data, 0);
+ }
+ if (stat != 0)
+ syserr("readaliases: db put (%s)", lhs);
+}
+
+
+/*
+** DB_MAP_CLOSE -- add distinguished entries and close the database
+*/
+
+void
+db_map_close(map)
+ MAP *map;
+{
+ register DB *db = map->map_db2;
+
+ if (tTd(38, 9))
+ printf("db_map_close(%s, %x)\n", map->map_file, map->map_mflags);
+
+ if (bitset(MF_WRITABLE, map->map_mflags))
+ {
+ /* write out the distinguished alias */
+ db_map_store(map, "@", "@");
+ }
+
+ if (db->close(db) != 0)
+ syserr("readaliases: db close failure");
+}
+
+#endif
+ /*
+** NIS Modules
+*/
+
+# ifdef NIS
+
+# ifndef YPERR_BUSY
+# define YPERR_BUSY 16
+# endif
+
+/*
+** NIS_MAP_OPEN -- open DBM map
+*/
+
+bool
+nis_map_open(map, mode)
+ MAP *map;
+ int mode;
+{
+ int yperr;
+ register char *p;
+ auto char *vp;
+ auto int vsize;
+ char *master;
+
+ if (tTd(38, 2))
+ printf("nis_map_open(%s)\n", map->map_file);
+
+ if (mode != O_RDONLY)
+ {
+ /* issue a pseudo-error message */
+#ifdef ENOSYS
+ errno = ENOSYS;
+#else
+# ifdef EFTYPE
+ errno = EFTYPE;
+# else
+ errno = ENXIO;
+# endif
+#endif
+ return FALSE;
+ }
+
+ p = strchr(map->map_file, '@');
+ if (p != NULL)
+ {
+ *p++ = '\0';
+ if (*p != '\0')
+ map->map_domain = p;
+ }
+
+ if (*map->map_file == '\0')
+ map->map_file = "mail.aliases";
+
+ if (map->map_domain == NULL)
+ {
+ yperr = yp_get_default_domain(&map->map_domain);
+ if (yperr != 0)
+ {
+ if (!bitset(MF_OPTIONAL, map->map_mflags))
+ syserr("NIS map %s specified, but NIS not running\n",
+ map->map_file);
+ return FALSE;
+ }
+ }
+
+ /* check to see if this map actually exists */
+ yperr = yp_match(map->map_domain, map->map_file, "@", 1,
+ &vp, &vsize);
+ if (tTd(38, 10))
+ printf("nis_map_open: yp_match(%s, %s) => %s\n",
+ map->map_domain, map->map_file, yperr_string(yperr));
+ if (yperr == 0 || yperr == YPERR_KEY || yperr == YPERR_BUSY)
+ return TRUE;
+
+ if (!bitset(MF_OPTIONAL, map->map_mflags))
+ syserr("Cannot bind to domain %s: %s", map->map_domain,
+ yperr_string(yperr));
+
+ return FALSE;
+}
+
+
+/*
+** NIS_MAP_LOOKUP -- look up a datum in a NIS map
+*/
+
+char *
+nis_map_lookup(map, name, av, statp)
+ MAP *map;
+ char *name;
+ char **av;
+ int *statp;
+{
+ char *vp;
+ auto int vsize;
+ int buflen;
+ int yperr;
+ char keybuf[MAXNAME + 1];
+
+ if (tTd(38, 20))
+ printf("nis_map_lookup(%s)\n", name);
+
+ buflen = strlen(name);
+ if (buflen > sizeof keybuf - 1)
+ buflen = sizeof keybuf - 1;
+ bcopy(name, keybuf, buflen + 1);
+ if (!bitset(MF_NOFOLDCASE, map->map_mflags))
+ makelower(keybuf);
+ yperr = YPERR_KEY;
+ if (bitset(MF_TRY0NULL, map->map_mflags))
+ {
+ yperr = yp_match(map->map_domain, map->map_file, keybuf, buflen,
+ &vp, &vsize);
+ if (yperr == 0)
+ map->map_mflags &= ~MF_TRY1NULL;
+ }
+ if (yperr == YPERR_KEY && bitset(MF_TRY1NULL, map->map_mflags))
+ {
+ buflen++;
+ yperr = yp_match(map->map_domain, map->map_file, keybuf, buflen,
+ &vp, &vsize);
+ if (yperr == 0)
+ map->map_mflags &= ~MF_TRY0NULL;
+ }
+ if (yperr != 0)
+ {
+ if (yperr != YPERR_KEY && yperr != YPERR_BUSY)
+ map->map_mflags &= ~(MF_VALID|MF_OPEN);
+ return NULL;
+ }
+ if (bitset(MF_MATCHONLY, map->map_mflags))
+ return map_rewrite(map, name, strlen(name), NULL);
+ else
+ return map_rewrite(map, vp, vsize, av);
+}
+
+
+/*
+** NIS_MAP_STORE
+*/
+
+void
+nis_map_store(map, lhs, rhs)
+ MAP *map;
+ char *lhs;
+ char *rhs;
+{
+ /* nothing */
+}
+
+
+/*
+** NIS_MAP_CLOSE
+*/
+
+void
+nis_map_close(map)
+ MAP *map;
+{
+ /* nothing */
+}
+
+#endif /* NIS */
+ /*
+** STAB (Symbol Table) Modules
+*/
+
+
+/*
+** STAB_MAP_LOOKUP -- look up alias in symbol table
+*/
+
+char *
+stab_map_lookup(map, name, av, pstat)
+ register MAP *map;
+ char *name;
+ char **av;
+ int *pstat;
+{
+ register STAB *s;
+
+ if (tTd(38, 20))
+ printf("stab_lookup(%s)\n", name);
+
+ s = stab(name, ST_ALIAS, ST_FIND);
+ if (s != NULL)
+ return (s->s_alias);
+ return (NULL);
+}
+
+
+/*
+** STAB_MAP_STORE -- store in symtab (actually using during init, not rebuild)
+*/
+
+void
+stab_map_store(map, lhs, rhs)
+ register MAP *map;
+ char *lhs;
+ char *rhs;
+{
+ register STAB *s;
+
+ s = stab(lhs, ST_ALIAS, ST_ENTER);
+ s->s_alias = newstr(rhs);
+}
+
+
+/*
+** STAB_MAP_OPEN -- initialize (reads data file)
+**
+** This is a wierd case -- it is only intended as a fallback for
+** aliases. For this reason, opens for write (only during a
+** "newaliases") always fails, and opens for read open the
+** actual underlying text file instead of the database.
+*/
+
+bool
+stab_map_open(map, mode)
+ register MAP *map;
+ int mode;
+{
+ FILE *af;
+ struct stat st;
+
+ if (tTd(38, 2))
+ printf("stab_map_open(%s)\n", map->map_file);
+
+ if (mode != O_RDONLY)
+ {
+ errno = ENODEV;
+ return FALSE;
+ }
+
+ af = fopen(map->map_file, "r");
+ if (af == NULL)
+ return FALSE;
+ readaliases(map, af, TRUE);
+
+ if (fstat(fileno(af), &st) >= 0)
+ map->map_mtime = st.st_mtime;
+ fclose(af);
+
+ return TRUE;
+}
+
+
+/*
+** STAB_MAP_CLOSE -- close symbol table.
+**
+** Since this is in memory, there is nothing to do.
+*/
+
+void
+stab_map_close(map)
+ MAP *map;
+{
+ /* ignore it */
+}
+ /*
+** Implicit Modules
+**
+** Tries several types. For back compatibility of aliases.
+*/
+
+
+/*
+** IMPL_MAP_LOOKUP -- lookup in best open database
+*/
+
+char *
+impl_map_lookup(map, name, av, pstat)
+ MAP *map;
+ char *name;
+ char **av;
+ int *pstat;
+{
+ if (tTd(38, 20))
+ printf("impl_map_lookup(%s)\n", name);
+
+#ifdef NEWDB
+ if (bitset(MF_IMPL_HASH, map->map_mflags))
+ return db_map_lookup(map, name, av, pstat);
+#endif
+#ifdef NDBM
+ if (bitset(MF_IMPL_NDBM, map->map_mflags))
+ return ndbm_map_lookup(map, name, av, pstat);
+#endif
+ return stab_map_lookup(map, name, av, pstat);
+}
+
+/*
+** IMPL_MAP_STORE -- store in open databases
+*/
+
+void
+impl_map_store(map, lhs, rhs)
+ MAP *map;
+ char *lhs;
+ char *rhs;
+{
+#ifdef NEWDB
+ if (bitset(MF_IMPL_HASH, map->map_mflags))
+ db_map_store(map, lhs, rhs);
+#endif
+#ifdef NDBM
+ if (bitset(MF_IMPL_NDBM, map->map_mflags))
+ ndbm_map_store(map, lhs, rhs);
+#endif
+ stab_map_store(map, lhs, rhs);
+}
+
+/*
+** IMPL_MAP_OPEN -- implicit database open
+*/
+
+bool
+impl_map_open(map, mode)
+ MAP *map;
+ int mode;
+{
+ struct stat stb;
+
+ if (tTd(38, 2))
+ printf("impl_map_open(%s, %d)\n", map->map_file, mode);
+
+ if (stat(map->map_file, &stb) < 0)
+ {
+ /* no alias file at all */
+ if (tTd(38, 3))
+ printf("no map file\n");
+ return FALSE;
+ }
+
+#ifdef NEWDB
+ map->map_mflags |= MF_IMPL_HASH;
+ if (hash_map_open(map, mode))
+ {
+#if defined(NDBM) && defined(NIS)
+ if (mode == O_RDONLY || access("/var/yp/Makefile", R_OK) != 0)
+#endif
+ return TRUE;
+ }
+ else
+ map->map_mflags &= ~MF_IMPL_HASH;
+#endif
+#ifdef NDBM
+ map->map_mflags |= MF_IMPL_NDBM;
+ if (ndbm_map_open(map, mode))
+ {
+ return TRUE;
+ }
+ else
+ map->map_mflags &= ~MF_IMPL_NDBM;
+#endif
+
+#if defined(NEWDB) || defined(NDBM)
+ if (Verbose)
+ message("WARNING: cannot open alias database %s", map->map_file);
+#else
+ if (mode != O_RDONLY)
+ usrerr("Cannot rebuild aliases: no database format defined");
+#endif
+
+ return stab_map_open(map, mode);
+}
+
+
+/*
+** IMPL_MAP_CLOSE -- close any open database(s)
+*/
+
+void
+impl_map_close(map)
+ MAP *map;
+{
+#ifdef NEWDB
+ if (bitset(MF_IMPL_HASH, map->map_mflags))
+ {
+ db_map_close(map);
+ map->map_mflags &= ~MF_IMPL_HASH;
+ }
+#endif
+
+#ifdef NDBM
+ if (bitset(MF_IMPL_NDBM, map->map_mflags))
+ {
+ ndbm_map_close(map);
+ map->map_mflags &= ~MF_IMPL_NDBM;
+ }
+#endif
+}
+ /*
+** NULL stubs
+*/
+
+bool
+null_map_open(map, mode)
+ MAP *map;
+ int mode;
+{
+ return TRUE;
+}
+
+void
+null_map_close(map)
+ MAP *map;
+{
+ return;
+}
+
+void
+null_map_store(map, key, val)
+ MAP *map;
+ char *key;
+ char *val;
+{
+ return;
+}
diff --git a/usr.sbin/sendmail/src/mci.c b/usr.sbin/sendmail/src/mci.c
new file mode 100644
index 0000000..8160b83
--- /dev/null
+++ b/usr.sbin/sendmail/src/mci.c
@@ -0,0 +1,398 @@
+/*
+ * Copyright (c) 1983 Eric P. Allman
+ * Copyright (c) 1988, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)mci.c 8.13 (Berkeley) 4/12/94";
+#endif /* not lint */
+
+#include "sendmail.h"
+
+/*
+** Mail Connection Information (MCI) Caching Module.
+**
+** There are actually two separate things cached. The first is
+** the set of all open connections -- these are stored in a
+** (small) list. The second is stored in the symbol table; it
+** has the overall status for all hosts, whether or not there
+** is a connection open currently.
+**
+** There should never be too many connections open (since this
+** could flood the socket table), nor should a connection be
+** allowed to sit idly for too long.
+**
+** MaxMciCache is the maximum number of open connections that
+** will be supported.
+**
+** MciCacheTimeout is the time (in seconds) that a connection
+** is permitted to survive without activity.
+**
+** We actually try any cached connections by sending a NOOP
+** before we use them; if the NOOP fails we close down the
+** connection and reopen it. Note that this means that a
+** server SMTP that doesn't support NOOP will hose the
+** algorithm -- but that doesn't seem too likely.
+*/
+
+MCI **MciCache; /* the open connection cache */
+ /*
+** MCI_CACHE -- enter a connection structure into the open connection cache
+**
+** This may cause something else to be flushed.
+**
+** Parameters:
+** mci -- the connection to cache.
+**
+** Returns:
+** none.
+*/
+
+mci_cache(mci)
+ register MCI *mci;
+{
+ register MCI **mcislot;
+ extern MCI **mci_scan();
+
+ if (MaxMciCache <= 0)
+ {
+ /* we don't support caching */
+ return;
+ }
+
+ /*
+ ** Find the best slot. This may cause expired connections
+ ** to be closed.
+ */
+
+ mcislot = mci_scan(mci);
+
+ /* if this is already cached, we are done */
+ if (bitset(MCIF_CACHED, mci->mci_flags))
+ return;
+
+ /* otherwise we may have to clear the slot */
+ if (*mcislot != NULL)
+ mci_uncache(mcislot, TRUE);
+
+ if (tTd(42, 5))
+ printf("mci_cache: caching %x (%s) in slot %d\n",
+ mci, mci->mci_host, mcislot - MciCache);
+#ifdef LOG
+ if (tTd(91, 100))
+ syslog(LOG_DEBUG, "%s: mci_cache: caching %x (%s) in slot %d",
+ CurEnv->e_id ? CurEnv->e_id : "NOQUEUE",
+ mci, mci->mci_host, mcislot - MciCache);
+#endif
+
+ *mcislot = mci;
+ mci->mci_flags |= MCIF_CACHED;
+}
+ /*
+** MCI_SCAN -- scan the cache, flush junk, and return best slot
+**
+** Parameters:
+** savemci -- never flush this one. Can be null.
+**
+** Returns:
+** The LRU (or empty) slot.
+*/
+
+MCI **
+mci_scan(savemci)
+ MCI *savemci;
+{
+ time_t now;
+ register MCI **bestmci;
+ register MCI *mci;
+ register int i;
+
+ if (MciCache == NULL)
+ {
+ /* first call */
+ MciCache = (MCI **) xalloc(MaxMciCache * sizeof *MciCache);
+ bzero((char *) MciCache, MaxMciCache * sizeof *MciCache);
+ return (&MciCache[0]);
+ }
+
+ now = curtime();
+ bestmci = &MciCache[0];
+ for (i = 0; i < MaxMciCache; i++)
+ {
+ mci = MciCache[i];
+ if (mci == NULL || mci->mci_state == MCIS_CLOSED)
+ {
+ bestmci = &MciCache[i];
+ continue;
+ }
+ if (mci->mci_lastuse + MciCacheTimeout < now && mci != savemci)
+ {
+ /* connection idle too long -- close it */
+ bestmci = &MciCache[i];
+ mci_uncache(bestmci, TRUE);
+ continue;
+ }
+ if (*bestmci == NULL)
+ continue;
+ if (mci->mci_lastuse < (*bestmci)->mci_lastuse)
+ bestmci = &MciCache[i];
+ }
+ return bestmci;
+}
+ /*
+** MCI_UNCACHE -- remove a connection from a slot.
+**
+** May close a connection.
+**
+** Parameters:
+** mcislot -- the slot to empty.
+** doquit -- if TRUE, send QUIT protocol on this connection.
+** if FALSE, we are assumed to be in a forked child;
+** all we want to do is close the file(s).
+**
+** Returns:
+** none.
+*/
+
+mci_uncache(mcislot, doquit)
+ register MCI **mcislot;
+ bool doquit;
+{
+ register MCI *mci;
+ extern ENVELOPE BlankEnvelope;
+
+ mci = *mcislot;
+ if (mci == NULL)
+ return;
+ *mcislot = NULL;
+
+ if (tTd(42, 5))
+ printf("mci_uncache: uncaching %x (%s) from slot %d (%d)\n",
+ mci, mci->mci_host, mcislot - MciCache, doquit);
+#ifdef LOG
+ if (tTd(91, 100))
+ syslog(LOG_DEBUG, "%s: mci_uncache: uncaching %x (%s) from slot %d (%d)",
+ CurEnv->e_id ? CurEnv->e_id : "NOQUEUE",
+ mci, mci->mci_host, mcislot - MciCache, doquit);
+#endif
+
+ if (doquit)
+ {
+ message("Closing connection to %s", mci->mci_host);
+
+ mci->mci_flags &= ~MCIF_CACHED;
+
+ /* only uses the envelope to flush the transcript file */
+ if (mci->mci_state != MCIS_CLOSED)
+ smtpquit(mci->mci_mailer, mci, &BlankEnvelope);
+#ifdef XLA
+ xla_host_end(mci->mci_host);
+#endif
+ }
+ else
+ {
+ if (mci->mci_in != NULL)
+ xfclose(mci->mci_in, "mci_uncache", "mci_in");
+ if (mci->mci_out != NULL)
+ xfclose(mci->mci_out, "mci_uncache", "mci_out");
+ mci->mci_in = mci->mci_out = NULL;
+ mci->mci_state = MCIS_CLOSED;
+ mci->mci_exitstat = EX_OK;
+ mci->mci_errno = 0;
+ mci->mci_flags = 0;
+ }
+}
+ /*
+** MCI_FLUSH -- flush the entire cache
+**
+** Parameters:
+** doquit -- if TRUE, send QUIT protocol.
+** if FALSE, just close the connection.
+** allbut -- but leave this one open.
+**
+** Returns:
+** none.
+*/
+
+mci_flush(doquit, allbut)
+ bool doquit;
+ MCI *allbut;
+{
+ register int i;
+
+ if (MciCache == NULL)
+ return;
+
+ for (i = 0; i < MaxMciCache; i++)
+ if (allbut != MciCache[i])
+ mci_uncache(&MciCache[i], doquit);
+}
+ /*
+** MCI_GET -- get information about a particular host
+*/
+
+MCI *
+mci_get(host, m)
+ char *host;
+ MAILER *m;
+{
+ register MCI *mci;
+ register STAB *s;
+
+#ifdef DAEMON
+ extern SOCKADDR CurHostAddr;
+
+ /* clear CurHostAddr so we don't get a bogus address with this name */
+ bzero(&CurHostAddr, sizeof CurHostAddr);
+#endif
+
+ /* clear out any expired connections */
+ mci_scan(NULL);
+
+ if (m->m_mno < 0)
+ syserr("negative mno %d (%s)", m->m_mno, m->m_name);
+ s = stab(host, ST_MCI + m->m_mno, ST_ENTER);
+ mci = &s->s_mci;
+ mci->mci_host = s->s_name;
+
+ if (tTd(42, 2))
+ {
+ printf("mci_get(%s %s): mci_state=%d, _flags=%x, _exitstat=%d, _errno=%d\n",
+ host, m->m_name, mci->mci_state, mci->mci_flags,
+ mci->mci_exitstat, mci->mci_errno);
+ }
+
+ if (mci->mci_state == MCIS_OPEN)
+ {
+ /* poke the connection to see if it's still alive */
+ smtpprobe(mci);
+
+ /* reset the stored state in the event of a timeout */
+ if (mci->mci_state != MCIS_OPEN)
+ {
+ mci->mci_errno = 0;
+ mci->mci_exitstat = EX_OK;
+ mci->mci_state = MCIS_CLOSED;
+ }
+ else
+ {
+ /* get peer host address for logging reasons only */
+ /* (this should really be in the mci struct) */
+ int socksize = sizeof CurHostAddr;
+
+ (void) getpeername(fileno(mci->mci_in),
+ (struct sockaddr *) &CurHostAddr, &socksize);
+ }
+ }
+ if (mci->mci_state == MCIS_CLOSED)
+ {
+ /* copy out any mailer flags needed in connection state */
+ if (bitnset(M_7BITS, m->m_flags))
+ mci->mci_flags |= MCIF_7BIT;
+ }
+
+ return mci;
+}
+ /*
+** MCI_DUMP -- dump the contents of an MCI structure.
+**
+** Parameters:
+** mci -- the MCI structure to dump.
+**
+** Returns:
+** none.
+**
+** Side Effects:
+** none.
+*/
+
+mci_dump(mci, logit)
+ register MCI *mci;
+ bool logit;
+{
+ register char *p;
+ char *sep;
+ char buf[1000];
+ extern char *ctime();
+
+ sep = logit ? " " : "\n\t";
+ p = buf;
+ sprintf(p, "MCI@%x: ", mci);
+ p += strlen(p);
+ if (mci == NULL)
+ {
+ sprintf(p, "NULL");
+ goto printit;
+ }
+ sprintf(p, "flags=%o, errno=%d, herrno=%d, exitstat=%d, state=%d, pid=%d,%s",
+ mci->mci_flags, mci->mci_errno, mci->mci_herrno,
+ mci->mci_exitstat, mci->mci_state, mci->mci_pid, sep);
+ p += strlen(p);
+ sprintf(p, "maxsize=%ld, phase=%s, mailer=%s,%s",
+ mci->mci_maxsize,
+ mci->mci_phase == NULL ? "NULL" : mci->mci_phase,
+ mci->mci_mailer == NULL ? "NULL" : mci->mci_mailer->m_name,
+ sep);
+ p += strlen(p);
+ sprintf(p, "host=%s, lastuse=%s",
+ mci->mci_host == NULL ? "NULL" : mci->mci_host,
+ ctime(&mci->mci_lastuse));
+printit:
+#ifdef LOG
+ if (logit)
+ syslog(LOG_DEBUG, "%s", buf);
+ else
+#endif
+ printf("%s\n", buf);
+}
+ /*
+** MCI_DUMP_ALL -- print the entire MCI cache
+**
+** Parameters:
+** logit -- if set, log the result instead of printing
+** to stdout.
+**
+** Returns:
+** none.
+*/
+
+mci_dump_all(logit)
+ bool logit;
+{
+ register int i;
+
+ if (MciCache == NULL)
+ return;
+
+ for (i = 0; i < MaxMciCache; i++)
+ mci_dump(MciCache[i], logit);
+}
diff --git a/usr.sbin/sendmail/src/newaliases.1 b/usr.sbin/sendmail/src/newaliases.1
new file mode 100644
index 0000000..c611b78
--- /dev/null
+++ b/usr.sbin/sendmail/src/newaliases.1
@@ -0,0 +1,68 @@
+.\" Copyright (c) 1985, 1990, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)newaliases.1 8.4 (Berkeley) 2/22/94
+.\"
+.Dd February 22, 1994
+.Dt NEWALIASES 1
+.Os BSD 4
+.Sh NAME
+.Nm newaliases
+.Nd rebuild the data base for the mail aliases file
+.Sh SYNOPSIS
+.Nm newaliases
+.Sh DESCRIPTION
+.Nm Newaliases
+rebuilds the random access data base for the mail aliases file
+.Pa /etc/aliases .
+It must be run each time this file is changed in order
+for the change to take effect.
+.Pp
+.Nm Newaliases
+is identical to
+.Dq Li "sendmail -bi" .
+.Pp
+The
+.Nm newaliases
+utility exits 0 on success, and >0 if an error occurs.
+.Sh FILES
+.Bl -tag -width /etc/aliases -compact
+.It Pa /etc/aliases
+The mail aliases file
+.El
+.Sh SEE ALSO
+.Xr aliases 5 ,
+.Xr sendmail 8
+.Sh HISTORY
+The
+.Nm newaliases
+command appeared in
+.Bx 4.0 .
diff --git a/usr.sbin/sendmail/src/parseaddr.c b/usr.sbin/sendmail/src/parseaddr.c
new file mode 100644
index 0000000..00621c2
--- /dev/null
+++ b/usr.sbin/sendmail/src/parseaddr.c
@@ -0,0 +1,1964 @@
+/*
+ * Copyright (c) 1983 Eric P. Allman
+ * Copyright (c) 1988, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)parseaddr.c 8.31 (Berkeley) 4/15/94";
+#endif /* not lint */
+
+# include "sendmail.h"
+
+/*
+** PARSEADDR -- Parse an address
+**
+** Parses an address and breaks it up into three parts: a
+** net to transmit the message on, the host to transmit it
+** to, and a user on that host. These are loaded into an
+** ADDRESS header with the values squirreled away if necessary.
+** The "user" part may not be a real user; the process may
+** just reoccur on that machine. For example, on a machine
+** with an arpanet connection, the address
+** csvax.bill@berkeley
+** will break up to a "user" of 'csvax.bill' and a host
+** of 'berkeley' -- to be transmitted over the arpanet.
+**
+** Parameters:
+** addr -- the address to parse.
+** a -- a pointer to the address descriptor buffer.
+** If NULL, a header will be created.
+** flags -- describe detail for parsing. See RF_ definitions
+** in sendmail.h.
+** delim -- the character to terminate the address, passed
+** to prescan.
+** delimptr -- if non-NULL, set to the location of the
+** delim character that was found.
+** e -- the envelope that will contain this address.
+**
+** Returns:
+** A pointer to the address descriptor header (`a' if
+** `a' is non-NULL).
+** NULL on error.
+**
+** Side Effects:
+** none
+*/
+
+/* following delimiters are inherent to the internal algorithms */
+# define DELIMCHARS "()<>,;\r\n" /* default word delimiters */
+
+ADDRESS *
+parseaddr(addr, a, flags, delim, delimptr, e)
+ char *addr;
+ register ADDRESS *a;
+ int flags;
+ int delim;
+ char **delimptr;
+ register ENVELOPE *e;
+{
+ register char **pvp;
+ auto char *delimptrbuf;
+ bool queueup;
+ char pvpbuf[PSBUFSIZE];
+ extern ADDRESS *buildaddr();
+ extern bool invalidaddr();
+
+ /*
+ ** Initialize and prescan address.
+ */
+
+ e->e_to = addr;
+ if (tTd(20, 1))
+ printf("\n--parseaddr(%s)\n", addr);
+
+ if (delimptr == NULL)
+ delimptr = &delimptrbuf;
+
+ pvp = prescan(addr, delim, pvpbuf, sizeof pvpbuf, delimptr);
+ if (pvp == NULL)
+ {
+ if (tTd(20, 1))
+ printf("parseaddr-->NULL\n");
+ return (NULL);
+ }
+
+ if (invalidaddr(addr, delim == '\0' ? NULL : *delimptr))
+ {
+ if (tTd(20, 1))
+ printf("parseaddr-->bad address\n");
+ return NULL;
+ }
+
+ /*
+ ** Save addr if we are going to have to.
+ **
+ ** We have to do this early because there is a chance that
+ ** the map lookups in the rewriting rules could clobber
+ ** static memory somewhere.
+ */
+
+ if (bitset(RF_COPYPADDR, flags) && addr != NULL)
+ {
+ char savec = **delimptr;
+
+ if (savec != '\0')
+ **delimptr = '\0';
+ e->e_to = addr = newstr(addr);
+ if (savec != '\0')
+ **delimptr = savec;
+ }
+
+ /*
+ ** Apply rewriting rules.
+ ** Ruleset 0 does basic parsing. It must resolve.
+ */
+
+ queueup = FALSE;
+ if (rewrite(pvp, 3, 0, e) == EX_TEMPFAIL)
+ queueup = TRUE;
+ if (rewrite(pvp, 0, 0, e) == EX_TEMPFAIL)
+ queueup = TRUE;
+
+
+ /*
+ ** Build canonical address from pvp.
+ */
+
+ a = buildaddr(pvp, a, flags, e);
+
+ /*
+ ** Make local copies of the host & user and then
+ ** transport them out.
+ */
+
+ allocaddr(a, flags, addr);
+ if (bitset(QBADADDR, a->q_flags))
+ return a;
+
+ /*
+ ** If there was a parsing failure, mark it for queueing.
+ */
+
+ if (queueup)
+ {
+ char *msg = "Transient parse error -- message queued for future delivery";
+
+ if (tTd(20, 1))
+ printf("parseaddr: queuing message\n");
+ message(msg);
+ if (e->e_message == NULL)
+ e->e_message = newstr(msg);
+ a->q_flags |= QQUEUEUP;
+ }
+
+ /*
+ ** Compute return value.
+ */
+
+ if (tTd(20, 1))
+ {
+ printf("parseaddr-->");
+ printaddr(a, FALSE);
+ }
+
+ return (a);
+}
+ /*
+** INVALIDADDR -- check for address containing meta-characters
+**
+** Parameters:
+** addr -- the address to check.
+**
+** Returns:
+** TRUE -- if the address has any "wierd" characters
+** FALSE -- otherwise.
+*/
+
+bool
+invalidaddr(addr, delimptr)
+ register char *addr;
+ char *delimptr;
+{
+ char savedelim;
+
+ if (delimptr != NULL)
+ {
+ savedelim = *delimptr;
+ if (savedelim != '\0')
+ *delimptr = '\0';
+ }
+#if 0
+ /* for testing.... */
+ if (strcmp(addr, "INvalidADDR") == 0)
+ {
+ usrerr("553 INvalid ADDRess");
+ goto addrfailure;
+ }
+#endif
+ for (; *addr != '\0'; addr++)
+ {
+ if ((*addr & 0340) == 0200)
+ break;
+ }
+ if (*addr == '\0')
+ {
+ if (savedelim != '\0' && delimptr != NULL)
+ *delimptr = savedelim;
+ return FALSE;
+ }
+ setstat(EX_USAGE);
+ usrerr("553 Address contained invalid control characters");
+ addrfailure:
+ if (savedelim != '\0' && delimptr != NULL)
+ *delimptr = savedelim;
+ return TRUE;
+}
+ /*
+** ALLOCADDR -- do local allocations of address on demand.
+**
+** Also lowercases the host name if requested.
+**
+** Parameters:
+** a -- the address to reallocate.
+** flags -- the copy flag (see RF_ definitions in sendmail.h
+** for a description).
+** paddr -- the printname of the address.
+**
+** Returns:
+** none.
+**
+** Side Effects:
+** Copies portions of a into local buffers as requested.
+*/
+
+allocaddr(a, flags, paddr)
+ register ADDRESS *a;
+ int flags;
+ char *paddr;
+{
+ if (tTd(24, 4))
+ printf("allocaddr(flags=%o, paddr=%s)\n", flags, paddr);
+
+ a->q_paddr = paddr;
+
+ if (a->q_user == NULL)
+ a->q_user = "";
+ if (a->q_host == NULL)
+ a->q_host = "";
+
+ if (bitset(RF_COPYPARSE, flags))
+ {
+ a->q_host = newstr(a->q_host);
+ if (a->q_user != a->q_paddr)
+ a->q_user = newstr(a->q_user);
+ }
+
+ if (a->q_paddr == NULL)
+ a->q_paddr = a->q_user;
+}
+ /*
+** PRESCAN -- Prescan name and make it canonical
+**
+** Scans a name and turns it into a set of tokens. This process
+** deletes blanks and comments (in parentheses).
+**
+** This routine knows about quoted strings and angle brackets.
+**
+** There are certain subtleties to this routine. The one that
+** comes to mind now is that backslashes on the ends of names
+** are silently stripped off; this is intentional. The problem
+** is that some versions of sndmsg (like at LBL) set the kill
+** character to something other than @ when reading addresses;
+** so people type "csvax.eric\@berkeley" -- which screws up the
+** berknet mailer.
+**
+** Parameters:
+** addr -- the name to chomp.
+** delim -- the delimiter for the address, normally
+** '\0' or ','; \0 is accepted in any case.
+** If '\t' then we are reading the .cf file.
+** pvpbuf -- place to put the saved text -- note that
+** the pointers are static.
+** pvpbsize -- size of pvpbuf.
+** delimptr -- if non-NULL, set to the location of the
+** terminating delimiter.
+**
+** Returns:
+** A pointer to a vector of tokens.
+** NULL on error.
+*/
+
+/* states and character types */
+# define OPR 0 /* operator */
+# define ATM 1 /* atom */
+# define QST 2 /* in quoted string */
+# define SPC 3 /* chewing up spaces */
+# define ONE 4 /* pick up one character */
+
+# define NSTATES 5 /* number of states */
+# define TYPE 017 /* mask to select state type */
+
+/* meta bits for table */
+# define M 020 /* meta character; don't pass through */
+# define B 040 /* cause a break */
+# define MB M|B /* meta-break */
+
+static short StateTab[NSTATES][NSTATES] =
+{
+ /* oldst chtype> OPR ATM QST SPC ONE */
+ /*OPR*/ OPR|B, ATM|B, QST|B, SPC|MB, ONE|B,
+ /*ATM*/ OPR|B, ATM, QST|B, SPC|MB, ONE|B,
+ /*QST*/ QST, QST, OPR, QST, QST,
+ /*SPC*/ OPR, ATM, QST, SPC|M, ONE,
+ /*ONE*/ OPR, OPR, OPR, OPR, OPR,
+};
+
+/* token type table -- it gets modified with $o characters */
+static TokTypeTab[256] =
+{
+ ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,SPC,SPC,SPC,SPC,SPC,ATM,ATM,
+ ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,
+ SPC,ATM,QST,ATM,ATM,ATM,ATM,ATM,ATM,SPC,ATM,ATM,ATM,ATM,ATM,ATM,
+ ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,
+ ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,
+ ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,
+ ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,
+ ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,
+ OPR,OPR,ONE,OPR,OPR,OPR,OPR,OPR,OPR,OPR,OPR,OPR,OPR,OPR,OPR,OPR,
+ OPR,OPR,OPR,ONE,ONE,ONE,OPR,OPR,OPR,OPR,OPR,OPR,OPR,OPR,OPR,OPR,
+ ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,
+ ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,
+ ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,
+ ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,
+ ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,
+ ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM,
+};
+
+#define toktype(c) ((int) TokTypeTab[(c) & 0xff])
+
+
+# define NOCHAR -1 /* signal nothing in lookahead token */
+
+char **
+prescan(addr, delim, pvpbuf, pvpbsize, delimptr)
+ char *addr;
+ char delim;
+ char pvpbuf[];
+ char **delimptr;
+{
+ register char *p;
+ register char *q;
+ register int c;
+ char **avp;
+ bool bslashmode;
+ int cmntcnt;
+ int anglecnt;
+ char *tok;
+ int state;
+ int newstate;
+ char *saveto = CurEnv->e_to;
+ static char *av[MAXATOM+1];
+ static char firsttime = TRUE;
+ extern int errno;
+
+ if (firsttime)
+ {
+ /* initialize the token type table */
+ char obuf[50];
+
+ firsttime = FALSE;
+ expand("\201o", obuf, &obuf[sizeof obuf - sizeof DELIMCHARS], CurEnv);
+ strcat(obuf, DELIMCHARS);
+ for (p = obuf; *p != '\0'; p++)
+ {
+ if (TokTypeTab[*p & 0xff] == ATM)
+ TokTypeTab[*p & 0xff] = OPR;
+ }
+ }
+
+ /* make sure error messages don't have garbage on them */
+ errno = 0;
+
+ q = pvpbuf;
+ bslashmode = FALSE;
+ cmntcnt = 0;
+ anglecnt = 0;
+ avp = av;
+ state = ATM;
+ c = NOCHAR;
+ p = addr;
+ CurEnv->e_to = p;
+ if (tTd(22, 11))
+ {
+ printf("prescan: ");
+ xputs(p);
+ (void) putchar('\n');
+ }
+
+ do
+ {
+ /* read a token */
+ tok = q;
+ for (;;)
+ {
+ /* store away any old lookahead character */
+ if (c != NOCHAR && !bslashmode)
+ {
+ /* see if there is room */
+ if (q >= &pvpbuf[pvpbsize - 5])
+ {
+ usrerr("553 Address too long");
+ returnnull:
+ if (delimptr != NULL)
+ *delimptr = p;
+ CurEnv->e_to = saveto;
+ return (NULL);
+ }
+
+ /* squirrel it away */
+ *q++ = c;
+ }
+
+ /* read a new input character */
+ c = *p++;
+ if (c == '\0')
+ {
+ /* diagnose and patch up bad syntax */
+ if (state == QST)
+ {
+ usrerr("653 Unbalanced '\"'");
+ c = '"';
+ }
+ else if (cmntcnt > 0)
+ {
+ usrerr("653 Unbalanced '('");
+ c = ')';
+ }
+ else if (anglecnt > 0)
+ {
+ c = '>';
+ usrerr("653 Unbalanced '<'");
+ }
+ else
+ break;
+
+ p--;
+ }
+ else if (c == delim && anglecnt <= 0 &&
+ cmntcnt <= 0 && state != QST)
+ break;
+
+ if (tTd(22, 101))
+ printf("c=%c, s=%d; ", c, state);
+
+ /* chew up special characters */
+ *q = '\0';
+ if (bslashmode)
+ {
+ bslashmode = FALSE;
+
+ /* kludge \! for naive users */
+ if (cmntcnt > 0)
+ {
+ c = NOCHAR;
+ continue;
+ }
+ else if (c != '!' || state == QST)
+ {
+ *q++ = '\\';
+ continue;
+ }
+ }
+
+ if (c == '\\')
+ {
+ bslashmode = TRUE;
+ }
+ else if (state == QST)
+ {
+ /* do nothing, just avoid next clauses */
+ }
+ else if (c == '(')
+ {
+ cmntcnt++;
+ c = NOCHAR;
+ }
+ else if (c == ')')
+ {
+ if (cmntcnt <= 0)
+ {
+ usrerr("653 Unbalanced ')'");
+ c = NOCHAR;
+ }
+ else
+ cmntcnt--;
+ }
+ else if (cmntcnt > 0)
+ c = NOCHAR;
+ else if (c == '<')
+ anglecnt++;
+ else if (c == '>')
+ {
+ if (anglecnt <= 0)
+ {
+ usrerr("653 Unbalanced '>'");
+ c = NOCHAR;
+ }
+ else
+ anglecnt--;
+ }
+ else if (delim == ' ' && isascii(c) && isspace(c))
+ c = ' ';
+
+ if (c == NOCHAR)
+ continue;
+
+ /* see if this is end of input */
+ if (c == delim && anglecnt <= 0 && state != QST)
+ break;
+
+ newstate = StateTab[state][toktype(c)];
+ if (tTd(22, 101))
+ printf("ns=%02o\n", newstate);
+ state = newstate & TYPE;
+ if (bitset(M, newstate))
+ c = NOCHAR;
+ if (bitset(B, newstate))
+ break;
+ }
+
+ /* new token */
+ if (tok != q)
+ {
+ *q++ = '\0';
+ if (tTd(22, 36))
+ {
+ printf("tok=");
+ xputs(tok);
+ (void) putchar('\n');
+ }
+ if (avp >= &av[MAXATOM])
+ {
+ syserr("553 prescan: too many tokens");
+ goto returnnull;
+ }
+ if (q - tok > MAXNAME)
+ {
+ syserr("553 prescan: token too long");
+ goto returnnull;
+ }
+ *avp++ = tok;
+ }
+ } while (c != '\0' && (c != delim || anglecnt > 0));
+ *avp = NULL;
+ p--;
+ if (delimptr != NULL)
+ *delimptr = p;
+ if (tTd(22, 12))
+ {
+ printf("prescan==>");
+ printav(av);
+ }
+ CurEnv->e_to = saveto;
+ if (av[0] == NULL)
+ {
+ if (tTd(22, 1))
+ printf("prescan: null leading token\n");
+ return (NULL);
+ }
+ return (av);
+}
+ /*
+** REWRITE -- apply rewrite rules to token vector.
+**
+** This routine is an ordered production system. Each rewrite
+** rule has a LHS (called the pattern) and a RHS (called the
+** rewrite); 'rwr' points the the current rewrite rule.
+**
+** For each rewrite rule, 'avp' points the address vector we
+** are trying to match against, and 'pvp' points to the pattern.
+** If pvp points to a special match value (MATCHZANY, MATCHANY,
+** MATCHONE, MATCHCLASS, MATCHNCLASS) then the address in avp
+** matched is saved away in the match vector (pointed to by 'mvp').
+**
+** When a match between avp & pvp does not match, we try to
+** back out. If we back up over MATCHONE, MATCHCLASS, or MATCHNCLASS
+** we must also back out the match in mvp. If we reach a
+** MATCHANY or MATCHZANY we just extend the match and start
+** over again.
+**
+** When we finally match, we rewrite the address vector
+** and try over again.
+**
+** Parameters:
+** pvp -- pointer to token vector.
+** ruleset -- the ruleset to use for rewriting.
+** reclevel -- recursion level (to catch loops).
+** e -- the current envelope.
+**
+** Returns:
+** A status code. If EX_TEMPFAIL, higher level code should
+** attempt recovery.
+**
+** Side Effects:
+** pvp is modified.
+*/
+
+struct match
+{
+ char **first; /* first token matched */
+ char **last; /* last token matched */
+ char **pattern; /* pointer to pattern */
+};
+
+# define MAXMATCH 9 /* max params per rewrite */
+
+# ifndef MAXRULERECURSION
+# define MAXRULERECURSION 50 /* max recursion depth */
+# endif
+
+
+int
+rewrite(pvp, ruleset, reclevel, e)
+ char **pvp;
+ int ruleset;
+ int reclevel;
+ register ENVELOPE *e;
+{
+ register char *ap; /* address pointer */
+ register char *rp; /* rewrite pointer */
+ register char **avp; /* address vector pointer */
+ register char **rvp; /* rewrite vector pointer */
+ register struct match *mlp; /* cur ptr into mlist */
+ register struct rewrite *rwr; /* pointer to current rewrite rule */
+ int ruleno; /* current rule number */
+ int rstat = EX_OK; /* return status */
+ int loopcount;
+ struct match mlist[MAXMATCH]; /* stores match on LHS */
+ char *npvp[MAXATOM+1]; /* temporary space for rebuild */
+
+ if (OpMode == MD_TEST || tTd(21, 2))
+ {
+ printf("rewrite: ruleset %2d input:", ruleset);
+ printav(pvp);
+ }
+ if (ruleset < 0 || ruleset >= MAXRWSETS)
+ {
+ syserr("554 rewrite: illegal ruleset number %d", ruleset);
+ return EX_CONFIG;
+ }
+ if (reclevel++ > MAXRULERECURSION)
+ {
+ syserr("rewrite: infinite recursion, ruleset %d", ruleset);
+ return EX_CONFIG;
+ }
+ if (pvp == NULL)
+ return EX_USAGE;
+
+ /*
+ ** Run through the list of rewrite rules, applying
+ ** any that match.
+ */
+
+ ruleno = 1;
+ loopcount = 0;
+ for (rwr = RewriteRules[ruleset]; rwr != NULL; )
+ {
+ if (tTd(21, 12))
+ {
+ printf("-----trying rule:");
+ printav(rwr->r_lhs);
+ }
+
+ /* try to match on this rule */
+ mlp = mlist;
+ rvp = rwr->r_lhs;
+ avp = pvp;
+ if (++loopcount > 100)
+ {
+ syserr("554 Infinite loop in ruleset %d, rule %d",
+ ruleset, ruleno);
+ if (tTd(21, 1))
+ {
+ printf("workspace: ");
+ printav(pvp);
+ }
+ break;
+ }
+
+ while ((ap = *avp) != NULL || *rvp != NULL)
+ {
+ rp = *rvp;
+ if (tTd(21, 35))
+ {
+ printf("ADVANCE rp=");
+ xputs(rp);
+ printf(", ap=");
+ xputs(ap);
+ printf("\n");
+ }
+ if (rp == NULL)
+ {
+ /* end-of-pattern before end-of-address */
+ goto backup;
+ }
+ if (ap == NULL && (*rp & 0377) != MATCHZANY &&
+ (*rp & 0377) != MATCHZERO)
+ {
+ /* end-of-input with patterns left */
+ goto backup;
+ }
+
+ switch (*rp & 0377)
+ {
+ register STAB *s;
+ char buf[MAXLINE];
+
+ case MATCHCLASS:
+ /* match any phrase in a class */
+ mlp->pattern = rvp;
+ mlp->first = avp;
+ extendclass:
+ ap = *avp;
+ if (ap == NULL)
+ goto backup;
+ mlp->last = avp++;
+ cataddr(mlp->first, mlp->last, buf, sizeof buf, '\0');
+ s = stab(buf, ST_CLASS, ST_FIND);
+ if (s == NULL || !bitnset(rp[1], s->s_class))
+ {
+ if (tTd(21, 36))
+ {
+ printf("EXTEND rp=");
+ xputs(rp);
+ printf(", ap=");
+ xputs(ap);
+ printf("\n");
+ }
+ goto extendclass;
+ }
+ if (tTd(21, 36))
+ printf("CLMATCH\n");
+ mlp++;
+ break;
+
+ case MATCHNCLASS:
+ /* match any token not in a class */
+ s = stab(ap, ST_CLASS, ST_FIND);
+ if (s != NULL && bitnset(rp[1], s->s_class))
+ goto backup;
+
+ /* fall through */
+
+ case MATCHONE:
+ case MATCHANY:
+ /* match exactly one token */
+ mlp->pattern = rvp;
+ mlp->first = avp;
+ mlp->last = avp++;
+ mlp++;
+ break;
+
+ case MATCHZANY:
+ /* match zero or more tokens */
+ mlp->pattern = rvp;
+ mlp->first = avp;
+ mlp->last = avp - 1;
+ mlp++;
+ break;
+
+ case MATCHZERO:
+ /* match zero tokens */
+ break;
+
+ case MACRODEXPAND:
+ /*
+ ** Match against run-time macro.
+ ** This algorithm is broken for the
+ ** general case (no recursive macros,
+ ** improper tokenization) but should
+ ** work for the usual cases.
+ */
+
+ ap = macvalue(rp[1], e);
+ mlp->first = avp;
+ if (tTd(21, 2))
+ printf("rewrite: LHS $&%c => \"%s\"\n",
+ rp[1],
+ ap == NULL ? "(NULL)" : ap);
+
+ if (ap == NULL)
+ break;
+ while (*ap != '\0')
+ {
+ if (*avp == NULL ||
+ strncasecmp(ap, *avp, strlen(*avp)) != 0)
+ {
+ /* no match */
+ avp = mlp->first;
+ goto backup;
+ }
+ ap += strlen(*avp++);
+ }
+
+ /* match */
+ break;
+
+ default:
+ /* must have exact match */
+ if (strcasecmp(rp, ap))
+ goto backup;
+ avp++;
+ break;
+ }
+
+ /* successful match on this token */
+ rvp++;
+ continue;
+
+ backup:
+ /* match failed -- back up */
+ while (--mlp >= mlist)
+ {
+ rvp = mlp->pattern;
+ rp = *rvp;
+ avp = mlp->last + 1;
+ ap = *avp;
+
+ if (tTd(21, 36))
+ {
+ printf("BACKUP rp=");
+ xputs(rp);
+ printf(", ap=");
+ xputs(ap);
+ printf("\n");
+ }
+
+ if (ap == NULL)
+ {
+ /* run off the end -- back up again */
+ continue;
+ }
+ if ((*rp & 0377) == MATCHANY ||
+ (*rp & 0377) == MATCHZANY)
+ {
+ /* extend binding and continue */
+ mlp->last = avp++;
+ rvp++;
+ mlp++;
+ break;
+ }
+ if ((*rp & 0377) == MATCHCLASS)
+ {
+ /* extend binding and try again */
+ mlp->last = avp;
+ goto extendclass;
+ }
+ }
+
+ if (mlp < mlist)
+ {
+ /* total failure to match */
+ break;
+ }
+ }
+
+ /*
+ ** See if we successfully matched
+ */
+
+ if (mlp < mlist || *rvp != NULL)
+ {
+ if (tTd(21, 10))
+ printf("----- rule fails\n");
+ rwr = rwr->r_next;
+ ruleno++;
+ loopcount = 0;
+ continue;
+ }
+
+ rvp = rwr->r_rhs;
+ if (tTd(21, 12))
+ {
+ printf("-----rule matches:");
+ printav(rvp);
+ }
+
+ rp = *rvp;
+ if ((*rp & 0377) == CANONUSER)
+ {
+ rvp++;
+ rwr = rwr->r_next;
+ ruleno++;
+ loopcount = 0;
+ }
+ else if ((*rp & 0377) == CANONHOST)
+ {
+ rvp++;
+ rwr = NULL;
+ }
+ else if ((*rp & 0377) == CANONNET)
+ rwr = NULL;
+
+ /* substitute */
+ for (avp = npvp; *rvp != NULL; rvp++)
+ {
+ register struct match *m;
+ register char **pp;
+
+ rp = *rvp;
+ if ((*rp & 0377) == MATCHREPL)
+ {
+ /* substitute from LHS */
+ m = &mlist[rp[1] - '1'];
+ if (m < mlist || m >= mlp)
+ {
+ syserr("554 rewrite: ruleset %d: replacement $%c out of bounds",
+ ruleset, rp[1]);
+ return EX_CONFIG;
+ }
+ if (tTd(21, 15))
+ {
+ printf("$%c:", rp[1]);
+ pp = m->first;
+ while (pp <= m->last)
+ {
+ printf(" %x=\"", *pp);
+ (void) fflush(stdout);
+ printf("%s\"", *pp++);
+ }
+ printf("\n");
+ }
+ pp = m->first;
+ while (pp <= m->last)
+ {
+ if (avp >= &npvp[MAXATOM])
+ {
+ syserr("554 rewrite: expansion too long");
+ return EX_DATAERR;
+ }
+ *avp++ = *pp++;
+ }
+ }
+ else
+ {
+ /* vanilla replacement */
+ if (avp >= &npvp[MAXATOM])
+ {
+ toolong:
+ syserr("554 rewrite: expansion too long");
+ return EX_DATAERR;
+ }
+ if ((*rp & 0377) != MACRODEXPAND)
+ *avp++ = rp;
+ else
+ {
+ *avp = macvalue(rp[1], e);
+ if (tTd(21, 2))
+ printf("rewrite: RHS $&%c => \"%s\"\n",
+ rp[1],
+ *avp == NULL ? "(NULL)" : *avp);
+ if (*avp != NULL)
+ avp++;
+ }
+ }
+ }
+ *avp++ = NULL;
+
+ /*
+ ** Check for any hostname/keyword lookups.
+ */
+
+ for (rvp = npvp; *rvp != NULL; rvp++)
+ {
+ char **hbrvp;
+ char **xpvp;
+ int trsize;
+ char *replac;
+ int endtoken;
+ STAB *map;
+ char *mapname;
+ char **key_rvp;
+ char **arg_rvp;
+ char **default_rvp;
+ char buf[MAXNAME + 1];
+ char *pvpb1[MAXATOM + 1];
+ char *argvect[10];
+ char pvpbuf[PSBUFSIZE];
+ char *nullpvp[1];
+
+ if ((**rvp & 0377) != HOSTBEGIN &&
+ (**rvp & 0377) != LOOKUPBEGIN)
+ continue;
+
+ /*
+ ** Got a hostname/keyword lookup.
+ **
+ ** This could be optimized fairly easily.
+ */
+
+ hbrvp = rvp;
+ if ((**rvp & 0377) == HOSTBEGIN)
+ {
+ endtoken = HOSTEND;
+ mapname = "host";
+ }
+ else
+ {
+ endtoken = LOOKUPEND;
+ mapname = *++rvp;
+ }
+ map = stab(mapname, ST_MAP, ST_FIND);
+ if (map == NULL)
+ syserr("554 rewrite: map %s not found", mapname);
+
+ /* extract the match part */
+ key_rvp = ++rvp;
+ default_rvp = NULL;
+ arg_rvp = argvect;
+ xpvp = NULL;
+ replac = pvpbuf;
+ while (*rvp != NULL && (**rvp & 0377) != endtoken)
+ {
+ int nodetype = **rvp & 0377;
+
+ if (nodetype != CANONHOST && nodetype != CANONUSER)
+ {
+ rvp++;
+ continue;
+ }
+
+ *rvp++ = NULL;
+
+ if (xpvp != NULL)
+ {
+ cataddr(xpvp, NULL, replac,
+ &pvpbuf[sizeof pvpbuf] - replac,
+ '\0');
+ *++arg_rvp = replac;
+ replac += strlen(replac) + 1;
+ xpvp = NULL;
+ }
+ switch (nodetype)
+ {
+ case CANONHOST:
+ xpvp = rvp;
+ break;
+
+ case CANONUSER:
+ default_rvp = rvp;
+ break;
+ }
+ }
+ if (*rvp != NULL)
+ *rvp++ = NULL;
+ if (xpvp != NULL)
+ {
+ cataddr(xpvp, NULL, replac,
+ &pvpbuf[sizeof pvpbuf] - replac,
+ '\0');
+ *++arg_rvp = replac;
+ }
+ *++arg_rvp = NULL;
+
+ /* save the remainder of the input string */
+ trsize = (int) (avp - rvp + 1) * sizeof *rvp;
+ bcopy((char *) rvp, (char *) pvpb1, trsize);
+
+ /* look it up */
+ cataddr(key_rvp, NULL, buf, sizeof buf, '\0');
+ argvect[0] = buf;
+ if (map != NULL && bitset(MF_OPEN, map->s_map.map_mflags))
+ {
+ auto int stat = EX_OK;
+
+ /* XXX should try to auto-open the map here */
+
+ if (tTd(60, 1))
+ printf("map_lookup(%s, %s) => ",
+ mapname, buf);
+ replac = (*map->s_map.map_class->map_lookup)(&map->s_map,
+ buf, argvect, &stat);
+ if (tTd(60, 1))
+ printf("%s (%d)\n",
+ replac ? replac : "NOT FOUND",
+ stat);
+
+ /* should recover if stat == EX_TEMPFAIL */
+ if (stat == EX_TEMPFAIL)
+ rstat = stat;
+ }
+ else
+ replac = NULL;
+
+ /* if no replacement, use default */
+ if (replac == NULL && default_rvp != NULL)
+ {
+ /* create the default */
+ cataddr(default_rvp, NULL, buf, sizeof buf, '\0');
+ replac = buf;
+ }
+
+ if (replac == NULL)
+ {
+ xpvp = key_rvp;
+ }
+ else if (*replac == '\0')
+ {
+ /* null replacement */
+ nullpvp[0] = NULL;
+ xpvp = nullpvp;
+ }
+ else
+ {
+ /* scan the new replacement */
+ xpvp = prescan(replac, '\0', pvpbuf,
+ sizeof pvpbuf, NULL);
+ if (xpvp == NULL)
+ {
+ /* prescan already printed error */
+ return EX_DATAERR;
+ }
+ }
+
+ /* append it to the token list */
+ for (avp = hbrvp; *xpvp != NULL; xpvp++)
+ {
+ *avp++ = newstr(*xpvp);
+ if (avp >= &npvp[MAXATOM])
+ goto toolong;
+ }
+
+ /* restore the old trailing information */
+ for (xpvp = pvpb1; (*avp++ = *xpvp++) != NULL; )
+ if (avp >= &npvp[MAXATOM])
+ goto toolong;
+
+ break;
+ }
+
+ /*
+ ** Check for subroutine calls.
+ */
+
+ if (*npvp != NULL && (**npvp & 0377) == CALLSUBR)
+ {
+ int stat;
+
+ if (npvp[1] == NULL)
+ {
+ syserr("parseaddr: NULL subroutine call in ruleset %d, rule %d",
+ ruleset, ruleno);
+ *pvp = NULL;
+ }
+ else
+ {
+ bcopy((char *) &npvp[2], (char *) pvp,
+ (int) (avp - npvp - 2) * sizeof *avp);
+ if (tTd(21, 3))
+ printf("-----callsubr %s\n", npvp[1]);
+ stat = rewrite(pvp, atoi(npvp[1]), reclevel, e);
+ if (rstat == EX_OK || stat == EX_TEMPFAIL)
+ rstat = stat;
+ if (*pvp != NULL && (**pvp & 0377) == CANONNET)
+ rwr = NULL;
+ }
+ }
+ else
+ {
+ bcopy((char *) npvp, (char *) pvp,
+ (int) (avp - npvp) * sizeof *avp);
+ }
+ if (tTd(21, 4))
+ {
+ printf("rewritten as:");
+ printav(pvp);
+ }
+ }
+
+ if (OpMode == MD_TEST || tTd(21, 2))
+ {
+ printf("rewrite: ruleset %2d returns:", ruleset);
+ printav(pvp);
+ }
+
+ return rstat;
+}
+ /*
+** BUILDADDR -- build address from token vector.
+**
+** Parameters:
+** tv -- token vector.
+** a -- pointer to address descriptor to fill.
+** If NULL, one will be allocated.
+** flags -- info regarding whether this is a sender or
+** a recipient.
+** e -- the current envelope.
+**
+** Returns:
+** NULL if there was an error.
+** 'a' otherwise.
+**
+** Side Effects:
+** fills in 'a'
+*/
+
+struct errcodes
+{
+ char *ec_name; /* name of error code */
+ int ec_code; /* numeric code */
+} ErrorCodes[] =
+{
+ "usage", EX_USAGE,
+ "nouser", EX_NOUSER,
+ "nohost", EX_NOHOST,
+ "unavailable", EX_UNAVAILABLE,
+ "software", EX_SOFTWARE,
+ "tempfail", EX_TEMPFAIL,
+ "protocol", EX_PROTOCOL,
+#ifdef EX_CONFIG
+ "config", EX_CONFIG,
+#endif
+ NULL, EX_UNAVAILABLE,
+};
+
+ADDRESS *
+buildaddr(tv, a, flags, e)
+ register char **tv;
+ register ADDRESS *a;
+ int flags;
+ register ENVELOPE *e;
+{
+ struct mailer **mp;
+ register struct mailer *m;
+ char *bp;
+ int spaceleft;
+ static MAILER errormailer;
+ static char *errorargv[] = { "ERROR", NULL };
+ static char buf[MAXNAME];
+
+ if (tTd(24, 5))
+ {
+ printf("buildaddr, flags=%o, tv=", flags);
+ printav(tv);
+ }
+
+ if (a == NULL)
+ a = (ADDRESS *) xalloc(sizeof *a);
+ bzero((char *) a, sizeof *a);
+
+ /* figure out what net/mailer to use */
+ if (*tv == NULL || (**tv & 0377) != CANONNET)
+ {
+ syserr("554 buildaddr: no net");
+badaddr:
+ a->q_flags |= QBADADDR;
+ a->q_mailer = &errormailer;
+ if (errormailer.m_name == NULL)
+ {
+ /* initialize the bogus mailer */
+ errormailer.m_name = "*error*";
+ errormailer.m_mailer = "ERROR";
+ errormailer.m_argv = errorargv;
+ }
+ return a;
+ }
+ tv++;
+ if (strcasecmp(*tv, "error") == 0)
+ {
+ if ((**++tv & 0377) == CANONHOST)
+ {
+ register struct errcodes *ep;
+
+ if (isascii(**++tv) && isdigit(**tv))
+ {
+ setstat(atoi(*tv));
+ }
+ else
+ {
+ for (ep = ErrorCodes; ep->ec_name != NULL; ep++)
+ if (strcasecmp(ep->ec_name, *tv) == 0)
+ break;
+ setstat(ep->ec_code);
+ }
+ tv++;
+ }
+ else
+ setstat(EX_UNAVAILABLE);
+ if ((**tv & 0377) != CANONUSER)
+ syserr("554 buildaddr: error: no user");
+ cataddr(++tv, NULL, buf, sizeof buf, ' ');
+ stripquotes(buf);
+ if (isascii(buf[0]) && isdigit(buf[0]) &&
+ isascii(buf[1]) && isdigit(buf[1]) &&
+ isascii(buf[2]) && isdigit(buf[2]) &&
+ buf[3] == ' ')
+ {
+ char fmt[10];
+
+ strncpy(fmt, buf, 3);
+ strcpy(&fmt[3], " %s");
+ usrerr(fmt, buf + 4);
+ }
+ else
+ {
+ usrerr("553 %s", buf);
+ }
+ goto badaddr;
+ }
+
+ for (mp = Mailer; (m = *mp++) != NULL; )
+ {
+ if (strcasecmp(m->m_name, *tv) == 0)
+ break;
+ }
+ if (m == NULL)
+ {
+ syserr("554 buildaddr: unknown mailer %s", *tv);
+ goto badaddr;
+ }
+ a->q_mailer = m;
+
+ /* figure out what host (if any) */
+ tv++;
+ if ((**tv & 0377) == CANONHOST)
+ {
+ bp = buf;
+ spaceleft = sizeof buf - 1;
+ while (*++tv != NULL && (**tv & 0377) != CANONUSER)
+ {
+ int i = strlen(*tv);
+
+ if (i > spaceleft)
+ {
+ /* out of space for this address */
+ if (spaceleft >= 0)
+ syserr("554 buildaddr: host too long (%.40s...)",
+ buf);
+ i = spaceleft;
+ spaceleft = 0;
+ }
+ if (i <= 0)
+ continue;
+ bcopy(*tv, bp, i);
+ bp += i;
+ spaceleft -= i;
+ }
+ *bp = '\0';
+ a->q_host = newstr(buf);
+ }
+ else
+ {
+ if (!bitnset(M_LOCALMAILER, m->m_flags))
+ {
+ syserr("554 buildaddr: no host");
+ goto badaddr;
+ }
+ a->q_host = NULL;
+ }
+
+ /* figure out the user */
+ if (*tv == NULL || (**tv & 0377) != CANONUSER)
+ {
+ syserr("554 buildaddr: no user");
+ goto badaddr;
+ }
+ tv++;
+
+ /* do special mapping for local mailer */
+ if (m == LocalMailer && *tv != NULL)
+ {
+ register char *p = *tv;
+
+ if (*p == '"')
+ p++;
+ if (*p == '|')
+ a->q_mailer = m = ProgMailer;
+ else if (*p == '/')
+ a->q_mailer = m = FileMailer;
+ else if (*p == ':')
+ {
+ /* may be :include: */
+ cataddr(tv, NULL, buf, sizeof buf, '\0');
+ stripquotes(buf);
+ if (strncasecmp(buf, ":include:", 9) == 0)
+ {
+ /* if :include:, don't need further rewriting */
+ a->q_mailer = m = InclMailer;
+ a->q_user = &buf[9];
+ return (a);
+ }
+ }
+ }
+
+ if (m == LocalMailer && *tv != NULL && strcmp(*tv, "@") == 0)
+ {
+ tv++;
+ a->q_flags |= QNOTREMOTE;
+ }
+
+ /* rewrite according recipient mailer rewriting rules */
+ define('h', a->q_host, e);
+ if (!bitset(RF_SENDERADDR|RF_HEADERADDR, flags))
+ {
+ /* sender addresses done later */
+ (void) rewrite(tv, 2, 0, e);
+ if (m->m_re_rwset > 0)
+ (void) rewrite(tv, m->m_re_rwset, 0, e);
+ }
+ (void) rewrite(tv, 4, 0, e);
+
+ /* save the result for the command line/RCPT argument */
+ cataddr(tv, NULL, buf, sizeof buf, '\0');
+ a->q_user = buf;
+
+ /*
+ ** Do mapping to lower case as requested by mailer
+ */
+
+ if (a->q_host != NULL && !bitnset(M_HST_UPPER, m->m_flags))
+ makelower(a->q_host);
+ if (!bitnset(M_USR_UPPER, m->m_flags))
+ makelower(a->q_user);
+
+ return (a);
+}
+ /*
+** CATADDR -- concatenate pieces of addresses (putting in <LWSP> subs)
+**
+** Parameters:
+** pvp -- parameter vector to rebuild.
+** evp -- last parameter to include. Can be NULL to
+** use entire pvp.
+** buf -- buffer to build the string into.
+** sz -- size of buf.
+** spacesub -- the space separator character; if null,
+** use SpaceSub.
+**
+** Returns:
+** none.
+**
+** Side Effects:
+** Destroys buf.
+*/
+
+cataddr(pvp, evp, buf, sz, spacesub)
+ char **pvp;
+ char **evp;
+ char *buf;
+ register int sz;
+ char spacesub;
+{
+ bool oatomtok = FALSE;
+ bool natomtok = FALSE;
+ register int i;
+ register char *p;
+
+ if (spacesub == '\0')
+ spacesub = SpaceSub;
+
+ if (pvp == NULL)
+ {
+ (void) strcpy(buf, "");
+ return;
+ }
+ p = buf;
+ sz -= 2;
+ while (*pvp != NULL && (i = strlen(*pvp)) < sz)
+ {
+ natomtok = (toktype(**pvp) == ATM);
+ if (oatomtok && natomtok)
+ *p++ = spacesub;
+ (void) strcpy(p, *pvp);
+ oatomtok = natomtok;
+ p += i;
+ sz -= i + 1;
+ if (pvp++ == evp)
+ break;
+ }
+ *p = '\0';
+}
+ /*
+** SAMEADDR -- Determine if two addresses are the same
+**
+** This is not just a straight comparison -- if the mailer doesn't
+** care about the host we just ignore it, etc.
+**
+** Parameters:
+** a, b -- pointers to the internal forms to compare.
+**
+** Returns:
+** TRUE -- they represent the same mailbox.
+** FALSE -- they don't.
+**
+** Side Effects:
+** none.
+*/
+
+bool
+sameaddr(a, b)
+ register ADDRESS *a;
+ register ADDRESS *b;
+{
+ register ADDRESS *ca, *cb;
+
+ /* if they don't have the same mailer, forget it */
+ if (a->q_mailer != b->q_mailer)
+ return (FALSE);
+
+ /* if the user isn't the same, we can drop out */
+ if (strcmp(a->q_user, b->q_user) != 0)
+ return (FALSE);
+
+ /* if we have good uids for both but they differ, these are different */
+ if (a->q_mailer == ProgMailer)
+ {
+ ca = getctladdr(a);
+ cb = getctladdr(b);
+ if (ca != NULL && cb != NULL &&
+ bitset(QGOODUID, ca->q_flags & cb->q_flags) &&
+ ca->q_uid != cb->q_uid)
+ return (FALSE);
+ }
+
+ /* otherwise compare hosts (but be careful for NULL ptrs) */
+ if (a->q_host == b->q_host)
+ {
+ /* probably both null pointers */
+ return (TRUE);
+ }
+ if (a->q_host == NULL || b->q_host == NULL)
+ {
+ /* only one is a null pointer */
+ return (FALSE);
+ }
+ if (strcmp(a->q_host, b->q_host) != 0)
+ return (FALSE);
+
+ return (TRUE);
+}
+ /*
+** PRINTADDR -- print address (for debugging)
+**
+** Parameters:
+** a -- the address to print
+** follow -- follow the q_next chain.
+**
+** Returns:
+** none.
+**
+** Side Effects:
+** none.
+*/
+
+printaddr(a, follow)
+ register ADDRESS *a;
+ bool follow;
+{
+ bool first = TRUE;
+ register MAILER *m;
+ MAILER pseudomailer;
+
+ while (a != NULL)
+ {
+ first = FALSE;
+ printf("%x=", a);
+ (void) fflush(stdout);
+
+ /* find the mailer -- carefully */
+ m = a->q_mailer;
+ if (m == NULL)
+ {
+ m = &pseudomailer;
+ m->m_mno = -1;
+ m->m_name = "NULL";
+ }
+
+ printf("%s:\n\tmailer %d (%s), host `%s', user `%s', ruser `%s'\n",
+ a->q_paddr, m->m_mno, m->m_name,
+ a->q_host, a->q_user,
+ a->q_ruser ? a->q_ruser : "<null>");
+ printf("\tnext=%x, flags=%o, alias %x, uid %d, gid %d\n",
+ a->q_next, a->q_flags, a->q_alias, a->q_uid, a->q_gid);
+ printf("\towner=%s, home=\"%s\", fullname=\"%s\"\n",
+ a->q_owner == NULL ? "(none)" : a->q_owner,
+ a->q_home == NULL ? "(none)" : a->q_home,
+ a->q_fullname == NULL ? "(none)" : a->q_fullname);
+
+ if (!follow)
+ return;
+ a = a->q_next;
+ }
+ if (first)
+ printf("[NULL]\n");
+}
+
+ /*
+** REMOTENAME -- return the name relative to the current mailer
+**
+** Parameters:
+** name -- the name to translate.
+** m -- the mailer that we want to do rewriting relative
+** to.
+** flags -- fine tune operations.
+** pstat -- pointer to status word.
+** e -- the current envelope.
+**
+** Returns:
+** the text string representing this address relative to
+** the receiving mailer.
+**
+** Side Effects:
+** none.
+**
+** Warnings:
+** The text string returned is tucked away locally;
+** copy it if you intend to save it.
+*/
+
+char *
+remotename(name, m, flags, pstat, e)
+ char *name;
+ struct mailer *m;
+ int flags;
+ int *pstat;
+ register ENVELOPE *e;
+{
+ register char **pvp;
+ char *fancy;
+ char *oldg = macvalue('g', e);
+ int rwset;
+ static char buf[MAXNAME];
+ char lbuf[MAXNAME];
+ char pvpbuf[PSBUFSIZE];
+ extern char *crackaddr();
+
+ if (tTd(12, 1))
+ printf("remotename(%s)\n", name);
+
+ /* don't do anything if we are tagging it as special */
+ if (bitset(RF_SENDERADDR, flags))
+ rwset = bitset(RF_HEADERADDR, flags) ? m->m_sh_rwset
+ : m->m_se_rwset;
+ else
+ rwset = bitset(RF_HEADERADDR, flags) ? m->m_rh_rwset
+ : m->m_re_rwset;
+ if (rwset < 0)
+ return (name);
+
+ /*
+ ** Do a heuristic crack of this name to extract any comment info.
+ ** This will leave the name as a comment and a $g macro.
+ */
+
+ if (bitset(RF_CANONICAL, flags) || bitnset(M_NOCOMMENT, m->m_flags))
+ fancy = "\201g";
+ else
+ fancy = crackaddr(name);
+
+ /*
+ ** Turn the name into canonical form.
+ ** Normally this will be RFC 822 style, i.e., "user@domain".
+ ** If this only resolves to "user", and the "C" flag is
+ ** specified in the sending mailer, then the sender's
+ ** domain will be appended.
+ */
+
+ pvp = prescan(name, '\0', pvpbuf, sizeof pvpbuf, NULL);
+ if (pvp == NULL)
+ return (name);
+ if (rewrite(pvp, 3, 0, e) == EX_TEMPFAIL)
+ *pstat = EX_TEMPFAIL;
+ if (bitset(RF_ADDDOMAIN, flags) && e->e_fromdomain != NULL)
+ {
+ /* append from domain to this address */
+ register char **pxp = pvp;
+
+ /* see if there is an "@domain" in the current name */
+ while (*pxp != NULL && strcmp(*pxp, "@") != 0)
+ pxp++;
+ if (*pxp == NULL)
+ {
+ /* no.... append the "@domain" from the sender */
+ register char **qxq = e->e_fromdomain;
+
+ while ((*pxp++ = *qxq++) != NULL)
+ continue;
+ if (rewrite(pvp, 3, 0, e) == EX_TEMPFAIL)
+ *pstat = EX_TEMPFAIL;
+ }
+ }
+
+ /*
+ ** Do more specific rewriting.
+ ** Rewrite using ruleset 1 or 2 depending on whether this is
+ ** a sender address or not.
+ ** Then run it through any receiving-mailer-specific rulesets.
+ */
+
+ if (bitset(RF_SENDERADDR, flags))
+ {
+ if (rewrite(pvp, 1, 0, e) == EX_TEMPFAIL)
+ *pstat = EX_TEMPFAIL;
+ }
+ else
+ {
+ if (rewrite(pvp, 2, 0, e) == EX_TEMPFAIL)
+ *pstat = EX_TEMPFAIL;
+ }
+ if (rwset > 0)
+ {
+ if (rewrite(pvp, rwset, 0, e) == EX_TEMPFAIL)
+ *pstat = EX_TEMPFAIL;
+ }
+
+ /*
+ ** Do any final sanitation the address may require.
+ ** This will normally be used to turn internal forms
+ ** (e.g., user@host.LOCAL) into external form. This
+ ** may be used as a default to the above rules.
+ */
+
+ if (rewrite(pvp, 4, 0, e) == EX_TEMPFAIL)
+ *pstat = EX_TEMPFAIL;
+
+ /*
+ ** Now restore the comment information we had at the beginning.
+ */
+
+ cataddr(pvp, NULL, lbuf, sizeof lbuf, '\0');
+ define('g', lbuf, e);
+
+ /* need to make sure route-addrs have <angle brackets> */
+ if (bitset(RF_CANONICAL, flags) && lbuf[0] == '@')
+ expand("<\201g>", buf, &buf[sizeof buf - 1], e);
+ else
+ expand(fancy, buf, &buf[sizeof buf - 1], e);
+
+ define('g', oldg, e);
+
+ if (tTd(12, 1))
+ printf("remotename => `%s'\n", buf);
+ return (buf);
+}
+ /*
+** MAPLOCALUSER -- run local username through ruleset 5 for final redirection
+**
+** Parameters:
+** a -- the address to map (but just the user name part).
+** sendq -- the sendq in which to install any replacement
+** addresses.
+**
+** Returns:
+** none.
+*/
+
+maplocaluser(a, sendq, e)
+ register ADDRESS *a;
+ ADDRESS **sendq;
+ ENVELOPE *e;
+{
+ register char **pvp;
+ register ADDRESS *a1 = NULL;
+ auto char *delimptr;
+ char pvpbuf[PSBUFSIZE];
+
+ if (tTd(29, 1))
+ {
+ printf("maplocaluser: ");
+ printaddr(a, FALSE);
+ }
+ pvp = prescan(a->q_user, '\0', pvpbuf, sizeof pvpbuf, &delimptr);
+ if (pvp == NULL)
+ return;
+
+ (void) rewrite(pvp, 5, 0, e);
+ if (pvp[0] == NULL || (pvp[0][0] & 0377) != CANONNET)
+ return;
+
+ /* if non-null, mailer destination specified -- has it changed? */
+ a1 = buildaddr(pvp, NULL, 0, e);
+ if (a1 == NULL || sameaddr(a, a1))
+ return;
+
+ /* mark old address as dead; insert new address */
+ a->q_flags |= QDONTSEND;
+ if (tTd(29, 5))
+ {
+ printf("maplocaluser: QDONTSEND ");
+ printaddr(a, FALSE);
+ }
+ a1->q_alias = a;
+ allocaddr(a1, RF_COPYALL, NULL);
+ (void) recipient(a1, sendq, e);
+}
+ /*
+** DEQUOTE_INIT -- initialize dequote map
+**
+** This is a no-op.
+**
+** Parameters:
+** map -- the internal map structure.
+** args -- arguments.
+**
+** Returns:
+** TRUE.
+*/
+
+bool
+dequote_init(map, args)
+ MAP *map;
+ char *args;
+{
+ register char *p = args;
+
+ for (;;)
+ {
+ while (isascii(*p) && isspace(*p))
+ p++;
+ if (*p != '-')
+ break;
+ switch (*++p)
+ {
+ case 'a':
+ map->map_app = ++p;
+ break;
+ }
+ while (*p != '\0' && !(isascii(*p) && isspace(*p)))
+ p++;
+ if (*p != '\0')
+ *p = '\0';
+ }
+ if (map->map_app != NULL)
+ map->map_app = newstr(map->map_app);
+
+ return TRUE;
+}
+ /*
+** DEQUOTE_MAP -- unquote an address
+**
+** Parameters:
+** map -- the internal map structure (ignored).
+** name -- the name to dequote.
+** av -- arguments (ignored).
+** statp -- pointer to status out-parameter.
+**
+** Returns:
+** NULL -- if there were no quotes, or if the resulting
+** unquoted buffer would not be acceptable to prescan.
+** else -- The dequoted buffer.
+*/
+
+char *
+dequote_map(map, name, av, statp)
+ MAP *map;
+ char *name;
+ char **av;
+ int *statp;
+{
+ register char *p;
+ register char *q;
+ register char c;
+ int anglecnt;
+ int cmntcnt;
+ int quotecnt;
+ int spacecnt;
+ bool quotemode;
+ bool bslashmode;
+
+ anglecnt = 0;
+ cmntcnt = 0;
+ quotecnt = 0;
+ spacecnt = 0;
+ quotemode = FALSE;
+ bslashmode = FALSE;
+
+ for (p = q = name; (c = *p++) != '\0'; )
+ {
+ if (bslashmode)
+ {
+ bslashmode = FALSE;
+ *q++ = c;
+ continue;
+ }
+
+ switch (c)
+ {
+ case '\\':
+ bslashmode = TRUE;
+ break;
+
+ case '(':
+ cmntcnt++;
+ break;
+
+ case ')':
+ if (cmntcnt-- <= 0)
+ return NULL;
+ break;
+
+ case ' ':
+ spacecnt++;
+ break;
+ }
+
+ if (cmntcnt > 0)
+ {
+ *q++ = c;
+ continue;
+ }
+
+ switch (c)
+ {
+ case '"':
+ quotemode = !quotemode;
+ quotecnt++;
+ continue;
+
+ case '<':
+ anglecnt++;
+ break;
+
+ case '>':
+ if (anglecnt-- <= 0)
+ return NULL;
+ break;
+ }
+ *q++ = c;
+ }
+
+ if (anglecnt != 0 || cmntcnt != 0 || bslashmode ||
+ quotemode || quotecnt <= 0 || spacecnt != 0)
+ return NULL;
+ *q++ = '\0';
+ return name;
+}
diff --git a/usr.sbin/sendmail/src/pathnames.h b/usr.sbin/sendmail/src/pathnames.h
new file mode 100644
index 0000000..a611c0b
--- /dev/null
+++ b/usr.sbin/sendmail/src/pathnames.h
@@ -0,0 +1,46 @@
+/*-
+ * Copyright (c) 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)pathnames.h 8.2 (Berkeley) 8/20/93
+ */
+
+#ifndef _PATH_SENDMAILCF
+# define _PATH_SENDMAILCF "/etc/sendmail.cf"
+#endif
+
+#ifndef _PATH_SENDMAILPID
+# ifdef BSD4_4
+# define _PATH_SENDMAILPID "/var/run/sendmail.pid"
+# else
+# define _PATH_SENDMAILPID "/etc/sendmail.pid"
+# endif
+#endif
diff --git a/usr.sbin/sendmail/src/queue.c b/usr.sbin/sendmail/src/queue.c
new file mode 100644
index 0000000..efedb72
--- /dev/null
+++ b/usr.sbin/sendmail/src/queue.c
@@ -0,0 +1,1571 @@
+/*
+ * Copyright (c) 1983 Eric P. Allman
+ * Copyright (c) 1988, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+# include "sendmail.h"
+
+#ifndef lint
+#ifdef QUEUE
+static char sccsid[] = "@(#)queue.c 8.41 (Berkeley) 4/18/94 (with queueing)";
+#else
+static char sccsid[] = "@(#)queue.c 8.41 (Berkeley) 4/18/94 (without queueing)";
+#endif
+#endif /* not lint */
+
+# include <errno.h>
+# include <pwd.h>
+# include <dirent.h>
+
+# ifdef QUEUE
+
+/*
+** Work queue.
+*/
+
+struct work
+{
+ char *w_name; /* name of control file */
+ long w_pri; /* priority of message, see below */
+ time_t w_ctime; /* creation time of message */
+ struct work *w_next; /* next in queue */
+};
+
+typedef struct work WORK;
+
+WORK *WorkQ; /* queue of things to be done */
+ /*
+** QUEUEUP -- queue a message up for future transmission.
+**
+** Parameters:
+** e -- the envelope to queue up.
+** queueall -- if TRUE, queue all addresses, rather than
+** just those with the QQUEUEUP flag set.
+** announce -- if TRUE, tell when you are queueing up.
+**
+** Returns:
+** none.
+**
+** Side Effects:
+** The current request are saved in a control file.
+** The queue file is left locked.
+*/
+
+queueup(e, queueall, announce)
+ register ENVELOPE *e;
+ bool queueall;
+ bool announce;
+{
+ char *qf;
+ register FILE *tfp;
+ register HDR *h;
+ register ADDRESS *q;
+ int fd;
+ int i;
+ bool newid;
+ register char *p;
+ MAILER nullmailer;
+ MCI mcibuf;
+ char buf[MAXLINE], tf[MAXLINE];
+
+ /*
+ ** Create control file.
+ */
+
+ newid = (e->e_id == NULL) || !bitset(EF_INQUEUE, e->e_flags);
+
+ /* if newid, queuename will create a locked qf file in e->lockfp */
+ strcpy(tf, queuename(e, 't'));
+ tfp = e->e_lockfp;
+ if (tfp == NULL)
+ newid = FALSE;
+
+ /* if newid, just write the qf file directly (instead of tf file) */
+ if (!newid)
+ {
+ /* get a locked tf file */
+ for (i = 0; i < 128; i++)
+ {
+ fd = open(tf, O_CREAT|O_WRONLY|O_EXCL, FileMode);
+ if (fd < 0)
+ {
+ if (errno != EEXIST)
+ break;
+#ifdef LOG
+ if (LogLevel > 0 && (i % 32) == 0)
+ syslog(LOG_ALERT, "queueup: cannot create %s, uid=%d: %s",
+ tf, geteuid(), errstring(errno));
+#endif
+ }
+ else
+ {
+ if (lockfile(fd, tf, NULL, LOCK_EX|LOCK_NB))
+ break;
+#ifdef LOG
+ else if (LogLevel > 0 && (i % 32) == 0)
+ syslog(LOG_ALERT, "queueup: cannot lock %s: %s",
+ tf, errstring(errno));
+#endif
+ close(fd);
+ }
+
+ if ((i % 32) == 31)
+ {
+ /* save the old temp file away */
+ (void) rename(tf, queuename(e, 'T'));
+ }
+ else
+ sleep(i % 32);
+ }
+ if (fd < 0 || (tfp = fdopen(fd, "w")) == NULL)
+ {
+ printopenfds(TRUE);
+ syserr("!queueup: cannot create queue temp file %s, uid=%d",
+ tf, geteuid());
+ }
+ }
+
+ if (tTd(40, 1))
+ printf("\n>>>>> queueing %s%s >>>>>\n", e->e_id,
+ newid ? " (new id)" : "");
+ if (tTd(40, 9))
+ {
+ printf(" tfp=");
+ dumpfd(fileno(tfp), TRUE, FALSE);
+ printf(" lockfp=");
+ if (e->e_lockfp == NULL)
+ printf("NULL\n");
+ else
+ dumpfd(fileno(e->e_lockfp), TRUE, FALSE);
+ }
+
+ /*
+ ** If there is no data file yet, create one.
+ */
+
+ if (e->e_df == NULL)
+ {
+ register FILE *dfp;
+ extern putbody();
+
+ e->e_df = queuename(e, 'd');
+ e->e_df = newstr(e->e_df);
+ fd = open(e->e_df, O_WRONLY|O_CREAT|O_TRUNC, FileMode);
+ if (fd < 0 || (dfp = fdopen(fd, "w")) == NULL)
+ syserr("!queueup: cannot create data temp file %s, uid=%d",
+ e->e_df, geteuid());
+ bzero(&mcibuf, sizeof mcibuf);
+ mcibuf.mci_out = dfp;
+ mcibuf.mci_mailer = FileMailer;
+ (*e->e_putbody)(&mcibuf, e, NULL);
+ (void) xfclose(dfp, "queueup dfp", e->e_id);
+ e->e_putbody = putbody;
+ }
+
+ /*
+ ** Output future work requests.
+ ** Priority and creation time should be first, since
+ ** they are required by orderq.
+ */
+
+ /* output message priority */
+ fprintf(tfp, "P%ld\n", e->e_msgpriority);
+
+ /* output creation time */
+ fprintf(tfp, "T%ld\n", e->e_ctime);
+
+ /* output type and name of data file */
+ if (e->e_bodytype != NULL)
+ fprintf(tfp, "B%s\n", e->e_bodytype);
+ fprintf(tfp, "D%s\n", e->e_df);
+
+ /* message from envelope, if it exists */
+ if (e->e_message != NULL)
+ fprintf(tfp, "M%s\n", e->e_message);
+
+ /* send various flag bits through */
+ p = buf;
+ if (bitset(EF_WARNING, e->e_flags))
+ *p++ = 'w';
+ if (bitset(EF_RESPONSE, e->e_flags))
+ *p++ = 'r';
+ *p++ = '\0';
+ if (buf[0] != '\0')
+ fprintf(tfp, "F%s\n", buf);
+
+ /* $r and $s and $_ macro values */
+ if ((p = macvalue('r', e)) != NULL)
+ fprintf(tfp, "$r%s\n", p);
+ if ((p = macvalue('s', e)) != NULL)
+ fprintf(tfp, "$s%s\n", p);
+ if ((p = macvalue('_', e)) != NULL)
+ fprintf(tfp, "$_%s\n", p);
+
+ /* output name of sender */
+ fprintf(tfp, "S%s\n", e->e_from.q_paddr);
+
+ /* output list of error recipients */
+ printctladdr(NULL, NULL);
+ for (q = e->e_errorqueue; q != NULL; q = q->q_next)
+ {
+ if (!bitset(QDONTSEND|QBADADDR, q->q_flags))
+ {
+ printctladdr(q, tfp);
+ fprintf(tfp, "E%s\n", q->q_paddr);
+ }
+ }
+
+ /* output list of recipient addresses */
+ for (q = e->e_sendqueue; q != NULL; q = q->q_next)
+ {
+ if (bitset(QQUEUEUP, q->q_flags) ||
+ (queueall && !bitset(QDONTSEND|QBADADDR|QSENT, q->q_flags)))
+ {
+ printctladdr(q, tfp);
+ fprintf(tfp, "R%s\n", q->q_paddr);
+ if (announce)
+ {
+ e->e_to = q->q_paddr;
+ message("queued");
+ if (LogLevel > 8)
+ logdelivery(NULL, NULL, "queued", NULL, e);
+ e->e_to = NULL;
+ }
+ if (tTd(40, 1))
+ {
+ printf("queueing ");
+ printaddr(q, FALSE);
+ }
+ }
+ }
+
+ /*
+ ** Output headers for this message.
+ ** Expand macros completely here. Queue run will deal with
+ ** everything as absolute headers.
+ ** All headers that must be relative to the recipient
+ ** can be cracked later.
+ ** We set up a "null mailer" -- i.e., a mailer that will have
+ ** no effect on the addresses as they are output.
+ */
+
+ bzero((char *) &nullmailer, sizeof nullmailer);
+ nullmailer.m_re_rwset = nullmailer.m_rh_rwset =
+ nullmailer.m_se_rwset = nullmailer.m_sh_rwset = -1;
+ nullmailer.m_eol = "\n";
+ bzero(&mcibuf, sizeof mcibuf);
+ mcibuf.mci_mailer = &nullmailer;
+ mcibuf.mci_out = tfp;
+
+ define('g', "\201f", e);
+ for (h = e->e_header; h != NULL; h = h->h_link)
+ {
+ extern bool bitzerop();
+
+ /* don't output null headers */
+ if (h->h_value == NULL || h->h_value[0] == '\0')
+ continue;
+
+ /* don't output resent headers on non-resent messages */
+ if (bitset(H_RESENT, h->h_flags) && !bitset(EF_RESENT, e->e_flags))
+ continue;
+
+ /* expand macros; if null, don't output header at all */
+ if (bitset(H_DEFAULT, h->h_flags))
+ {
+ (void) expand(h->h_value, buf, &buf[sizeof buf], e);
+ if (buf[0] == '\0')
+ continue;
+ }
+
+ /* output this header */
+ fprintf(tfp, "H");
+
+ /* if conditional, output the set of conditions */
+ if (!bitzerop(h->h_mflags) && bitset(H_CHECK|H_ACHECK, h->h_flags))
+ {
+ int j;
+
+ (void) putc('?', tfp);
+ for (j = '\0'; j <= '\177'; j++)
+ if (bitnset(j, h->h_mflags))
+ (void) putc(j, tfp);
+ (void) putc('?', tfp);
+ }
+
+ /* output the header: expand macros, convert addresses */
+ if (bitset(H_DEFAULT, h->h_flags))
+ {
+ fprintf(tfp, "%s: %s\n", h->h_field, buf);
+ }
+ else if (bitset(H_FROM|H_RCPT, h->h_flags))
+ {
+ bool oldstyle = bitset(EF_OLDSTYLE, e->e_flags);
+ FILE *savetrace = TrafficLogFile;
+
+ TrafficLogFile = NULL;
+
+ if (bitset(H_FROM, h->h_flags))
+ oldstyle = FALSE;
+
+ commaize(h, h->h_value, oldstyle, &mcibuf, e);
+
+ TrafficLogFile = savetrace;
+ }
+ else
+ fprintf(tfp, "%s: %s\n", h->h_field, h->h_value);
+ }
+
+ /*
+ ** Clean up.
+ */
+
+ if (fflush(tfp) < 0 || fsync(fileno(tfp)) < 0 || ferror(tfp))
+ {
+ if (newid)
+ syserr("!552 Error writing control file %s", tf);
+ else
+ syserr("!452 Error writing control file %s", tf);
+ }
+
+ if (!newid)
+ {
+ /* rename (locked) tf to be (locked) qf */
+ qf = queuename(e, 'q');
+ if (rename(tf, qf) < 0)
+ syserr("cannot rename(%s, %s), df=%s, uid=%d",
+ tf, qf, e->e_df, geteuid());
+
+ /* close and unlock old (locked) qf */
+ if (e->e_lockfp != NULL)
+ (void) xfclose(e->e_lockfp, "queueup lockfp", e->e_id);
+ e->e_lockfp = tfp;
+ }
+ else
+ qf = tf;
+ errno = 0;
+ e->e_flags |= EF_INQUEUE;
+
+# ifdef LOG
+ /* save log info */
+ if (LogLevel > 79)
+ syslog(LOG_DEBUG, "%s: queueup, qf=%s, df=%s\n", e->e_id, qf, e->e_df);
+# endif /* LOG */
+
+ if (tTd(40, 1))
+ printf("<<<<< done queueing %s <<<<<\n\n", e->e_id);
+ return;
+}
+
+printctladdr(a, tfp)
+ register ADDRESS *a;
+ FILE *tfp;
+{
+ char *uname;
+ register struct passwd *pw;
+ register ADDRESS *q;
+ uid_t uid;
+ static ADDRESS *lastctladdr;
+ static uid_t lastuid;
+
+ /* initialization */
+ if (a == NULL || a->q_alias == NULL || tfp == NULL)
+ {
+ if (lastctladdr != NULL && tfp != NULL)
+ fprintf(tfp, "C\n");
+ lastctladdr = NULL;
+ lastuid = 0;
+ return;
+ }
+
+ /* find the active uid */
+ q = getctladdr(a);
+ if (q == NULL)
+ uid = 0;
+ else
+ uid = q->q_uid;
+ a = a->q_alias;
+
+ /* check to see if this is the same as last time */
+ if (lastctladdr != NULL && uid == lastuid &&
+ strcmp(lastctladdr->q_paddr, a->q_paddr) == 0)
+ return;
+ lastuid = uid;
+ lastctladdr = a;
+
+ if (uid == 0 || (pw = getpwuid(uid)) == NULL)
+ uname = "";
+ else
+ uname = pw->pw_name;
+
+ fprintf(tfp, "C%s:%s\n", uname, a->q_paddr);
+}
+
+ /*
+** RUNQUEUE -- run the jobs in the queue.
+**
+** Gets the stuff out of the queue in some presumably logical
+** order and processes them.
+**
+** Parameters:
+** forkflag -- TRUE if the queue scanning should be done in
+** a child process. We double-fork so it is not our
+** child and we don't have to clean up after it.
+**
+** Returns:
+** none.
+**
+** Side Effects:
+** runs things in the mail queue.
+*/
+
+ENVELOPE QueueEnvelope; /* the queue run envelope */
+
+runqueue(forkflag)
+ bool forkflag;
+{
+ register ENVELOPE *e;
+ extern ENVELOPE BlankEnvelope;
+
+ /*
+ ** If no work will ever be selected, don't even bother reading
+ ** the queue.
+ */
+
+ CurrentLA = getla(); /* get load average */
+
+ if (shouldqueue(0L, curtime()))
+ {
+ if (Verbose)
+ printf("Skipping queue run -- load average too high\n");
+ if (forkflag && QueueIntvl != 0)
+ (void) setevent(QueueIntvl, runqueue, TRUE);
+ return;
+ }
+
+ /*
+ ** See if we want to go off and do other useful work.
+ */
+
+ if (forkflag)
+ {
+ int pid;
+#ifdef SIGCHLD
+ extern void reapchild();
+
+ (void) setsignal(SIGCHLD, reapchild);
+#endif
+
+ pid = dofork();
+ if (pid != 0)
+ {
+ /* parent -- pick up intermediate zombie */
+#ifndef SIGCHLD
+ (void) waitfor(pid);
+#endif /* SIGCHLD */
+ if (QueueIntvl != 0)
+ (void) setevent(QueueIntvl, runqueue, TRUE);
+ return;
+ }
+ /* child -- double fork */
+#ifndef SIGCHLD
+ if (fork() != 0)
+ exit(EX_OK);
+#else /* SIGCHLD */
+ (void) setsignal(SIGCHLD, SIG_DFL);
+#endif /* SIGCHLD */
+ }
+
+ setproctitle("running queue: %s", QueueDir);
+
+# ifdef LOG
+ if (LogLevel > 69)
+ syslog(LOG_DEBUG, "runqueue %s, pid=%d, forkflag=%d",
+ QueueDir, getpid(), forkflag);
+# endif /* LOG */
+
+ /*
+ ** Release any resources used by the daemon code.
+ */
+
+# ifdef DAEMON
+ clrdaemon();
+# endif /* DAEMON */
+
+ /* force it to run expensive jobs */
+ NoConnect = FALSE;
+
+ /*
+ ** Create ourselves an envelope
+ */
+
+ CurEnv = &QueueEnvelope;
+ e = newenvelope(&QueueEnvelope, CurEnv);
+ e->e_flags = BlankEnvelope.e_flags;
+
+ /*
+ ** Make sure the alias database is open.
+ */
+
+ initmaps(FALSE, e);
+
+ /*
+ ** Start making passes through the queue.
+ ** First, read and sort the entire queue.
+ ** Then, process the work in that order.
+ ** But if you take too long, start over.
+ */
+
+ /* order the existing work requests */
+ (void) orderq(FALSE);
+
+ /* process them once at a time */
+ while (WorkQ != NULL)
+ {
+ WORK *w = WorkQ;
+
+ WorkQ = WorkQ->w_next;
+
+ /*
+ ** Ignore jobs that are too expensive for the moment.
+ */
+
+ if (shouldqueue(w->w_pri, w->w_ctime))
+ {
+ if (Verbose)
+ printf("\nSkipping %s\n", w->w_name + 2);
+ }
+ else
+ {
+ pid_t pid;
+ extern pid_t dowork();
+
+ pid = dowork(w->w_name + 2, ForkQueueRuns, FALSE, e);
+ errno = 0;
+ if (pid != 0)
+ (void) waitfor(pid);
+ }
+ free(w->w_name);
+ free((char *) w);
+ }
+
+ /* exit without the usual cleanup */
+ e->e_id = NULL;
+ finis();
+}
+ /*
+** ORDERQ -- order the work queue.
+**
+** Parameters:
+** doall -- if set, include everything in the queue (even
+** the jobs that cannot be run because the load
+** average is too high). Otherwise, exclude those
+** jobs.
+**
+** Returns:
+** The number of request in the queue (not necessarily
+** the number of requests in WorkQ however).
+**
+** Side Effects:
+** Sets WorkQ to the queue of available work, in order.
+*/
+
+# define NEED_P 001
+# define NEED_T 002
+# define NEED_R 004
+# define NEED_S 010
+
+orderq(doall)
+ bool doall;
+{
+ register struct dirent *d;
+ register WORK *w;
+ DIR *f;
+ register int i;
+ WORK wlist[QUEUESIZE+1];
+ int wn = -1;
+ extern workcmpf();
+
+ if (tTd(41, 1))
+ {
+ printf("orderq:\n");
+ if (QueueLimitId != NULL)
+ printf("\tQueueLimitId = %s\n", QueueLimitId);
+ if (QueueLimitSender != NULL)
+ printf("\tQueueLimitSender = %s\n", QueueLimitSender);
+ if (QueueLimitRecipient != NULL)
+ printf("\tQueueLimitRecipient = %s\n", QueueLimitRecipient);
+ }
+
+ /* clear out old WorkQ */
+ for (w = WorkQ; w != NULL; )
+ {
+ register WORK *nw = w->w_next;
+
+ WorkQ = nw;
+ free(w->w_name);
+ free((char *) w);
+ w = nw;
+ }
+
+ /* open the queue directory */
+ f = opendir(".");
+ if (f == NULL)
+ {
+ syserr("orderq: cannot open \"%s\" as \".\"", QueueDir);
+ return (0);
+ }
+
+ /*
+ ** Read the work directory.
+ */
+
+ while ((d = readdir(f)) != NULL)
+ {
+ FILE *cf;
+ register char *p;
+ char lbuf[MAXNAME];
+ extern bool strcontainedin();
+
+ /* is this an interesting entry? */
+ if (d->d_name[0] != 'q' || d->d_name[1] != 'f')
+ continue;
+
+ if (QueueLimitId != NULL &&
+ !strcontainedin(QueueLimitId, d->d_name))
+ continue;
+
+ /*
+ ** Check queue name for plausibility. This handles
+ ** both old and new type ids.
+ */
+
+ p = d->d_name + 2;
+ if (isupper(p[0]) && isupper(p[2]))
+ p += 3;
+ else if (isupper(p[1]))
+ p += 2;
+ else
+ p = d->d_name;
+ for (i = 0; isdigit(*p); p++)
+ i++;
+ if (i < 5 || *p != '\0')
+ {
+ if (Verbose)
+ printf("orderq: bogus qf name %s\n", d->d_name);
+#ifdef LOG
+ if (LogLevel > 3)
+ syslog(LOG_CRIT, "orderq: bogus qf name %s",
+ d->d_name);
+#endif
+ if (strlen(d->d_name) >= MAXNAME)
+ d->d_name[MAXNAME - 1] = '\0';
+ strcpy(lbuf, d->d_name);
+ lbuf[0] = 'Q';
+ (void) rename(d->d_name, lbuf);
+ continue;
+ }
+
+ /* yes -- open control file (if not too many files) */
+ if (++wn >= QUEUESIZE)
+ continue;
+
+ cf = fopen(d->d_name, "r");
+ if (cf == NULL)
+ {
+ /* this may be some random person sending hir msgs */
+ /* syserr("orderq: cannot open %s", cbuf); */
+ if (tTd(41, 2))
+ printf("orderq: cannot open %s (%d)\n",
+ d->d_name, errno);
+ errno = 0;
+ wn--;
+ continue;
+ }
+ w = &wlist[wn];
+ w->w_name = newstr(d->d_name);
+
+ /* make sure jobs in creation don't clog queue */
+ w->w_pri = 0x7fffffff;
+ w->w_ctime = 0;
+
+ /* extract useful information */
+ i = NEED_P | NEED_T;
+ if (QueueLimitSender != NULL)
+ i |= NEED_S;
+ if (QueueLimitRecipient != NULL)
+ i |= NEED_R;
+ while (i != 0 && fgets(lbuf, sizeof lbuf, cf) != NULL)
+ {
+ extern long atol();
+ extern bool strcontainedin();
+
+ switch (lbuf[0])
+ {
+ case 'P':
+ w->w_pri = atol(&lbuf[1]);
+ i &= ~NEED_P;
+ break;
+
+ case 'T':
+ w->w_ctime = atol(&lbuf[1]);
+ i &= ~NEED_T;
+ break;
+
+ case 'R':
+ if (QueueLimitRecipient != NULL &&
+ strcontainedin(QueueLimitRecipient, &lbuf[1]))
+ i &= ~NEED_R;
+ break;
+
+ case 'S':
+ if (QueueLimitSender != NULL &&
+ strcontainedin(QueueLimitSender, &lbuf[1]))
+ i &= ~NEED_S;
+ break;
+ }
+ }
+ (void) fclose(cf);
+
+ if ((!doall && shouldqueue(w->w_pri, w->w_ctime)) ||
+ bitset(NEED_R|NEED_S, i))
+ {
+ /* don't even bother sorting this job in */
+ wn--;
+ }
+ }
+ (void) closedir(f);
+ wn++;
+
+ /*
+ ** Sort the work directory.
+ */
+
+ qsort((char *) wlist, min(wn, QUEUESIZE), sizeof *wlist, workcmpf);
+
+ /*
+ ** Convert the work list into canonical form.
+ ** Should be turning it into a list of envelopes here perhaps.
+ */
+
+ WorkQ = NULL;
+ for (i = min(wn, QUEUESIZE); --i >= 0; )
+ {
+ w = (WORK *) xalloc(sizeof *w);
+ w->w_name = wlist[i].w_name;
+ w->w_pri = wlist[i].w_pri;
+ w->w_ctime = wlist[i].w_ctime;
+ w->w_next = WorkQ;
+ WorkQ = w;
+ }
+
+ if (tTd(40, 1))
+ {
+ for (w = WorkQ; w != NULL; w = w->w_next)
+ printf("%32s: pri=%ld\n", w->w_name, w->w_pri);
+ }
+
+ return (wn);
+}
+ /*
+** WORKCMPF -- compare function for ordering work.
+**
+** Parameters:
+** a -- the first argument.
+** b -- the second argument.
+**
+** Returns:
+** -1 if a < b
+** 0 if a == b
+** +1 if a > b
+**
+** Side Effects:
+** none.
+*/
+
+workcmpf(a, b)
+ register WORK *a;
+ register WORK *b;
+{
+ long pa = a->w_pri;
+ long pb = b->w_pri;
+
+ if (pa == pb)
+ return (0);
+ else if (pa > pb)
+ return (1);
+ else
+ return (-1);
+}
+ /*
+** DOWORK -- do a work request.
+**
+** Parameters:
+** id -- the ID of the job to run.
+** forkflag -- if set, run this in background.
+** requeueflag -- if set, reinstantiate the queue quickly.
+** This is used when expanding aliases in the queue.
+** If forkflag is also set, it doesn't wait for the
+** child.
+** e - the envelope in which to run it.
+**
+** Returns:
+** process id of process that is running the queue job.
+**
+** Side Effects:
+** The work request is satisfied if possible.
+*/
+
+pid_t
+dowork(id, forkflag, requeueflag, e)
+ char *id;
+ bool forkflag;
+ bool requeueflag;
+ register ENVELOPE *e;
+{
+ register pid_t pid;
+ extern bool readqf();
+
+ if (tTd(40, 1))
+ printf("dowork(%s)\n", id);
+
+ /*
+ ** Fork for work.
+ */
+
+ if (forkflag)
+ {
+ pid = fork();
+ if (pid < 0)
+ {
+ syserr("dowork: cannot fork");
+ return 0;
+ }
+ else if (pid > 0)
+ {
+ /* parent -- clean out connection cache */
+ mci_flush(FALSE, NULL);
+ }
+ }
+ else
+ {
+ pid = 0;
+ }
+
+ if (pid == 0)
+ {
+ /*
+ ** CHILD
+ ** Lock the control file to avoid duplicate deliveries.
+ ** Then run the file as though we had just read it.
+ ** We save an idea of the temporary name so we
+ ** can recover on interrupt.
+ */
+
+ /* set basic modes, etc. */
+ (void) alarm(0);
+ clearenvelope(e, FALSE);
+ e->e_flags |= EF_QUEUERUN|EF_GLOBALERRS;
+ e->e_errormode = EM_MAIL;
+ e->e_id = id;
+ GrabTo = UseErrorsTo = FALSE;
+ ExitStat = EX_OK;
+ if (forkflag)
+ {
+ disconnect(1, e);
+ OpMode = MD_DELIVER;
+ }
+# ifdef LOG
+ if (LogLevel > 76)
+ syslog(LOG_DEBUG, "%s: dowork, pid=%d", e->e_id,
+ getpid());
+# endif /* LOG */
+
+ /* don't use the headers from sendmail.cf... */
+ e->e_header = NULL;
+
+ /* read the queue control file -- return if locked */
+ if (!readqf(e))
+ {
+ if (tTd(40, 4))
+ printf("readqf(%s) failed\n", e->e_id);
+ if (forkflag)
+ exit(EX_OK);
+ else
+ return 0;
+ }
+
+ e->e_flags |= EF_INQUEUE;
+ eatheader(e, requeueflag);
+
+ if (requeueflag)
+ queueup(e, TRUE, FALSE);
+
+ /* do the delivery */
+ sendall(e, SM_DELIVER);
+
+ /* finish up and exit */
+ if (forkflag)
+ finis();
+ else
+ dropenvelope(e);
+ }
+ e->e_id = NULL;
+ return pid;
+}
+ /*
+** READQF -- read queue file and set up environment.
+**
+** Parameters:
+** e -- the envelope of the job to run.
+**
+** Returns:
+** TRUE if it successfully read the queue file.
+** FALSE otherwise.
+**
+** Side Effects:
+** The queue file is returned locked.
+*/
+
+bool
+readqf(e)
+ register ENVELOPE *e;
+{
+ register FILE *qfp;
+ ADDRESS *ctladdr;
+ struct stat st;
+ char *bp;
+ char qf[20];
+ char buf[MAXLINE];
+ extern long atol();
+ extern ADDRESS *setctluser();
+
+ /*
+ ** Read and process the file.
+ */
+
+ strcpy(qf, queuename(e, 'q'));
+ qfp = fopen(qf, "r+");
+ if (qfp == NULL)
+ {
+ if (tTd(40, 8))
+ printf("readqf(%s): fopen failure (%s)\n",
+ qf, errstring(errno));
+ if (errno != ENOENT)
+ syserr("readqf: no control file %s", qf);
+ return FALSE;
+ }
+
+ if (!lockfile(fileno(qfp), qf, NULL, LOCK_EX|LOCK_NB))
+ {
+ /* being processed by another queuer */
+ if (tTd(40, 8))
+ printf("readqf(%s): locked\n", qf);
+ if (Verbose)
+ printf("%s: locked\n", e->e_id);
+# ifdef LOG
+ if (LogLevel > 19)
+ syslog(LOG_DEBUG, "%s: locked", e->e_id);
+# endif /* LOG */
+ (void) fclose(qfp);
+ return FALSE;
+ }
+
+ /*
+ ** Check the queue file for plausibility to avoid attacks.
+ */
+
+ if (fstat(fileno(qfp), &st) < 0)
+ {
+ /* must have been being processed by someone else */
+ if (tTd(40, 8))
+ printf("readqf(%s): fstat failure (%s)\n",
+ qf, errstring(errno));
+ fclose(qfp);
+ return FALSE;
+ }
+
+ if (st.st_uid != geteuid())
+ {
+# ifdef LOG
+ if (LogLevel > 0)
+ {
+ syslog(LOG_ALERT, "%s: bogus queue file, uid=%d, mode=%o",
+ e->e_id, st.st_uid, st.st_mode);
+ }
+# endif /* LOG */
+ if (tTd(40, 8))
+ printf("readqf(%s): bogus file\n", qf);
+ rename(qf, queuename(e, 'Q'));
+ fclose(qfp);
+ return FALSE;
+ }
+
+ if (st.st_size == 0)
+ {
+ /* must be a bogus file -- just remove it */
+ (void) unlink(qf);
+ fclose(qfp);
+ return FALSE;
+ }
+
+ if (st.st_nlink == 0)
+ {
+ /*
+ ** Race condition -- we got a file just as it was being
+ ** unlinked. Just assume it is zero length.
+ */
+
+ fclose(qfp);
+ return FALSE;
+ }
+
+ /* good file -- save this lock */
+ e->e_lockfp = qfp;
+
+ /* do basic system initialization */
+ initsys(e);
+ define('i', e->e_id, e);
+
+ LineNumber = 0;
+ e->e_flags |= EF_GLOBALERRS;
+ OpMode = MD_DELIVER;
+ if (Verbose)
+ printf("\nRunning %s\n", e->e_id);
+ ctladdr = NULL;
+ while ((bp = fgetfolded(buf, sizeof buf, qfp)) != NULL)
+ {
+ register char *p;
+ struct stat st;
+
+ if (tTd(40, 4))
+ printf("+++++ %s\n", bp);
+ switch (bp[0])
+ {
+ case 'C': /* specify controlling user */
+ ctladdr = setctluser(&bp[1]);
+ break;
+
+ case 'R': /* specify recipient */
+ (void) sendtolist(&bp[1], ctladdr, &e->e_sendqueue, e);
+ break;
+
+ case 'E': /* specify error recipient */
+ (void) sendtolist(&bp[1], ctladdr, &e->e_errorqueue, e);
+ break;
+
+ case 'H': /* header */
+ (void) chompheader(&bp[1], FALSE, e);
+ break;
+
+ case 'M': /* message */
+ /* ignore this; we want a new message next time */
+ break;
+
+ case 'S': /* sender */
+ setsender(newstr(&bp[1]), e, NULL, TRUE);
+ break;
+
+ case 'B': /* body type */
+ e->e_bodytype = newstr(&bp[1]);
+ break;
+
+ case 'D': /* data file name */
+ e->e_df = newstr(&bp[1]);
+ e->e_dfp = fopen(e->e_df, "r");
+ if (e->e_dfp == NULL)
+ {
+ syserr("readqf: cannot open %s", e->e_df);
+ e->e_msgsize = -1;
+ }
+ else if (fstat(fileno(e->e_dfp), &st) >= 0)
+ e->e_msgsize = st.st_size;
+ break;
+
+ case 'T': /* init time */
+ e->e_ctime = atol(&bp[1]);
+ break;
+
+ case 'P': /* message priority */
+ e->e_msgpriority = atol(&bp[1]) + WkTimeFact;
+ break;
+
+ case 'F': /* flag bits */
+ for (p = &bp[1]; *p != '\0'; p++)
+ {
+ switch (*p)
+ {
+ case 'w': /* warning sent */
+ e->e_flags |= EF_WARNING;
+ break;
+
+ case 'r': /* response */
+ e->e_flags |= EF_RESPONSE;
+ break;
+ }
+ }
+ break;
+
+ case '$': /* define macro */
+ define(bp[1], newstr(&bp[2]), e);
+ break;
+
+ case '\0': /* blank line; ignore */
+ break;
+
+ default:
+ syserr("readqf: %s: line %d: bad line \"%s\"",
+ qf, LineNumber, bp);
+ fclose(qfp);
+ rename(qf, queuename(e, 'Q'));
+ return FALSE;
+ }
+
+ if (bp != buf)
+ free(bp);
+ }
+
+ /*
+ ** If we haven't read any lines, this queue file is empty.
+ ** Arrange to remove it without referencing any null pointers.
+ */
+
+ if (LineNumber == 0)
+ {
+ errno = 0;
+ e->e_flags |= EF_CLRQUEUE | EF_FATALERRS | EF_RESPONSE;
+ }
+ return TRUE;
+}
+ /*
+** PRINTQUEUE -- print out a representation of the mail queue
+**
+** Parameters:
+** none.
+**
+** Returns:
+** none.
+**
+** Side Effects:
+** Prints a listing of the mail queue on the standard output.
+*/
+
+printqueue()
+{
+ register WORK *w;
+ FILE *f;
+ int nrequests;
+ char buf[MAXLINE];
+
+ /*
+ ** Check for permission to print the queue
+ */
+
+ if (bitset(PRIV_RESTRICTMAILQ, PrivacyFlags) && RealUid != 0)
+ {
+ struct stat st;
+# ifdef NGROUPS
+ int n;
+ GIDSET_T gidset[NGROUPS];
+# endif
+
+ if (stat(QueueDir, &st) < 0)
+ {
+ syserr("Cannot stat %s", QueueDir);
+ return;
+ }
+# ifdef NGROUPS
+ n = getgroups(NGROUPS, gidset);
+ while (--n >= 0)
+ {
+ if (gidset[n] == st.st_gid)
+ break;
+ }
+ if (n < 0)
+# else
+ if (RealGid != st.st_gid)
+# endif
+ {
+ usrerr("510 You are not permitted to see the queue");
+ setstat(EX_NOPERM);
+ return;
+ }
+ }
+
+ /*
+ ** Read and order the queue.
+ */
+
+ nrequests = orderq(TRUE);
+
+ /*
+ ** Print the work list that we have read.
+ */
+
+ /* first see if there is anything */
+ if (nrequests <= 0)
+ {
+ printf("Mail queue is empty\n");
+ return;
+ }
+
+ CurrentLA = getla(); /* get load average */
+
+ printf("\t\tMail Queue (%d request%s", nrequests, nrequests == 1 ? "" : "s");
+ if (nrequests > QUEUESIZE)
+ printf(", only %d printed", QUEUESIZE);
+ if (Verbose)
+ printf(")\n--Q-ID-- --Size-- -Priority- ---Q-Time--- -----------Sender/Recipient-----------\n");
+ else
+ printf(")\n--Q-ID-- --Size-- -----Q-Time----- ------------Sender/Recipient------------\n");
+ for (w = WorkQ; w != NULL; w = w->w_next)
+ {
+ struct stat st;
+ auto time_t submittime = 0;
+ long dfsize = -1;
+ int flags = 0;
+ char message[MAXLINE];
+ char bodytype[MAXNAME];
+
+ printf("%8s", w->w_name + 2);
+ f = fopen(w->w_name, "r");
+ if (f == NULL)
+ {
+ printf(" (job completed)\n");
+ errno = 0;
+ continue;
+ }
+ if (!lockfile(fileno(f), w->w_name, NULL, LOCK_SH|LOCK_NB))
+ printf("*");
+ else if (shouldqueue(w->w_pri, w->w_ctime))
+ printf("X");
+ else
+ printf(" ");
+ errno = 0;
+
+ message[0] = bodytype[0] = '\0';
+ while (fgets(buf, sizeof buf, f) != NULL)
+ {
+ register int i;
+ register char *p;
+
+ fixcrlf(buf, TRUE);
+ switch (buf[0])
+ {
+ case 'M': /* error message */
+ if ((i = strlen(&buf[1])) >= sizeof message)
+ i = sizeof message - 1;
+ bcopy(&buf[1], message, i);
+ message[i] = '\0';
+ break;
+
+ case 'B': /* body type */
+ if ((i = strlen(&buf[1])) >= sizeof bodytype)
+ i = sizeof bodytype - 1;
+ bcopy(&buf[1], bodytype, i);
+ bodytype[i] = '\0';
+ break;
+
+ case 'S': /* sender name */
+ if (Verbose)
+ printf("%8ld %10ld%c%.12s %.38s",
+ dfsize,
+ w->w_pri,
+ bitset(EF_WARNING, flags) ? '+' : ' ',
+ ctime(&submittime) + 4,
+ &buf[1]);
+ else
+ printf("%8ld %.16s %.45s", dfsize,
+ ctime(&submittime), &buf[1]);
+ if (message[0] != '\0' || bodytype[0] != '\0')
+ {
+ printf("\n %10.10s", bodytype);
+ if (message[0] != '\0')
+ printf(" (%.60s)", message);
+ }
+ break;
+
+ case 'C': /* controlling user */
+ if (Verbose)
+ printf("\n\t\t\t\t (---%.34s---)",
+ &buf[1]);
+ break;
+
+ case 'R': /* recipient name */
+ if (Verbose)
+ printf("\n\t\t\t\t\t %.38s", &buf[1]);
+ else
+ printf("\n\t\t\t\t %.45s", &buf[1]);
+ break;
+
+ case 'T': /* creation time */
+ submittime = atol(&buf[1]);
+ break;
+
+ case 'D': /* data file name */
+ if (stat(&buf[1], &st) >= 0)
+ dfsize = st.st_size;
+ break;
+
+ case 'F': /* flag bits */
+ for (p = &buf[1]; *p != '\0'; p++)
+ {
+ switch (*p)
+ {
+ case 'w':
+ flags |= EF_WARNING;
+ break;
+ }
+ }
+ }
+ }
+ if (submittime == (time_t) 0)
+ printf(" (no control file)");
+ printf("\n");
+ (void) fclose(f);
+ }
+}
+
+# endif /* QUEUE */
+ /*
+** QUEUENAME -- build a file name in the queue directory for this envelope.
+**
+** Assigns an id code if one does not already exist.
+** This code is very careful to avoid trashing existing files
+** under any circumstances.
+**
+** Parameters:
+** e -- envelope to build it in/from.
+** type -- the file type, used as the first character
+** of the file name.
+**
+** Returns:
+** a pointer to the new file name (in a static buffer).
+**
+** Side Effects:
+** If no id code is already assigned, queuename will
+** assign an id code, create a qf file, and leave a
+** locked, open-for-write file pointer in the envelope.
+*/
+
+char *
+queuename(e, type)
+ register ENVELOPE *e;
+ int type;
+{
+ static int pid = -1;
+ static char c0;
+ static char c1;
+ static char c2;
+ time_t now;
+ struct tm *tm;
+ static char buf[MAXNAME];
+
+ if (e->e_id == NULL)
+ {
+ char qf[20];
+
+ /* find a unique id */
+ if (pid != getpid())
+ {
+ /* new process -- start back at "AA" */
+ pid = getpid();
+ now = curtime();
+ tm = localtime(&now);
+ c0 = 'A' + tm->tm_hour;
+ c1 = 'A';
+ c2 = 'A' - 1;
+ }
+ (void) sprintf(qf, "qf%cAA%05d", c0, pid);
+
+ while (c1 < '~' || c2 < 'Z')
+ {
+ int i;
+
+ if (c2 >= 'Z')
+ {
+ c1++;
+ c2 = 'A' - 1;
+ }
+ qf[3] = c1;
+ qf[4] = ++c2;
+ if (tTd(7, 20))
+ printf("queuename: trying \"%s\"\n", qf);
+
+ i = open(qf, O_WRONLY|O_CREAT|O_EXCL, FileMode);
+ if (i < 0)
+ {
+ if (errno == EEXIST)
+ continue;
+ syserr("queuename: Cannot create \"%s\" in \"%s\" (euid=%d)",
+ qf, QueueDir, geteuid());
+ exit(EX_UNAVAILABLE);
+ }
+ if (lockfile(i, qf, NULL, LOCK_EX|LOCK_NB))
+ {
+ e->e_lockfp = fdopen(i, "w");
+ break;
+ }
+
+ /* a reader got the file; abandon it and try again */
+ (void) close(i);
+ }
+ if (c1 >= '~' && c2 >= 'Z')
+ {
+ syserr("queuename: Cannot create \"%s\" in \"%s\" (euid=%d)",
+ qf, QueueDir, geteuid());
+ exit(EX_OSERR);
+ }
+ e->e_id = newstr(&qf[2]);
+ define('i', e->e_id, e);
+ if (tTd(7, 1))
+ printf("queuename: assigned id %s, env=%x\n", e->e_id, e);
+ if (tTd(7, 9))
+ {
+ printf(" lockfd=");
+ dumpfd(fileno(e->e_lockfp), TRUE, FALSE);
+ }
+# ifdef LOG
+ if (LogLevel > 93)
+ syslog(LOG_DEBUG, "%s: assigned id", e->e_id);
+# endif /* LOG */
+ }
+
+ if (type == '\0')
+ return (NULL);
+ (void) sprintf(buf, "%cf%s", type, e->e_id);
+ if (tTd(7, 2))
+ printf("queuename: %s\n", buf);
+ return (buf);
+}
+ /*
+** UNLOCKQUEUE -- unlock the queue entry for a specified envelope
+**
+** Parameters:
+** e -- the envelope to unlock.
+**
+** Returns:
+** none
+**
+** Side Effects:
+** unlocks the queue for `e'.
+*/
+
+unlockqueue(e)
+ ENVELOPE *e;
+{
+ if (tTd(51, 4))
+ printf("unlockqueue(%s)\n", e->e_id);
+
+ /* if there is a lock file in the envelope, close it */
+ if (e->e_lockfp != NULL)
+ xfclose(e->e_lockfp, "unlockqueue", e->e_id);
+ e->e_lockfp = NULL;
+
+ /* don't create a queue id if we don't already have one */
+ if (e->e_id == NULL)
+ return;
+
+ /* remove the transcript */
+# ifdef LOG
+ if (LogLevel > 87)
+ syslog(LOG_DEBUG, "%s: unlock", e->e_id);
+# endif /* LOG */
+ if (!tTd(51, 104))
+ xunlink(queuename(e, 'x'));
+
+}
+ /*
+** SETCTLUSER -- create a controlling address
+**
+** Create a fake "address" given only a local login name; this is
+** used as a "controlling user" for future recipient addresses.
+**
+** Parameters:
+** user -- the user name of the controlling user.
+**
+** Returns:
+** An address descriptor for the controlling user.
+**
+** Side Effects:
+** none.
+*/
+
+ADDRESS *
+setctluser(user)
+ char *user;
+{
+ register ADDRESS *a;
+ struct passwd *pw;
+ char *p;
+
+ /*
+ ** See if this clears our concept of controlling user.
+ */
+
+ if (user == NULL || *user == '\0')
+ return NULL;
+
+ /*
+ ** Set up addr fields for controlling user.
+ */
+
+ a = (ADDRESS *) xalloc(sizeof *a);
+ bzero((char *) a, sizeof *a);
+
+ p = strchr(user, ':');
+ if (p != NULL)
+ *p++ = '\0';
+ if (*user != '\0' && (pw = getpwnam(user)) != NULL)
+ {
+ if (strcmp(pw->pw_dir, "/") == 0)
+ a->q_home = "";
+ else
+ a->q_home = newstr(pw->pw_dir);
+ a->q_uid = pw->pw_uid;
+ a->q_gid = pw->pw_gid;
+ a->q_user = newstr(user);
+ a->q_flags |= QGOODUID;
+ }
+ else
+ {
+ a->q_user = newstr(DefUser);
+ }
+
+ a->q_flags |= QPRIMARY; /* flag as a "ctladdr" */
+ a->q_mailer = LocalMailer;
+ if (p == NULL)
+ a->q_paddr = a->q_user;
+ else
+ a->q_paddr = newstr(p);
+ return a;
+}
diff --git a/usr.sbin/sendmail/src/readcf.c b/usr.sbin/sendmail/src/readcf.c
new file mode 100644
index 0000000..bd902c0
--- /dev/null
+++ b/usr.sbin/sendmail/src/readcf.c
@@ -0,0 +1,1681 @@
+/*
+ * Copyright (c) 1983 Eric P. Allman
+ * Copyright (c) 1988, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)readcf.c 8.23 (Berkeley) 3/18/94";
+#endif /* not lint */
+
+# include "sendmail.h"
+# include <pwd.h>
+# include <grp.h>
+#if NAMED_BIND
+# include <arpa/nameser.h>
+# include <resolv.h>
+#endif
+
+/*
+** READCF -- read control file.
+**
+** This routine reads the control file and builds the internal
+** form.
+**
+** The file is formatted as a sequence of lines, each taken
+** atomically. The first character of each line describes how
+** the line is to be interpreted. The lines are:
+** Dxval Define macro x to have value val.
+** Cxword Put word into class x.
+** Fxfile [fmt] Read file for lines to put into
+** class x. Use scanf string 'fmt'
+** or "%s" if not present. Fmt should
+** only produce one string-valued result.
+** Hname: value Define header with field-name 'name'
+** and value as specified; this will be
+** macro expanded immediately before
+** use.
+** Sn Use rewriting set n.
+** Rlhs rhs Rewrite addresses that match lhs to
+** be rhs.
+** Mn arg=val... Define mailer. n is the internal name.
+** Args specify mailer parameters.
+** Oxvalue Set option x to value.
+** Pname=value Set precedence name to value.
+** Vversioncode[/vendorcode]
+** Version level/vendor name of
+** configuration syntax.
+** Kmapname mapclass arguments....
+** Define keyed lookup of a given class.
+** Arguments are class dependent.
+**
+** Parameters:
+** cfname -- control file name.
+** safe -- TRUE if this is the system config file;
+** FALSE otherwise.
+** e -- the main envelope.
+**
+** Returns:
+** none.
+**
+** Side Effects:
+** Builds several internal tables.
+*/
+
+readcf(cfname, safe, e)
+ char *cfname;
+ bool safe;
+ register ENVELOPE *e;
+{
+ FILE *cf;
+ int ruleset = 0;
+ char *q;
+ struct rewrite *rwp = NULL;
+ char *bp;
+ auto char *ep;
+ int nfuzzy;
+ char *file;
+ bool optional;
+ char buf[MAXLINE];
+ register char *p;
+ extern char **copyplist();
+ struct stat statb;
+ char exbuf[MAXLINE];
+ char pvpbuf[MAXLINE + MAXATOM];
+ extern char *munchstring();
+ extern void makemapentry();
+
+ FileName = cfname;
+ LineNumber = 0;
+
+ cf = fopen(cfname, "r");
+ if (cf == NULL)
+ {
+ syserr("cannot open");
+ exit(EX_OSFILE);
+ }
+
+ if (fstat(fileno(cf), &statb) < 0)
+ {
+ syserr("cannot fstat");
+ exit(EX_OSFILE);
+ }
+
+ if (!S_ISREG(statb.st_mode))
+ {
+ syserr("not a plain file");
+ exit(EX_OSFILE);
+ }
+
+ if (OpMode != MD_TEST && bitset(S_IWGRP|S_IWOTH, statb.st_mode))
+ {
+ if (OpMode == MD_DAEMON || OpMode == MD_FREEZE)
+ fprintf(stderr, "%s: WARNING: dangerous write permissions\n",
+ FileName);
+#ifdef LOG
+ if (LogLevel > 0)
+ syslog(LOG_CRIT, "%s: WARNING: dangerous write permissions",
+ FileName);
+#endif
+ }
+
+#ifdef XLA
+ xla_zero();
+#endif
+
+ while ((bp = fgetfolded(buf, sizeof buf, cf)) != NULL)
+ {
+ if (bp[0] == '#')
+ {
+ if (bp != buf)
+ free(bp);
+ continue;
+ }
+
+ /* map $ into \201 for macro expansion */
+ for (p = bp; *p != '\0'; p++)
+ {
+ if (*p == '#' && p > bp && ConfigLevel >= 3)
+ {
+ /* this is an on-line comment */
+ register char *e;
+
+ switch (*--p & 0377)
+ {
+ case MACROEXPAND:
+ /* it's from $# -- let it go through */
+ p++;
+ break;
+
+ case '\\':
+ /* it's backslash escaped */
+ (void) strcpy(p, p + 1);
+ break;
+
+ default:
+ /* delete preceeding white space */
+ while (isascii(*p) && isspace(*p) && p > bp)
+ p--;
+ if ((e = strchr(++p, '\n')) != NULL)
+ (void) strcpy(p, e);
+ else
+ p[0] = p[1] = '\0';
+ break;
+ }
+ continue;
+ }
+
+ if (*p != '$')
+ continue;
+
+ if (p[1] == '$')
+ {
+ /* actual dollar sign.... */
+ (void) strcpy(p, p + 1);
+ continue;
+ }
+
+ /* convert to macro expansion character */
+ *p = MACROEXPAND;
+ }
+
+ /* interpret this line */
+ errno = 0;
+ switch (bp[0])
+ {
+ case '\0':
+ case '#': /* comment */
+ break;
+
+ case 'R': /* rewriting rule */
+ for (p = &bp[1]; *p != '\0' && *p != '\t'; p++)
+ continue;
+
+ if (*p == '\0')
+ {
+ syserr("invalid rewrite line \"%s\" (tab expected)", bp);
+ break;
+ }
+
+ /* allocate space for the rule header */
+ if (rwp == NULL)
+ {
+ RewriteRules[ruleset] = rwp =
+ (struct rewrite *) xalloc(sizeof *rwp);
+ }
+ else
+ {
+ rwp->r_next = (struct rewrite *) xalloc(sizeof *rwp);
+ rwp = rwp->r_next;
+ }
+ rwp->r_next = NULL;
+
+ /* expand and save the LHS */
+ *p = '\0';
+ expand(&bp[1], exbuf, &exbuf[sizeof exbuf], e);
+ rwp->r_lhs = prescan(exbuf, '\t', pvpbuf,
+ sizeof pvpbuf, NULL);
+ nfuzzy = 0;
+ if (rwp->r_lhs != NULL)
+ {
+ register char **ap;
+
+ rwp->r_lhs = copyplist(rwp->r_lhs, TRUE);
+
+ /* count the number of fuzzy matches in LHS */
+ for (ap = rwp->r_lhs; *ap != NULL; ap++)
+ {
+ char *botch;
+
+ botch = NULL;
+ switch (**ap & 0377)
+ {
+ case MATCHZANY:
+ case MATCHANY:
+ case MATCHONE:
+ case MATCHCLASS:
+ case MATCHNCLASS:
+ nfuzzy++;
+ break;
+
+ case MATCHREPL:
+ botch = "$0-$9";
+ break;
+
+ case CANONNET:
+ botch = "$#";
+ break;
+
+ case CANONUSER:
+ botch = "$:";
+ break;
+
+ case CALLSUBR:
+ botch = "$>";
+ break;
+
+ case CONDIF:
+ botch = "$?";
+ break;
+
+ case CONDELSE:
+ botch = "$|";
+ break;
+
+ case CONDFI:
+ botch = "$.";
+ break;
+
+ case HOSTBEGIN:
+ botch = "$[";
+ break;
+
+ case HOSTEND:
+ botch = "$]";
+ break;
+
+ case LOOKUPBEGIN:
+ botch = "$(";
+ break;
+
+ case LOOKUPEND:
+ botch = "$)";
+ break;
+ }
+ if (botch != NULL)
+ syserr("Inappropriate use of %s on LHS",
+ botch);
+ }
+ }
+ else
+ syserr("R line: null LHS");
+
+ /* expand and save the RHS */
+ while (*++p == '\t')
+ continue;
+ q = p;
+ while (*p != '\0' && *p != '\t')
+ p++;
+ *p = '\0';
+ expand(q, exbuf, &exbuf[sizeof exbuf], e);
+ rwp->r_rhs = prescan(exbuf, '\t', pvpbuf,
+ sizeof pvpbuf, NULL);
+ if (rwp->r_rhs != NULL)
+ {
+ register char **ap;
+
+ rwp->r_rhs = copyplist(rwp->r_rhs, TRUE);
+
+ /* check no out-of-bounds replacements */
+ nfuzzy += '0';
+ for (ap = rwp->r_rhs; *ap != NULL; ap++)
+ {
+ char *botch;
+
+ botch = NULL;
+ switch (**ap & 0377)
+ {
+ case MATCHREPL:
+ if ((*ap)[1] <= '0' || (*ap)[1] > nfuzzy)
+ {
+ syserr("replacement $%c out of bounds",
+ (*ap)[1]);
+ }
+ break;
+
+ case MATCHZANY:
+ botch = "$*";
+ break;
+
+ case MATCHANY:
+ botch = "$+";
+ break;
+
+ case MATCHONE:
+ botch = "$-";
+ break;
+
+ case MATCHCLASS:
+ botch = "$=";
+ break;
+
+ case MATCHNCLASS:
+ botch = "$~";
+ break;
+ }
+ if (botch != NULL)
+ syserr("Inappropriate use of %s on RHS",
+ botch);
+ }
+ }
+ else
+ syserr("R line: null RHS");
+ break;
+
+ case 'S': /* select rewriting set */
+ for (p = &bp[1]; isascii(*p) && isspace(*p); p++)
+ continue;
+ if (!isascii(*p) || !isdigit(*p))
+ {
+ syserr("invalid argument to S line: \"%.20s\"",
+ &bp[1]);
+ break;
+ }
+ ruleset = atoi(p);
+ if (ruleset >= MAXRWSETS || ruleset < 0)
+ {
+ syserr("bad ruleset %d (%d max)", ruleset, MAXRWSETS);
+ ruleset = 0;
+ }
+ rwp = NULL;
+ break;
+
+ case 'D': /* macro definition */
+ p = munchstring(&bp[2], NULL);
+ define(bp[1], newstr(p), e);
+ break;
+
+ case 'H': /* required header line */
+ (void) chompheader(&bp[1], TRUE, e);
+ break;
+
+ case 'C': /* word class */
+ /* scan the list of words and set class for all */
+ expand(&bp[2], exbuf, &exbuf[sizeof exbuf], e);
+ for (p = exbuf; *p != '\0'; )
+ {
+ register char *wd;
+ char delim;
+
+ while (*p != '\0' && isascii(*p) && isspace(*p))
+ p++;
+ wd = p;
+ while (*p != '\0' && !(isascii(*p) && isspace(*p)))
+ p++;
+ delim = *p;
+ *p = '\0';
+ if (wd[0] != '\0')
+ setclass(bp[1], wd);
+ *p = delim;
+ }
+ break;
+
+ case 'F': /* word class from file */
+ for (p = &bp[2]; isascii(*p) && isspace(*p); )
+ p++;
+ if (p[0] == '-' && p[1] == 'o')
+ {
+ optional = TRUE;
+ while (*p != '\0' && !(isascii(*p) && isspace(*p)))
+ p++;
+ while (isascii(*p) && isspace(*p))
+ *p++;
+ }
+ else
+ optional = FALSE;
+ file = p;
+ while (*p != '\0' && !(isascii(*p) && isspace(*p)))
+ p++;
+ if (*p == '\0')
+ p = "%s";
+ else
+ {
+ *p = '\0';
+ while (isascii(*++p) && isspace(*p))
+ continue;
+ }
+ fileclass(bp[1], file, p, safe, optional);
+ break;
+
+#ifdef XLA
+ case 'L': /* extended load average description */
+ xla_init(&bp[1]);
+ break;
+#endif
+
+ case 'M': /* define mailer */
+ makemailer(&bp[1]);
+ break;
+
+ case 'O': /* set option */
+ setoption(bp[1], &bp[2], safe, FALSE, e);
+ break;
+
+ case 'P': /* set precedence */
+ if (NumPriorities >= MAXPRIORITIES)
+ {
+ toomany('P', MAXPRIORITIES);
+ break;
+ }
+ for (p = &bp[1]; *p != '\0' && *p != '=' && *p != '\t'; p++)
+ continue;
+ if (*p == '\0')
+ goto badline;
+ *p = '\0';
+ Priorities[NumPriorities].pri_name = newstr(&bp[1]);
+ Priorities[NumPriorities].pri_val = atoi(++p);
+ NumPriorities++;
+ break;
+
+ case 'T': /* trusted user(s) */
+ /* this option is obsolete, but will be ignored */
+ break;
+
+ case 'V': /* configuration syntax version */
+ for (p = &bp[1]; isascii(*p) && isspace(*p); p++)
+ continue;
+ if (!isascii(*p) || !isdigit(*p))
+ {
+ syserr("invalid argument to V line: \"%.20s\"",
+ &bp[1]);
+ break;
+ }
+ ConfigLevel = strtol(p, &ep, 10);
+ if (ConfigLevel >= 5)
+ {
+ /* level 5 configs have short name in $w */
+ p = macvalue('w', e);
+ if (p != NULL && (p = strchr(p, '.')) != NULL)
+ *p = '\0';
+ }
+ if (*ep++ == '/')
+ {
+ /* extract vendor code */
+ for (p = ep; isascii(*p) && isalpha(*p); )
+ p++;
+ *p = '\0';
+
+ if (!setvendor(ep))
+ syserr("invalid V line vendor code: \"%s\"",
+ ep);
+ }
+ break;
+
+ case 'K':
+ makemapentry(&bp[1]);
+ break;
+
+ default:
+ badline:
+ syserr("unknown control line \"%s\"", bp);
+ }
+ if (bp != buf)
+ free(bp);
+ }
+ if (ferror(cf))
+ {
+ syserr("I/O read error", cfname);
+ exit(EX_OSFILE);
+ }
+ fclose(cf);
+ FileName = NULL;
+
+ if (stab("host", ST_MAP, ST_FIND) == NULL)
+ {
+ /* user didn't initialize: set up host map */
+ strcpy(buf, "host host");
+#if NAMED_BIND
+ if (ConfigLevel >= 2)
+ strcat(buf, " -a.");
+#endif
+ makemapentry(buf);
+ }
+}
+ /*
+** TOOMANY -- signal too many of some option
+**
+** Parameters:
+** id -- the id of the error line
+** maxcnt -- the maximum possible values
+**
+** Returns:
+** none.
+**
+** Side Effects:
+** gives a syserr.
+*/
+
+toomany(id, maxcnt)
+ char id;
+ int maxcnt;
+{
+ syserr("too many %c lines, %d max", id, maxcnt);
+}
+ /*
+** FILECLASS -- read members of a class from a file
+**
+** Parameters:
+** class -- class to define.
+** filename -- name of file to read.
+** fmt -- scanf string to use for match.
+** safe -- if set, this is a safe read.
+** optional -- if set, it is not an error for the file to
+** not exist.
+**
+** Returns:
+** none
+**
+** Side Effects:
+**
+** puts all lines in filename that match a scanf into
+** the named class.
+*/
+
+fileclass(class, filename, fmt, safe, optional)
+ int class;
+ char *filename;
+ char *fmt;
+ bool safe;
+ bool optional;
+{
+ FILE *f;
+ struct stat stbuf;
+ char buf[MAXLINE];
+
+ if (tTd(37, 2))
+ printf("fileclass(%s, fmt=%s)\n", filename, fmt);
+
+ if (filename[0] == '|')
+ {
+ syserr("fileclass: pipes (F%c%s) not supported due to security problems",
+ class, filename);
+ return;
+ }
+ if (stat(filename, &stbuf) < 0)
+ {
+ if (tTd(37, 2))
+ printf(" cannot stat (%s)\n", errstring(errno));
+ if (!optional)
+ syserr("fileclass: cannot stat %s", filename);
+ return;
+ }
+ if (!S_ISREG(stbuf.st_mode))
+ {
+ syserr("fileclass: %s not a regular file", filename);
+ return;
+ }
+ if (!safe && access(filename, R_OK) < 0)
+ {
+ syserr("fileclass: access denied on %s", filename);
+ return;
+ }
+ f = fopen(filename, "r");
+ if (f == NULL)
+ {
+ syserr("fileclass: cannot open %s", filename);
+ return;
+ }
+
+ while (fgets(buf, sizeof buf, f) != NULL)
+ {
+ register STAB *s;
+ register char *p;
+# ifdef SCANF
+ char wordbuf[MAXNAME+1];
+
+ if (sscanf(buf, fmt, wordbuf) != 1)
+ continue;
+ p = wordbuf;
+# else /* SCANF */
+ p = buf;
+# endif /* SCANF */
+
+ /*
+ ** Break up the match into words.
+ */
+
+ while (*p != '\0')
+ {
+ register char *q;
+
+ /* strip leading spaces */
+ while (isascii(*p) && isspace(*p))
+ p++;
+ if (*p == '\0')
+ break;
+
+ /* find the end of the word */
+ q = p;
+ while (*p != '\0' && !(isascii(*p) && isspace(*p)))
+ p++;
+ if (*p != '\0')
+ *p++ = '\0';
+
+ /* enter the word in the symbol table */
+ setclass(class, q);
+ }
+ }
+
+ (void) fclose(f);
+}
+ /*
+** MAKEMAILER -- define a new mailer.
+**
+** Parameters:
+** line -- description of mailer. This is in labeled
+** fields. The fields are:
+** P -- the path to the mailer
+** F -- the flags associated with the mailer
+** A -- the argv for this mailer
+** S -- the sender rewriting set
+** R -- the recipient rewriting set
+** E -- the eol string
+** The first word is the canonical name of the mailer.
+**
+** Returns:
+** none.
+**
+** Side Effects:
+** enters the mailer into the mailer table.
+*/
+
+makemailer(line)
+ char *line;
+{
+ register char *p;
+ register struct mailer *m;
+ register STAB *s;
+ int i;
+ char fcode;
+ auto char *endp;
+ extern int NextMailer;
+ extern char **makeargv();
+ extern char *munchstring();
+ extern long atol();
+
+ /* allocate a mailer and set up defaults */
+ m = (struct mailer *) xalloc(sizeof *m);
+ bzero((char *) m, sizeof *m);
+ m->m_eol = "\n";
+
+ /* collect the mailer name */
+ for (p = line; *p != '\0' && *p != ',' && !(isascii(*p) && isspace(*p)); p++)
+ continue;
+ if (*p != '\0')
+ *p++ = '\0';
+ m->m_name = newstr(line);
+
+ /* now scan through and assign info from the fields */
+ while (*p != '\0')
+ {
+ auto char *delimptr;
+
+ while (*p != '\0' && (*p == ',' || (isascii(*p) && isspace(*p))))
+ p++;
+
+ /* p now points to field code */
+ fcode = *p;
+ while (*p != '\0' && *p != '=' && *p != ',')
+ p++;
+ if (*p++ != '=')
+ {
+ syserr("mailer %s: `=' expected", m->m_name);
+ return;
+ }
+ while (isascii(*p) && isspace(*p))
+ p++;
+
+ /* p now points to the field body */
+ p = munchstring(p, &delimptr);
+
+ /* install the field into the mailer struct */
+ switch (fcode)
+ {
+ case 'P': /* pathname */
+ m->m_mailer = newstr(p);
+ break;
+
+ case 'F': /* flags */
+ for (; *p != '\0'; p++)
+ if (!(isascii(*p) && isspace(*p)))
+ setbitn(*p, m->m_flags);
+ break;
+
+ case 'S': /* sender rewriting ruleset */
+ case 'R': /* recipient rewriting ruleset */
+ i = strtol(p, &endp, 10);
+ if (i < 0 || i >= MAXRWSETS)
+ {
+ syserr("invalid rewrite set, %d max", MAXRWSETS);
+ return;
+ }
+ if (fcode == 'S')
+ m->m_sh_rwset = m->m_se_rwset = i;
+ else
+ m->m_rh_rwset = m->m_re_rwset = i;
+
+ p = endp;
+ if (*p++ == '/')
+ {
+ i = strtol(p, NULL, 10);
+ if (i < 0 || i >= MAXRWSETS)
+ {
+ syserr("invalid rewrite set, %d max",
+ MAXRWSETS);
+ return;
+ }
+ if (fcode == 'S')
+ m->m_sh_rwset = i;
+ else
+ m->m_rh_rwset = i;
+ }
+ break;
+
+ case 'E': /* end of line string */
+ m->m_eol = newstr(p);
+ break;
+
+ case 'A': /* argument vector */
+ m->m_argv = makeargv(p);
+ break;
+
+ case 'M': /* maximum message size */
+ m->m_maxsize = atol(p);
+ break;
+
+ case 'L': /* maximum line length */
+ m->m_linelimit = atoi(p);
+ break;
+
+ case 'D': /* working directory */
+ m->m_execdir = newstr(p);
+ break;
+ }
+
+ p = delimptr;
+ }
+
+ /* do some heuristic cleanup for back compatibility */
+ if (bitnset(M_LIMITS, m->m_flags))
+ {
+ if (m->m_linelimit == 0)
+ m->m_linelimit = SMTPLINELIM;
+ if (ConfigLevel < 2)
+ setbitn(M_7BITS, m->m_flags);
+ }
+
+ /* do some rationality checking */
+ if (m->m_argv == NULL)
+ {
+ syserr("M%s: A= argument required", m->m_name);
+ return;
+ }
+ if (m->m_mailer == NULL)
+ {
+ syserr("M%s: P= argument required", m->m_name);
+ return;
+ }
+
+ if (NextMailer >= MAXMAILERS)
+ {
+ syserr("too many mailers defined (%d max)", MAXMAILERS);
+ return;
+ }
+
+ s = stab(m->m_name, ST_MAILER, ST_ENTER);
+ if (s->s_mailer != NULL)
+ {
+ i = s->s_mailer->m_mno;
+ free(s->s_mailer);
+ }
+ else
+ {
+ i = NextMailer++;
+ }
+ Mailer[i] = s->s_mailer = m;
+ m->m_mno = i;
+}
+ /*
+** MUNCHSTRING -- translate a string into internal form.
+**
+** Parameters:
+** p -- the string to munch.
+** delimptr -- if non-NULL, set to the pointer of the
+** field delimiter character.
+**
+** Returns:
+** the munched string.
+*/
+
+char *
+munchstring(p, delimptr)
+ register char *p;
+ char **delimptr;
+{
+ register char *q;
+ bool backslash = FALSE;
+ bool quotemode = FALSE;
+ static char buf[MAXLINE];
+
+ for (q = buf; *p != '\0'; p++)
+ {
+ if (backslash)
+ {
+ /* everything is roughly literal */
+ backslash = FALSE;
+ switch (*p)
+ {
+ case 'r': /* carriage return */
+ *q++ = '\r';
+ continue;
+
+ case 'n': /* newline */
+ *q++ = '\n';
+ continue;
+
+ case 'f': /* form feed */
+ *q++ = '\f';
+ continue;
+
+ case 'b': /* backspace */
+ *q++ = '\b';
+ continue;
+ }
+ *q++ = *p;
+ }
+ else
+ {
+ if (*p == '\\')
+ backslash = TRUE;
+ else if (*p == '"')
+ quotemode = !quotemode;
+ else if (quotemode || *p != ',')
+ *q++ = *p;
+ else
+ break;
+ }
+ }
+
+ if (delimptr != NULL)
+ *delimptr = p;
+ *q++ = '\0';
+ return (buf);
+}
+ /*
+** MAKEARGV -- break up a string into words
+**
+** Parameters:
+** p -- the string to break up.
+**
+** Returns:
+** a char **argv (dynamically allocated)
+**
+** Side Effects:
+** munges p.
+*/
+
+char **
+makeargv(p)
+ register char *p;
+{
+ char *q;
+ int i;
+ char **avp;
+ char *argv[MAXPV + 1];
+
+ /* take apart the words */
+ i = 0;
+ while (*p != '\0' && i < MAXPV)
+ {
+ q = p;
+ while (*p != '\0' && !(isascii(*p) && isspace(*p)))
+ p++;
+ while (isascii(*p) && isspace(*p))
+ *p++ = '\0';
+ argv[i++] = newstr(q);
+ }
+ argv[i++] = NULL;
+
+ /* now make a copy of the argv */
+ avp = (char **) xalloc(sizeof *avp * i);
+ bcopy((char *) argv, (char *) avp, sizeof *avp * i);
+
+ return (avp);
+}
+ /*
+** PRINTRULES -- print rewrite rules (for debugging)
+**
+** Parameters:
+** none.
+**
+** Returns:
+** none.
+**
+** Side Effects:
+** prints rewrite rules.
+*/
+
+printrules()
+{
+ register struct rewrite *rwp;
+ register int ruleset;
+
+ for (ruleset = 0; ruleset < 10; ruleset++)
+ {
+ if (RewriteRules[ruleset] == NULL)
+ continue;
+ printf("\n----Rule Set %d:", ruleset);
+
+ for (rwp = RewriteRules[ruleset]; rwp != NULL; rwp = rwp->r_next)
+ {
+ printf("\nLHS:");
+ printav(rwp->r_lhs);
+ printf("RHS:");
+ printav(rwp->r_rhs);
+ }
+ }
+}
+
+ /*
+** SETOPTION -- set global processing option
+**
+** Parameters:
+** opt -- option name.
+** val -- option value (as a text string).
+** safe -- set if this came from a configuration file.
+** Some options (if set from the command line) will
+** reset the user id to avoid security problems.
+** sticky -- if set, don't let other setoptions override
+** this value.
+** e -- the main envelope.
+**
+** Returns:
+** none.
+**
+** Side Effects:
+** Sets options as implied by the arguments.
+*/
+
+static BITMAP StickyOpt; /* set if option is stuck */
+
+
+#if NAMED_BIND
+
+struct resolverflags
+{
+ char *rf_name; /* name of the flag */
+ long rf_bits; /* bits to set/clear */
+} ResolverFlags[] =
+{
+ "debug", RES_DEBUG,
+ "aaonly", RES_AAONLY,
+ "usevc", RES_USEVC,
+ "primary", RES_PRIMARY,
+ "igntc", RES_IGNTC,
+ "recurse", RES_RECURSE,
+ "defnames", RES_DEFNAMES,
+ "stayopen", RES_STAYOPEN,
+ "dnsrch", RES_DNSRCH,
+ "true", 0, /* to avoid error on old syntax */
+ NULL, 0
+};
+
+#endif
+
+setoption(opt, val, safe, sticky, e)
+ char opt;
+ char *val;
+ bool safe;
+ bool sticky;
+ register ENVELOPE *e;
+{
+ register char *p;
+ extern bool atobool();
+ extern time_t convtime();
+ extern int QueueLA;
+ extern int RefuseLA;
+ extern bool Warn_Q_option;
+ extern bool trusteduser();
+
+ if (tTd(37, 1))
+ printf("setoption %c=%s", opt, val);
+
+ /*
+ ** See if this option is preset for us.
+ */
+
+ if (!sticky && bitnset(opt, StickyOpt))
+ {
+ if (tTd(37, 1))
+ printf(" (ignored)\n");
+ return;
+ }
+
+ /*
+ ** Check to see if this option can be specified by this user.
+ */
+
+ if (!safe && RealUid == 0)
+ safe = TRUE;
+ if (!safe && strchr("bCdeijLmoprsvw7", opt) == NULL)
+ {
+ if (opt != 'M' || (val[0] != 'r' && val[0] != 's'))
+ {
+ if (tTd(37, 1))
+ printf(" (unsafe)");
+ if (RealUid != geteuid())
+ {
+ if (tTd(37, 1))
+ printf("(Resetting uid)");
+ (void) setgid(RealGid);
+ (void) setuid(RealUid);
+ }
+ }
+ }
+ if (tTd(37, 1))
+ printf("\n");
+
+ switch (opt)
+ {
+ case '7': /* force seven-bit input */
+ SevenBit = atobool(val);
+ break;
+
+ case 'A': /* set default alias file */
+ if (val[0] == '\0')
+ setalias("aliases");
+ else
+ setalias(val);
+ break;
+
+ case 'a': /* look N minutes for "@:@" in alias file */
+ if (val[0] == '\0')
+ SafeAlias = 5 * 60; /* five minutes */
+ else
+ SafeAlias = convtime(val, 'm');
+ break;
+
+ case 'B': /* substitution for blank character */
+ SpaceSub = val[0];
+ if (SpaceSub == '\0')
+ SpaceSub = ' ';
+ break;
+
+ case 'b': /* min blocks free on queue fs/max msg size */
+ p = strchr(val, '/');
+ if (p != NULL)
+ {
+ *p++ = '\0';
+ MaxMessageSize = atol(p);
+ }
+ MinBlocksFree = atol(val);
+ break;
+
+ case 'c': /* don't connect to "expensive" mailers */
+ NoConnect = atobool(val);
+ break;
+
+ case 'C': /* checkpoint every N addresses */
+ CheckpointInterval = atoi(val);
+ break;
+
+ case 'd': /* delivery mode */
+ switch (*val)
+ {
+ case '\0':
+ e->e_sendmode = SM_DELIVER;
+ break;
+
+ case SM_QUEUE: /* queue only */
+#ifndef QUEUE
+ syserr("need QUEUE to set -odqueue");
+#endif /* QUEUE */
+ /* fall through..... */
+
+ case SM_DELIVER: /* do everything */
+ case SM_FORK: /* fork after verification */
+ e->e_sendmode = *val;
+ break;
+
+ default:
+ syserr("Unknown delivery mode %c", *val);
+ exit(EX_USAGE);
+ }
+ break;
+
+ case 'D': /* rebuild alias database as needed */
+ AutoRebuild = atobool(val);
+ break;
+
+ case 'E': /* error message header/header file */
+ if (*val != '\0')
+ ErrMsgFile = newstr(val);
+ break;
+
+ case 'e': /* set error processing mode */
+ switch (*val)
+ {
+ case EM_QUIET: /* be silent about it */
+ case EM_MAIL: /* mail back */
+ case EM_BERKNET: /* do berknet error processing */
+ case EM_WRITE: /* write back (or mail) */
+ HoldErrs = TRUE;
+ /* fall through... */
+
+ case EM_PRINT: /* print errors normally (default) */
+ e->e_errormode = *val;
+ break;
+ }
+ break;
+
+ case 'F': /* file mode */
+ FileMode = atooct(val) & 0777;
+ break;
+
+ case 'f': /* save Unix-style From lines on front */
+ SaveFrom = atobool(val);
+ break;
+
+ case 'G': /* match recipients against GECOS field */
+ MatchGecos = atobool(val);
+ break;
+
+ case 'g': /* default gid */
+ if (isascii(*val) && isdigit(*val))
+ DefGid = atoi(val);
+ else
+ {
+ register struct group *gr;
+
+ DefGid = -1;
+ gr = getgrnam(val);
+ if (gr == NULL)
+ syserr("readcf: option g: unknown group %s", val);
+ else
+ DefGid = gr->gr_gid;
+ }
+ break;
+
+ case 'H': /* help file */
+ if (val[0] == '\0')
+ HelpFile = "sendmail.hf";
+ else
+ HelpFile = newstr(val);
+ break;
+
+ case 'h': /* maximum hop count */
+ MaxHopCount = atoi(val);
+ break;
+
+ case 'I': /* use internet domain name server */
+#if NAMED_BIND
+ UseNameServer = TRUE;
+ for (p = val; *p != 0; )
+ {
+ bool clearmode;
+ char *q;
+ struct resolverflags *rfp;
+
+ while (*p == ' ')
+ p++;
+ if (*p == '\0')
+ break;
+ clearmode = FALSE;
+ if (*p == '-')
+ clearmode = TRUE;
+ else if (*p != '+')
+ p--;
+ p++;
+ q = p;
+ while (*p != '\0' && !(isascii(*p) && isspace(*p)))
+ p++;
+ if (*p != '\0')
+ *p++ = '\0';
+ for (rfp = ResolverFlags; rfp->rf_name != NULL; rfp++)
+ {
+ if (strcasecmp(q, rfp->rf_name) == 0)
+ break;
+ }
+ if (rfp->rf_name == NULL)
+ syserr("readcf: I option value %s unrecognized", q);
+ else if (clearmode)
+ _res.options &= ~rfp->rf_bits;
+ else
+ _res.options |= rfp->rf_bits;
+ }
+ if (tTd(8, 2))
+ printf("_res.options = %x\n", _res.options);
+#else
+ usrerr("name server (I option) specified but BIND not compiled in");
+#endif
+ break;
+
+ case 'i': /* ignore dot lines in message */
+ IgnrDot = atobool(val);
+ break;
+
+ case 'j': /* send errors in MIME (RFC 1341) format */
+ SendMIMEErrors = atobool(val);
+ break;
+
+ case 'J': /* .forward search path */
+ ForwardPath = newstr(val);
+ break;
+
+ case 'k': /* connection cache size */
+ MaxMciCache = atoi(val);
+ if (MaxMciCache < 0)
+ MaxMciCache = 0;
+ break;
+
+ case 'K': /* connection cache timeout */
+ MciCacheTimeout = convtime(val, 'm');
+ break;
+
+ case 'l': /* use Errors-To: header */
+ UseErrorsTo = atobool(val);
+ break;
+
+ case 'L': /* log level */
+ if (safe || LogLevel < atoi(val))
+ LogLevel = atoi(val);
+ break;
+
+ case 'M': /* define macro */
+ define(val[0], newstr(&val[1]), CurEnv);
+ sticky = FALSE;
+ break;
+
+ case 'm': /* send to me too */
+ MeToo = atobool(val);
+ break;
+
+ case 'n': /* validate RHS in newaliases */
+ CheckAliases = atobool(val);
+ break;
+
+ /* 'N' available -- was "net name" */
+
+ case 'O': /* daemon options */
+ setdaemonoptions(val);
+ break;
+
+ case 'o': /* assume old style headers */
+ if (atobool(val))
+ CurEnv->e_flags |= EF_OLDSTYLE;
+ else
+ CurEnv->e_flags &= ~EF_OLDSTYLE;
+ break;
+
+ case 'p': /* select privacy level */
+ p = val;
+ for (;;)
+ {
+ register struct prival *pv;
+ extern struct prival PrivacyValues[];
+
+ while (isascii(*p) && (isspace(*p) || ispunct(*p)))
+ p++;
+ if (*p == '\0')
+ break;
+ val = p;
+ while (isascii(*p) && isalnum(*p))
+ p++;
+ if (*p != '\0')
+ *p++ = '\0';
+
+ for (pv = PrivacyValues; pv->pv_name != NULL; pv++)
+ {
+ if (strcasecmp(val, pv->pv_name) == 0)
+ break;
+ }
+ if (pv->pv_name == NULL)
+ syserr("readcf: Op line: %s unrecognized", val);
+ PrivacyFlags |= pv->pv_flag;
+ }
+ break;
+
+ case 'P': /* postmaster copy address for returned mail */
+ PostMasterCopy = newstr(val);
+ break;
+
+ case 'q': /* slope of queue only function */
+ QueueFactor = atoi(val);
+ break;
+
+ case 'Q': /* queue directory */
+ if (val[0] == '\0')
+ QueueDir = "mqueue";
+ else
+ QueueDir = newstr(val);
+ if (RealUid != 0 && !safe)
+ Warn_Q_option = TRUE;
+ break;
+
+ case 'R': /* don't prune routes */
+ DontPruneRoutes = atobool(val);
+ break;
+
+ case 'r': /* read timeout */
+ settimeouts(val);
+ break;
+
+ case 'S': /* status file */
+ if (val[0] == '\0')
+ StatFile = "sendmail.st";
+ else
+ StatFile = newstr(val);
+ break;
+
+ case 's': /* be super safe, even if expensive */
+ SuperSafe = atobool(val);
+ break;
+
+ case 'T': /* queue timeout */
+ p = strchr(val, '/');
+ if (p != NULL)
+ {
+ *p++ = '\0';
+ TimeOuts.to_q_warning = convtime(p, 'd');
+ }
+ TimeOuts.to_q_return = convtime(val, 'h');
+ break;
+
+ case 't': /* time zone name */
+ TimeZoneSpec = newstr(val);
+ break;
+
+ case 'U': /* location of user database */
+ UdbSpec = newstr(val);
+ break;
+
+ case 'u': /* set default uid */
+ if (isascii(*val) && isdigit(*val))
+ DefUid = atoi(val);
+ else
+ {
+ register struct passwd *pw;
+
+ DefUid = -1;
+ pw = getpwnam(val);
+ if (pw == NULL)
+ syserr("readcf: option u: unknown user %s", val);
+ else
+ DefUid = pw->pw_uid;
+ }
+ setdefuser();
+ break;
+
+ case 'V': /* fallback MX host */
+ FallBackMX = newstr(val);
+ break;
+
+ case 'v': /* run in verbose mode */
+ Verbose = atobool(val);
+ break;
+
+ case 'w': /* if we are best MX, try host directly */
+ TryNullMXList = atobool(val);
+ break;
+
+ /* 'W' available -- was wizard password */
+
+ case 'x': /* load avg at which to auto-queue msgs */
+ QueueLA = atoi(val);
+ break;
+
+ case 'X': /* load avg at which to auto-reject connections */
+ RefuseLA = atoi(val);
+ break;
+
+ case 'y': /* work recipient factor */
+ WkRecipFact = atoi(val);
+ break;
+
+ case 'Y': /* fork jobs during queue runs */
+ ForkQueueRuns = atobool(val);
+ break;
+
+ case 'z': /* work message class factor */
+ WkClassFact = atoi(val);
+ break;
+
+ case 'Z': /* work time factor */
+ WkTimeFact = atoi(val);
+ break;
+
+ default:
+ break;
+ }
+ if (sticky)
+ setbitn(opt, StickyOpt);
+ return;
+}
+ /*
+** SETCLASS -- set a word into a class
+**
+** Parameters:
+** class -- the class to put the word in.
+** word -- the word to enter
+**
+** Returns:
+** none.
+**
+** Side Effects:
+** puts the word into the symbol table.
+*/
+
+setclass(class, word)
+ int class;
+ char *word;
+{
+ register STAB *s;
+
+ if (tTd(37, 8))
+ printf("setclass(%c, %s)\n", class, word);
+ s = stab(word, ST_CLASS, ST_ENTER);
+ setbitn(class, s->s_class);
+}
+ /*
+** MAKEMAPENTRY -- create a map entry
+**
+** Parameters:
+** line -- the config file line
+**
+** Returns:
+** TRUE if it successfully entered the map entry.
+** FALSE otherwise (usually syntax error).
+**
+** Side Effects:
+** Enters the map into the dictionary.
+*/
+
+void
+makemapentry(line)
+ char *line;
+{
+ register char *p;
+ char *mapname;
+ char *classname;
+ register STAB *s;
+ STAB *class;
+
+ for (p = line; isascii(*p) && isspace(*p); p++)
+ continue;
+ if (!(isascii(*p) && isalnum(*p)))
+ {
+ syserr("readcf: config K line: no map name");
+ return;
+ }
+
+ mapname = p;
+ while (isascii(*++p) && isalnum(*p))
+ continue;
+ if (*p != '\0')
+ *p++ = '\0';
+ while (isascii(*p) && isspace(*p))
+ p++;
+ if (!(isascii(*p) && isalnum(*p)))
+ {
+ syserr("readcf: config K line, map %s: no map class", mapname);
+ return;
+ }
+ classname = p;
+ while (isascii(*++p) && isalnum(*p))
+ continue;
+ if (*p != '\0')
+ *p++ = '\0';
+ while (isascii(*p) && isspace(*p))
+ p++;
+
+ /* look up the class */
+ class = stab(classname, ST_MAPCLASS, ST_FIND);
+ if (class == NULL)
+ {
+ syserr("readcf: map %s: class %s not available", mapname, classname);
+ return;
+ }
+
+ /* enter the map */
+ s = stab(mapname, ST_MAP, ST_ENTER);
+ s->s_map.map_class = &class->s_mapclass;
+ s->s_map.map_mname = newstr(mapname);
+
+ if (class->s_mapclass.map_parse(&s->s_map, p))
+ s->s_map.map_mflags |= MF_VALID;
+
+ if (tTd(37, 5))
+ {
+ printf("map %s, class %s, flags %x, file %s,\n",
+ s->s_map.map_mname, s->s_map.map_class->map_cname,
+ s->s_map.map_mflags,
+ s->s_map.map_file == NULL ? "(null)" : s->s_map.map_file);
+ printf("\tapp %s, domain %s, rebuild %s\n",
+ s->s_map.map_app == NULL ? "(null)" : s->s_map.map_app,
+ s->s_map.map_domain == NULL ? "(null)" : s->s_map.map_domain,
+ s->s_map.map_rebuild == NULL ? "(null)" : s->s_map.map_rebuild);
+ }
+}
+ /*
+** SETTIMEOUTS -- parse and set timeout values
+**
+** Parameters:
+** val -- a pointer to the values. If NULL, do initial
+** settings.
+**
+** Returns:
+** none.
+**
+** Side Effects:
+** Initializes the TimeOuts structure
+*/
+
+#define SECONDS
+#define MINUTES * 60
+#define HOUR * 3600
+
+settimeouts(val)
+ register char *val;
+{
+ register char *p;
+ extern time_t convtime();
+
+ if (val == NULL)
+ {
+ TimeOuts.to_initial = (time_t) 5 MINUTES;
+ TimeOuts.to_helo = (time_t) 5 MINUTES;
+ TimeOuts.to_mail = (time_t) 10 MINUTES;
+ TimeOuts.to_rcpt = (time_t) 1 HOUR;
+ TimeOuts.to_datainit = (time_t) 5 MINUTES;
+ TimeOuts.to_datablock = (time_t) 1 HOUR;
+ TimeOuts.to_datafinal = (time_t) 1 HOUR;
+ TimeOuts.to_rset = (time_t) 5 MINUTES;
+ TimeOuts.to_quit = (time_t) 2 MINUTES;
+ TimeOuts.to_nextcommand = (time_t) 1 HOUR;
+ TimeOuts.to_miscshort = (time_t) 2 MINUTES;
+ TimeOuts.to_ident = (time_t) 30 SECONDS;
+ return;
+ }
+
+ for (;; val = p)
+ {
+ while (isascii(*val) && isspace(*val))
+ val++;
+ if (*val == '\0')
+ break;
+ for (p = val; *p != '\0' && *p != ','; p++)
+ continue;
+ if (*p != '\0')
+ *p++ = '\0';
+
+ if (isascii(*val) && isdigit(*val))
+ {
+ /* old syntax -- set everything */
+ TimeOuts.to_mail = convtime(val, 'm');
+ TimeOuts.to_rcpt = TimeOuts.to_mail;
+ TimeOuts.to_datainit = TimeOuts.to_mail;
+ TimeOuts.to_datablock = TimeOuts.to_mail;
+ TimeOuts.to_datafinal = TimeOuts.to_mail;
+ TimeOuts.to_nextcommand = TimeOuts.to_mail;
+ continue;
+ }
+ else
+ {
+ register char *q = strchr(val, '=');
+ time_t to;
+
+ if (q == NULL)
+ {
+ /* syntax error */
+ continue;
+ }
+ *q++ = '\0';
+ to = convtime(q, 'm');
+
+ if (strcasecmp(val, "initial") == 0)
+ TimeOuts.to_initial = to;
+ else if (strcasecmp(val, "mail") == 0)
+ TimeOuts.to_mail = to;
+ else if (strcasecmp(val, "rcpt") == 0)
+ TimeOuts.to_rcpt = to;
+ else if (strcasecmp(val, "datainit") == 0)
+ TimeOuts.to_datainit = to;
+ else if (strcasecmp(val, "datablock") == 0)
+ TimeOuts.to_datablock = to;
+ else if (strcasecmp(val, "datafinal") == 0)
+ TimeOuts.to_datafinal = to;
+ else if (strcasecmp(val, "command") == 0)
+ TimeOuts.to_nextcommand = to;
+ else if (strcasecmp(val, "rset") == 0)
+ TimeOuts.to_rset = to;
+ else if (strcasecmp(val, "helo") == 0)
+ TimeOuts.to_helo = to;
+ else if (strcasecmp(val, "quit") == 0)
+ TimeOuts.to_quit = to;
+ else if (strcasecmp(val, "misc") == 0)
+ TimeOuts.to_miscshort = to;
+ else if (strcasecmp(val, "ident") == 0)
+ TimeOuts.to_ident = to;
+ else
+ syserr("settimeouts: invalid timeout %s", val);
+ }
+ }
+}
diff --git a/usr.sbin/sendmail/src/recipient.c b/usr.sbin/sendmail/src/recipient.c
new file mode 100644
index 0000000..c6c15c4
--- /dev/null
+++ b/usr.sbin/sendmail/src/recipient.c
@@ -0,0 +1,1059 @@
+/*
+ * Copyright (c) 1983 Eric P. Allman
+ * Copyright (c) 1988, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)recipient.c 8.44 (Berkeley) 2/28/94";
+#endif /* not lint */
+
+# include "sendmail.h"
+# include <pwd.h>
+
+/*
+** SENDTOLIST -- Designate a send list.
+**
+** The parameter is a comma-separated list of people to send to.
+** This routine arranges to send to all of them.
+**
+** Parameters:
+** list -- the send list.
+** ctladdr -- the address template for the person to
+** send to -- effective uid/gid are important.
+** This is typically the alias that caused this
+** expansion.
+** sendq -- a pointer to the head of a queue to put
+** these people into.
+** e -- the envelope in which to add these recipients.
+**
+** Returns:
+** The number of addresses actually on the list.
+**
+** Side Effects:
+** none.
+*/
+
+# define MAXRCRSN 10
+
+sendtolist(list, ctladdr, sendq, e)
+ char *list;
+ ADDRESS *ctladdr;
+ ADDRESS **sendq;
+ register ENVELOPE *e;
+{
+ register char *p;
+ register ADDRESS *al; /* list of addresses to send to */
+ bool firstone; /* set on first address sent */
+ char delimiter; /* the address delimiter */
+ int naddrs;
+ char *oldto = e->e_to;
+
+ if (list == NULL)
+ {
+ syserr("sendtolist: null list");
+ return 0;
+ }
+
+ if (tTd(25, 1))
+ {
+ printf("sendto: %s\n ctladdr=", list);
+ printaddr(ctladdr, FALSE);
+ }
+
+ /* heuristic to determine old versus new style addresses */
+ if (ctladdr == NULL &&
+ (strchr(list, ',') != NULL || strchr(list, ';') != NULL ||
+ strchr(list, '<') != NULL || strchr(list, '(') != NULL))
+ e->e_flags &= ~EF_OLDSTYLE;
+ delimiter = ' ';
+ if (!bitset(EF_OLDSTYLE, e->e_flags) || ctladdr != NULL)
+ delimiter = ',';
+
+ firstone = TRUE;
+ al = NULL;
+ naddrs = 0;
+
+ for (p = list; *p != '\0'; )
+ {
+ auto char *delimptr;
+ register ADDRESS *a;
+
+ /* parse the address */
+ while ((isascii(*p) && isspace(*p)) || *p == ',')
+ p++;
+ a = parseaddr(p, NULLADDR, RF_COPYALL, delimiter, &delimptr, e);
+ p = delimptr;
+ if (a == NULL)
+ continue;
+ a->q_next = al;
+ a->q_alias = ctladdr;
+
+ /* see if this should be marked as a primary address */
+ if (ctladdr == NULL ||
+ (firstone && *p == '\0' && bitset(QPRIMARY, ctladdr->q_flags)))
+ a->q_flags |= QPRIMARY;
+
+ if (ctladdr != NULL && sameaddr(ctladdr, a))
+ ctladdr->q_flags |= QSELFREF;
+ al = a;
+ firstone = FALSE;
+ }
+
+ /* arrange to send to everyone on the local send list */
+ while (al != NULL)
+ {
+ register ADDRESS *a = al;
+
+ al = a->q_next;
+ a = recipient(a, sendq, e);
+
+ /* arrange to inherit full name */
+ if (a->q_fullname == NULL && ctladdr != NULL)
+ a->q_fullname = ctladdr->q_fullname;
+ naddrs++;
+ }
+
+ e->e_to = oldto;
+ return (naddrs);
+}
+ /*
+** RECIPIENT -- Designate a message recipient
+**
+** Saves the named person for future mailing.
+**
+** Parameters:
+** a -- the (preparsed) address header for the recipient.
+** sendq -- a pointer to the head of a queue to put the
+** recipient in. Duplicate supression is done
+** in this queue.
+** e -- the current envelope.
+**
+** Returns:
+** The actual address in the queue. This will be "a" if
+** the address is not a duplicate, else the original address.
+**
+** Side Effects:
+** none.
+*/
+
+ADDRESS *
+recipient(a, sendq, e)
+ register ADDRESS *a;
+ register ADDRESS **sendq;
+ register ENVELOPE *e;
+{
+ register ADDRESS *q;
+ ADDRESS **pq;
+ register struct mailer *m;
+ register char *p;
+ bool quoted = FALSE; /* set if the addr has a quote bit */
+ int findusercount = 0;
+ char buf[MAXNAME]; /* unquoted image of the user name */
+ extern int safefile();
+
+ e->e_to = a->q_paddr;
+ m = a->q_mailer;
+ errno = 0;
+ if (tTd(26, 1))
+ {
+ printf("\nrecipient: ");
+ printaddr(a, FALSE);
+ }
+
+ /* if this is primary, add it to the original recipient list */
+ if (a->q_alias == NULL)
+ {
+ if (e->e_origrcpt == NULL)
+ e->e_origrcpt = a->q_paddr;
+ else if (e->e_origrcpt != a->q_paddr)
+ e->e_origrcpt = "";
+ }
+
+ /* break aliasing loops */
+ if (AliasLevel > MAXRCRSN)
+ {
+ usrerr("554 aliasing/forwarding loop broken");
+ return (a);
+ }
+
+ /*
+ ** Finish setting up address structure.
+ */
+
+ /* set the queue timeout */
+ a->q_timeout = TimeOuts.to_q_return;
+
+ /* get unquoted user for file, program or user.name check */
+ (void) strcpy(buf, a->q_user);
+ for (p = buf; *p != '\0' && !quoted; p++)
+ {
+ if (*p == '\\')
+ quoted = TRUE;
+ }
+ stripquotes(buf);
+
+ /* check for direct mailing to restricted mailers */
+ if (m == ProgMailer)
+ {
+ if (a->q_alias == NULL)
+ {
+ a->q_flags |= QBADADDR;
+ usrerr("550 Cannot mail directly to programs");
+ }
+ else if (bitset(QBOGUSSHELL, a->q_alias->q_flags))
+ {
+ a->q_flags |= QBADADDR;
+ usrerr("550 User %s@%s doesn't have a valid shell for mailing to programs",
+ a->q_alias->q_ruser, MyHostName);
+ }
+ else if (bitset(QUNSAFEADDR, a->q_alias->q_flags))
+ {
+ a->q_flags |= QBADADDR;
+ usrerr("550 Address %s is unsafe for mailing to programs",
+ a->q_alias->q_paddr);
+ }
+ }
+
+ /*
+ ** Look up this person in the recipient list.
+ ** If they are there already, return, otherwise continue.
+ ** If the list is empty, just add it. Notice the cute
+ ** hack to make from addresses suppress things correctly:
+ ** the QDONTSEND bit will be set in the send list.
+ ** [Please note: the emphasis is on "hack."]
+ */
+
+ for (pq = sendq; (q = *pq) != NULL; pq = &q->q_next)
+ {
+ if (sameaddr(q, a))
+ {
+ if (tTd(26, 1))
+ {
+ printf("%s in sendq: ", a->q_paddr);
+ printaddr(q, FALSE);
+ }
+ if (!bitset(QPRIMARY, q->q_flags))
+ {
+ if (!bitset(QDONTSEND, a->q_flags))
+ message("duplicate suppressed");
+ q->q_flags |= a->q_flags;
+ }
+ else if (bitset(QSELFREF, q->q_flags))
+ q->q_flags |= a->q_flags & ~QDONTSEND;
+ a = q;
+ goto testselfdestruct;
+ }
+ }
+
+ /* add address on list */
+ *pq = a;
+ a->q_next = NULL;
+
+ /*
+ ** Alias the name and handle special mailer types.
+ */
+
+ trylocaluser:
+ if (tTd(29, 7))
+ printf("at trylocaluser %s\n", a->q_user);
+
+ if (bitset(QDONTSEND|QBADADDR|QVERIFIED, a->q_flags))
+ goto testselfdestruct;
+
+ if (m == InclMailer)
+ {
+ a->q_flags |= QDONTSEND;
+ if (a->q_alias == NULL)
+ {
+ a->q_flags |= QBADADDR;
+ usrerr("550 Cannot mail directly to :include:s");
+ }
+ else
+ {
+ int ret;
+
+ message("including file %s", a->q_user);
+ ret = include(a->q_user, FALSE, a, sendq, e);
+ if (transienterror(ret))
+ {
+#ifdef LOG
+ if (LogLevel > 2)
+ syslog(LOG_ERR, "%s: include %s: transient error: %s",
+ e->e_id == NULL ? "NOQUEUE" : e->e_id,
+ a->q_user, errstring(ret));
+#endif
+ a->q_flags |= QQUEUEUP;
+ a->q_flags &= ~QDONTSEND;
+ usrerr("451 Cannot open %s: %s",
+ a->q_user, errstring(ret));
+ }
+ else if (ret != 0)
+ {
+ a->q_flags |= QBADADDR;
+ usrerr("550 Cannot open %s: %s",
+ a->q_user, errstring(ret));
+ }
+ }
+ }
+ else if (m == FileMailer)
+ {
+ extern bool writable();
+
+ /* check if writable or creatable */
+ if (a->q_alias == NULL)
+ {
+ a->q_flags |= QBADADDR;
+ usrerr("550 Cannot mail directly to files");
+ }
+ else if (bitset(QBOGUSSHELL, a->q_alias->q_flags))
+ {
+ a->q_flags |= QBADADDR;
+ usrerr("550 User %s@%s doesn't have a valid shell for mailing to files",
+ a->q_alias->q_ruser, MyHostName);
+ }
+ else if (bitset(QUNSAFEADDR, a->q_alias->q_flags))
+ {
+ a->q_flags |= QBADADDR;
+ usrerr("550 Address %s is unsafe for mailing to files",
+ a->q_alias->q_paddr);
+ }
+ else if (!writable(buf, getctladdr(a), SFF_ANYFILE))
+ {
+ a->q_flags |= QBADADDR;
+ giveresponse(EX_CANTCREAT, m, NULL, a->q_alias, e);
+ }
+ }
+
+ if (m != LocalMailer)
+ {
+ if (!bitset(QDONTSEND, a->q_flags))
+ e->e_nrcpts++;
+ goto testselfdestruct;
+ }
+
+ /* try aliasing */
+ alias(a, sendq, e);
+
+# ifdef USERDB
+ /* if not aliased, look it up in the user database */
+ if (!bitset(QDONTSEND|QNOTREMOTE|QVERIFIED, a->q_flags))
+ {
+ extern int udbexpand();
+
+ if (udbexpand(a, sendq, e) == EX_TEMPFAIL)
+ {
+ a->q_flags |= QQUEUEUP;
+ if (e->e_message == NULL)
+ e->e_message = newstr("Deferred: user database error");
+# ifdef LOG
+ if (LogLevel > 8)
+ syslog(LOG_INFO, "%s: deferred: udbexpand: %s",
+ e->e_id == NULL ? "NOQUEUE" : e->e_id,
+ errstring(errno));
+# endif
+ message("queued (user database error): %s",
+ errstring(errno));
+ e->e_nrcpts++;
+ goto testselfdestruct;
+ }
+ }
+# endif
+
+ /* if it was an alias or a UDB expansion, just return now */
+ if (bitset(QDONTSEND|QQUEUEUP|QVERIFIED, a->q_flags))
+ goto testselfdestruct;
+
+ /*
+ ** If we have a level two config file, then pass the name through
+ ** Ruleset 5 before sending it off. Ruleset 5 has the right
+ ** to send rewrite it to another mailer. This gives us a hook
+ ** after local aliasing has been done.
+ */
+
+ if (tTd(29, 5))
+ {
+ printf("recipient: testing local? cl=%d, rr5=%x\n\t",
+ ConfigLevel, RewriteRules[5]);
+ printaddr(a, FALSE);
+ }
+ if (!bitset(QNOTREMOTE, a->q_flags) && ConfigLevel >= 2 &&
+ RewriteRules[5] != NULL)
+ {
+ maplocaluser(a, sendq, e);
+ }
+
+ /*
+ ** If it didn't get rewritten to another mailer, go ahead
+ ** and deliver it.
+ */
+
+ if (!bitset(QDONTSEND|QQUEUEUP, a->q_flags))
+ {
+ auto bool fuzzy;
+ register struct passwd *pw;
+ extern struct passwd *finduser();
+
+ /* warning -- finduser may trash buf */
+ pw = finduser(buf, &fuzzy);
+ if (pw == NULL)
+ {
+ a->q_flags |= QBADADDR;
+ giveresponse(EX_NOUSER, m, NULL, a->q_alias, e);
+ }
+ else
+ {
+ char nbuf[MAXNAME];
+
+ if (fuzzy)
+ {
+ /* name was a fuzzy match */
+ a->q_user = newstr(pw->pw_name);
+ if (findusercount++ > 3)
+ {
+ a->q_flags |= QBADADDR;
+ usrerr("554 aliasing/forwarding loop for %s broken",
+ pw->pw_name);
+ return (a);
+ }
+
+ /* see if it aliases */
+ (void) strcpy(buf, pw->pw_name);
+ goto trylocaluser;
+ }
+ if (strcmp(pw->pw_dir, "/") == 0)
+ a->q_home = "";
+ else
+ a->q_home = newstr(pw->pw_dir);
+ a->q_uid = pw->pw_uid;
+ a->q_gid = pw->pw_gid;
+ a->q_ruser = newstr(pw->pw_name);
+ a->q_flags |= QGOODUID;
+ buildfname(pw->pw_gecos, pw->pw_name, nbuf);
+ if (nbuf[0] != '\0')
+ a->q_fullname = newstr(nbuf);
+ if (pw->pw_shell != NULL && pw->pw_shell[0] != '\0' &&
+ !usershellok(pw->pw_shell))
+ {
+ a->q_flags |= QBOGUSSHELL;
+ }
+ if (!quoted)
+ forward(a, sendq, e);
+ }
+ }
+ if (!bitset(QDONTSEND, a->q_flags))
+ e->e_nrcpts++;
+
+ testselfdestruct:
+ if (tTd(26, 8))
+ {
+ printf("testselfdestruct: ");
+ printaddr(a, TRUE);
+ }
+ if (a->q_alias == NULL && a != &e->e_from &&
+ bitset(QDONTSEND, a->q_flags))
+ {
+ q = *sendq;
+ while (q != NULL && bitset(QDONTSEND, q->q_flags))
+ q = q->q_next;
+ if (q == NULL)
+ {
+ a->q_flags |= QBADADDR;
+ usrerr("554 aliasing/forwarding loop broken");
+ }
+ }
+ return (a);
+}
+ /*
+** FINDUSER -- find the password entry for a user.
+**
+** This looks a lot like getpwnam, except that it may want to
+** do some fancier pattern matching in /etc/passwd.
+**
+** This routine contains most of the time of many sendmail runs.
+** It deserves to be optimized.
+**
+** Parameters:
+** name -- the name to match against.
+** fuzzyp -- an outarg that is set to TRUE if this entry
+** was found using the fuzzy matching algorithm;
+** set to FALSE otherwise.
+**
+** Returns:
+** A pointer to a pw struct.
+** NULL if name is unknown or ambiguous.
+**
+** Side Effects:
+** may modify name.
+*/
+
+struct passwd *
+finduser(name, fuzzyp)
+ char *name;
+ bool *fuzzyp;
+{
+ register struct passwd *pw;
+ register char *p;
+ extern struct passwd *getpwent();
+ extern struct passwd *getpwnam();
+
+ if (tTd(29, 4))
+ printf("finduser(%s): ", name);
+
+ *fuzzyp = FALSE;
+
+ /* DEC Hesiod getpwnam accepts numeric strings -- short circuit it */
+ for (p = name; *p != '\0'; p++)
+ if (!isascii(*p) || !isdigit(*p))
+ break;
+ if (*p == '\0')
+ {
+ if (tTd(29, 4))
+ printf("failed (numeric input)\n");
+ return NULL;
+ }
+
+ /* look up this login name using fast path */
+ if ((pw = getpwnam(name)) != NULL)
+ {
+ if (tTd(29, 4))
+ printf("found (non-fuzzy)\n");
+ return (pw);
+ }
+
+#ifdef MATCHGECOS
+ /* see if fuzzy matching allowed */
+ if (!MatchGecos)
+ {
+ if (tTd(29, 4))
+ printf("not found (fuzzy disabled)\n");
+ return NULL;
+ }
+
+ /* search for a matching full name instead */
+ for (p = name; *p != '\0'; p++)
+ {
+ if (*p == (SpaceSub & 0177) || *p == '_')
+ *p = ' ';
+ }
+ (void) setpwent();
+ while ((pw = getpwent()) != NULL)
+ {
+ char buf[MAXNAME];
+
+ buildfname(pw->pw_gecos, pw->pw_name, buf);
+ if (strchr(buf, ' ') != NULL && !strcasecmp(buf, name))
+ {
+ if (tTd(29, 4))
+ printf("fuzzy matches %s\n", pw->pw_name);
+ message("sending to login name %s", pw->pw_name);
+ *fuzzyp = TRUE;
+ return (pw);
+ }
+ }
+ if (tTd(29, 4))
+ printf("no fuzzy match found\n");
+#else
+ if (tTd(29, 4))
+ printf("not found (fuzzy disabled)\n");
+#endif
+ return (NULL);
+}
+ /*
+** WRITABLE -- predicate returning if the file is writable.
+**
+** This routine must duplicate the algorithm in sys/fio.c.
+** Unfortunately, we cannot use the access call since we
+** won't necessarily be the real uid when we try to
+** actually open the file.
+**
+** Notice that ANY file with ANY execute bit is automatically
+** not writable. This is also enforced by mailfile.
+**
+** Parameters:
+** filename -- the file name to check.
+** ctladdr -- the controlling address for this file.
+** flags -- SFF_* flags to control the function.
+**
+** Returns:
+** TRUE -- if we will be able to write this file.
+** FALSE -- if we cannot write this file.
+**
+** Side Effects:
+** none.
+*/
+
+bool
+writable(filename, ctladdr, flags)
+ char *filename;
+ ADDRESS *ctladdr;
+ int flags;
+{
+ uid_t euid;
+ gid_t egid;
+ int bits;
+ register char *p;
+ char *uname;
+ struct stat stb;
+ extern char RealUserName[];
+
+ if (tTd(29, 5))
+ printf("writable(%s, %x)\n", filename, flags);
+
+#ifdef HASLSTAT
+ if ((bitset(SFF_NOSLINK, flags) ? lstat(filename, &stb)
+ : stat(filename, &stb)) < 0)
+#else
+ if (stat(filename, &stb) < 0)
+#endif
+ {
+ /* file does not exist -- see if directory is safe */
+ p = strrchr(filename, '/');
+ if (p == NULL)
+ {
+ errno = ENOTDIR;
+ return FALSE;
+ }
+ *p = '\0';
+ errno = safefile(filename, RealUid, RealGid, RealUserName,
+ SFF_MUSTOWN, S_IWRITE|S_IEXEC);
+ *p = '/';
+ return errno == 0;
+ }
+
+#ifdef SUID_ROOT_FILES_OK
+ /* really ought to be passed down -- and not a good idea */
+ flags |= SFF_ROOTOK;
+#endif
+
+ /*
+ ** File does exist -- check that it is writable.
+ */
+
+ if (bitset(0111, stb.st_mode))
+ {
+ if (tTd(29, 5))
+ printf("failed (mode %o: x bits)\n", stb.st_mode);
+ errno = EPERM;
+ return (FALSE);
+ }
+
+ if (ctladdr != NULL && geteuid() == 0)
+ {
+ euid = ctladdr->q_uid;
+ egid = ctladdr->q_gid;
+ uname = ctladdr->q_user;
+ }
+ else
+ {
+ euid = RealUid;
+ egid = RealGid;
+ uname = RealUserName;
+ }
+ if (euid == 0)
+ {
+ euid = DefUid;
+ uname = DefUser;
+ }
+ if (egid == 0)
+ egid = DefGid;
+ if (geteuid() == 0)
+ {
+ if (bitset(S_ISUID, stb.st_mode) &&
+ (stb.st_uid != 0 || bitset(SFF_ROOTOK, flags)))
+ {
+ euid = stb.st_uid;
+ uname = NULL;
+ }
+ if (bitset(S_ISGID, stb.st_mode) &&
+ (stb.st_gid != 0 || bitset(SFF_ROOTOK, flags)))
+ egid = stb.st_gid;
+ }
+
+ if (tTd(29, 5))
+ printf("\teu/gid=%d/%d, st_u/gid=%d/%d\n",
+ euid, egid, stb.st_uid, stb.st_gid);
+
+ errno = safefile(filename, euid, egid, uname, flags, S_IWRITE);
+ return errno == 0;
+}
+ /*
+** INCLUDE -- handle :include: specification.
+**
+** Parameters:
+** fname -- filename to include.
+** forwarding -- if TRUE, we are reading a .forward file.
+** if FALSE, it's a :include: file.
+** ctladdr -- address template to use to fill in these
+** addresses -- effective user/group id are
+** the important things.
+** sendq -- a pointer to the head of the send queue
+** to put these addresses in.
+**
+** Returns:
+** open error status
+**
+** Side Effects:
+** reads the :include: file and sends to everyone
+** listed in that file.
+**
+** Security Note:
+** If you have restricted chown (that is, you can't
+** give a file away), it is reasonable to allow programs
+** and files called from this :include: file to be to be
+** run as the owner of the :include: file. This is bogus
+** if there is any chance of someone giving away a file.
+** We assume that pre-POSIX systems can give away files.
+**
+** There is an additional restriction that if you
+** forward to a :include: file, it will not take on
+** the ownership of the :include: file. This may not
+** be necessary, but shouldn't hurt.
+*/
+
+static jmp_buf CtxIncludeTimeout;
+static int includetimeout();
+
+#ifndef S_IWOTH
+# define S_IWOTH (S_IWRITE >> 6)
+#endif
+
+int
+include(fname, forwarding, ctladdr, sendq, e)
+ char *fname;
+ bool forwarding;
+ ADDRESS *ctladdr;
+ ADDRESS **sendq;
+ ENVELOPE *e;
+{
+ register FILE *fp = NULL;
+ char *oldto = e->e_to;
+ char *oldfilename = FileName;
+ int oldlinenumber = LineNumber;
+ register EVENT *ev = NULL;
+ int nincludes;
+ register ADDRESS *ca;
+ uid_t saveduid, uid;
+ gid_t savedgid, gid;
+ char *uname;
+ int rval = 0;
+ int sfflags = forwarding ? SFF_MUSTOWN : SFF_ANYFILE;
+ struct stat st;
+ char buf[MAXLINE];
+#ifdef _POSIX_CHOWN_RESTRICTED
+# if _POSIX_CHOWN_RESTRICTED == -1
+# define safechown FALSE
+# else
+# define safechown TRUE
+# endif
+#else
+# ifdef _PC_CHOWN_RESTRICTED
+ bool safechown;
+# else
+# ifdef BSD
+# define safechown TRUE
+# else
+# define safechown FALSE
+# endif
+# endif
+#endif
+ extern bool chownsafe();
+
+ if (tTd(27, 2))
+ printf("include(%s)\n", fname);
+ if (tTd(27, 4))
+ printf(" ruid=%d euid=%d\n", getuid(), geteuid());
+ if (tTd(27, 14))
+ {
+ printf("ctladdr ");
+ printaddr(ctladdr, FALSE);
+ }
+
+ if (tTd(27, 9))
+ printf("include: old uid = %d/%d\n", getuid(), geteuid());
+
+ ca = getctladdr(ctladdr);
+ if (ca == NULL)
+ {
+ uid = DefUid;
+ gid = DefGid;
+ uname = DefUser;
+ saveduid = -1;
+ }
+ else
+ {
+ uid = ca->q_uid;
+ gid = ca->q_gid;
+ uname = ca->q_user;
+#ifdef HASSETREUID
+ saveduid = geteuid();
+ savedgid = getegid();
+ if (saveduid == 0)
+ {
+ initgroups(uname, gid);
+ if (uid != 0)
+ (void) setreuid(0, uid);
+ }
+#endif
+ }
+
+ if (tTd(27, 9))
+ printf("include: new uid = %d/%d\n", getuid(), geteuid());
+
+ /*
+ ** If home directory is remote mounted but server is down,
+ ** this can hang or give errors; use a timeout to avoid this
+ */
+
+ if (setjmp(CtxIncludeTimeout) != 0)
+ {
+ ctladdr->q_flags |= QQUEUEUP;
+ errno = 0;
+
+ /* return pseudo-error code */
+ rval = EOPENTIMEOUT;
+ goto resetuid;
+ }
+ ev = setevent((time_t) 60, includetimeout, 0);
+
+ /* the input file must be marked safe */
+ rval = safefile(fname, uid, gid, uname, sfflags, S_IREAD);
+ if (rval != 0)
+ {
+ /* don't use this :include: file */
+ if (tTd(27, 4))
+ printf("include: not safe (uid=%d): %s\n",
+ uid, errstring(rval));
+ }
+ else
+ {
+ fp = fopen(fname, "r");
+ if (fp == NULL)
+ {
+ rval = errno;
+ if (tTd(27, 4))
+ printf("include: open: %s\n", errstring(rval));
+ }
+ }
+ clrevent(ev);
+
+resetuid:
+
+#ifdef HASSETREUID
+ if (saveduid == 0)
+ {
+ if (uid != 0)
+ if (setreuid(-1, 0) < 0 || setreuid(RealUid, 0) < 0)
+ syserr("setreuid(%d, 0) failure (real=%d, eff=%d)",
+ RealUid, getuid(), geteuid());
+ setgid(savedgid);
+ }
+#endif
+
+ if (tTd(27, 9))
+ printf("include: reset uid = %d/%d\n", getuid(), geteuid());
+
+ if (rval == EOPENTIMEOUT)
+ usrerr("451 open timeout on %s", fname);
+
+ if (fp == NULL)
+ return rval;
+
+ if (fstat(fileno(fp), &st) < 0)
+ {
+ rval = errno;
+ syserr("Cannot fstat %s!", fname);
+ return rval;
+ }
+
+#ifndef safechown
+ safechown = chownsafe(fileno(fp));
+#endif
+ if (ca == NULL && safechown)
+ {
+ ctladdr->q_uid = st.st_uid;
+ ctladdr->q_gid = st.st_gid;
+ ctladdr->q_flags |= QGOODUID;
+ }
+ if (ca != NULL && ca->q_uid == st.st_uid)
+ {
+ /* optimization -- avoid getpwuid if we already have info */
+ ctladdr->q_flags |= ca->q_flags & QBOGUSSHELL;
+ ctladdr->q_ruser = ca->q_ruser;
+ }
+ else
+ {
+ char *sh;
+ register struct passwd *pw;
+
+ sh = "/SENDMAIL/ANY/SHELL/";
+ pw = getpwuid(st.st_uid);
+ if (pw != NULL)
+ {
+ ctladdr->q_ruser = newstr(pw->pw_name);
+ if (safechown)
+ sh = pw->pw_shell;
+ }
+ if (pw == NULL)
+ ctladdr->q_flags |= QBOGUSSHELL;
+ else if(!usershellok(sh))
+ {
+ if (safechown)
+ ctladdr->q_flags |= QBOGUSSHELL;
+ else
+ ctladdr->q_flags |= QUNSAFEADDR;
+ }
+ }
+
+ if (bitset(EF_VRFYONLY, e->e_flags))
+ {
+ /* don't do any more now */
+ ctladdr->q_flags |= QVERIFIED;
+ e->e_nrcpts++;
+ xfclose(fp, "include", fname);
+ return rval;
+ }
+
+ /*
+ ** Check to see if some bad guy can write this file
+ **
+ ** This should really do something clever with group
+ ** permissions; currently we just view world writable
+ ** as unsafe. Also, we don't check for writable
+ ** directories in the path. We've got to leave
+ ** something for the local sysad to do.
+ */
+
+ if (bitset(S_IWOTH, st.st_mode))
+ ctladdr->q_flags |= QUNSAFEADDR;
+
+ /* read the file -- each line is a comma-separated list. */
+ FileName = fname;
+ LineNumber = 0;
+ ctladdr->q_flags &= ~QSELFREF;
+ nincludes = 0;
+ while (fgets(buf, sizeof buf, fp) != NULL)
+ {
+ register char *p = strchr(buf, '\n');
+
+ LineNumber++;
+ if (p != NULL)
+ *p = '\0';
+ if (buf[0] == '#' || buf[0] == '\0')
+ continue;
+ e->e_to = NULL;
+ message("%s to %s",
+ forwarding ? "forwarding" : "sending", buf);
+#ifdef LOG
+ if (forwarding && LogLevel > 9)
+ syslog(LOG_INFO, "%s: forward %s => %s",
+ e->e_id == NULL ? "NOQUEUE" : e->e_id,
+ oldto, buf);
+#endif
+
+ AliasLevel++;
+ nincludes += sendtolist(buf, ctladdr, sendq, e);
+ AliasLevel--;
+ }
+
+ if (ferror(fp) && tTd(27, 3))
+ printf("include: read error: %s\n", errstring(errno));
+ if (nincludes > 0 && !bitset(QSELFREF, ctladdr->q_flags))
+ {
+ if (tTd(27, 5))
+ {
+ printf("include: QDONTSEND ");
+ printaddr(ctladdr, FALSE);
+ }
+ ctladdr->q_flags |= QDONTSEND;
+ }
+
+ (void) xfclose(fp, "include", fname);
+ FileName = oldfilename;
+ LineNumber = oldlinenumber;
+ e->e_to = oldto;
+ return rval;
+}
+
+static
+includetimeout()
+{
+ longjmp(CtxIncludeTimeout, 1);
+}
+ /*
+** SENDTOARGV -- send to an argument vector.
+**
+** Parameters:
+** argv -- argument vector to send to.
+** e -- the current envelope.
+**
+** Returns:
+** none.
+**
+** Side Effects:
+** puts all addresses on the argument vector onto the
+** send queue.
+*/
+
+sendtoargv(argv, e)
+ register char **argv;
+ register ENVELOPE *e;
+{
+ register char *p;
+
+ while ((p = *argv++) != NULL)
+ {
+ (void) sendtolist(p, NULLADDR, &e->e_sendqueue, e);
+ }
+}
+ /*
+** GETCTLADDR -- get controlling address from an address header.
+**
+** If none, get one corresponding to the effective userid.
+**
+** Parameters:
+** a -- the address to find the controller of.
+**
+** Returns:
+** the controlling address.
+**
+** Side Effects:
+** none.
+*/
+
+ADDRESS *
+getctladdr(a)
+ register ADDRESS *a;
+{
+ while (a != NULL && !bitset(QGOODUID, a->q_flags))
+ a = a->q_alias;
+ return (a);
+}
diff --git a/usr.sbin/sendmail/src/savemail.c b/usr.sbin/sendmail/src/savemail.c
new file mode 100644
index 0000000..6467def
--- /dev/null
+++ b/usr.sbin/sendmail/src/savemail.c
@@ -0,0 +1,833 @@
+/*
+ * Copyright (c) 1983 Eric P. Allman
+ * Copyright (c) 1988, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)savemail.c 8.28 (Berkeley) 3/11/94";
+#endif /* not lint */
+
+# include "sendmail.h"
+# include <pwd.h>
+
+/*
+** SAVEMAIL -- Save mail on error
+**
+** If mailing back errors, mail it back to the originator
+** together with an error message; otherwise, just put it in
+** dead.letter in the user's home directory (if he exists on
+** this machine).
+**
+** Parameters:
+** e -- the envelope containing the message in error.
+**
+** Returns:
+** none
+**
+** Side Effects:
+** Saves the letter, by writing or mailing it back to the
+** sender, or by putting it in dead.letter in her home
+** directory.
+*/
+
+/* defines for state machine */
+# define ESM_REPORT 0 /* report to sender's terminal */
+# define ESM_MAIL 1 /* mail back to sender */
+# define ESM_QUIET 2 /* messages have already been returned */
+# define ESM_DEADLETTER 3 /* save in ~/dead.letter */
+# define ESM_POSTMASTER 4 /* return to postmaster */
+# define ESM_USRTMP 5 /* save in /usr/tmp/dead.letter */
+# define ESM_PANIC 6 /* leave the locked queue/transcript files */
+# define ESM_DONE 7 /* the message is successfully delivered */
+
+# ifndef _PATH_VARTMP
+# define _PATH_VARTMP "/usr/tmp/"
+# endif
+
+
+savemail(e)
+ register ENVELOPE *e;
+{
+ register struct passwd *pw;
+ register FILE *fp;
+ int state;
+ auto ADDRESS *q = NULL;
+ register char *p;
+ MCI mcibuf;
+ char buf[MAXLINE+1];
+ extern struct passwd *getpwnam();
+ extern char *ttypath();
+ typedef int (*fnptr)();
+ extern bool writable();
+
+ if (tTd(6, 1))
+ {
+ printf("\nsavemail, errormode = %c, id = %s, ExitStat = %d\n e_from=",
+ e->e_errormode, e->e_id == NULL ? "NONE" : e->e_id,
+ ExitStat);
+ printaddr(&e->e_from, FALSE);
+ }
+
+ if (e->e_id == NULL)
+ {
+ /* can't return a message with no id */
+ return;
+ }
+
+ /*
+ ** In the unhappy event we don't know who to return the mail
+ ** to, make someone up.
+ */
+
+ if (e->e_from.q_paddr == NULL)
+ {
+ e->e_sender = "Postmaster";
+ if (parseaddr(e->e_sender, &e->e_from,
+ RF_COPYPARSE|RF_SENDERADDR, '\0', NULL, e) == NULL)
+ {
+ syserr("553 Cannot parse Postmaster!");
+ ExitStat = EX_SOFTWARE;
+ finis();
+ }
+ }
+ e->e_to = NULL;
+
+ /*
+ ** Basic state machine.
+ **
+ ** This machine runs through the following states:
+ **
+ ** ESM_QUIET Errors have already been printed iff the
+ ** sender is local.
+ ** ESM_REPORT Report directly to the sender's terminal.
+ ** ESM_MAIL Mail response to the sender.
+ ** ESM_DEADLETTER Save response in ~/dead.letter.
+ ** ESM_POSTMASTER Mail response to the postmaster.
+ ** ESM_PANIC Save response anywhere possible.
+ */
+
+ /* determine starting state */
+ switch (e->e_errormode)
+ {
+ case EM_WRITE:
+ state = ESM_REPORT;
+ break;
+
+ case EM_BERKNET:
+ /* mail back, but return o.k. exit status */
+ ExitStat = EX_OK;
+
+ /* fall through.... */
+
+ case EM_MAIL:
+ state = ESM_MAIL;
+ break;
+
+ case EM_PRINT:
+ case '\0':
+ state = ESM_QUIET;
+ break;
+
+ case EM_QUIET:
+ /* no need to return anything at all */
+ return;
+
+ default:
+ syserr("554 savemail: bogus errormode x%x\n", e->e_errormode);
+ state = ESM_MAIL;
+ break;
+ }
+
+ /* if this is already an error response, send to postmaster */
+ if (bitset(EF_RESPONSE, e->e_flags))
+ {
+ if (e->e_parent != NULL &&
+ bitset(EF_RESPONSE, e->e_parent->e_flags))
+ {
+ /* got an error sending a response -- can it */
+ return;
+ }
+ state = ESM_POSTMASTER;
+ }
+
+ while (state != ESM_DONE)
+ {
+ if (tTd(6, 5))
+ printf(" state %d\n", state);
+
+ switch (state)
+ {
+ case ESM_QUIET:
+ if (e->e_from.q_mailer == LocalMailer)
+ state = ESM_DEADLETTER;
+ else
+ state = ESM_MAIL;
+ break;
+
+ case ESM_REPORT:
+
+ /*
+ ** If the user is still logged in on the same terminal,
+ ** then write the error messages back to hir (sic).
+ */
+
+ p = ttypath();
+ if (p == NULL || freopen(p, "w", stdout) == NULL)
+ {
+ state = ESM_MAIL;
+ break;
+ }
+
+ expand("\201n", buf, &buf[sizeof buf - 1], e);
+ printf("\r\nMessage from %s...\r\n", buf);
+ printf("Errors occurred while sending mail.\r\n");
+ if (e->e_xfp != NULL)
+ {
+ (void) fflush(e->e_xfp);
+ fp = fopen(queuename(e, 'x'), "r");
+ }
+ else
+ fp = NULL;
+ if (fp == NULL)
+ {
+ syserr("Cannot open %s", queuename(e, 'x'));
+ printf("Transcript of session is unavailable.\r\n");
+ }
+ else
+ {
+ printf("Transcript follows:\r\n");
+ while (fgets(buf, sizeof buf, fp) != NULL &&
+ !ferror(stdout))
+ fputs(buf, stdout);
+ (void) xfclose(fp, "savemail transcript", e->e_id);
+ }
+ printf("Original message will be saved in dead.letter.\r\n");
+ state = ESM_DEADLETTER;
+ break;
+
+ case ESM_MAIL:
+ /*
+ ** If mailing back, do it.
+ ** Throw away all further output. Don't alias,
+ ** since this could cause loops, e.g., if joe
+ ** mails to joe@x, and for some reason the network
+ ** for @x is down, then the response gets sent to
+ ** joe@x, which gives a response, etc. Also force
+ ** the mail to be delivered even if a version of
+ ** it has already been sent to the sender.
+ **
+ ** If this is a configuration or local software
+ ** error, send to the local postmaster as well,
+ ** since the originator can't do anything
+ ** about it anyway. Note that this is a full
+ ** copy of the message (intentionally) so that
+ ** the Postmaster can forward things along.
+ */
+
+ if (ExitStat == EX_CONFIG || ExitStat == EX_SOFTWARE)
+ {
+ (void) sendtolist("postmaster",
+ NULLADDR, &e->e_errorqueue, e);
+ }
+ if (strcmp(e->e_from.q_paddr, "<>") != 0)
+ {
+ (void) sendtolist(e->e_from.q_paddr,
+ NULLADDR, &e->e_errorqueue, e);
+ }
+
+ /*
+ ** Deliver a non-delivery report to the
+ ** Postmaster-designate (not necessarily
+ ** Postmaster). This does not include the
+ ** body of the message, for privacy reasons.
+ ** You really shouldn't need this.
+ */
+
+ e->e_flags |= EF_PM_NOTIFY;
+
+ /* check to see if there are any good addresses */
+ for (q = e->e_errorqueue; q != NULL; q = q->q_next)
+ if (!bitset(QBADADDR|QDONTSEND, q->q_flags))
+ break;
+ if (q == NULL)
+ {
+ /* this is an error-error */
+ state = ESM_POSTMASTER;
+ break;
+ }
+ if (returntosender(e->e_message, e->e_errorqueue,
+ (e->e_class >= 0), e) == 0)
+ {
+ state = ESM_DONE;
+ break;
+ }
+
+ /* didn't work -- return to postmaster */
+ state = ESM_POSTMASTER;
+ break;
+
+ case ESM_POSTMASTER:
+ /*
+ ** Similar to previous case, but to system postmaster.
+ */
+
+ q = NULL;
+ if (sendtolist("postmaster", NULL, &q, e) <= 0)
+ {
+ syserr("553 cannot parse postmaster!");
+ ExitStat = EX_SOFTWARE;
+ state = ESM_USRTMP;
+ break;
+ }
+ if (returntosender(e->e_message,
+ q, (e->e_class >= 0), e) == 0)
+ {
+ state = ESM_DONE;
+ break;
+ }
+
+ /* didn't work -- last resort */
+ state = ESM_USRTMP;
+ break;
+
+ case ESM_DEADLETTER:
+ /*
+ ** Save the message in dead.letter.
+ ** If we weren't mailing back, and the user is
+ ** local, we should save the message in
+ ** ~/dead.letter so that the poor person doesn't
+ ** have to type it over again -- and we all know
+ ** what poor typists UNIX users are.
+ */
+
+ p = NULL;
+ if (e->e_from.q_mailer == LocalMailer)
+ {
+ if (e->e_from.q_home != NULL)
+ p = e->e_from.q_home;
+ else if ((pw = getpwnam(e->e_from.q_user)) != NULL)
+ p = pw->pw_dir;
+ }
+ if (p == NULL)
+ {
+ /* no local directory */
+ state = ESM_MAIL;
+ break;
+ }
+ if (e->e_dfp != NULL)
+ {
+ bool oldverb = Verbose;
+
+ /* we have a home directory; open dead.letter */
+ define('z', p, e);
+ expand("\201z/dead.letter", buf, &buf[sizeof buf - 1], e);
+ Verbose = TRUE;
+ message("Saving message in %s", buf);
+ Verbose = oldverb;
+ e->e_to = buf;
+ q = NULL;
+ (void) sendtolist(buf, &e->e_from, &q, e);
+ if (q != NULL &&
+ !bitset(QBADADDR, q->q_flags) &&
+ deliver(e, q) == 0)
+ state = ESM_DONE;
+ else
+ state = ESM_MAIL;
+ }
+ else
+ {
+ /* no data file -- try mailing back */
+ state = ESM_MAIL;
+ }
+ break;
+
+ case ESM_USRTMP:
+ /*
+ ** Log the mail in /usr/tmp/dead.letter.
+ */
+
+ if (e->e_class < 0)
+ {
+ state = ESM_DONE;
+ break;
+ }
+
+ strcpy(buf, _PATH_VARTMP);
+ strcat(buf, "dead.letter");
+ if (!writable(buf, NULLADDR, SFF_NOSLINK))
+ {
+ state = ESM_PANIC;
+ break;
+ }
+ fp = dfopen(buf, O_WRONLY|O_CREAT|O_APPEND, FileMode);
+ if (fp == NULL)
+ {
+ state = ESM_PANIC;
+ break;
+ }
+
+ bzero(&mcibuf, sizeof mcibuf);
+ mcibuf.mci_out = fp;
+ mcibuf.mci_mailer = FileMailer;
+ if (bitnset(M_7BITS, FileMailer->m_flags))
+ mcibuf.mci_flags |= MCIF_7BIT;
+
+ putfromline(&mcibuf, e);
+ (*e->e_puthdr)(&mcibuf, e);
+ putline("\n", &mcibuf);
+ (*e->e_putbody)(&mcibuf, e, NULL);
+ putline("\n", &mcibuf);
+ (void) fflush(fp);
+ state = ferror(fp) ? ESM_PANIC : ESM_DONE;
+ (void) xfclose(fp, "savemail", "/usr/tmp/dead.letter");
+ break;
+
+ default:
+ syserr("554 savemail: unknown state %d", state);
+
+ /* fall through ... */
+
+ case ESM_PANIC:
+ /* leave the locked queue & transcript files around */
+ syserr("!554 savemail: cannot save rejected email anywhere");
+ }
+ }
+}
+ /*
+** RETURNTOSENDER -- return a message to the sender with an error.
+**
+** Parameters:
+** msg -- the explanatory message.
+** returnq -- the queue of people to send the message to.
+** sendbody -- if TRUE, also send back the body of the
+** message; otherwise just send the header.
+** e -- the current envelope.
+**
+** Returns:
+** zero -- if everything went ok.
+** else -- some error.
+**
+** Side Effects:
+** Returns the current message to the sender via
+** mail.
+*/
+
+static bool SendBody;
+
+#define MAXRETURNS 6 /* max depth of returning messages */
+#define ERRORFUDGE 100 /* nominal size of error message text */
+
+returntosender(msg, returnq, sendbody, e)
+ char *msg;
+ ADDRESS *returnq;
+ bool sendbody;
+ register ENVELOPE *e;
+{
+ char buf[MAXNAME];
+ extern putheader(), errbody();
+ register ENVELOPE *ee;
+ ENVELOPE *oldcur = CurEnv;
+ ENVELOPE errenvelope;
+ static int returndepth;
+ register ADDRESS *q;
+
+ if (returnq == NULL)
+ return (-1);
+
+ if (msg == NULL)
+ msg = "Unable to deliver mail";
+
+ if (tTd(6, 1))
+ {
+ printf("Return To Sender: msg=\"%s\", depth=%d, e=%x, returnq=",
+ msg, returndepth, e);
+ printaddr(returnq, TRUE);
+ }
+
+ if (++returndepth >= MAXRETURNS)
+ {
+ if (returndepth != MAXRETURNS)
+ syserr("554 returntosender: infinite recursion on %s", returnq->q_paddr);
+ /* don't "unrecurse" and fake a clean exit */
+ /* returndepth--; */
+ return (0);
+ }
+
+ SendBody = sendbody;
+ define('g', e->e_from.q_paddr, e);
+ define('u', NULL, e);
+ ee = newenvelope(&errenvelope, e);
+ define('a', "\201b", ee);
+ define('r', "internal", ee);
+ define('s', "localhost", ee);
+ define('_', "localhost", ee);
+ ee->e_puthdr = putheader;
+ ee->e_putbody = errbody;
+ ee->e_flags |= EF_RESPONSE|EF_METOO;
+ if (!bitset(EF_OLDSTYLE, e->e_flags))
+ ee->e_flags &= ~EF_OLDSTYLE;
+ ee->e_sendqueue = returnq;
+ ee->e_msgsize = ERRORFUDGE;
+ if (!NoReturn)
+ ee->e_msgsize += e->e_msgsize;
+ initsys(ee);
+ for (q = returnq; q != NULL; q = q->q_next)
+ {
+ if (bitset(QBADADDR, q->q_flags))
+ continue;
+
+ if (!bitset(QDONTSEND, q->q_flags))
+ ee->e_nrcpts++;
+
+ if (!DontPruneRoutes && pruneroute(q->q_paddr))
+ parseaddr(q->q_paddr, q, RF_COPYPARSE, '\0', NULL, e);
+
+ if (q->q_alias == NULL)
+ addheader("To", q->q_paddr, ee);
+ }
+
+# ifdef LOG
+ if (LogLevel > 5)
+ syslog(LOG_INFO, "%s: %s: return to sender: %s",
+ e->e_id, ee->e_id, msg);
+# endif
+
+ (void) sprintf(buf, "Returned mail: %s", msg);
+ addheader("Subject", buf, ee);
+ if (SendMIMEErrors)
+ {
+ addheader("MIME-Version", "1.0", ee);
+ (void) sprintf(buf, "%s.%ld/%s",
+ ee->e_id, curtime(), MyHostName);
+ ee->e_msgboundary = newstr(buf);
+ (void) sprintf(buf, "multipart/mixed; boundary=\"%s\"",
+ ee->e_msgboundary);
+ addheader("Content-Type", buf, ee);
+ }
+
+ /* fake up an address header for the from person */
+ expand("\201n", buf, &buf[sizeof buf - 1], e);
+ if (parseaddr(buf, &ee->e_from, RF_COPYALL|RF_SENDERADDR, '\0', NULL, e) == NULL)
+ {
+ syserr("553 Can't parse myself!");
+ ExitStat = EX_SOFTWARE;
+ returndepth--;
+ return (-1);
+ }
+ ee->e_sender = ee->e_from.q_paddr;
+
+ /* push state into submessage */
+ CurEnv = ee;
+ define('f', "\201n", ee);
+ define('x', "Mail Delivery Subsystem", ee);
+ eatheader(ee, TRUE);
+
+ /* mark statistics */
+ markstats(ee, NULLADDR);
+
+ /* actually deliver the error message */
+ sendall(ee, SM_DEFAULT);
+
+ /* restore state */
+ dropenvelope(ee);
+ CurEnv = oldcur;
+ returndepth--;
+
+ /* should check for delivery errors here */
+ return (0);
+}
+ /*
+** ERRBODY -- output the body of an error message.
+**
+** Typically this is a copy of the transcript plus a copy of the
+** original offending message.
+**
+** Parameters:
+** mci -- the mailer connection information.
+** e -- the envelope we are working in.
+**
+** Returns:
+** none
+**
+** Side Effects:
+** Outputs the body of an error message.
+*/
+
+errbody(mci, e)
+ register MCI *mci;
+ register ENVELOPE *e;
+{
+ register FILE *xfile;
+ char *p;
+ register ADDRESS *q;
+ bool printheader;
+ char buf[MAXLINE];
+
+ if (e->e_parent == NULL)
+ {
+ syserr("errbody: null parent");
+ putline(" ----- Original message lost -----\n", mci);
+ return;
+ }
+
+ /*
+ ** Output MIME header.
+ */
+
+ if (e->e_msgboundary != NULL)
+ {
+ putline("This is a MIME-encapsulated message", mci);
+ putline("", mci);
+ (void) sprintf(buf, "--%s", e->e_msgboundary);
+ putline(buf, mci);
+ putline("", mci);
+ }
+
+ /*
+ ** Output introductory information.
+ */
+
+ for (q = e->e_parent->e_sendqueue; q != NULL; q = q->q_next)
+ if (bitset(QBADADDR, q->q_flags))
+ break;
+ if (q == NULL &&
+ !bitset(EF_FATALERRS|EF_SENDRECEIPT, e->e_parent->e_flags))
+ {
+ putline(" **********************************************",
+ mci);
+ putline(" ** THIS IS A WARNING MESSAGE ONLY **",
+ mci);
+ putline(" ** YOU DO NOT NEED TO RESEND YOUR MESSAGE **",
+ mci);
+ putline(" **********************************************",
+ mci);
+ putline("", mci);
+ }
+ sprintf(buf, "The original message was received at %s",
+ arpadate(ctime(&e->e_parent->e_ctime)));
+ putline(buf, mci);
+ expand("from \201_", buf, &buf[sizeof buf - 1], e->e_parent);
+ putline(buf, mci);
+ putline("", mci);
+
+ /*
+ ** Output error message header (if specified and available).
+ */
+
+ if (ErrMsgFile != NULL)
+ {
+ if (*ErrMsgFile == '/')
+ {
+ xfile = fopen(ErrMsgFile, "r");
+ if (xfile != NULL)
+ {
+ while (fgets(buf, sizeof buf, xfile) != NULL)
+ {
+ expand(buf, buf, &buf[sizeof buf - 1], e);
+ putline(buf, mci);
+ }
+ (void) fclose(xfile);
+ putline("\n", mci);
+ }
+ }
+ else
+ {
+ expand(ErrMsgFile, buf, &buf[sizeof buf - 1], e);
+ putline(buf, mci);
+ putline("", mci);
+ }
+ }
+
+ /*
+ ** Output message introduction
+ */
+
+ printheader = TRUE;
+ for (q = e->e_parent->e_sendqueue; q != NULL; q = q->q_next)
+ {
+ if (bitset(QBADADDR|QREPORT, q->q_flags))
+ {
+ if (printheader)
+ {
+ putline(" ----- The following addresses had delivery problems -----",
+ mci);
+ printheader = FALSE;
+ }
+ strcpy(buf, q->q_paddr);
+ if (bitset(QBADADDR, q->q_flags))
+ strcat(buf, " (unrecoverable error)");
+ else
+ strcat(buf, " (transient failure)");
+ putline(buf, mci);
+ if (q->q_alias != NULL)
+ {
+ strcpy(buf, " (expanded from: ");
+ strcat(buf, q->q_alias->q_paddr);
+ strcat(buf, ")");
+ putline(buf, mci);
+ }
+ }
+ }
+ if (!printheader)
+ putline("\n", mci);
+
+ /*
+ ** Output transcript of errors
+ */
+
+ (void) fflush(stdout);
+ p = queuename(e->e_parent, 'x');
+ if ((xfile = fopen(p, "r")) == NULL)
+ {
+ syserr("Cannot open %s", p);
+ putline(" ----- Transcript of session is unavailable -----\n", mci);
+ }
+ else
+ {
+ putline(" ----- Transcript of session follows -----\n", mci);
+ if (e->e_xfp != NULL)
+ (void) fflush(e->e_xfp);
+ while (fgets(buf, sizeof buf, xfile) != NULL)
+ putline(buf, mci);
+ (void) xfclose(xfile, "errbody xscript", p);
+ }
+ errno = 0;
+
+ /*
+ ** Output text of original message
+ */
+
+ if (NoReturn)
+ SendBody = FALSE;
+ putline("", mci);
+ if (e->e_parent->e_df != NULL)
+ {
+ if (SendBody)
+ putline(" ----- Original message follows -----\n", mci);
+ else
+ putline(" ----- Message header follows -----\n", mci);
+ (void) fflush(mci->mci_out);
+
+ if (e->e_msgboundary != NULL)
+ {
+ putline("", mci);
+ (void) sprintf(buf, "--%s", e->e_msgboundary);
+ putline(buf, mci);
+ putline("Content-Type: message/rfc822", mci);
+ putline("", mci);
+ }
+ putheader(mci, e->e_parent);
+ putline("", mci);
+ if (SendBody)
+ putbody(mci, e->e_parent, e->e_msgboundary);
+ else
+ putline(" ----- Message body suppressed -----", mci);
+ }
+ else
+ {
+ putline(" ----- No message was collected -----\n", mci);
+ }
+
+ if (e->e_msgboundary != NULL)
+ {
+ putline("", mci);
+ (void) sprintf(buf, "--%s--", e->e_msgboundary);
+ putline(buf, mci);
+ }
+ putline("", mci);
+
+ /*
+ ** Cleanup and exit
+ */
+
+ if (errno != 0)
+ syserr("errbody: I/O error");
+}
+ /*
+** PRUNEROUTE -- prune an RFC-822 source route
+**
+** Trims down a source route to the last internet-registered hop.
+** This is encouraged by RFC 1123 section 5.3.3.
+**
+** Parameters:
+** addr -- the address
+**
+** Returns:
+** TRUE -- address was modified
+** FALSE -- address could not be pruned
+**
+** Side Effects:
+** modifies addr in-place
+*/
+
+pruneroute(addr)
+ char *addr;
+{
+#if NAMED_BIND
+ char *start, *at, *comma;
+ char c;
+ int rcode;
+ char hostbuf[BUFSIZ];
+ char *mxhosts[MAXMXHOSTS + 1];
+
+ /* check to see if this is really a route-addr */
+ if (*addr != '<' || addr[1] != '@' || addr[strlen(addr) - 1] != '>')
+ return FALSE;
+ start = strchr(addr, ':');
+ at = strrchr(addr, '@');
+ if (start == NULL || at == NULL || at < start)
+ return FALSE;
+
+ /* slice off the angle brackets */
+ strcpy(hostbuf, at + 1);
+ hostbuf[strlen(hostbuf) - 1] = '\0';
+
+ while (start)
+ {
+ if (getmxrr(hostbuf, mxhosts, FALSE, &rcode) > 0)
+ {
+ strcpy(addr + 1, start + 1);
+ return TRUE;
+ }
+ c = *start;
+ *start = '\0';
+ comma = strrchr(addr, ',');
+ if (comma && comma[1] == '@')
+ strcpy(hostbuf, comma + 2);
+ else
+ comma = 0;
+ *start = c;
+ start = comma;
+ }
+#endif
+ return FALSE;
+}
diff --git a/usr.sbin/sendmail/src/sendmail.8 b/usr.sbin/sendmail/src/sendmail.8
new file mode 100644
index 0000000..ee0f700
--- /dev/null
+++ b/usr.sbin/sendmail/src/sendmail.8
@@ -0,0 +1,501 @@
+.\" Copyright (c) 1988, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)sendmail.8 8.4 (Berkeley) 12/11/93
+.\"
+.Dd December 11, 1993
+.Dt SENDMAIL 8
+.Os BSD 4
+.Sh NAME
+.Nm sendmail
+.Nd send mail over the internet
+.Sh SYNOPSIS
+.Nm sendmail
+.Op Ar flags
+.Op Ar address ...
+.Nm newaliases
+.Nm mailq
+.Op Fl v
+.Sh DESCRIPTION
+.Nm Sendmail
+sends a message to one or more
+.Em recipients ,
+routing the message over whatever networks
+are necessary.
+.Nm Sendmail
+does internetwork forwarding as necessary
+to deliver the message to the correct place.
+.Pp
+.Nm Sendmail
+is not intended as a user interface routine;
+other programs provide user-friendly
+front ends;
+.Nm sendmail
+is used only to deliver pre-formatted messages.
+.Pp
+With no flags,
+.Nm sendmail
+reads its standard input
+up to an end-of-file
+or a line consisting only of a single dot
+and sends a copy of the message found there
+to all of the addresses listed.
+It determines the network(s) to use
+based on the syntax and contents of the addresses.
+.Pp
+Local addresses are looked up in a file
+and aliased appropriately.
+Aliasing can be prevented by preceding the address
+with a backslash.
+Normally the sender is not included in any alias
+expansions, e.g.,
+if `john' sends to `group',
+and `group' includes `john' in the expansion,
+then the letter will not be delivered to `john'.
+.Ss Parameters
+.Bl -tag -width Fl
+.It Fl B Ns Ar type
+Set the body type to
+.Ar type .
+Current legal values
+.Li 7BIT
+or
+.Li 8BITMIME .
+.It Fl ba
+Go into
+.Tn ARPANET
+mode.
+All input lines must end with a CR-LF,
+and all messages will be generated with a CR-LF at the end.
+Also,
+the ``From:'' and ``Sender:''
+fields are examined for the name of the sender.
+.It Fl bd
+Run as a daemon. This requires Berkeley
+.Tn IPC .
+.Nm Sendmail
+will fork and run in background
+listening on socket 25 for incoming
+.Tn SMTP
+connections.
+This is normally run from
+.Pa /etc/rc .
+.It Fl bi
+Initialize the alias database.
+.It Fl bm
+Deliver mail in the usual way (default).
+.It Fl bp
+Print a listing of the queue.
+.It Fl bs
+Use the
+.Tn SMTP
+protocol as described in
+.Tn RFC821
+on standard input and output.
+This flag implies all the operations of the
+.Fl ba
+flag that are compatible with
+.Tn SMTP .
+.It Fl bt
+Run in address test mode.
+This mode reads addresses and shows the steps in parsing;
+it is used for debugging configuration tables.
+.It Fl bv
+Verify names only \- do not try to collect or deliver a message.
+Verify mode is normally used for validating
+users or mailing lists.
+.It Fl C Ns Ar file
+Use alternate configuration file.
+.Nm Sendmail
+refuses to run as root if an alternate configuration file is specified.
+.It Fl d Ns Ar X
+Set debugging value to
+.Ar X .
+.ne 1i
+.It Fl F Ns Ar fullname
+Set the full name of the sender.
+.It Fl f Ns Ar name
+Sets the name of the ``from'' person
+(i.e., the sender of the mail).
+.Fl f
+can only be used
+by ``trusted'' users
+(normally
+.Em root ,
+.Em daemon ,
+and
+.Em network )
+or if the person you are trying to become
+is the same as the person you are.
+.It Fl h Ns Ar N
+Set the hop count to
+.Ar N .
+The hop count is incremented every time the mail is
+processed.
+When it reaches a limit,
+the mail is returned with an error message,
+the victim of an aliasing loop.
+If not specified,
+``Received:'' lines in the message are counted.
+.It Fl n
+Don't do aliasing.
+.It Fl o Ns Ar x Em value
+Set option
+.Ar x
+to the specified
+.Em value .
+Options are described below.
+.It Fl p Ns Ar protocol
+Set the name of the protocol used to receive the message.
+This can be a simple protocol name such as ``UUCP''
+or a protocol and hostname, such as ``UUCP:ucbvax''.
+.It Fl q Ns Bq Ar time
+Processed saved messages in the queue at given intervals.
+If
+.Ar time
+is omitted,
+process the queue once.
+.Xr Time
+is given as a tagged number,
+with
+.Ql s
+being seconds,
+.Ql m
+being minutes,
+.Ql h
+being hours,
+.Ql d
+being days,
+and
+.Ql w
+being weeks.
+For example,
+.Ql \-q1h30m
+or
+.Ql \-q90m
+would both set the timeout to one hour thirty minutes.
+If
+.Ar time
+is specified,
+.Nm sendmail
+will run in background.
+This option can be used safely with
+.Fl bd .
+.It Fl r Ns Ar name
+An alternate and obsolete form of the
+.Fl f
+flag.
+.It Fl t
+Read message for recipients.
+To:, Cc:, and Bcc: lines will be scanned for recipient addresses.
+The Bcc: line will be deleted before transmission.
+Any addresses in the argument list will be suppressed,
+that is,
+they will
+.Em not
+receive copies even if listed in the message header.
+.It Fl v
+Go into verbose mode.
+Alias expansions will be announced, etc.
+.It Fl X Ar logfile
+Log all traffic in and out of mailers in the indicated log file.
+This should only be used as a last resort
+for debugging mailer bugs.
+It will log a lot of data very quickly.
+.El
+.Ss Options
+There are also a number of processing options that may be set.
+Normally these will only be used by a system administrator.
+Options may be set either on the command line
+using the
+.Fl o
+flag
+or in the configuration file.
+This is a partial list;
+for a complete list (and details), consult the
+.%T "Sendmail Installation and Operation Guide" .
+The options are:
+.Bl -tag -width Fl
+.It Li A Ns Ar file
+Use alternate alias file.
+.It Li b Ns Ar nblocks
+The minimum number of free blocks needed on the spool filesystem.
+.It Li c
+On mailers that are considered ``expensive'' to connect to,
+don't initiate immediate connection.
+This requires queueing.
+.It Li C Ar N
+Checkpoint the queue file after every
+.Ar N
+successful deliveries (default 10).
+This avoids excessive duplicate deliveries
+when sending to long mailing lists
+interrupted by system crashes.
+.It Li d Ns Ar x
+Set the delivery mode to
+.Ar x .
+Delivery modes are
+.Ql i
+for interactive (synchronous) delivery,
+.Ql b
+for background (asynchronous) delivery,
+and
+.Ql q
+for queue only \- i.e.,
+actual delivery is done the next time the queue is run.
+.It Li D
+Try to automatically rebuild the alias database
+if necessary.
+.It Li e Ns Ar x
+Set error processing to mode
+.Ar x .
+Valid modes are
+.Ql m
+to mail back the error message,
+.Ql w
+to ``write'' back the error message
+(or mail it back if the sender is not logged in),
+.Ql p
+to print the errors on the terminal
+(default),
+.Ql q
+to throw away error messages
+(only exit status is returned),
+and
+.Ql e
+to do special processing for the BerkNet.
+If the text of the message is not mailed back
+by
+modes
+.Ql m
+or
+.Ql w
+and if the sender is local to this machine,
+a copy of the message is appended to the file
+.Pa dead.letter
+in the sender's home directory.
+.It Li f
+Save
+.Tn UNIX Ns \-style
+From lines at the front of messages.
+.It Li G
+Match local mail names against the GECOS portion of the password file.
+.It Li g Ar N
+The default group id to use when calling mailers.
+.It Li H Ns Ar file
+The
+.Tn SMTP
+help file.
+.It Li h Ar N
+The maximum number of times a message is allowed to ``hop''
+before we decide it is in a loop.
+.It Li i
+Do not take dots on a line by themselves
+as a message terminator.
+.It Li j
+Send error messages in MIME format.
+.It Li K Ns Ar timeout
+Set connection cache timeout.
+.It Li k Ns Ar N
+Set connection cache size.
+.It Li L Ns Ar n
+The log level.
+.It Li l
+Pay attention to the Errors-To: header.
+.It Li m
+Send to ``me'' (the sender) also if I am in an alias expansion.
+.It Li n
+Validate the right hand side of aliases during a
+.Xr newaliases 1
+command.
+.It Li o
+If set, this message may have
+old style headers.
+If not set,
+this message is guaranteed to have new style headers
+(i.e., commas instead of spaces between addresses).
+If set, an adaptive algorithm is used that will correctly
+determine the header format in most cases.
+.It Li Q Ns Ar queuedir
+Select the directory in which to queue messages.
+.It Li S Ns Ar file
+Save statistics in the named file.
+.It Li s
+Always instantiate the queue file,
+even under circumstances where it is not strictly necessary.
+This provides safety against system crashes during delivery.
+.It Li T Ns Ar time
+Set the timeout on undelivered messages in the queue to the specified time.
+After delivery has failed
+(e.g., because of a host being down)
+for this amount of time,
+failed messages will be returned to the sender.
+The default is three days.
+.It Li t Ns Ar stz , Ar dtz
+Set the name of the time zone.
+.It Li U Ns Ar userdatabase
+If set, a user database is consulted to get forwarding information.
+You can consider this an adjunct to the aliasing mechanism,
+except that the database is intended to be distributed;
+aliases are local to a particular host.
+This may not be available if your sendmail does not have the
+.Dv USERDB
+option compiled in.
+.It Li u Ns Ar N
+Set the default user id for mailers.
+.It Li Y
+Fork each job during queue runs.
+May be convenient on memory-poor machines.
+.It Li 7
+Strip incoming messages to seven bits.
+.El
+.Pp
+In aliases,
+the first character of a name may be
+a vertical bar to cause interpretation of
+the rest of the name as a command
+to pipe the mail to.
+It may be necessary to quote the name
+to keep
+.Nm sendmail
+from suppressing the blanks from between arguments.
+For example, a common alias is:
+.Pp
+.Bd -literal -offset indent -compact
+msgs: "|/usr/bin/msgs -s"
+.Ed
+.Pp
+Aliases may also have the syntax
+.Dq :include: Ns Ar filename
+to ask
+.Xr sendmail
+to read the named file for a list of recipients.
+For example, an alias such as:
+.Pp
+.Bd -literal -offset indent -compact
+poets: ":include:/usr/local/lib/poets.list"
+.Ed
+.Pp
+would read
+.Pa /usr/local/lib/poets.list
+for the list of addresses making up the group.
+.Pp
+.Nm Sendmail
+returns an exit status
+describing what it did.
+The codes are defined in
+.Aq Pa sysexits.h :
+.Bl -tag -width EX_UNAVAILABLE -compact -offset indent
+.It Dv EX_OK
+Successful completion on all addresses.
+.It Dv EX_NOUSER
+User name not recognized.
+.It Dv EX_UNAVAILABLE
+Catchall meaning necessary resources
+were not available.
+.It Dv EX_SYNTAX
+Syntax error in address.
+.It Dv EX_SOFTWARE
+Internal software error,
+including bad arguments.
+.It Dv EX_OSERR
+Temporary operating system error,
+such as
+.Dq cannot fork .
+.It Dv EX_NOHOST
+Host name not recognized.
+.It Dv EX_TEMPFAIL
+Message could not be sent immediately,
+but was queued.
+.El
+.Pp
+If invoked as
+.Nm newaliases ,
+.Nm sendmail
+will rebuild the alias database.
+If invoked as
+.Nm mailq ,
+.Nm sendmail
+will print the contents of the mail queue.
+.Sh FILES
+Except for the file
+.Pa /etc/sendmail.cf
+itself,
+the following pathnames are all specified in
+.Pa /etc/sendmail.cf.
+Thus,
+these values are only approximations.
+.Pp
+.Bl -tag -width /usr/lib/sendmail.fc -compact
+.It Pa /etc/aliases
+raw data for alias names
+.It Pa /etc/aliases.db
+data base of alias names
+.It Pa /etc/sendmail.cf
+configuration file
+.It Pa /etc/sendmail.hf
+help file
+.It Pa /var/log/sendmail.st
+collected statistics
+.It Pa /var/spool/mqueue/*
+temp files
+.It Pa /var/run/sendmail.pid
+The process id of the daemon
+.El
+.Sh SEE ALSO
+.Xr binmail 1 ,
+.Xr mail 1 ,
+.Xr rmail 1 ,
+.Xr syslog 3 ,
+.Xr aliases 5 ,
+.Xr mailaddr 7 ,
+.Xr rc 8 ;
+.Pp
+DARPA
+Internet Request For Comments
+.%T RFC819 ,
+.%T RFC821 ,
+.%T RFC822 .
+.Rs
+.%T "Sendmail \- An Internetwork Mail Router"
+.%V SMM
+.%N \&No. 9
+.Re
+.Rs
+.%T "Sendmail Installation and Operation Guide"
+.%V SMM
+.%N \&No. 8
+.Re
+.Sh HISTORY
+The
+.Nm
+command appeared in
+.Bx 4.2 .
diff --git a/usr.sbin/sendmail/src/sendmail.h b/usr.sbin/sendmail/src/sendmail.h
new file mode 100644
index 0000000..4a42b2c
--- /dev/null
+++ b/usr.sbin/sendmail/src/sendmail.h
@@ -0,0 +1,973 @@
+/*
+ * Copyright (c) 1983 Eric P. Allman
+ * Copyright (c) 1988, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)sendmail.h 8.43 (Berkeley) 4/14/94
+ */
+
+/*
+** SENDMAIL.H -- Global definitions for sendmail.
+*/
+
+# ifdef _DEFINE
+# define EXTERN
+# ifndef lint
+static char SmailSccsId[] = "@(#)sendmail.h 8.43 4/14/94";
+# endif
+# else /* _DEFINE */
+# define EXTERN extern
+# endif /* _DEFINE */
+
+# include <unistd.h>
+# include <stddef.h>
+# include <stdlib.h>
+# include <stdio.h>
+# include <ctype.h>
+# include <setjmp.h>
+# include <sysexits.h>
+# include <string.h>
+# include <time.h>
+# include <errno.h>
+
+# include "conf.h"
+# include "useful.h"
+
+# ifdef LOG
+# include <syslog.h>
+# endif /* LOG */
+
+# ifdef DAEMON
+# include <sys/socket.h>
+# endif
+# ifdef NETUNIX
+# include <sys/un.h>
+# endif
+# ifdef NETINET
+# include <netinet/in.h>
+# endif
+# ifdef NETISO
+# include <netiso/iso.h>
+# endif
+# ifdef NETNS
+# include <netns/ns.h>
+# endif
+# ifdef NETX25
+# include <netccitt/x25.h>
+# endif
+
+
+
+
+/*
+** Data structure for bit maps.
+**
+** Each bit in this map can be referenced by an ascii character.
+** This is 128 possible bits, or 12 8-bit bytes.
+*/
+
+#define BITMAPBYTES 16 /* number of bytes in a bit map */
+#define BYTEBITS 8 /* number of bits in a byte */
+
+/* internal macros */
+#define _BITWORD(bit) (bit / (BYTEBITS * sizeof (int)))
+#define _BITBIT(bit) (1 << (bit % (BYTEBITS * sizeof (int))))
+
+typedef int BITMAP[BITMAPBYTES / sizeof (int)];
+
+/* test bit number N */
+#define bitnset(bit, map) ((map)[_BITWORD(bit)] & _BITBIT(bit))
+
+/* set bit number N */
+#define setbitn(bit, map) (map)[_BITWORD(bit)] |= _BITBIT(bit)
+
+/* clear bit number N */
+#define clrbitn(bit, map) (map)[_BITWORD(bit)] &= ~_BITBIT(bit)
+
+/* clear an entire bit map */
+#define clrbitmap(map) bzero((char *) map, BITMAPBYTES)
+ /*
+** Address structure.
+** Addresses are stored internally in this structure.
+*/
+
+struct address
+{
+ char *q_paddr; /* the printname for the address */
+ char *q_user; /* user name */
+ char *q_ruser; /* real user name, or NULL if q_user */
+ char *q_host; /* host name */
+ struct mailer *q_mailer; /* mailer to use */
+ u_short q_flags; /* status flags, see below */
+ uid_t q_uid; /* user-id of receiver (if known) */
+ gid_t q_gid; /* group-id of receiver (if known) */
+ char *q_home; /* home dir (local mailer only) */
+ char *q_fullname; /* full name if known */
+ struct address *q_next; /* chain */
+ struct address *q_alias; /* address this results from */
+ char *q_owner; /* owner of q_alias */
+ struct address *q_tchain; /* temporary use chain */
+ time_t q_timeout; /* timeout for this address */
+};
+
+typedef struct address ADDRESS;
+
+# define QDONTSEND 000001 /* don't send to this address */
+# define QBADADDR 000002 /* this address is verified bad */
+# define QGOODUID 000004 /* the q_uid q_gid fields are good */
+# define QPRIMARY 000010 /* set from argv */
+# define QQUEUEUP 000020 /* queue for later transmission */
+# define QSENT 000040 /* has been successfully delivered */
+# define QNOTREMOTE 000100 /* not an address for remote forwarding */
+# define QSELFREF 000200 /* this address references itself */
+# define QVERIFIED 000400 /* verified, but not expanded */
+# define QREPORT 001000 /* report this address in return message */
+# define QBOGUSSHELL 002000 /* this entry has an invalid shell listed */
+# define QUNSAFEADDR 004000 /* address aquired through an unsafe path */
+
+# define NULLADDR ((ADDRESS *) NULL)
+ /*
+** Mailer definition structure.
+** Every mailer known to the system is declared in this
+** structure. It defines the pathname of the mailer, some
+** flags associated with it, and the argument vector to
+** pass to it. The flags are defined in conf.c
+**
+** The argument vector is expanded before actual use. All
+** words except the first are passed through the macro
+** processor.
+*/
+
+struct mailer
+{
+ char *m_name; /* symbolic name of this mailer */
+ char *m_mailer; /* pathname of the mailer to use */
+ BITMAP m_flags; /* status flags, see below */
+ short m_mno; /* mailer number internally */
+ char **m_argv; /* template argument vector */
+ short m_sh_rwset; /* rewrite set: sender header addresses */
+ short m_se_rwset; /* rewrite set: sender envelope addresses */
+ short m_rh_rwset; /* rewrite set: recipient header addresses */
+ short m_re_rwset; /* rewrite set: recipient envelope addresses */
+ char *m_eol; /* end of line string */
+ long m_maxsize; /* size limit on message to this mailer */
+ int m_linelimit; /* max # characters per line */
+ char *m_execdir; /* directory to chdir to before execv */
+};
+
+typedef struct mailer MAILER;
+
+/* bits for m_flags */
+# define M_ESMTP 'a' /* run Extended SMTP protocol */
+# define M_BLANKEND 'b' /* ensure blank line at end of message */
+# define M_NOCOMMENT 'c' /* don't include comment part of address */
+# define M_CANONICAL 'C' /* make addresses canonical "u@dom" */
+ /* 'D' /* CF: include Date: */
+# define M_EXPENSIVE 'e' /* it costs to use this mailer.... */
+# define M_ESCFROM 'E' /* escape From lines to >From */
+# define M_FOPT 'f' /* mailer takes picky -f flag */
+ /* 'F' /* CF: include From: or Resent-From: */
+# define M_NO_NULL_FROM 'g' /* sender of errors should be $g */
+# define M_HST_UPPER 'h' /* preserve host case distinction */
+# define M_PREHEAD 'H' /* MAIL11V3: preview headers */
+# define M_INTERNAL 'I' /* SMTP to another sendmail site */
+# define M_LOCALMAILER 'l' /* delivery is to this host */
+# define M_LIMITS 'L' /* must enforce SMTP line limits */
+# define M_MUSER 'm' /* can handle multiple users at once */
+ /* 'M' /* CF: include Message-Id: */
+# define M_NHDR 'n' /* don't insert From line */
+# define M_MANYSTATUS 'N' /* MAIL11V3: DATA returns multi-status */
+# define M_FROMPATH 'p' /* use reverse-path in MAIL FROM: */
+ /* 'P' /* CF: include Return-Path: */
+# define M_ROPT 'r' /* mailer takes picky -r flag */
+# define M_SECURE_PORT 'R' /* try to send on a reserved TCP port */
+# define M_STRIPQ 's' /* strip quote chars from user/host */
+# define M_RESTR 'S' /* must be daemon to execute */
+# define M_USR_UPPER 'u' /* preserve user case distinction */
+# define M_UGLYUUCP 'U' /* this wants an ugly UUCP from line */
+ /* 'V' /* UIUC: !-relativize all addresses */
+ /* 'x' /* CF: include Full-Name: */
+# define M_XDOT 'X' /* use hidden-dot algorithm */
+# define M_7BITS '7' /* use 7-bit path */
+
+EXTERN MAILER *Mailer[MAXMAILERS+1];
+
+EXTERN MAILER *LocalMailer; /* ptr to local mailer */
+EXTERN MAILER *ProgMailer; /* ptr to program mailer */
+EXTERN MAILER *FileMailer; /* ptr to *file* mailer */
+EXTERN MAILER *InclMailer; /* ptr to *include* mailer */
+ /*
+** Header structure.
+** This structure is used internally to store header items.
+*/
+
+struct header
+{
+ char *h_field; /* the name of the field */
+ char *h_value; /* the value of that field */
+ struct header *h_link; /* the next header */
+ u_short h_flags; /* status bits, see below */
+ BITMAP h_mflags; /* m_flags bits needed */
+};
+
+typedef struct header HDR;
+
+/*
+** Header information structure.
+** Defined in conf.c, this struct declares the header fields
+** that have some magic meaning.
+*/
+
+struct hdrinfo
+{
+ char *hi_field; /* the name of the field */
+ u_short hi_flags; /* status bits, see below */
+};
+
+extern struct hdrinfo HdrInfo[];
+
+/* bits for h_flags and hi_flags */
+# define H_EOH 00001 /* this field terminates header */
+# define H_RCPT 00002 /* contains recipient addresses */
+# define H_DEFAULT 00004 /* if another value is found, drop this */
+# define H_RESENT 00010 /* this address is a "Resent-..." address */
+# define H_CHECK 00020 /* check h_mflags against m_flags */
+# define H_ACHECK 00040 /* ditto, but always (not just default) */
+# define H_FORCE 00100 /* force this field, even if default */
+# define H_TRACE 00200 /* this field contains trace information */
+# define H_FROM 00400 /* this is a from-type field */
+# define H_VALID 01000 /* this field has a validated value */
+# define H_RECEIPTTO 02000 /* this field has return receipt info */
+# define H_ERRORSTO 04000 /* this field has error address info */
+ /*
+** Information about currently open connections to mailers, or to
+** hosts that we have looked up recently.
+*/
+
+# define MCI struct mailer_con_info
+
+MCI
+{
+ short mci_flags; /* flag bits, see below */
+ short mci_errno; /* error number on last connection */
+ short mci_herrno; /* h_errno from last DNS lookup */
+ short mci_exitstat; /* exit status from last connection */
+ short mci_state; /* SMTP state */
+ long mci_maxsize; /* max size this server will accept */
+ FILE *mci_in; /* input side of connection */
+ FILE *mci_out; /* output side of connection */
+ int mci_pid; /* process id of subordinate proc */
+ char *mci_phase; /* SMTP phase string */
+ struct mailer *mci_mailer; /* ptr to the mailer for this conn */
+ char *mci_host; /* host name */
+ time_t mci_lastuse; /* last usage time */
+};
+
+
+/* flag bits */
+#define MCIF_VALID 000001 /* this entry is valid */
+#define MCIF_TEMP 000002 /* don't cache this connection */
+#define MCIF_CACHED 000004 /* currently in open cache */
+#define MCIF_ESMTP 000010 /* this host speaks ESMTP */
+#define MCIF_EXPN 000020 /* EXPN command supported */
+#define MCIF_SIZE 000040 /* SIZE option supported */
+#define MCIF_8BITMIME 000100 /* BODY=8BITMIME supported */
+#define MCIF_7BIT 000200 /* strip this message to 7 bits */
+#define MCIF_MULTSTAT 000400 /* MAIL11V3: handles MULT status */
+
+/* states */
+#define MCIS_CLOSED 0 /* no traffic on this connection */
+#define MCIS_OPENING 1 /* sending initial protocol */
+#define MCIS_OPEN 2 /* open, initial protocol sent */
+#define MCIS_ACTIVE 3 /* message being sent */
+#define MCIS_QUITING 4 /* running quit protocol */
+#define MCIS_SSD 5 /* service shutting down */
+#define MCIS_ERROR 6 /* I/O error on connection */
+ /*
+** Envelope structure.
+** This structure defines the message itself. There is usually
+** only one of these -- for the message that we originally read
+** and which is our primary interest -- but other envelopes can
+** be generated during processing. For example, error messages
+** will have their own envelope.
+*/
+
+# define ENVELOPE struct envelope
+
+ENVELOPE
+{
+ HDR *e_header; /* head of header list */
+ long e_msgpriority; /* adjusted priority of this message */
+ time_t e_ctime; /* time message appeared in the queue */
+ char *e_to; /* the target person */
+ char *e_receiptto; /* return receipt address */
+ ADDRESS e_from; /* the person it is from */
+ char *e_sender; /* e_from.q_paddr w comments stripped */
+ char **e_fromdomain; /* the domain part of the sender */
+ ADDRESS *e_sendqueue; /* list of message recipients */
+ ADDRESS *e_errorqueue; /* the queue for error responses */
+ long e_msgsize; /* size of the message in bytes */
+ long e_flags; /* flags, see below */
+ int e_nrcpts; /* number of recipients */
+ short e_class; /* msg class (priority, junk, etc.) */
+ short e_hopcount; /* number of times processed */
+ short e_nsent; /* number of sends since checkpoint */
+ short e_sendmode; /* message send mode */
+ short e_errormode; /* error return mode */
+ int (*e_puthdr)__P((MCI *, ENVELOPE *));
+ /* function to put header of message */
+ int (*e_putbody)__P((MCI *, ENVELOPE *, char *));
+ /* function to put body of message */
+ struct envelope *e_parent; /* the message this one encloses */
+ struct envelope *e_sibling; /* the next envelope of interest */
+ char *e_bodytype; /* type of message body */
+ char *e_df; /* location of temp file */
+ FILE *e_dfp; /* temporary file */
+ char *e_id; /* code for this entry in queue */
+ FILE *e_xfp; /* transcript file */
+ FILE *e_lockfp; /* the lock file for this message */
+ char *e_message; /* error message */
+ char *e_statmsg; /* stat msg (changes per delivery) */
+ char *e_msgboundary; /* MIME-style message part boundary */
+ char *e_origrcpt; /* original recipient (one only) */
+ char *e_macro[128]; /* macro definitions */
+};
+
+/* values for e_flags */
+#define EF_OLDSTYLE 0x0000001 /* use spaces (not commas) in hdrs */
+#define EF_INQUEUE 0x0000002 /* this message is fully queued */
+#define EF_CLRQUEUE 0x0000008 /* disk copy is no longer needed */
+#define EF_SENDRECEIPT 0x0000010 /* send a return receipt */
+#define EF_FATALERRS 0x0000020 /* fatal errors occured */
+#define EF_KEEPQUEUE 0x0000040 /* keep queue files always */
+#define EF_RESPONSE 0x0000080 /* this is an error or return receipt */
+#define EF_RESENT 0x0000100 /* this message is being forwarded */
+#define EF_VRFYONLY 0x0000200 /* verify only (don't expand aliases) */
+#define EF_WARNING 0x0000400 /* warning message has been sent */
+#define EF_QUEUERUN 0x0000800 /* this envelope is from queue */
+#define EF_GLOBALERRS 0x0001000 /* treat errors as global */
+#define EF_PM_NOTIFY 0x0002000 /* send return mail to postmaster */
+#define EF_METOO 0x0004000 /* send to me too */
+#define EF_LOGSENDER 0x0008000 /* need to log the sender */
+#define EF_NORECEIPT 0x0010000 /* suppress all return-receipts */
+
+EXTERN ENVELOPE *CurEnv; /* envelope currently being processed */
+ /*
+** Message priority classes.
+**
+** The message class is read directly from the Priority: header
+** field in the message.
+**
+** CurEnv->e_msgpriority is the number of bytes in the message plus
+** the creation time (so that jobs ``tend'' to be ordered correctly),
+** adjusted by the message class, the number of recipients, and the
+** amount of time the message has been sitting around. This number
+** is used to order the queue. Higher values mean LOWER priority.
+**
+** Each priority class point is worth WkClassFact priority points;
+** each recipient is worth WkRecipFact priority points. Each time
+** we reprocess a message the priority is adjusted by WkTimeFact.
+** WkTimeFact should normally decrease the priority so that jobs
+** that have historically failed will be run later; thanks go to
+** Jay Lepreau at Utah for pointing out the error in my thinking.
+**
+** The "class" is this number, unadjusted by the age or size of
+** this message. Classes with negative representations will have
+** error messages thrown away if they are not local.
+*/
+
+struct priority
+{
+ char *pri_name; /* external name of priority */
+ int pri_val; /* internal value for same */
+};
+
+EXTERN struct priority Priorities[MAXPRIORITIES];
+EXTERN int NumPriorities; /* pointer into Priorities */
+ /*
+** Rewrite rules.
+*/
+
+struct rewrite
+{
+ char **r_lhs; /* pattern match */
+ char **r_rhs; /* substitution value */
+ struct rewrite *r_next;/* next in chain */
+};
+
+EXTERN struct rewrite *RewriteRules[MAXRWSETS];
+
+/*
+** Special characters in rewriting rules.
+** These are used internally only.
+** The COND* rules are actually used in macros rather than in
+** rewriting rules, but are given here because they
+** cannot conflict.
+*/
+
+/* left hand side items */
+# define MATCHZANY 0220 /* match zero or more tokens */
+# define MATCHANY 0221 /* match one or more tokens */
+# define MATCHONE 0222 /* match exactly one token */
+# define MATCHCLASS 0223 /* match one token in a class */
+# define MATCHNCLASS 0224 /* match anything not in class */
+# define MATCHREPL 0225 /* replacement on RHS for above */
+
+/* right hand side items */
+# define CANONNET 0226 /* canonical net, next token */
+# define CANONHOST 0227 /* canonical host, next token */
+# define CANONUSER 0230 /* canonical user, next N tokens */
+# define CALLSUBR 0231 /* call another rewriting set */
+
+/* conditionals in macros */
+# define CONDIF 0232 /* conditional if-then */
+# define CONDELSE 0233 /* conditional else */
+# define CONDFI 0234 /* conditional fi */
+
+/* bracket characters for host name lookup */
+# define HOSTBEGIN 0235 /* hostname lookup begin */
+# define HOSTEND 0236 /* hostname lookup end */
+
+/* bracket characters for generalized lookup */
+# define LOOKUPBEGIN 0205 /* generalized lookup begin */
+# define LOOKUPEND 0206 /* generalized lookup end */
+
+/* macro substitution character */
+# define MACROEXPAND 0201 /* macro expansion */
+# define MACRODEXPAND 0202 /* deferred macro expansion */
+
+/* to make the code clearer */
+# define MATCHZERO CANONHOST
+
+/* external <==> internal mapping table */
+struct metamac
+{
+ char metaname; /* external code (after $) */
+ u_char metaval; /* internal code (as above) */
+};
+ /*
+** Name canonification short circuit.
+**
+** If the name server for a host is down, the process of trying to
+** canonify the name can hang. This is similar to (but alas, not
+** identical to) looking up the name for delivery. This stab type
+** caches the result of the name server lookup so we don't hang
+** multiple times.
+*/
+
+#define NAMECANON struct _namecanon
+
+NAMECANON
+{
+ short nc_errno; /* cached errno */
+ short nc_herrno; /* cached h_errno */
+ short nc_stat; /* cached exit status code */
+ short nc_flags; /* flag bits */
+ char *nc_cname; /* the canonical name */
+};
+
+/* values for nc_flags */
+#define NCF_VALID 0x0001 /* entry valid */
+ /*
+** Mapping functions
+**
+** These allow arbitrary mappings in the config file. The idea
+** (albeit not the implementation) comes from IDA sendmail.
+*/
+
+# define MAPCLASS struct _mapclass
+# define MAP struct _map
+
+
+/*
+** An actual map.
+*/
+
+MAP
+{
+ MAPCLASS *map_class; /* the class of this map */
+ char *map_mname; /* name of this map */
+ int map_mflags; /* flags, see below */
+ char *map_file; /* the (nominal) filename */
+ ARBPTR_T map_db1; /* the open database ptr */
+ ARBPTR_T map_db2; /* an "extra" database pointer */
+ char *map_app; /* to append to successful matches */
+ char *map_domain; /* the (nominal) NIS domain */
+ char *map_rebuild; /* program to run to do auto-rebuild */
+ time_t map_mtime; /* last database modification time */
+};
+
+/* bit values for map_flags */
+# define MF_VALID 0x0001 /* this entry is valid */
+# define MF_INCLNULL 0x0002 /* include null byte in key */
+# define MF_OPTIONAL 0x0004 /* don't complain if map not found */
+# define MF_NOFOLDCASE 0x0008 /* don't fold case in keys */
+# define MF_MATCHONLY 0x0010 /* don't use the map value */
+# define MF_OPEN 0x0020 /* this entry is open */
+# define MF_WRITABLE 0x0040 /* open for writing */
+# define MF_ALIAS 0x0080 /* this is an alias file */
+# define MF_TRY0NULL 0x0100 /* try with no null byte */
+# define MF_TRY1NULL 0x0200 /* try with the null byte */
+# define MF_LOCKED 0x0400 /* this map is currently locked */
+# define MF_ALIASWAIT 0x0800 /* alias map in aliaswait state */
+# define MF_IMPL_HASH 0x1000 /* implicit: underlying hash database */
+# define MF_IMPL_NDBM 0x2000 /* implicit: underlying NDBM database */
+
+
+/*
+** The class of a map -- essentially the functions to call
+*/
+
+MAPCLASS
+{
+ char *map_cname; /* name of this map class */
+ char *map_ext; /* extension for database file */
+ short map_cflags; /* flag bits, see below */
+ bool (*map_parse)__P((MAP *, char *));
+ /* argument parsing function */
+ char *(*map_lookup)__P((MAP *, char *, char **, int *));
+ /* lookup function */
+ void (*map_store)__P((MAP *, char *, char *));
+ /* store function */
+ bool (*map_open)__P((MAP *, int));
+ /* open function */
+ void (*map_close)__P((MAP *));
+ /* close function */
+};
+
+/* bit values for map_cflags */
+#define MCF_ALIASOK 0x0001 /* can be used for aliases */
+#define MCF_ALIASONLY 0x0002 /* usable only for aliases */
+#define MCF_REBUILDABLE 0x0004 /* can rebuild alias files */
+ /*
+** Symbol table definitions
+*/
+
+struct symtab
+{
+ char *s_name; /* name to be entered */
+ char s_type; /* general type (see below) */
+ struct symtab *s_next; /* pointer to next in chain */
+ union
+ {
+ BITMAP sv_class; /* bit-map of word classes */
+ ADDRESS *sv_addr; /* pointer to address header */
+ MAILER *sv_mailer; /* pointer to mailer */
+ char *sv_alias; /* alias */
+ MAPCLASS sv_mapclass; /* mapping function class */
+ MAP sv_map; /* mapping function */
+ char *sv_hostsig; /* host signature */
+ MCI sv_mci; /* mailer connection info */
+ NAMECANON sv_namecanon; /* canonical name cache */
+ } s_value;
+};
+
+typedef struct symtab STAB;
+
+/* symbol types */
+# define ST_UNDEF 0 /* undefined type */
+# define ST_CLASS 1 /* class map */
+# define ST_ADDRESS 2 /* an address in parsed format */
+# define ST_MAILER 3 /* a mailer header */
+# define ST_ALIAS 4 /* an alias */
+# define ST_MAPCLASS 5 /* mapping function class */
+# define ST_MAP 6 /* mapping function */
+# define ST_HOSTSIG 7 /* host signature */
+# define ST_NAMECANON 8 /* cached canonical name */
+# define ST_MCI 16 /* mailer connection info (offset) */
+
+# define s_class s_value.sv_class
+# define s_address s_value.sv_addr
+# define s_mailer s_value.sv_mailer
+# define s_alias s_value.sv_alias
+# define s_mci s_value.sv_mci
+# define s_mapclass s_value.sv_mapclass
+# define s_hostsig s_value.sv_hostsig
+# define s_map s_value.sv_map
+# define s_namecanon s_value.sv_namecanon
+
+extern STAB *stab __P((char *, int, int));
+extern void stabapply __P((void (*)(STAB *, int), int));
+
+/* opcodes to stab */
+# define ST_FIND 0 /* find entry */
+# define ST_ENTER 1 /* enter if not there */
+ /*
+** STRUCT EVENT -- event queue.
+**
+** Maintained in sorted order.
+**
+** We store the pid of the process that set this event to insure
+** that when we fork we will not take events intended for the parent.
+*/
+
+struct event
+{
+ time_t ev_time; /* time of the function call */
+ int (*ev_func)__P((int));
+ /* function to call */
+ int ev_arg; /* argument to ev_func */
+ int ev_pid; /* pid that set this event */
+ struct event *ev_link; /* link to next item */
+};
+
+typedef struct event EVENT;
+
+EXTERN EVENT *EventQueue; /* head of event queue */
+ /*
+** Operation, send, and error modes
+**
+** The operation mode describes the basic operation of sendmail.
+** This can be set from the command line, and is "send mail" by
+** default.
+**
+** The send mode tells how to send mail. It can be set in the
+** configuration file. It's setting determines how quickly the
+** mail will be delivered versus the load on your system. If the
+** -v (verbose) flag is given, it will be forced to SM_DELIVER
+** mode.
+**
+** The error mode tells how to return errors.
+*/
+
+EXTERN char OpMode; /* operation mode, see below */
+
+#define MD_DELIVER 'm' /* be a mail sender */
+#define MD_SMTP 's' /* run SMTP on standard input */
+#define MD_ARPAFTP 'a' /* obsolete ARPANET mode (Grey Book) */
+#define MD_DAEMON 'd' /* run as a daemon */
+#define MD_VERIFY 'v' /* verify: don't collect or deliver */
+#define MD_TEST 't' /* test mode: resolve addrs only */
+#define MD_INITALIAS 'i' /* initialize alias database */
+#define MD_PRINT 'p' /* print the queue */
+#define MD_FREEZE 'z' /* freeze the configuration file */
+
+
+/* values for e_sendmode -- send modes */
+#define SM_DELIVER 'i' /* interactive delivery */
+#define SM_QUICKD 'j' /* deliver w/o queueing */
+#define SM_FORK 'b' /* deliver in background */
+#define SM_QUEUE 'q' /* queue, don't deliver */
+#define SM_VERIFY 'v' /* verify only (used internally) */
+
+/* used only as a parameter to sendall */
+#define SM_DEFAULT '\0' /* unspecified, use SendMode */
+
+
+/* values for e_errormode -- error handling modes */
+#define EM_PRINT 'p' /* print errors */
+#define EM_MAIL 'm' /* mail back errors */
+#define EM_WRITE 'w' /* write back errors */
+#define EM_BERKNET 'e' /* special berknet processing */
+#define EM_QUIET 'q' /* don't print messages (stat only) */
+ /*
+** Additional definitions
+*/
+
+
+/*
+** Privacy flags
+** These are bit values for the PrivacyFlags word.
+*/
+
+#define PRIV_PUBLIC 0 /* what have I got to hide? */
+#define PRIV_NEEDMAILHELO 00001 /* insist on HELO for MAIL, at least */
+#define PRIV_NEEDEXPNHELO 00002 /* insist on HELO for EXPN */
+#define PRIV_NEEDVRFYHELO 00004 /* insist on HELO for VRFY */
+#define PRIV_NOEXPN 00010 /* disallow EXPN command entirely */
+#define PRIV_NOVRFY 00020 /* disallow VRFY command entirely */
+#define PRIV_AUTHWARNINGS 00040 /* flag possible authorization probs */
+#define PRIV_NORECEIPTS 00100 /* disallow return receipts */
+#define PRIV_RESTRICTMAILQ 01000 /* restrict mailq command */
+#define PRIV_RESTRICTQRUN 02000 /* restrict queue run */
+#define PRIV_GOAWAY 00777 /* don't give no info, anyway, anyhow */
+
+/* struct defining such things */
+struct prival
+{
+ char *pv_name; /* name of privacy flag */
+ int pv_flag; /* numeric level */
+};
+
+
+/*
+** Flags passed to remotename, parseaddr, allocaddr, and buildaddr.
+*/
+
+#define RF_SENDERADDR 0001 /* this is a sender address */
+#define RF_HEADERADDR 0002 /* this is a header address */
+#define RF_CANONICAL 0004 /* strip comment information */
+#define RF_ADDDOMAIN 0010 /* OK to do domain extension */
+#define RF_COPYPARSE 0020 /* copy parsed user & host */
+#define RF_COPYPADDR 0040 /* copy print address */
+#define RF_COPYALL (RF_COPYPARSE|RF_COPYPADDR)
+#define RF_COPYNONE 0
+
+
+/*
+** Flags passed to safefile.
+*/
+
+#define SFF_ANYFILE 0 /* no special restrictions */
+#define SFF_MUSTOWN 0x0001 /* user must own this file */
+#define SFF_NOSLINK 0x0002 /* file cannot be a symbolic link */
+#define SFF_ROOTOK 0x0004 /* ok for root to own this file */
+
+
+/*
+** Regular UNIX sockaddrs are too small to handle ISO addresses, so
+** we are forced to declare a supertype here.
+*/
+
+union bigsockaddr
+{
+ struct sockaddr sa; /* general version */
+#ifdef NETUNIX
+ struct sockaddr_un sunix; /* UNIX family */
+#endif
+#ifdef NETINET
+ struct sockaddr_in sin; /* INET family */
+#endif
+#ifdef NETISO
+ struct sockaddr_iso siso; /* ISO family */
+#endif
+#ifdef NETNS
+ struct sockaddr_ns sns; /* XNS family */
+#endif
+#ifdef NETX25
+ struct sockaddr_x25 sx25; /* X.25 family */
+#endif
+};
+
+#define SOCKADDR union bigsockaddr
+ /*
+** Global variables.
+*/
+
+EXTERN bool FromFlag; /* if set, "From" person is explicit */
+EXTERN bool MeToo; /* send to the sender also */
+EXTERN bool IgnrDot; /* don't let dot end messages */
+EXTERN bool SaveFrom; /* save leading "From" lines */
+EXTERN bool Verbose; /* set if blow-by-blow desired */
+EXTERN bool GrabTo; /* if set, get recipients from msg */
+EXTERN bool NoReturn; /* don't return letter to sender */
+EXTERN bool SuprErrs; /* set if we are suppressing errors */
+EXTERN bool HoldErrs; /* only output errors to transcript */
+EXTERN bool NoConnect; /* don't connect to non-local mailers */
+EXTERN bool SuperSafe; /* be extra careful, even if expensive */
+EXTERN bool ForkQueueRuns; /* fork for each job when running the queue */
+EXTERN bool AutoRebuild; /* auto-rebuild the alias database as needed */
+EXTERN bool CheckAliases; /* parse addresses during newaliases */
+EXTERN bool NoAlias; /* suppress aliasing */
+EXTERN bool UseNameServer; /* use internet domain name server */
+EXTERN bool SevenBit; /* force 7-bit data */
+EXTERN time_t SafeAlias; /* interval to wait until @:@ in alias file */
+EXTERN FILE *InChannel; /* input connection */
+EXTERN FILE *OutChannel; /* output connection */
+EXTERN uid_t RealUid; /* when Daemon, real uid of caller */
+EXTERN gid_t RealGid; /* when Daemon, real gid of caller */
+EXTERN uid_t DefUid; /* default uid to run as */
+EXTERN gid_t DefGid; /* default gid to run as */
+EXTERN char *DefUser; /* default user to run as (from DefUid) */
+EXTERN int OldUmask; /* umask when sendmail starts up */
+EXTERN int Errors; /* set if errors (local to single pass) */
+EXTERN int ExitStat; /* exit status code */
+EXTERN int AliasLevel; /* depth of aliasing */
+EXTERN int LineNumber; /* line number in current input */
+EXTERN int LogLevel; /* level of logging to perform */
+EXTERN int FileMode; /* mode on files */
+EXTERN int QueueLA; /* load average starting forced queueing */
+EXTERN int RefuseLA; /* load average refusing connections are */
+EXTERN int CurrentLA; /* current load average */
+EXTERN long QueueFactor; /* slope of queue function */
+EXTERN time_t QueueIntvl; /* intervals between running the queue */
+EXTERN char *HelpFile; /* location of SMTP help file */
+EXTERN char *ErrMsgFile; /* file to prepend to all error messages */
+EXTERN char *StatFile; /* location of statistics summary */
+EXTERN char *QueueDir; /* location of queue directory */
+EXTERN char *FileName; /* name to print on error messages */
+EXTERN char *SmtpPhase; /* current phase in SMTP processing */
+EXTERN char *MyHostName; /* name of this host for SMTP messages */
+EXTERN char *RealHostName; /* name of host we are talking to */
+EXTERN SOCKADDR RealHostAddr; /* address of host we are talking to */
+EXTERN char *CurHostName; /* current host we are dealing with */
+EXTERN jmp_buf TopFrame; /* branch-to-top-of-loop-on-error frame */
+EXTERN bool QuickAbort; /* .... but only if we want a quick abort */
+EXTERN bool LogUsrErrs; /* syslog user errors (e.g., SMTP RCPT cmd) */
+EXTERN bool SendMIMEErrors; /* send error messages in MIME format */
+EXTERN bool MatchGecos; /* look for user names in gecos field */
+EXTERN bool UseErrorsTo; /* use Errors-To: header (back compat) */
+EXTERN bool TryNullMXList; /* if we are the best MX, try host directly */
+extern bool CheckLoopBack; /* check for loopback on HELO packet */
+EXTERN bool InChild; /* true if running in an SMTP subprocess */
+EXTERN bool DisConnected; /* running with OutChannel redirected to xf */
+EXTERN char SpaceSub; /* substitution for <lwsp> */
+EXTERN int PrivacyFlags; /* privacy flags */
+EXTERN char *ConfFile; /* location of configuration file [conf.c] */
+extern char *PidFile; /* location of proc id file [conf.c] */
+extern ADDRESS NullAddress; /* a null (template) address [main.c] */
+EXTERN long WkClassFact; /* multiplier for message class -> priority */
+EXTERN long WkRecipFact; /* multiplier for # of recipients -> priority */
+EXTERN long WkTimeFact; /* priority offset each time this job is run */
+EXTERN char *UdbSpec; /* user database source spec */
+EXTERN int MaxHopCount; /* max # of hops until bounce */
+EXTERN int ConfigLevel; /* config file level */
+EXTERN char *TimeZoneSpec; /* override time zone specification */
+EXTERN char *ForwardPath; /* path to search for .forward files */
+EXTERN long MinBlocksFree; /* min # of blocks free on queue fs */
+EXTERN char *FallBackMX; /* fall back MX host */
+EXTERN long MaxMessageSize; /* advertised max size we will accept */
+EXTERN char *PostMasterCopy; /* address to get errs cc's */
+EXTERN int CheckpointInterval; /* queue file checkpoint interval */
+EXTERN bool DontPruneRoutes; /* don't prune source routes */
+extern bool BrokenSmtpPeers; /* peers can't handle 2-line greeting */
+EXTERN int MaxMciCache; /* maximum entries in MCI cache */
+EXTERN time_t MciCacheTimeout; /* maximum idle time on connections */
+EXTERN char *QueueLimitRecipient; /* limit queue runs to this recipient */
+EXTERN char *QueueLimitSender; /* limit queue runs to this sender */
+EXTERN char *QueueLimitId; /* limit queue runs to this id */
+EXTERN FILE *TrafficLogFile; /* file in which to log all traffic */
+extern int errno;
+
+
+/*
+** Timeouts
+**
+** Indicated values are the MINIMUM per RFC 1123 section 5.3.2.
+*/
+
+EXTERN struct
+{
+ /* RFC 1123-specified timeouts [minimum value] */
+ time_t to_initial; /* initial greeting timeout [5m] */
+ time_t to_mail; /* MAIL command [5m] */
+ time_t to_rcpt; /* RCPT command [5m] */
+ time_t to_datainit; /* DATA initiation [2m] */
+ time_t to_datablock; /* DATA block [3m] */
+ time_t to_datafinal; /* DATA completion [10m] */
+ time_t to_nextcommand; /* next command [5m] */
+ /* following timeouts are not mentioned in RFC 1123 */
+ time_t to_rset; /* RSET command */
+ time_t to_helo; /* HELO command */
+ time_t to_quit; /* QUIT command */
+ time_t to_miscshort; /* misc short commands (NOOP, VERB, etc) */
+ time_t to_ident; /* IDENT protocol requests */
+ /* following are per message */
+ time_t to_q_return; /* queue return timeout */
+ time_t to_q_warning; /* queue warning timeout */
+} TimeOuts;
+
+
+/*
+** Trace information
+*/
+
+/* trace vector and macros for debugging flags */
+EXTERN u_char tTdvect[100];
+# define tTd(flag, level) (tTdvect[flag] >= level)
+# define tTdlevel(flag) (tTdvect[flag])
+ /*
+** Miscellaneous information.
+*/
+
+
+
+/*
+** Some in-line functions
+*/
+
+/* set exit status */
+#define setstat(s) { \
+ if (ExitStat == EX_OK || ExitStat == EX_TEMPFAIL) \
+ ExitStat = s; \
+ }
+
+/* make a copy of a string */
+#define newstr(s) strcpy(xalloc(strlen(s) + 1), s)
+
+#define STRUCTCOPY(s, d) d = s
+
+
+/*
+** Declarations of useful functions
+*/
+
+extern ADDRESS *parseaddr __P((char *, ADDRESS *, int, int, char **, ENVELOPE *));
+extern char *xalloc __P((int));
+extern bool sameaddr __P((ADDRESS *, ADDRESS *));
+extern FILE *dfopen __P((char *, int, int));
+extern EVENT *setevent __P((time_t, int(*)(), int));
+extern char *sfgets __P((char *, int, FILE *, time_t, char *));
+extern char *queuename __P((ENVELOPE *, int));
+extern time_t curtime __P(());
+extern bool transienterror __P((int));
+extern const char *errstring __P((int));
+extern void expand __P((char *, char *, char *, ENVELOPE *));
+extern void define __P((int, char *, ENVELOPE *));
+extern char *macvalue __P((int, ENVELOPE *));
+extern char **prescan __P((char *, int, char[], int, char **));
+extern int rewrite __P((char **, int, int, ENVELOPE *));
+extern char *fgetfolded __P((char *, int, FILE *));
+extern ADDRESS *recipient __P((ADDRESS *, ADDRESS **, ENVELOPE *));
+extern ENVELOPE *newenvelope __P((ENVELOPE *, ENVELOPE *));
+extern void dropenvelope __P((ENVELOPE *));
+extern void clearenvelope __P((ENVELOPE *, int));
+extern char *username __P(());
+extern MCI *mci_get __P((char *, MAILER *));
+extern char *pintvl __P((time_t, int));
+extern char *map_rewrite __P((MAP *, char *, int, char **));
+extern ADDRESS *getctladdr __P((ADDRESS *));
+extern char *anynet_ntoa __P((SOCKADDR *));
+extern char *remotename __P((char *, MAILER *, int, int *, ENVELOPE *));
+extern bool shouldqueue __P((long, time_t));
+extern bool lockfile __P((int, char *, char *, int));
+extern char *hostsignature __P((MAILER *, char *, ENVELOPE *));
+extern void openxscript __P((ENVELOPE *));
+extern void closexscript __P((ENVELOPE *));
+extern sigfunc_t setsignal __P((int, sigfunc_t));
+extern char *shortenstring __P((char *, int));
+extern bool usershellok __P((char *));
+extern void commaize __P((HDR *, char *, int, MCI *, ENVELOPE *));
+
+/* ellipsis is a different case though */
+#ifdef __STDC__
+extern void auth_warning(ENVELOPE *, const char *, ...);
+extern void syserr(const char *, ...);
+extern void usrerr(const char *, ...);
+extern void message(const char *, ...);
+extern void nmessage(const char *, ...);
+#else
+extern void auth_warning();
+extern void syserr();
+extern void usrerr();
+extern void message();
+extern void nmessage();
+#endif
diff --git a/usr.sbin/sendmail/src/sendmail.hf b/usr.sbin/sendmail/src/sendmail.hf
new file mode 100644
index 0000000..142a7f5
--- /dev/null
+++ b/usr.sbin/sendmail/src/sendmail.hf
@@ -0,0 +1,58 @@
+cpyr
+cpyr Copyright (c) 1983 Eric P. Allman
+cpyr Copyright (c) 1988, 1993
+cpyr The Regents of the University of California. All rights reserved.
+cpyr
+cpyr @(#)sendmail.hf 8.2 (Berkeley) 7/16/93
+cpyr
+smtp Commands:
+smtp HELO EHLO MAIL RCPT DATA
+smtp RSET NOOP QUIT HELP VRFY
+smtp EXPN VERB
+smtp For more info use "HELP <topic>".
+smtp To report bugs in the implementation send email to
+smtp sendmail@CS.Berkeley.EDU.
+smtp For local information send email to Postmaster at your site.
+help HELP [ <topic> ]
+help The HELP command gives help info.
+helo HELO <hostname>
+helo Introduce yourself.
+ehlo EHLO <hostname>
+ehlo Introduce yourself, and request extended SMTP mode.
+mail MAIL FROM: <sender>
+mail Specifies the sender.
+rcpt RCPT TO: <recipient>
+rcpt Specifies the recipient. Can be used any number of times.
+data DATA
+data Following text is collected as the message.
+data End with a single dot.
+rset RSET
+rset Resets the system.
+quit QUIT
+quit Exit sendmail (SMTP).
+verb VERB
+verb Go into verbose mode. This sends 0xy responses that are
+verb are not RFC821 standard (but should be) They are recognized
+verb by humans and other sendmail implementations.
+vrfy VRFY <recipient>
+vrfy Verify an address. If you want to see what it aliases
+vrfy to, use EXPN instead.
+expn EXPN <recipient>
+expn Expand an address. If the address indicates a mailing
+expn list, return the contents of that list.
+noop NOOP
+noop Do nothing.
+send SEND FROM: <sender>
+send replaces the MAIL command, and can be used to send
+send directly to a users terminal. Not supported in this
+send implementation.
+soml SOML FROM: <sender>
+soml Send or mail. If the user is logged in, send directly,
+soml otherwise mail. Not supported in this implementation.
+saml SAML FROM: <sender>
+saml Send and mail. Send directly to the user's terminal,
+saml and also mail a letter. Not supported in this
+saml implementation.
+turn TURN
+turn Reverses the direction of the connection. Not currently
+turn implemented.
diff --git a/usr.sbin/sendmail/src/srvrsmtp.c b/usr.sbin/sendmail/src/srvrsmtp.c
new file mode 100644
index 0000000..eef525d
--- /dev/null
+++ b/usr.sbin/sendmail/src/srvrsmtp.c
@@ -0,0 +1,1032 @@
+/*
+ * Copyright (c) 1983 Eric P. Allman
+ * Copyright (c) 1988, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+# include "sendmail.h"
+
+#ifndef lint
+#ifdef SMTP
+static char sccsid[] = "@(#)srvrsmtp.c 8.37 (Berkeley) 4/13/94 (with SMTP)";
+#else
+static char sccsid[] = "@(#)srvrsmtp.c 8.37 (Berkeley) 4/13/94 (without SMTP)";
+#endif
+#endif /* not lint */
+
+# include <errno.h>
+
+# ifdef SMTP
+
+/*
+** SMTP -- run the SMTP protocol.
+**
+** Parameters:
+** none.
+**
+** Returns:
+** never.
+**
+** Side Effects:
+** Reads commands from the input channel and processes
+** them.
+*/
+
+struct cmd
+{
+ char *cmdname; /* command name */
+ int cmdcode; /* internal code, see below */
+};
+
+/* values for cmdcode */
+# define CMDERROR 0 /* bad command */
+# define CMDMAIL 1 /* mail -- designate sender */
+# define CMDRCPT 2 /* rcpt -- designate recipient */
+# define CMDDATA 3 /* data -- send message text */
+# define CMDRSET 4 /* rset -- reset state */
+# define CMDVRFY 5 /* vrfy -- verify address */
+# define CMDEXPN 6 /* expn -- expand address */
+# define CMDNOOP 7 /* noop -- do nothing */
+# define CMDQUIT 8 /* quit -- close connection and die */
+# define CMDHELO 9 /* helo -- be polite */
+# define CMDHELP 10 /* help -- give usage info */
+# define CMDEHLO 11 /* ehlo -- extended helo (RFC 1425) */
+/* non-standard commands */
+# define CMDONEX 16 /* onex -- sending one transaction only */
+# define CMDVERB 17 /* verb -- go into verbose mode */
+/* use this to catch and log "door handle" attempts on your system */
+# define CMDLOGBOGUS 23 /* bogus command that should be logged */
+/* debugging-only commands, only enabled if SMTPDEBUG is defined */
+# define CMDDBGQSHOW 24 /* showq -- show send queue */
+# define CMDDBGDEBUG 25 /* debug -- set debug mode */
+
+static struct cmd CmdTab[] =
+{
+ "mail", CMDMAIL,
+ "rcpt", CMDRCPT,
+ "data", CMDDATA,
+ "rset", CMDRSET,
+ "vrfy", CMDVRFY,
+ "expn", CMDEXPN,
+ "help", CMDHELP,
+ "noop", CMDNOOP,
+ "quit", CMDQUIT,
+ "helo", CMDHELO,
+ "ehlo", CMDEHLO,
+ "verb", CMDVERB,
+ "onex", CMDONEX,
+ /*
+ * remaining commands are here only
+ * to trap and log attempts to use them
+ */
+ "showq", CMDDBGQSHOW,
+ "debug", CMDDBGDEBUG,
+ "wiz", CMDLOGBOGUS,
+ NULL, CMDERROR,
+};
+
+bool OneXact = FALSE; /* one xaction only this run */
+char *CurSmtpClient; /* who's at the other end of channel */
+
+static char *skipword();
+extern char RealUserName[];
+
+
+#define MAXBADCOMMANDS 25 /* maximum number of bad commands */
+
+smtp(e)
+ register ENVELOPE *e;
+{
+ register char *p;
+ register struct cmd *c;
+ char *cmd;
+ auto ADDRESS *vrfyqueue;
+ ADDRESS *a;
+ bool gotmail; /* mail command received */
+ bool gothello; /* helo command received */
+ bool vrfy; /* set if this is a vrfy command */
+ char *protocol; /* sending protocol */
+ char *sendinghost; /* sending hostname */
+ unsigned long msize; /* approximate maximum message size */
+ char *peerhostname; /* name of SMTP peer or "localhost" */
+ auto char *delimptr;
+ char *id;
+ int nrcpts; /* number of RCPT commands */
+ bool doublequeue;
+ int badcommands = 0; /* count of bad commands */
+ char inp[MAXLINE];
+ char cmdbuf[MAXLINE];
+ extern char Version[];
+ extern ENVELOPE BlankEnvelope;
+
+ if (fileno(OutChannel) != fileno(stdout))
+ {
+ /* arrange for debugging output to go to remote host */
+ (void) dup2(fileno(OutChannel), fileno(stdout));
+ }
+ settime(e);
+ peerhostname = RealHostName;
+ if (peerhostname == NULL)
+ peerhostname = "localhost";
+ CurHostName = peerhostname;
+ CurSmtpClient = macvalue('_', e);
+ if (CurSmtpClient == NULL)
+ CurSmtpClient = CurHostName;
+
+ setproctitle("server %s startup", CurSmtpClient);
+ expand("\201e", inp, &inp[sizeof inp], e);
+ if (BrokenSmtpPeers)
+ {
+ p = strchr(inp, '\n');
+ if (p != NULL)
+ *p = '\0';
+ message("220 %s", inp);
+ }
+ else
+ {
+ char *q = inp;
+
+ while (q != NULL)
+ {
+ p = strchr(q, '\n');
+ if (p != NULL)
+ *p++ = '\0';
+ message("220-%s", q);
+ q = p;
+ }
+ message("220 ESMTP spoken here");
+ }
+ protocol = NULL;
+ sendinghost = macvalue('s', e);
+ gothello = FALSE;
+ gotmail = FALSE;
+ for (;;)
+ {
+ /* arrange for backout */
+ if (setjmp(TopFrame) > 0)
+ {
+ /* if() nesting is necessary for Cray UNICOS */
+ if (InChild)
+ {
+ QuickAbort = FALSE;
+ SuprErrs = TRUE;
+ finis();
+ }
+ }
+ QuickAbort = FALSE;
+ HoldErrs = FALSE;
+ LogUsrErrs = FALSE;
+ e->e_flags &= ~(EF_VRFYONLY|EF_GLOBALERRS);
+
+ /* setup for the read */
+ e->e_to = NULL;
+ Errors = 0;
+ (void) fflush(stdout);
+
+ /* read the input line */
+ SmtpPhase = "server cmd read";
+ setproctitle("server %s cmd read", CurHostName);
+ p = sfgets(inp, sizeof inp, InChannel, TimeOuts.to_nextcommand,
+ SmtpPhase);
+
+ /* handle errors */
+ if (p == NULL)
+ {
+ /* end of file, just die */
+ disconnect(1, e);
+ message("421 %s Lost input channel from %s",
+ MyHostName, CurSmtpClient);
+#ifdef LOG
+ if (LogLevel > (gotmail ? 1 : 19))
+ syslog(LOG_NOTICE, "lost input channel from %s",
+ CurSmtpClient);
+#endif
+ if (InChild)
+ ExitStat = EX_QUIT;
+ finis();
+ }
+
+ /* clean up end of line */
+ fixcrlf(inp, TRUE);
+
+ /* echo command to transcript */
+ if (e->e_xfp != NULL)
+ fprintf(e->e_xfp, "<<< %s\n", inp);
+
+ if (e->e_id == NULL)
+ setproctitle("%s: %.80s", CurSmtpClient, inp);
+ else
+ setproctitle("%s %s: %.80s", e->e_id, CurSmtpClient, inp);
+
+ /* break off command */
+ for (p = inp; isascii(*p) && isspace(*p); p++)
+ continue;
+ cmd = cmdbuf;
+ while (*p != '\0' &&
+ !(isascii(*p) && isspace(*p)) &&
+ cmd < &cmdbuf[sizeof cmdbuf - 2])
+ *cmd++ = *p++;
+ *cmd = '\0';
+
+ /* throw away leading whitespace */
+ while (isascii(*p) && isspace(*p))
+ p++;
+
+ /* decode command */
+ for (c = CmdTab; c->cmdname != NULL; c++)
+ {
+ if (!strcasecmp(c->cmdname, cmdbuf))
+ break;
+ }
+
+ /* reset errors */
+ errno = 0;
+
+ /* process command */
+ switch (c->cmdcode)
+ {
+ case CMDHELO: /* hello -- introduce yourself */
+ case CMDEHLO: /* extended hello */
+ if (c->cmdcode == CMDEHLO)
+ {
+ protocol = "ESMTP";
+ SmtpPhase = "server EHLO";
+ }
+ else
+ {
+ protocol = "SMTP";
+ SmtpPhase = "server HELO";
+ }
+ sendinghost = newstr(p);
+ gothello = TRUE;
+ if (c->cmdcode != CMDEHLO)
+ {
+ /* print old message and be done with it */
+ message("250 %s Hello %s, pleased to meet you",
+ MyHostName, CurSmtpClient);
+ break;
+ }
+
+ /* print extended message and brag */
+ message("250-%s Hello %s, pleased to meet you",
+ MyHostName, CurSmtpClient);
+ if (!bitset(PRIV_NOEXPN, PrivacyFlags))
+ message("250-EXPN");
+ if (MaxMessageSize > 0)
+ message("250-SIZE %ld", MaxMessageSize);
+ else
+ message("250-SIZE");
+ message("250 HELP");
+ break;
+
+ case CMDMAIL: /* mail -- designate sender */
+ SmtpPhase = "server MAIL";
+
+ /* check for validity of this command */
+ if (!gothello)
+ {
+ /* set sending host to our known value */
+ if (sendinghost == NULL)
+ sendinghost = peerhostname;
+
+ if (bitset(PRIV_NEEDMAILHELO, PrivacyFlags))
+ {
+ message("503 Polite people say HELO first");
+ break;
+ }
+ }
+ if (gotmail)
+ {
+ message("503 Sender already specified");
+ if (InChild)
+ finis();
+ break;
+ }
+ if (InChild)
+ {
+ errno = 0;
+ syserr("503 Nested MAIL command: MAIL %s", p);
+ finis();
+ }
+
+ /* fork a subprocess to process this command */
+ if (runinchild("SMTP-MAIL", e) > 0)
+ break;
+ if (!gothello)
+ {
+ auth_warning(e,
+ "Host %s didn't use HELO protocol",
+ peerhostname);
+ }
+#ifdef PICKY_HELO_CHECK
+ if (strcasecmp(sendinghost, peerhostname) != 0 &&
+ (strcasecmp(peerhostname, "localhost") != 0 ||
+ strcasecmp(sendinghost, MyHostName) != 0))
+ {
+ auth_warning(e, "Host %s claimed to be %s",
+ peerhostname, sendinghost);
+ }
+#endif
+
+ if (protocol == NULL)
+ protocol = "SMTP";
+ define('r', protocol, e);
+ define('s', sendinghost, e);
+ initsys(e);
+ nrcpts = 0;
+ e->e_flags |= EF_LOGSENDER;
+ setproctitle("%s %s: %.80s", e->e_id, CurSmtpClient, inp);
+
+ /* child -- go do the processing */
+ p = skipword(p, "from");
+ if (p == NULL)
+ break;
+ if (setjmp(TopFrame) > 0)
+ {
+ /* this failed -- undo work */
+ if (InChild)
+ {
+ QuickAbort = FALSE;
+ SuprErrs = TRUE;
+ e->e_flags &= ~EF_FATALERRS;
+ finis();
+ }
+ break;
+ }
+ QuickAbort = TRUE;
+
+ /* must parse sender first */
+ delimptr = NULL;
+ setsender(p, e, &delimptr, FALSE);
+ p = delimptr;
+ if (p != NULL && *p != '\0')
+ *p++ = '\0';
+
+ /* check for possible spoofing */
+ if (RealUid != 0 && OpMode == MD_SMTP &&
+ (e->e_from.q_mailer != LocalMailer &&
+ strcmp(e->e_from.q_user, RealUserName) != 0))
+ {
+ auth_warning(e, "%s owned process doing -bs",
+ RealUserName);
+ }
+
+ /* now parse ESMTP arguments */
+ msize = 0;
+ while (p != NULL && *p != '\0')
+ {
+ char *kp;
+ char *vp = NULL;
+
+ /* locate the beginning of the keyword */
+ while (isascii(*p) && isspace(*p))
+ p++;
+ if (*p == '\0')
+ break;
+ kp = p;
+
+ /* skip to the value portion */
+ while (isascii(*p) && isalnum(*p) || *p == '-')
+ p++;
+ if (*p == '=')
+ {
+ *p++ = '\0';
+ vp = p;
+
+ /* skip to the end of the value */
+ while (*p != '\0' && *p != ' ' &&
+ !(isascii(*p) && iscntrl(*p)) &&
+ *p != '=')
+ p++;
+ }
+
+ if (*p != '\0')
+ *p++ = '\0';
+
+ if (tTd(19, 1))
+ printf("MAIL: got arg %s=\"%s\"\n", kp,
+ vp == NULL ? "<null>" : vp);
+
+ if (strcasecmp(kp, "size") == 0)
+ {
+ if (vp == NULL)
+ {
+ usrerr("501 SIZE requires a value");
+ /* NOTREACHED */
+ }
+# ifdef __STDC__
+ msize = strtoul(vp, (char **) NULL, 10);
+# else
+ msize = strtol(vp, (char **) NULL, 10);
+# endif
+ }
+ else if (strcasecmp(kp, "body") == 0)
+ {
+ if (vp == NULL)
+ {
+ usrerr("501 BODY requires a value");
+ /* NOTREACHED */
+ }
+# ifdef MIME
+ if (strcasecmp(vp, "8bitmime") == 0)
+ {
+ e->e_bodytype = "8BITMIME";
+ SevenBit = FALSE;
+ }
+ else if (strcasecmp(vp, "7bit") == 0)
+ {
+ e->e_bodytype = "7BIT";
+ SevenBit = TRUE;
+ }
+ else
+ {
+ usrerr("501 Unknown BODY type %s",
+ vp);
+ }
+# endif
+ }
+ else
+ {
+ usrerr("501 %s parameter unrecognized", kp);
+ /* NOTREACHED */
+ }
+ }
+
+ if (MaxMessageSize > 0 && msize > MaxMessageSize)
+ {
+ usrerr("552 Message size exceeds fixed maximum message size (%ld)",
+ MaxMessageSize);
+ /* NOTREACHED */
+ }
+
+ if (!enoughspace(msize))
+ {
+ message("452 Insufficient disk space; try again later");
+ break;
+ }
+ message("250 Sender ok");
+ gotmail = TRUE;
+ break;
+
+ case CMDRCPT: /* rcpt -- designate recipient */
+ if (!gotmail)
+ {
+ usrerr("503 Need MAIL before RCPT");
+ break;
+ }
+ SmtpPhase = "server RCPT";
+ if (setjmp(TopFrame) > 0)
+ {
+ e->e_flags &= ~EF_FATALERRS;
+ break;
+ }
+ QuickAbort = TRUE;
+ LogUsrErrs = TRUE;
+
+ if (e->e_sendmode != SM_DELIVER)
+ e->e_flags |= EF_VRFYONLY;
+
+ p = skipword(p, "to");
+ if (p == NULL)
+ break;
+ a = parseaddr(p, NULLADDR, RF_COPYALL, ' ', NULL, e);
+ if (a == NULL)
+ break;
+ a->q_flags |= QPRIMARY;
+ a = recipient(a, &e->e_sendqueue, e);
+ if (Errors != 0)
+ break;
+
+ /* no errors during parsing, but might be a duplicate */
+ e->e_to = p;
+ if (!bitset(QBADADDR, a->q_flags))
+ {
+ message("250 Recipient ok%s",
+ bitset(QQUEUEUP, a->q_flags) ?
+ " (will queue)" : "");
+ nrcpts++;
+ }
+ else
+ {
+ /* punt -- should keep message in ADDRESS.... */
+ message("550 Addressee unknown");
+ }
+ e->e_to = NULL;
+ break;
+
+ case CMDDATA: /* data -- text of mail */
+ SmtpPhase = "server DATA";
+ if (!gotmail)
+ {
+ message("503 Need MAIL command");
+ break;
+ }
+ else if (nrcpts <= 0)
+ {
+ message("503 Need RCPT (recipient)");
+ break;
+ }
+
+ /* check to see if we need to re-expand aliases */
+ /* also reset QBADADDR on already-diagnosted addrs */
+ doublequeue = FALSE;
+ for (a = e->e_sendqueue; a != NULL; a = a->q_next)
+ {
+ if (bitset(QVERIFIED, a->q_flags))
+ {
+ /* need to re-expand aliases */
+ doublequeue = TRUE;
+ }
+ if (bitset(QBADADDR, a->q_flags))
+ {
+ /* make this "go away" */
+ a->q_flags |= QDONTSEND;
+ a->q_flags &= ~QBADADDR;
+ }
+ }
+
+ /* collect the text of the message */
+ SmtpPhase = "collect";
+ collect(TRUE, doublequeue, e);
+ if (Errors != 0)
+ goto abortmessage;
+ HoldErrs = TRUE;
+
+ /*
+ ** Arrange to send to everyone.
+ ** If sending to multiple people, mail back
+ ** errors rather than reporting directly.
+ ** In any case, don't mail back errors for
+ ** anything that has happened up to
+ ** now (the other end will do this).
+ ** Truncate our transcript -- the mail has gotten
+ ** to us successfully, and if we have
+ ** to mail this back, it will be easier
+ ** on the reader.
+ ** Then send to everyone.
+ ** Finally give a reply code. If an error has
+ ** already been given, don't mail a
+ ** message back.
+ ** We goose error returns by clearing error bit.
+ */
+
+ SmtpPhase = "delivery";
+ if (nrcpts != 1 && !doublequeue)
+ {
+ HoldErrs = TRUE;
+ e->e_errormode = EM_MAIL;
+ }
+ e->e_xfp = freopen(queuename(e, 'x'), "w", e->e_xfp);
+ id = e->e_id;
+
+ /* send to all recipients */
+ sendall(e, doublequeue ? SM_QUEUE : SM_DEFAULT);
+ e->e_to = NULL;
+
+ /* issue success if appropriate and reset */
+ if (Errors == 0 || HoldErrs)
+ message("250 %s Message accepted for delivery", id);
+
+ if (bitset(EF_FATALERRS, e->e_flags) && !HoldErrs)
+ {
+ /* avoid sending back an extra message */
+ e->e_flags &= ~EF_FATALERRS;
+ e->e_flags |= EF_CLRQUEUE;
+ }
+ else
+ {
+ /* from now on, we have to operate silently */
+ HoldErrs = TRUE;
+ e->e_errormode = EM_MAIL;
+
+ /* if we just queued, poke it */
+ if (doublequeue && e->e_sendmode != SM_QUEUE)
+ {
+ extern pid_t dowork();
+
+ unlockqueue(e);
+ (void) dowork(id, TRUE, TRUE, e);
+ }
+ }
+
+ abortmessage:
+ /* if in a child, pop back to our parent */
+ if (InChild)
+ finis();
+
+ /* clean up a bit */
+ gotmail = FALSE;
+ dropenvelope(e);
+ CurEnv = e = newenvelope(e, CurEnv);
+ e->e_flags = BlankEnvelope.e_flags;
+ break;
+
+ case CMDRSET: /* rset -- reset state */
+ message("250 Reset state");
+ e->e_flags |= EF_CLRQUEUE;
+ if (InChild)
+ finis();
+
+ /* clean up a bit */
+ gotmail = FALSE;
+ dropenvelope(e);
+ CurEnv = e = newenvelope(e, CurEnv);
+ break;
+
+ case CMDVRFY: /* vrfy -- verify address */
+ case CMDEXPN: /* expn -- expand address */
+ vrfy = c->cmdcode == CMDVRFY;
+ if (bitset(vrfy ? PRIV_NOVRFY : PRIV_NOEXPN,
+ PrivacyFlags))
+ {
+ if (vrfy)
+ message("252 Who's to say?");
+ else
+ message("502 Sorry, we do not allow this operation");
+#ifdef LOG
+ if (LogLevel > 5)
+ syslog(LOG_INFO, "%s: %s [rejected]",
+ CurSmtpClient, inp);
+#endif
+ break;
+ }
+ else if (!gothello &&
+ bitset(vrfy ? PRIV_NEEDVRFYHELO : PRIV_NEEDEXPNHELO,
+ PrivacyFlags))
+ {
+ message("503 I demand that you introduce yourself first");
+ break;
+ }
+ if (runinchild(vrfy ? "SMTP-VRFY" : "SMTP-EXPN", e) > 0)
+ break;
+#ifdef LOG
+ if (LogLevel > 5)
+ syslog(LOG_INFO, "%s: %s", CurSmtpClient, inp);
+#endif
+ vrfyqueue = NULL;
+ QuickAbort = TRUE;
+ if (vrfy)
+ e->e_flags |= EF_VRFYONLY;
+ while (*p != '\0' && isascii(*p) && isspace(*p))
+ *p++;
+ if (*p == '\0')
+ {
+ message("501 Argument required");
+ Errors++;
+ }
+ else
+ {
+ (void) sendtolist(p, NULLADDR, &vrfyqueue, e);
+ }
+ if (Errors != 0)
+ {
+ if (InChild)
+ finis();
+ break;
+ }
+ if (vrfyqueue == NULL)
+ {
+ message("554 Nothing to %s", vrfy ? "VRFY" : "EXPN");
+ }
+ while (vrfyqueue != NULL)
+ {
+ a = vrfyqueue;
+ while ((a = a->q_next) != NULL &&
+ bitset(QDONTSEND|QBADADDR, a->q_flags))
+ continue;
+ if (!bitset(QDONTSEND|QBADADDR, vrfyqueue->q_flags))
+ printvrfyaddr(vrfyqueue, a == NULL);
+ vrfyqueue = vrfyqueue->q_next;
+ }
+ if (InChild)
+ finis();
+ break;
+
+ case CMDHELP: /* help -- give user info */
+ help(p);
+ break;
+
+ case CMDNOOP: /* noop -- do nothing */
+ message("250 OK");
+ break;
+
+ case CMDQUIT: /* quit -- leave mail */
+ message("221 %s closing connection", MyHostName);
+
+doquit:
+ /* avoid future 050 messages */
+ disconnect(1, e);
+
+ if (InChild)
+ ExitStat = EX_QUIT;
+ finis();
+
+ case CMDVERB: /* set verbose mode */
+ if (bitset(PRIV_NOEXPN, PrivacyFlags))
+ {
+ /* this would give out the same info */
+ message("502 Verbose unavailable");
+ break;
+ }
+ Verbose = TRUE;
+ e->e_sendmode = SM_DELIVER;
+ message("250 Verbose mode");
+ break;
+
+ case CMDONEX: /* doing one transaction only */
+ OneXact = TRUE;
+ message("250 Only one transaction");
+ break;
+
+# ifdef SMTPDEBUG
+ case CMDDBGQSHOW: /* show queues */
+ printf("Send Queue=");
+ printaddr(e->e_sendqueue, TRUE);
+ break;
+
+ case CMDDBGDEBUG: /* set debug mode */
+ tTsetup(tTdvect, sizeof tTdvect, "0-99.1");
+ tTflag(p);
+ message("200 Debug set");
+ break;
+
+# else /* not SMTPDEBUG */
+ case CMDDBGQSHOW: /* show queues */
+ case CMDDBGDEBUG: /* set debug mode */
+# endif /* SMTPDEBUG */
+ case CMDLOGBOGUS: /* bogus command */
+# ifdef LOG
+ if (LogLevel > 0)
+ syslog(LOG_CRIT,
+ "\"%s\" command from %s (%s)",
+ c->cmdname, peerhostname,
+ anynet_ntoa(&RealHostAddr));
+# endif
+ /* FALL THROUGH */
+
+ case CMDERROR: /* unknown command */
+ if (++badcommands > MAXBADCOMMANDS)
+ {
+ message("421 %s Too many bad commands; closing connection",
+ MyHostName);
+ goto doquit;
+ }
+
+ message("500 Command unrecognized");
+ break;
+
+ default:
+ errno = 0;
+ syserr("500 smtp: unknown code %d", c->cmdcode);
+ break;
+ }
+ }
+}
+ /*
+** SKIPWORD -- skip a fixed word.
+**
+** Parameters:
+** p -- place to start looking.
+** w -- word to skip.
+**
+** Returns:
+** p following w.
+** NULL on error.
+**
+** Side Effects:
+** clobbers the p data area.
+*/
+
+static char *
+skipword(p, w)
+ register char *p;
+ char *w;
+{
+ register char *q;
+ char *firstp = p;
+
+ /* find beginning of word */
+ while (isascii(*p) && isspace(*p))
+ p++;
+ q = p;
+
+ /* find end of word */
+ while (*p != '\0' && *p != ':' && !(isascii(*p) && isspace(*p)))
+ p++;
+ while (isascii(*p) && isspace(*p))
+ *p++ = '\0';
+ if (*p != ':')
+ {
+ syntax:
+ message("501 Syntax error in parameters scanning \"%s\"",
+ firstp);
+ Errors++;
+ return (NULL);
+ }
+ *p++ = '\0';
+ while (isascii(*p) && isspace(*p))
+ p++;
+
+ if (*p == '\0')
+ goto syntax;
+
+ /* see if the input word matches desired word */
+ if (strcasecmp(q, w))
+ goto syntax;
+
+ return (p);
+}
+ /*
+** PRINTVRFYADDR -- print an entry in the verify queue
+**
+** Parameters:
+** a -- the address to print
+** last -- set if this is the last one.
+**
+** Returns:
+** none.
+**
+** Side Effects:
+** Prints the appropriate 250 codes.
+*/
+
+printvrfyaddr(a, last)
+ register ADDRESS *a;
+ bool last;
+{
+ char fmtbuf[20];
+
+ strcpy(fmtbuf, "250");
+ fmtbuf[3] = last ? ' ' : '-';
+
+ if (a->q_fullname == NULL)
+ {
+ if (strchr(a->q_user, '@') == NULL)
+ strcpy(&fmtbuf[4], "<%s@%s>");
+ else
+ strcpy(&fmtbuf[4], "<%s>");
+ message(fmtbuf, a->q_user, MyHostName);
+ }
+ else
+ {
+ if (strchr(a->q_user, '@') == NULL)
+ strcpy(&fmtbuf[4], "%s <%s@%s>");
+ else
+ strcpy(&fmtbuf[4], "%s <%s>");
+ message(fmtbuf, a->q_fullname, a->q_user, MyHostName);
+ }
+}
+ /*
+** HELP -- implement the HELP command.
+**
+** Parameters:
+** topic -- the topic we want help for.
+**
+** Returns:
+** none.
+**
+** Side Effects:
+** outputs the help file to message output.
+*/
+
+help(topic)
+ char *topic;
+{
+ register FILE *hf;
+ int len;
+ char buf[MAXLINE];
+ bool noinfo;
+
+ if (HelpFile == NULL || (hf = fopen(HelpFile, "r")) == NULL)
+ {
+ /* no help */
+ errno = 0;
+ message("502 HELP not implemented");
+ return;
+ }
+
+ if (topic == NULL || *topic == '\0')
+ topic = "smtp";
+ else
+ makelower(topic);
+
+ len = strlen(topic);
+ noinfo = TRUE;
+
+ while (fgets(buf, sizeof buf, hf) != NULL)
+ {
+ if (strncmp(buf, topic, len) == 0)
+ {
+ register char *p;
+
+ p = strchr(buf, '\t');
+ if (p == NULL)
+ p = buf;
+ else
+ p++;
+ fixcrlf(p, TRUE);
+ message("214-%s", p);
+ noinfo = FALSE;
+ }
+ }
+
+ if (noinfo)
+ message("504 HELP topic unknown");
+ else
+ message("214 End of HELP info");
+ (void) fclose(hf);
+}
+ /*
+** RUNINCHILD -- return twice -- once in the child, then in the parent again
+**
+** Parameters:
+** label -- a string used in error messages
+**
+** Returns:
+** zero in the child
+** one in the parent
+**
+** Side Effects:
+** none.
+*/
+
+runinchild(label, e)
+ char *label;
+ register ENVELOPE *e;
+{
+ int childpid;
+
+ if (!OneXact)
+ {
+ childpid = dofork();
+ if (childpid < 0)
+ {
+ syserr("%s: cannot fork", label);
+ return (1);
+ }
+ if (childpid > 0)
+ {
+ auto int st;
+
+ /* parent -- wait for child to complete */
+ setproctitle("server %s child wait", CurHostName);
+ st = waitfor(childpid);
+ if (st == -1)
+ syserr("%s: lost child", label);
+ else if (!WIFEXITED(st))
+ syserr("%s: died on signal %d",
+ label, st & 0177);
+
+ /* if we exited on a QUIT command, complete the process */
+ if (WEXITSTATUS(st) == EX_QUIT)
+ {
+ disconnect(1, e);
+ finis();
+ }
+
+ return (1);
+ }
+ else
+ {
+ /* child */
+ InChild = TRUE;
+ QuickAbort = FALSE;
+ clearenvelope(e, FALSE);
+ }
+ }
+
+ /* open alias database */
+ initmaps(FALSE, e);
+
+ return (0);
+}
+
+# endif /* SMTP */
diff --git a/usr.sbin/sendmail/src/stab.c b/usr.sbin/sendmail/src/stab.c
new file mode 100644
index 0000000..07893e5
--- /dev/null
+++ b/usr.sbin/sendmail/src/stab.c
@@ -0,0 +1,166 @@
+/*
+ * Copyright (c) 1983 Eric P. Allman
+ * Copyright (c) 1988, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)stab.c 8.1 (Berkeley) 6/7/93";
+#endif /* not lint */
+
+# include "sendmail.h"
+
+/*
+** STAB -- manage the symbol table
+**
+** Parameters:
+** name -- the name to be looked up or inserted.
+** type -- the type of symbol.
+** op -- what to do:
+** ST_ENTER -- enter the name if not
+** already present.
+** ST_FIND -- find it only.
+**
+** Returns:
+** pointer to a STAB entry for this name.
+** NULL if not found and not entered.
+**
+** Side Effects:
+** can update the symbol table.
+*/
+
+# define STABSIZE 400
+
+static STAB *SymTab[STABSIZE];
+
+STAB *
+stab(name, type, op)
+ char *name;
+ int type;
+ int op;
+{
+ register STAB *s;
+ register STAB **ps;
+ register int hfunc;
+ register char *p;
+ extern char lower();
+
+ if (tTd(36, 5))
+ printf("STAB: %s %d ", name, type);
+
+ /*
+ ** Compute the hashing function
+ **
+ ** We could probably do better....
+ */
+
+ hfunc = type;
+ for (p = name; *p != '\0'; p++)
+ hfunc = (((hfunc << 7) | lower(*p)) & 077777) % STABSIZE;
+
+ if (tTd(36, 9))
+ printf("(hfunc=%d) ", hfunc);
+
+ ps = &SymTab[hfunc];
+ while ((s = *ps) != NULL && (strcasecmp(name, s->s_name) || s->s_type != type))
+ ps = &s->s_next;
+
+ /*
+ ** Dispose of the entry.
+ */
+
+ if (s != NULL || op == ST_FIND)
+ {
+ if (tTd(36, 5))
+ {
+ if (s == NULL)
+ printf("not found\n");
+ else
+ {
+ long *lp = (long *) s->s_class;
+
+ printf("type %d val %lx %lx %lx %lx\n",
+ s->s_type, lp[0], lp[1], lp[2], lp[3]);
+ }
+ }
+ return (s);
+ }
+
+ /*
+ ** Make a new entry and link it in.
+ */
+
+ if (tTd(36, 5))
+ printf("entered\n");
+
+ /* make new entry */
+ s = (STAB *) xalloc(sizeof *s);
+ bzero((char *) s, sizeof *s);
+ s->s_name = newstr(name);
+ makelower(s->s_name);
+ s->s_type = type;
+
+ /* link it in */
+ *ps = s;
+
+ return (s);
+}
+ /*
+** STABAPPLY -- apply function to all stab entries
+**
+** Parameters:
+** func -- the function to apply. It will be given one
+** parameter (the stab entry).
+** arg -- an arbitrary argument, passed to func.
+**
+** Returns:
+** none.
+*/
+
+void
+stabapply(func, arg)
+ void (*func)__P((STAB *, int));
+ int arg;
+{
+ register STAB **shead;
+ register STAB *s;
+
+ for (shead = SymTab; shead < &SymTab[STABSIZE]; shead++)
+ {
+ for (s = *shead; s != NULL; s = s->s_next)
+ {
+ if (tTd(38, 90))
+ printf("stabapply: trying %d/%s\n",
+ s->s_type, s->s_name);
+ func(s, arg);
+ }
+ }
+}
diff --git a/usr.sbin/sendmail/src/stats.c b/usr.sbin/sendmail/src/stats.c
new file mode 100644
index 0000000..2dc6827
--- /dev/null
+++ b/usr.sbin/sendmail/src/stats.c
@@ -0,0 +1,130 @@
+/*
+ * Copyright (c) 1983 Eric P. Allman
+ * Copyright (c) 1988, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)stats.c 8.3 (Berkeley) 8/28/93";
+#endif /* not lint */
+
+# include "sendmail.h"
+# include "mailstats.h"
+
+struct statistics Stat;
+
+bool GotStats = FALSE; /* set when we have stats to merge */
+
+#define ONE_K 1000 /* one thousand (twenty-four?) */
+#define KBYTES(x) (((x) + (ONE_K - 1)) / ONE_K)
+ /*
+** MARKSTATS -- mark statistics
+*/
+
+markstats(e, to)
+ register ENVELOPE *e;
+ register ADDRESS *to;
+{
+ if (to == NULL)
+ {
+ if (e->e_from.q_mailer != NULL)
+ {
+ Stat.stat_nf[e->e_from.q_mailer->m_mno]++;
+ Stat.stat_bf[e->e_from.q_mailer->m_mno] +=
+ KBYTES(e->e_msgsize);
+ }
+ }
+ else
+ {
+ Stat.stat_nt[to->q_mailer->m_mno]++;
+ Stat.stat_bt[to->q_mailer->m_mno] += KBYTES(e->e_msgsize);
+ }
+ GotStats = TRUE;
+}
+ /*
+** POSTSTATS -- post statistics in the statistics file
+**
+** Parameters:
+** sfile -- the name of the statistics file.
+**
+** Returns:
+** none.
+**
+** Side Effects:
+** merges the Stat structure with the sfile file.
+*/
+
+poststats(sfile)
+ char *sfile;
+{
+ register int fd;
+ struct statistics stat;
+ extern off_t lseek();
+
+ if (sfile == NULL || !GotStats)
+ return;
+
+ (void) time(&Stat.stat_itime);
+ Stat.stat_size = sizeof Stat;
+
+ fd = open(sfile, O_RDWR);
+ if (fd < 0)
+ {
+ errno = 0;
+ return;
+ }
+ (void) lockfile(fd, sfile, NULL, LOCK_EX);
+ if (read(fd, (char *) &stat, sizeof stat) == sizeof stat &&
+ stat.stat_size == sizeof stat)
+ {
+ /* merge current statistics into statfile */
+ register int i;
+
+ for (i = 0; i < MAXMAILERS; i++)
+ {
+ stat.stat_nf[i] += Stat.stat_nf[i];
+ stat.stat_bf[i] += Stat.stat_bf[i];
+ stat.stat_nt[i] += Stat.stat_nt[i];
+ stat.stat_bt[i] += Stat.stat_bt[i];
+ }
+ }
+ else
+ bcopy((char *) &Stat, (char *) &stat, sizeof stat);
+
+ /* write out results */
+ (void) lseek(fd, (off_t) 0, 0);
+ (void) write(fd, (char *) &stat, sizeof stat);
+ (void) close(fd);
+
+ /* clear the structure to avoid future disappointment */
+ bzero(&Stat, sizeof stat);
+ GotStats = FALSE;
+}
diff --git a/usr.sbin/sendmail/src/sysexits.c b/usr.sbin/sendmail/src/sysexits.c
new file mode 100644
index 0000000..fff3783
--- /dev/null
+++ b/usr.sbin/sendmail/src/sysexits.c
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 1983 Eric P. Allman
+ * Copyright (c) 1988, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)sysexits.c 8.1 (Berkeley) 6/7/93";
+#endif /* not lint */
+
+#include <sysexits.h>
+
+/*
+** SYSEXITS.C -- error messages corresponding to sysexits.h
+**
+** If the first character of the string is a colon, interpolate
+** the current errno after the rest of the string.
+*/
+
+char *SysExMsg[] =
+{
+ /* 64 USAGE */ " 500 Bad usage",
+ /* 65 DATAERR */ " 501 Data format error",
+ /* 66 NOINPUT */ ":550 Cannot open input",
+ /* 67 NOUSER */ " 550 User unknown",
+ /* 68 NOHOST */ " 550 Host unknown",
+ /* 69 UNAVAILABLE */ " 554 Service unavailable",
+ /* 70 SOFTWARE */ ":554 Internal error",
+ /* 71 OSERR */ ":451 Operating system error",
+ /* 72 OSFILE */ ":554 System file missing",
+ /* 73 CANTCREAT */ ":550 Can't create output",
+ /* 74 IOERR */ ":451 I/O error",
+ /* 75 TEMPFAIL */ " 250 Deferred",
+ /* 76 PROTOCOL */ " 554 Remote protocol error",
+ /* 77 NOPERM */ ":550 Insufficient permission",
+ /* 78 CONFIG */ " 554 Local configuration error",
+};
+
+int N_SysEx = sizeof(SysExMsg) / sizeof(SysExMsg[0]);
diff --git a/usr.sbin/sendmail/src/trace.c b/usr.sbin/sendmail/src/trace.c
new file mode 100644
index 0000000..29421ee
--- /dev/null
+++ b/usr.sbin/sendmail/src/trace.c
@@ -0,0 +1,131 @@
+/*
+ * Copyright (c) 1983 Eric P. Allman
+ * Copyright (c) 1988, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)trace.c 8.2 (Berkeley) 3/14/94";
+#endif /* not lint */
+
+# include "sendmail.h"
+
+/*
+** TtSETUP -- set up for trace package.
+**
+** Parameters:
+** vect -- pointer to trace vector.
+** size -- number of flags in trace vector.
+** defflags -- flags to set if no value given.
+**
+** Returns:
+** none
+**
+** Side Effects:
+** environment is set up.
+*/
+
+u_char *tTvect;
+int tTsize;
+static char *DefFlags;
+
+tTsetup(vect, size, defflags)
+ u_char *vect;
+ int size;
+ char *defflags;
+{
+ tTvect = vect;
+ tTsize = size;
+ DefFlags = defflags;
+}
+ /*
+** TtFLAG -- process an external trace flag description.
+**
+** Parameters:
+** s -- the trace flag.
+**
+** Returns:
+** none.
+**
+** Side Effects:
+** sets/clears trace flags.
+*/
+
+tTflag(s)
+ register char *s;
+{
+ unsigned int first, last;
+ register unsigned int i;
+
+ if (*s == '\0')
+ s = DefFlags;
+
+ for (;;)
+ {
+ /* find first flag to set */
+ i = 0;
+ while (isdigit(*s))
+ i = i * 10 + (*s++ - '0');
+ first = i;
+
+ /* find last flag to set */
+ if (*s == '-')
+ {
+ i = 0;
+ while (isdigit(*++s))
+ i = i * 10 + (*s - '0');
+ }
+ last = i;
+
+ /* find the level to set it to */
+ i = 1;
+ if (*s == '.')
+ {
+ i = 0;
+ while (isdigit(*++s))
+ i = i * 10 + (*s - '0');
+ }
+
+ /* clean up args */
+ if (first >= tTsize)
+ first = tTsize - 1;
+ if (last >= tTsize)
+ last = tTsize - 1;
+
+ /* set the flags */
+ while (first <= last)
+ tTvect[first++] = i;
+
+ /* more arguments? */
+ if (*s++ == '\0')
+ return;
+ }
+}
diff --git a/usr.sbin/sendmail/src/udb.c b/usr.sbin/sendmail/src/udb.c
new file mode 100644
index 0000000..7887cb3
--- /dev/null
+++ b/usr.sbin/sendmail/src/udb.c
@@ -0,0 +1,985 @@
+/*
+ * Copyright (c) 1983 Eric P. Allman
+ * Copyright (c) 1988, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "sendmail.h"
+
+#ifndef lint
+#ifdef USERDB
+static char sccsid [] = "@(#)udb.c 8.8 (Berkeley) 4/14/94 (with USERDB)";
+#else
+static char sccsid [] = "@(#)udb.c 8.8 (Berkeley) 4/14/94 (without USERDB)";
+#endif
+#endif
+
+#ifdef USERDB
+
+#include <errno.h>
+#include <netdb.h>
+#include <db.h>
+
+#ifdef HESIOD
+#include <hesiod.h>
+#endif /* HESIOD */
+
+/*
+** UDB.C -- interface between sendmail and Berkeley User Data Base.
+**
+** This depends on the 4.4BSD db package.
+*/
+
+
+struct udbent
+{
+ char *udb_spec; /* string version of spec */
+ int udb_type; /* type of entry */
+ char *udb_default; /* default host for outgoing mail */
+ union
+ {
+ /* type UE_REMOTE -- do remote call for lookup */
+ struct
+ {
+ struct sockaddr_in _udb_addr; /* address */
+ int _udb_timeout; /* timeout */
+ } udb_remote;
+#define udb_addr udb_u.udb_remote._udb_addr
+#define udb_timeout udb_u.udb_remote._udb_timeout
+
+ /* type UE_FORWARD -- forward message to remote */
+ struct
+ {
+ char *_udb_fwdhost; /* name of forward host */
+ } udb_forward;
+#define udb_fwdhost udb_u.udb_forward._udb_fwdhost
+
+ /* type UE_FETCH -- lookup in local database */
+ struct
+ {
+ char *_udb_dbname; /* pathname of database */
+ DB *_udb_dbp; /* open database ptr */
+ } udb_lookup;
+#define udb_dbname udb_u.udb_lookup._udb_dbname
+#define udb_dbp udb_u.udb_lookup._udb_dbp
+ } udb_u;
+};
+
+#define UDB_EOLIST 0 /* end of list */
+#define UDB_SKIP 1 /* skip this entry */
+#define UDB_REMOTE 2 /* look up in remote database */
+#define UDB_DBFETCH 3 /* look up in local database */
+#define UDB_FORWARD 4 /* forward to remote host */
+#define UDB_HESIOD 5 /* look up via hesiod */
+
+#define MAXUDBENT 10 /* maximum number of UDB entries */
+
+
+struct option
+{
+ char *name;
+ char *val;
+};
+ /*
+** UDBEXPAND -- look up user in database and expand
+**
+** Parameters:
+** a -- address to expand.
+** sendq -- pointer to head of sendq to put the expansions in.
+**
+** Returns:
+** EX_TEMPFAIL -- if something "odd" happened -- probably due
+** to accessing a file on an NFS server that is down.
+** EX_OK -- otherwise.
+**
+** Side Effects:
+** Modifies sendq.
+*/
+
+int UdbPort = 1616;
+int UdbTimeout = 10;
+
+struct udbent UdbEnts[MAXUDBENT + 1];
+int UdbSock = -1;
+bool UdbInitialized = FALSE;
+
+int
+udbexpand(a, sendq, e)
+ register ADDRESS *a;
+ ADDRESS **sendq;
+ register ENVELOPE *e;
+{
+ int i;
+ register char *p;
+ DBT key;
+ DBT info;
+ bool breakout;
+ register struct udbent *up;
+ int keylen;
+ int naddrs;
+ char keybuf[MAXKEY];
+ char buf[BUFSIZ];
+
+ if (tTd(28, 1))
+ printf("udbexpand(%s)\n", a->q_paddr);
+
+ /* make certain we are supposed to send to this address */
+ if (bitset(QDONTSEND|QVERIFIED, a->q_flags))
+ return EX_OK;
+ e->e_to = a->q_paddr;
+
+ /* on first call, locate the database */
+ if (!UdbInitialized)
+ {
+ extern int _udbx_init();
+
+ if (_udbx_init() == EX_TEMPFAIL)
+ return EX_TEMPFAIL;
+ }
+
+ /* short circuit the process if no chance of a match */
+ if (UdbSpec == NULL || UdbSpec[0] == '\0')
+ return EX_OK;
+
+ /* short circuit name begins with '\\' since it can't possibly match */
+ if (a->q_user[0] == '\\')
+ return EX_OK;
+
+ /* if name is too long, assume it won't match */
+ if (strlen(a->q_user) > sizeof keybuf - 12)
+ return EX_OK;
+
+ /* if name begins with a colon, it indicates our metadata */
+ if (a->q_user[0] == ':')
+ return EX_OK;
+
+ /* build actual database key */
+ (void) strcpy(keybuf, a->q_user);
+ (void) strcat(keybuf, ":maildrop");
+ keylen = strlen(keybuf);
+
+ breakout = FALSE;
+ for (up = UdbEnts; !breakout; up++)
+ {
+ char *user;
+
+ /*
+ ** Select action based on entry type.
+ **
+ ** On dropping out of this switch, "class" should
+ ** explain the type of the data, and "user" should
+ ** contain the user information.
+ */
+
+ switch (up->udb_type)
+ {
+ case UDB_DBFETCH:
+ key.data = keybuf;
+ key.size = keylen;
+ if (tTd(28, 80))
+ printf("udbexpand: trying %s (%d) via db\n",
+ keybuf, keylen);
+ i = (*up->udb_dbp->seq)(up->udb_dbp, &key, &info, R_CURSOR);
+ if (i > 0 || info.size <= 0)
+ {
+ if (tTd(28, 2))
+ printf("udbexpand: no match on %s (%d)\n",
+ keybuf, keylen);
+ continue;
+ }
+ if (tTd(28, 80))
+ printf("udbexpand: match %.*s: %.*s\n",
+ key.size, key.data, info.size, info.data);
+
+ naddrs = 0;
+ a->q_flags &= ~QSELFREF;
+ while (i == 0 && key.size == keylen &&
+ bcmp(key.data, keybuf, keylen) == 0)
+ {
+ if (bitset(EF_VRFYONLY, e->e_flags))
+ {
+ a->q_flags |= QVERIFIED;
+ e->e_nrcpts++;
+ return EX_OK;
+ }
+
+ breakout = TRUE;
+ if (info.size < sizeof buf)
+ user = buf;
+ else
+ user = xalloc(info.size + 1);
+ bcopy(info.data, user, info.size);
+ user[info.size] = '\0';
+
+ message("expanded to %s", user);
+#ifdef LOG
+ if (LogLevel >= 10)
+ syslog(LOG_INFO, "%s: expand %s => %s",
+ e->e_id, e->e_to, user);
+#endif
+ AliasLevel++;
+ naddrs += sendtolist(user, a, sendq, e);
+ AliasLevel--;
+
+ if (user != buf)
+ free(user);
+
+ /* get the next record */
+ i = (*up->udb_dbp->seq)(up->udb_dbp, &key, &info, R_NEXT);
+ }
+
+ /* if nothing ever matched, try next database */
+ if (!breakout)
+ continue;
+
+ if (naddrs > 0 && !bitset(QSELFREF, a->q_flags))
+ {
+ if (tTd(28, 5))
+ {
+ printf("udbexpand: QDONTSEND ");
+ printaddr(a, FALSE);
+ }
+ a->q_flags |= QDONTSEND;
+ }
+ if (i < 0)
+ {
+ syserr("udbexpand: db-get %.*s stat %d",
+ key.size, key.data, i);
+ return EX_TEMPFAIL;
+ }
+
+ /*
+ ** If this address has a -request address, reflect
+ ** it into the envelope.
+ */
+
+ (void) strcpy(keybuf, a->q_user);
+ (void) strcat(keybuf, ":mailsender");
+ keylen = strlen(keybuf);
+ key.data = keybuf;
+ key.size = keylen;
+ i = (*up->udb_dbp->get)(up->udb_dbp, &key, &info, 0);
+ if (i != 0 || info.size <= 0)
+ break;
+ a->q_owner = xalloc(info.size + 1);
+ bcopy(info.data, a->q_owner, info.size);
+ a->q_owner[info.size] = '\0';
+
+ /* announce delivery; NORECEIPT bit set later */
+ if (e->e_xfp != NULL)
+ {
+ fprintf(e->e_xfp,
+ "Message delivered to mailing list %s\n",
+ a->q_paddr);
+ e->e_flags |= EF_SENDRECEIPT;
+ }
+ break;
+
+#ifdef HESIOD
+ case UDB_HESIOD:
+ key.data = keybuf;
+ key.size = keylen;
+ if (tTd(28, 80))
+ printf("udbexpand: trying %s (%d) via hesiod\n",
+ keybuf, keylen);
+ /* look up the key via hesiod */
+ i = hes_udb_get(&key, &info);
+ if (i > 0 || info.size <= 0)
+ {
+ if (tTd(28, 2))
+ printf("udbexpand: no match on %s (%d)\n",
+ keybuf, keylen);
+ continue;
+ }
+ if (tTd(28, 80))
+ printf("udbexpand: match %.*s: %.*s\n",
+ key.size, key.data, info.size, info.data);
+ a->q_flags &= ~QSELFREF;
+
+ if (bitset(EF_VRFYONLY, e->e_flags))
+ {
+ a->q_flags |= QVERIFIED;
+ e->e_nrcpts++;
+ free(info.data);
+ return EX_OK;
+ }
+
+ breakout = TRUE;
+ if (info.size < sizeof buf)
+ user = buf;
+ else
+ user = xalloc(info.size + 1);
+ bcopy(info.data, user, info.size);
+ user[info.size] = '\0';
+ free(info.data);
+
+ message("hesioded to %s", user);
+#ifdef LOG
+ if (LogLevel >= 10)
+ syslog(LOG_INFO, "%s: hesiod %s => %s",
+ e->e_id, e->e_to, user);
+#endif
+ AliasLevel++;
+ naddrs = sendtolist(user, a, sendq, e);
+ AliasLevel--;
+
+ if (user != buf)
+ free(user);
+
+ if (naddrs > 0 && !bitset(QSELFREF, a->q_flags))
+ {
+ if (tTd(28, 5))
+ {
+ printf("udbexpand: QDONTSEND ");
+ printaddr(a, FALSE);
+ }
+ a->q_flags |= QDONTSEND;
+ }
+ if (i < 0)
+ {
+ syserr("udbexpand: hesiod-get %.*s stat %d",
+ key.size, key.data, i);
+ return EX_TEMPFAIL;
+ }
+
+ /*
+ ** If this address has a -request address, reflect
+ ** it into the envelope.
+ */
+
+ (void) strcpy(keybuf, a->q_user);
+ (void) strcat(keybuf, ":mailsender");
+ keylen = strlen(keybuf);
+ key.data = keybuf;
+ key.size = keylen;
+ i = hes_udb_get(&key, &info);
+ if (i != 0 || info.size <= 0)
+ break;
+ a->q_owner = xalloc(info.size + 1);
+ bcopy(info.data, a->q_owner, info.size);
+ a->q_owner[info.size] = '\0';
+ free(info.data);
+ break;
+#endif /* HESIOD */
+
+ case UDB_REMOTE:
+ /* not yet implemented */
+ continue;
+
+ case UDB_FORWARD:
+ if (bitset(EF_VRFYONLY, e->e_flags))
+ return EX_OK;
+ i = strlen(up->udb_fwdhost) + strlen(a->q_user) + 1;
+ if (i < sizeof buf)
+ user = buf;
+ else
+ user = xalloc(i + 1);
+ (void) sprintf(user, "%s@%s", a->q_user, up->udb_fwdhost);
+ message("expanded to %s", user);
+ a->q_flags &= ~QSELFREF;
+ AliasLevel++;
+ naddrs = sendtolist(user, a, sendq, e);
+ AliasLevel--;
+ if (naddrs > 0 && !bitset(QSELFREF, a->q_flags))
+ {
+ if (tTd(28, 5))
+ {
+ printf("udbexpand: QDONTSEND ");
+ printaddr(a, FALSE);
+ }
+ a->q_flags |= QDONTSEND;
+ }
+ if (user != buf)
+ free(user);
+ breakout = TRUE;
+ break;
+
+ case UDB_EOLIST:
+ breakout = TRUE;
+ continue;
+
+ default:
+ /* unknown entry type */
+ continue;
+ }
+ }
+ return EX_OK;
+}
+ /*
+** UDBSENDER -- return canonical external name of sender, given local name
+**
+** Parameters:
+** sender -- the name of the sender on the local machine.
+**
+** Returns:
+** The external name for this sender, if derivable from the
+** database.
+** NULL -- if nothing is changed from the database.
+**
+** Side Effects:
+** none.
+*/
+
+char *
+udbsender(sender)
+ char *sender;
+{
+ extern char *udbmatch();
+
+ return udbmatch(sender, "mailname");
+}
+
+
+char *
+udbmatch(user, field)
+ char *user;
+ char *field;
+{
+ register char *p;
+ register struct udbent *up;
+ int i;
+ int keylen;
+ DBT key, info;
+ char keybuf[MAXKEY];
+
+ if (tTd(28, 1))
+ printf("udbmatch(%s, %s)\n", user, field);
+
+ if (!UdbInitialized)
+ {
+ if (_udbx_init() == EX_TEMPFAIL)
+ return NULL;
+ }
+
+ /* short circuit if no spec */
+ if (UdbSpec == NULL || UdbSpec[0] == '\0')
+ return NULL;
+
+ /* short circuit name begins with '\\' since it can't possibly match */
+ if (user[0] == '\\')
+ return NULL;
+
+ /* long names can never match and are a pain to deal with */
+ if ((strlen(user) + strlen(field)) > sizeof keybuf - 4)
+ return NULL;
+
+ /* names beginning with colons indicate metadata */
+ if (user[0] == ':')
+ return NULL;
+
+ /* build database key */
+ (void) strcpy(keybuf, user);
+ (void) strcat(keybuf, ":");
+ (void) strcat(keybuf, field);
+ keylen = strlen(keybuf);
+
+ for (up = UdbEnts; up->udb_type != UDB_EOLIST; up++)
+ {
+ /*
+ ** Select action based on entry type.
+ */
+
+ switch (up->udb_type)
+ {
+ case UDB_DBFETCH:
+ key.data = keybuf;
+ key.size = keylen;
+ i = (*up->udb_dbp->get)(up->udb_dbp, &key, &info, 0);
+ if (i != 0 || info.size <= 0)
+ {
+ if (tTd(28, 2))
+ printf("udbmatch: no match on %s (%d) via db\n",
+ keybuf, keylen);
+ continue;
+ }
+
+ p = xalloc(info.size + 1);
+ bcopy(info.data, p, info.size);
+ p[info.size] = '\0';
+ if (tTd(28, 1))
+ printf("udbmatch ==> %s\n", p);
+ return p;
+ break;
+
+#ifdef HESIOD
+ case UDB_HESIOD:
+ key.data = keybuf;
+ key.size = keylen;
+ i = hes_udb_get(&key, &info);
+ if (i != 0 || info.size <= 0)
+ {
+ if (tTd(28, 2))
+ printf("udbmatch: no match on %s (%d) via hesiod\n",
+ keybuf, keylen);
+ continue;
+ }
+
+ p = xalloc(info.size + 1);
+ bcopy(info.data, p, info.size);
+ p[info.size] = '\0';
+ free(info.data);
+ if (tTd(28, 1))
+ printf("udbmatch ==> %s\n", p);
+ return p;
+ break;
+#endif /* HESIOD */
+ }
+ }
+
+ if (strcmp(field, "mailname") != 0)
+ return NULL;
+
+ /*
+ ** Nothing yet. Search again for a default case. But only
+ ** use it if we also have a forward (:maildrop) pointer already
+ ** in the database.
+ */
+
+ /* build database key */
+ (void) strcpy(keybuf, user);
+ (void) strcat(keybuf, ":maildrop");
+ keylen = strlen(keybuf);
+
+ for (up = UdbEnts; up->udb_type != UDB_EOLIST; up++)
+ {
+ switch (up->udb_type)
+ {
+ case UDB_DBFETCH:
+ /* get the default case for this database */
+ if (up->udb_default == NULL)
+ {
+ key.data = ":default:mailname";
+ key.size = strlen(key.data);
+ i = (*up->udb_dbp->get)(up->udb_dbp, &key, &info, 0);
+ if (i != 0 || info.size <= 0)
+ {
+ /* no default case */
+ up->udb_default = "";
+ continue;
+ }
+
+ /* save the default case */
+ up->udb_default = xalloc(info.size + 1);
+ bcopy(info.data, up->udb_default, info.size);
+ up->udb_default[info.size] = '\0';
+ }
+ else if (up->udb_default[0] == '\0')
+ continue;
+
+ /* we have a default case -- verify user:maildrop */
+ key.data = keybuf;
+ key.size = keylen;
+ i = (*up->udb_dbp->get)(up->udb_dbp, &key, &info, 0);
+ if (i != 0 || info.size <= 0)
+ {
+ /* nope -- no aliasing for this user */
+ continue;
+ }
+
+ /* they exist -- build the actual address */
+ p = xalloc(strlen(user) + strlen(up->udb_default) + 2);
+ (void) strcpy(p, user);
+ (void) strcat(p, "@");
+ (void) strcat(p, up->udb_default);
+ if (tTd(28, 1))
+ printf("udbmatch ==> %s\n", p);
+ return p;
+ break;
+
+#ifdef HESIOD
+ case UDB_HESIOD:
+ /* get the default case for this database */
+ if (up->udb_default == NULL)
+ {
+ key.data = ":default:mailname";
+ key.size = strlen(key.data);
+ i = hes_udb_get(&key, &info);
+
+ if (i != 0 || info.size <= 0)
+ {
+ /* no default case */
+ up->udb_default = "";
+ continue;
+ }
+
+ /* save the default case */
+ up->udb_default = xalloc(info.size + 1);
+ bcopy(info.data, up->udb_default, info.size);
+ up->udb_default[info.size] = '\0';
+ free(info.data);
+ }
+ else if (up->udb_default[0] == '\0')
+ continue;
+
+ /* we have a default case -- verify user:maildrop */
+ key.data = keybuf;
+ key.size = keylen;
+ i = hes_udb_get(&key, &info);
+ if (i != 0 || info.size <= 0)
+ {
+ /* nope -- no aliasing for this user */
+ continue;
+ }
+
+ free(info.data);
+ /* they exist -- build the actual address */
+ p = xalloc(strlen(user) + strlen(up->udb_default) + 2);
+ (void) strcpy(p, user);
+ (void) strcat(p, "@");
+ (void) strcat(p, up->udb_default);
+ if (tTd(28, 1))
+ printf("udbmatch ==> %s\n", p);
+ return p;
+ break;
+#endif /* HESIOD */
+ }
+ }
+
+ /* still nothing.... too bad */
+ return NULL;
+}
+ /*
+** _UDBX_INIT -- parse the UDB specification, opening any valid entries.
+**
+** Parameters:
+** none.
+**
+** Returns:
+** EX_TEMPFAIL -- if it appeared it couldn't get hold of a
+** database due to a host being down or some similar
+** (recoverable) situation.
+** EX_OK -- otherwise.
+**
+** Side Effects:
+** Fills in the UdbEnts structure from UdbSpec.
+*/
+
+#define MAXUDBOPTS 27
+
+int
+_udbx_init()
+{
+ register char *p;
+ int i;
+ register struct udbent *up;
+ char buf[BUFSIZ];
+
+ if (UdbInitialized)
+ return EX_OK;
+
+# ifdef UDB_DEFAULT_SPEC
+ if (UdbSpec == NULL)
+ UdbSpec = UDB_DEFAULT_SPEC;
+# endif
+
+ p = UdbSpec;
+ up = UdbEnts;
+ while (p != NULL)
+ {
+ char *spec;
+ auto int rcode;
+ int nopts;
+ int nmx;
+ register struct hostent *h;
+ char *mxhosts[MAXMXHOSTS + 1];
+ struct option opts[MAXUDBOPTS + 1];
+
+ while (*p == ' ' || *p == '\t' || *p == ',')
+ p++;
+ if (*p == '\0')
+ break;
+ spec = p;
+ p = strchr(p, ',');
+ if (p != NULL)
+ *p++ = '\0';
+
+ /* extract options */
+ nopts = _udb_parsespec(spec, opts, MAXUDBOPTS);
+
+ /*
+ ** Decode database specification.
+ **
+ ** In the sendmail tradition, the leading character
+ ** defines the semantics of the rest of the entry.
+ **
+ ** +hostname -- send a datagram to the udb server
+ ** on host "hostname" asking for the
+ ** home mail server for this user.
+ ** *hostname -- similar to +hostname, except that the
+ ** hostname is searched as an MX record;
+ ** resulting hosts are searched as for
+ ** +mxhostname. If no MX host is found,
+ ** this is the same as +hostname.
+ ** @hostname -- forward email to the indicated host.
+ ** This should be the last in the list,
+ ** since it always matches the input.
+ ** /dbname -- search the named database on the local
+ ** host using the Berkeley db package.
+ */
+
+ switch (*spec)
+ {
+ case '+': /* search remote database */
+ case '*': /* search remote database (expand MX) */
+ if (*spec == '*')
+ {
+#if NAMED_BIND
+ nmx = getmxrr(spec + 1, mxhosts, FALSE, &rcode);
+#else
+ mxhosts[0] = spec + 1;
+ nmx = 1;
+ rcode = 0;
+#endif
+ if (tTd(28, 16))
+ {
+ int i;
+
+ printf("getmxrr(%s): %d", spec + 1, nmx);
+ for (i = 0; i <= nmx; i++)
+ printf(" %s", mxhosts[i]);
+ printf("\n");
+ }
+ }
+ else
+ {
+ nmx = 1;
+ mxhosts[0] = spec + 1;
+ }
+
+ for (i = 0; i < nmx; i++)
+ {
+ h = gethostbyname(mxhosts[i]);
+ if (h == NULL)
+ continue;
+ up->udb_type = UDB_REMOTE;
+ up->udb_addr.sin_family = h->h_addrtype;
+ bcopy(h->h_addr_list[0],
+ (char *) &up->udb_addr.sin_addr,
+ sizeof up->udb_addr.sin_addr);
+ up->udb_addr.sin_port = UdbPort;
+ up->udb_timeout = UdbTimeout;
+ up++;
+ }
+
+ /* set up a datagram socket */
+ if (UdbSock < 0)
+ {
+ UdbSock = socket(AF_INET, SOCK_DGRAM, 0);
+ (void) fcntl(UdbSock, F_SETFD, 1);
+ }
+ break;
+
+ case '@': /* forward to remote host */
+ up->udb_type = UDB_FORWARD;
+ up->udb_fwdhost = spec + 1;
+ up++;
+ break;
+
+ case 'h': /* use hesiod */
+ case 'H':
+#ifdef HESIOD
+ if (strcasecmp(spec, "hesiod") != 0)
+ break;
+ up->udb_type = UDB_HESIOD;
+ up++;
+#endif /* HESIOD */
+ break;
+
+ case '/': /* look up remote name */
+ up->udb_dbname = spec;
+ errno = 0;
+ up->udb_dbp = dbopen(spec, O_RDONLY, 0644, DB_BTREE, NULL);
+ if (up->udb_dbp == NULL)
+ {
+ if (errno != ENOENT && errno != EACCES)
+ {
+#ifdef LOG
+ if (LogLevel > 2)
+ syslog(LOG_ERR, "dbopen(%s): %s",
+ spec, errstring(errno));
+#endif
+ up->udb_type = UDB_EOLIST;
+ goto tempfail;
+ }
+ break;
+ }
+ up->udb_type = UDB_DBFETCH;
+ up++;
+ break;
+ }
+ }
+ up->udb_type = UDB_EOLIST;
+
+ if (tTd(28, 4))
+ {
+ for (up = UdbEnts; up->udb_type != UDB_EOLIST; up++)
+ {
+ switch (up->udb_type)
+ {
+ case UDB_REMOTE:
+ printf("REMOTE: addr %s, timeo %d\n",
+ anynet_ntoa((SOCKADDR *) &up->udb_addr),
+ up->udb_timeout);
+ break;
+
+ case UDB_DBFETCH:
+ printf("FETCH: file %s\n",
+ up->udb_dbname);
+ break;
+
+ case UDB_FORWARD:
+ printf("FORWARD: host %s\n",
+ up->udb_fwdhost);
+ break;
+
+ case UDB_HESIOD:
+ printf("HESIOD\n");
+ break;
+
+ default:
+ printf("UNKNOWN\n");
+ break;
+ }
+ }
+ }
+
+ UdbInitialized = TRUE;
+ errno = 0;
+ return EX_OK;
+
+ /*
+ ** On temporary failure, back out anything we've already done
+ */
+
+ tempfail:
+ for (up = UdbEnts; up->udb_type != UDB_EOLIST; up++)
+ {
+ if (up->udb_type == UDB_DBFETCH)
+ {
+ (*up->udb_dbp->close)(up->udb_dbp);
+ }
+ }
+ return EX_TEMPFAIL;
+}
+
+int
+_udb_parsespec(udbspec, opt, maxopts)
+ char *udbspec;
+ struct option opt[];
+ int maxopts;
+{
+ register char *spec;
+ register char *spec_end;
+ register int optnum;
+
+ spec_end = strchr(udbspec, ':');
+ for (optnum = 0; optnum < maxopts && (spec = spec_end) != NULL; optnum++)
+ {
+ register char *p;
+
+ while (isascii(*spec) && isspace(*spec))
+ spec++;
+ spec_end = strchr(spec, ':');
+ if (spec_end != NULL)
+ *spec_end++ = '\0';
+
+ opt[optnum].name = spec;
+ opt[optnum].val = NULL;
+ p = strchr(spec, '=');
+ if (p != NULL)
+ opt[optnum].val = ++p;
+ }
+ return optnum;
+}
+
+#ifdef HESIOD
+
+int
+hes_udb_get(key, info)
+ DBT *key;
+ DBT *info;
+{
+ char *name, *type;
+ char *p, **hp;
+
+ name = key->data;
+ type = strchr(name, ':');
+ if (type == NULL)
+ return 1;
+
+ *type++ = '\0';
+
+ if (tTd(28, 1))
+ printf("hes_udb_get(%s, %s)\n", name, type);
+
+ /* make the hesiod query */
+ hp = hes_resolve(name, type);
+ if (hp == NULL)
+ {
+ /* network problem or timeout */
+ if (hes_error() == HES_ER_NET)
+ return -1;
+
+ return 1;
+ }
+ else
+ {
+ /*
+ ** If there are multiple matches, just return the
+ ** first one and free the others.
+ **
+ ** XXX These should really be returned; for example,
+ ** XXX it is legal for :maildrop to be multi-valued.
+ */
+
+ for (p = hp[1]; p; p++)
+ free(p);
+
+ info->data = hp[0];
+ info->size = (size_t) strlen(info->data);
+ }
+
+ return 0;
+}
+#endif /* HESIOD */
+
+#else /* not USERDB */
+
+int
+udbexpand(a, sendq, e)
+ ADDRESS *a;
+ ADDRESS **sendq;
+ ENVELOPE *e;
+{
+ return EX_OK;
+}
+
+#endif /* USERDB */
diff --git a/usr.sbin/sendmail/src/useful.h b/usr.sbin/sendmail/src/useful.h
new file mode 100644
index 0000000..ba33a79
--- /dev/null
+++ b/usr.sbin/sendmail/src/useful.h
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 1988, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)useful.h 8.2 (Berkeley) 9/24/93
+ */
+
+# include <sys/types.h>
+
+/* support for bool type */
+typedef char bool;
+# define TRUE 1
+# define FALSE 0
+
+# ifndef NULL
+# define NULL 0
+# endif /* NULL */
+
+/* bit hacking */
+# define bitset(bit, word) (((word) & (bit)) != 0)
+
+/* some simple functions */
+# ifndef max
+# define max(a, b) ((a) > (b) ? (a) : (b))
+# define min(a, b) ((a) < (b) ? (a) : (b))
+# endif
+
+/* assertions */
+# ifndef NASSERT
+# define ASSERT(expr, msg, parm)\
+ if (!(expr))\
+ {\
+ fprintf(stderr, "assertion botch: %s:%d: ", __FILE__, __LINE__);\
+ fprintf(stderr, msg, parm);\
+ }
+# else /* NASSERT */
+# define ASSERT(expr, msg, parm)
+# endif /* NASSERT */
+
+/* sccs id's */
+# ifndef lint
+# ifdef __STDC__
+# define SCCSID(arg) static char SccsId[] = #arg;
+# else
+# define SCCSID(arg) static char SccsId[] = "arg";
+# endif
+# else
+# define SCCSID(arg)
+# endif
diff --git a/usr.sbin/sendmail/src/usersmtp.c b/usr.sbin/sendmail/src/usersmtp.c
new file mode 100644
index 0000000..06acd3f
--- /dev/null
+++ b/usr.sbin/sendmail/src/usersmtp.c
@@ -0,0 +1,905 @@
+/*
+ * Copyright (c) 1983 Eric P. Allman
+ * Copyright (c) 1988, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+# include "sendmail.h"
+
+#ifndef lint
+#ifdef SMTP
+static char sccsid[] = "@(#)usersmtp.c 8.18 (Berkeley) 1/24/94 (with SMTP)";
+#else
+static char sccsid[] = "@(#)usersmtp.c 8.18 (Berkeley) 1/24/94 (without SMTP)";
+#endif
+#endif /* not lint */
+
+# include <sysexits.h>
+# include <errno.h>
+
+# ifdef SMTP
+
+/*
+** USERSMTP -- run SMTP protocol from the user end.
+**
+** This protocol is described in RFC821.
+*/
+
+#define REPLYTYPE(r) ((r) / 100) /* first digit of reply code */
+#define REPLYCLASS(r) (((r) / 10) % 10) /* second digit of reply code */
+#define SMTPCLOSING 421 /* "Service Shutting Down" */
+
+char SmtpMsgBuffer[MAXLINE]; /* buffer for commands */
+char SmtpReplyBuffer[MAXLINE]; /* buffer for replies */
+char SmtpError[MAXLINE] = ""; /* save failure error messages */
+int SmtpPid; /* pid of mailer */
+bool SmtpNeedIntro; /* need "while talking" in transcript */
+
+#ifdef __STDC__
+extern smtpmessage(char *f, MAILER *m, MCI *mci, ...);
+#endif
+ /*
+** SMTPINIT -- initialize SMTP.
+**
+** Opens the connection and sends the initial protocol.
+**
+** Parameters:
+** m -- mailer to create connection to.
+** pvp -- pointer to parameter vector to pass to
+** the mailer.
+**
+** Returns:
+** none.
+**
+** Side Effects:
+** creates connection and sends initial protocol.
+*/
+
+smtpinit(m, mci, e)
+ struct mailer *m;
+ register MCI *mci;
+ ENVELOPE *e;
+{
+ register int r;
+ register char *p;
+ extern void esmtp_check();
+ extern void helo_options();
+
+ if (tTd(18, 1))
+ {
+ printf("smtpinit ");
+ mci_dump(mci, FALSE);
+ }
+
+ /*
+ ** Open the connection to the mailer.
+ */
+
+ SmtpError[0] = '\0';
+ CurHostName = mci->mci_host; /* XXX UGLY XXX */
+ SmtpNeedIntro = TRUE;
+ switch (mci->mci_state)
+ {
+ case MCIS_ACTIVE:
+ /* need to clear old information */
+ smtprset(m, mci, e);
+ /* fall through */
+
+ case MCIS_OPEN:
+ return;
+
+ case MCIS_ERROR:
+ case MCIS_SSD:
+ /* shouldn't happen */
+ smtpquit(m, mci, e);
+ /* fall through */
+
+ case MCIS_CLOSED:
+ syserr("451 smtpinit: state CLOSED");
+ return;
+
+ case MCIS_OPENING:
+ break;
+ }
+
+ mci->mci_state = MCIS_OPENING;
+
+ /*
+ ** Get the greeting message.
+ ** This should appear spontaneously. Give it five minutes to
+ ** happen.
+ */
+
+ SmtpPhase = mci->mci_phase = "client greeting";
+ setproctitle("%s %s: %s", e->e_id, CurHostName, mci->mci_phase);
+ r = reply(m, mci, e, TimeOuts.to_initial, esmtp_check);
+ if (r < 0 || REPLYTYPE(r) == 4)
+ goto tempfail1;
+ if (REPLYTYPE(r) != 2)
+ goto unavailable;
+
+ /*
+ ** Send the HELO command.
+ ** My mother taught me to always introduce myself.
+ */
+
+ if (bitnset(M_ESMTP, m->m_flags))
+ mci->mci_flags |= MCIF_ESMTP;
+
+tryhelo:
+ if (bitset(MCIF_ESMTP, mci->mci_flags))
+ {
+ smtpmessage("EHLO %s", m, mci, MyHostName);
+ SmtpPhase = mci->mci_phase = "client EHLO";
+ }
+ else
+ {
+ smtpmessage("HELO %s", m, mci, MyHostName);
+ SmtpPhase = mci->mci_phase = "client HELO";
+ }
+ setproctitle("%s %s: %s", e->e_id, CurHostName, mci->mci_phase);
+ r = reply(m, mci, e, TimeOuts.to_helo, helo_options);
+ if (r < 0)
+ goto tempfail1;
+ else if (REPLYTYPE(r) == 5)
+ {
+ if (bitset(MCIF_ESMTP, mci->mci_flags))
+ {
+ /* try old SMTP instead */
+ mci->mci_flags &= ~MCIF_ESMTP;
+ goto tryhelo;
+ }
+ goto unavailable;
+ }
+ else if (REPLYTYPE(r) != 2)
+ goto tempfail1;
+
+ /*
+ ** Check to see if we actually ended up talking to ourself.
+ ** This means we didn't know about an alias or MX, or we managed
+ ** to connect to an echo server.
+ **
+ ** If this code remains at all, "CheckLoopBack" should be
+ ** a mailer flag. This is a MAYBENEXTRELEASE feature.
+ */
+
+ p = strchr(&SmtpReplyBuffer[4], ' ');
+ if (p != NULL)
+ *p = '\0';
+ if (CheckLoopBack && strcasecmp(&SmtpReplyBuffer[4], MyHostName) == 0)
+ {
+ syserr("553 %s config error: mail loops back to myself",
+ MyHostName);
+ mci->mci_exitstat = EX_CONFIG;
+ mci->mci_errno = 0;
+ smtpquit(m, mci, e);
+ return;
+ }
+
+ /*
+ ** If this is expected to be another sendmail, send some internal
+ ** commands.
+ */
+
+ if (bitnset(M_INTERNAL, m->m_flags))
+ {
+ /* tell it to be verbose */
+ smtpmessage("VERB", m, mci);
+ r = reply(m, mci, e, TimeOuts.to_miscshort, NULL);
+ if (r < 0)
+ goto tempfail2;
+ }
+
+ if (mci->mci_state != MCIS_CLOSED)
+ {
+ mci->mci_state = MCIS_OPEN;
+ return;
+ }
+
+ /* got a 421 error code during startup */
+
+ tempfail1:
+ tempfail2:
+ mci->mci_exitstat = EX_TEMPFAIL;
+ if (mci->mci_errno == 0)
+ mci->mci_errno = errno;
+ if (mci->mci_state != MCIS_CLOSED)
+ smtpquit(m, mci, e);
+ return;
+
+ unavailable:
+ mci->mci_exitstat = EX_UNAVAILABLE;
+ mci->mci_errno = errno;
+ smtpquit(m, mci, e);
+ return;
+}
+ /*
+** ESMTP_CHECK -- check to see if this implementation likes ESMTP protocol
+**
+**
+** Parameters:
+** line -- the response line.
+** m -- the mailer.
+** mci -- the mailer connection info.
+** e -- the envelope.
+**
+** Returns:
+** none.
+*/
+
+void
+esmtp_check(line, m, mci, e)
+ char *line;
+ MAILER *m;
+ register MCI *mci;
+ ENVELOPE *e;
+{
+ if (strlen(line) < 5)
+ return;
+ line += 4;
+ if (strncmp(line, "ESMTP ", 6) == 0)
+ mci->mci_flags |= MCIF_ESMTP;
+}
+ /*
+** HELO_OPTIONS -- process the options on a HELO line.
+**
+** Parameters:
+** line -- the response line.
+** m -- the mailer.
+** mci -- the mailer connection info.
+** e -- the envelope.
+**
+** Returns:
+** none.
+*/
+
+void
+helo_options(line, m, mci, e)
+ char *line;
+ MAILER *m;
+ register MCI *mci;
+ ENVELOPE *e;
+{
+ register char *p;
+
+ if (strlen(line) < 5)
+ return;
+ line += 4;
+ p = strchr(line, ' ');
+ if (p != NULL)
+ *p++ = '\0';
+ if (strcasecmp(line, "size") == 0)
+ {
+ mci->mci_flags |= MCIF_SIZE;
+ if (p != NULL)
+ mci->mci_maxsize = atol(p);
+ }
+ else if (strcasecmp(line, "8bitmime") == 0)
+ {
+ mci->mci_flags |= MCIF_8BITMIME;
+ mci->mci_flags &= ~MCIF_7BIT;
+ }
+ else if (strcasecmp(line, "expn") == 0)
+ mci->mci_flags |= MCIF_EXPN;
+}
+ /*
+** SMTPMAILFROM -- send MAIL command
+**
+** Parameters:
+** m -- the mailer.
+** mci -- the mailer connection structure.
+** e -- the envelope (including the sender to specify).
+*/
+
+smtpmailfrom(m, mci, e)
+ struct mailer *m;
+ MCI *mci;
+ ENVELOPE *e;
+{
+ int r;
+ char *bufp;
+ char buf[MAXNAME];
+ char optbuf[MAXLINE];
+
+ if (tTd(18, 2))
+ printf("smtpmailfrom: CurHost=%s\n", CurHostName);
+
+ /* set up appropriate options to include */
+ if (bitset(MCIF_SIZE, mci->mci_flags) && e->e_msgsize > 0)
+ sprintf(optbuf, " SIZE=%ld", e->e_msgsize);
+ else
+ strcpy(optbuf, "");
+
+ /*
+ ** Send the MAIL command.
+ ** Designates the sender.
+ */
+
+ mci->mci_state = MCIS_ACTIVE;
+
+ if (bitset(EF_RESPONSE, e->e_flags) &&
+ !bitnset(M_NO_NULL_FROM, m->m_flags))
+ (void) strcpy(buf, "");
+ else
+ expand("\201g", buf, &buf[sizeof buf - 1], e);
+ if (buf[0] == '<')
+ {
+ /* strip off <angle brackets> (put back on below) */
+ bufp = &buf[strlen(buf) - 1];
+ if (*bufp == '>')
+ *bufp = '\0';
+ bufp = &buf[1];
+ }
+ else
+ bufp = buf;
+ if (e->e_from.q_mailer == LocalMailer ||
+ !bitnset(M_FROMPATH, m->m_flags))
+ {
+ smtpmessage("MAIL From:<%s>%s", m, mci, bufp, optbuf);
+ }
+ else
+ {
+ smtpmessage("MAIL From:<@%s%c%s>%s", m, mci, MyHostName,
+ *bufp == '@' ? ',' : ':', bufp, optbuf);
+ }
+ SmtpPhase = mci->mci_phase = "client MAIL";
+ setproctitle("%s %s: %s", e->e_id, CurHostName, mci->mci_phase);
+ r = reply(m, mci, e, TimeOuts.to_mail, NULL);
+ if (r < 0 || REPLYTYPE(r) == 4)
+ {
+ mci->mci_exitstat = EX_TEMPFAIL;
+ mci->mci_errno = errno;
+ smtpquit(m, mci, e);
+ return EX_TEMPFAIL;
+ }
+ else if (r == 250)
+ {
+ mci->mci_exitstat = EX_OK;
+ return EX_OK;
+ }
+ else if (r == 552)
+ {
+ /* signal service unavailable */
+ mci->mci_exitstat = EX_UNAVAILABLE;
+ smtpquit(m, mci, e);
+ return EX_UNAVAILABLE;
+ }
+
+#ifdef LOG
+ if (LogLevel > 1)
+ {
+ syslog(LOG_CRIT, "%s: SMTP MAIL protocol error: %s",
+ e->e_id, SmtpReplyBuffer);
+ }
+#endif
+
+ /* protocol error -- close up */
+ smtpquit(m, mci, e);
+ mci->mci_exitstat = EX_PROTOCOL;
+ return EX_PROTOCOL;
+}
+ /*
+** SMTPRCPT -- designate recipient.
+**
+** Parameters:
+** to -- address of recipient.
+** m -- the mailer we are sending to.
+** mci -- the connection info for this transaction.
+** e -- the envelope for this transaction.
+**
+** Returns:
+** exit status corresponding to recipient status.
+**
+** Side Effects:
+** Sends the mail via SMTP.
+*/
+
+smtprcpt(to, m, mci, e)
+ ADDRESS *to;
+ register MAILER *m;
+ MCI *mci;
+ ENVELOPE *e;
+{
+ register int r;
+
+ smtpmessage("RCPT To:<%s>", m, mci, to->q_user);
+
+ SmtpPhase = mci->mci_phase = "client RCPT";
+ setproctitle("%s %s: %s", e->e_id, CurHostName, mci->mci_phase);
+ r = reply(m, mci, e, TimeOuts.to_rcpt, NULL);
+ if (r < 0 || REPLYTYPE(r) == 4)
+ return (EX_TEMPFAIL);
+ else if (REPLYTYPE(r) == 2)
+ return (EX_OK);
+ else if (r == 550 || r == 551 || r == 553)
+ return (EX_NOUSER);
+ else if (r == 552 || r == 554)
+ return (EX_UNAVAILABLE);
+
+#ifdef LOG
+ if (LogLevel > 1)
+ {
+ syslog(LOG_CRIT, "%s: SMTP RCPT protocol error: %s",
+ e->e_id, SmtpReplyBuffer);
+ }
+#endif
+
+ return (EX_PROTOCOL);
+}
+ /*
+** SMTPDATA -- send the data and clean up the transaction.
+**
+** Parameters:
+** m -- mailer being sent to.
+** e -- the envelope for this message.
+**
+** Returns:
+** exit status corresponding to DATA command.
+**
+** Side Effects:
+** none.
+*/
+
+static jmp_buf CtxDataTimeout;
+static int datatimeout();
+
+smtpdata(m, mci, e)
+ struct mailer *m;
+ register MCI *mci;
+ register ENVELOPE *e;
+{
+ register int r;
+ register EVENT *ev;
+ time_t timeout;
+
+ /*
+ ** Send the data.
+ ** First send the command and check that it is ok.
+ ** Then send the data.
+ ** Follow it up with a dot to terminate.
+ ** Finally get the results of the transaction.
+ */
+
+ /* send the command and check ok to proceed */
+ smtpmessage("DATA", m, mci);
+ SmtpPhase = mci->mci_phase = "client DATA 354";
+ setproctitle("%s %s: %s", e->e_id, CurHostName, mci->mci_phase);
+ r = reply(m, mci, e, TimeOuts.to_datainit, NULL);
+ if (r < 0 || REPLYTYPE(r) == 4)
+ {
+ smtpquit(m, mci, e);
+ return (EX_TEMPFAIL);
+ }
+ else if (r == 554)
+ {
+ smtprset(m, mci, e);
+ return (EX_UNAVAILABLE);
+ }
+ else if (r != 354)
+ {
+#ifdef LOG
+ if (LogLevel > 1)
+ {
+ syslog(LOG_CRIT, "%s: SMTP DATA-1 protocol error: %s",
+ e->e_id, SmtpReplyBuffer);
+ }
+#endif
+ smtprset(m, mci, e);
+ return (EX_PROTOCOL);
+ }
+
+ /*
+ ** Set timeout around data writes. Make it at least large
+ ** enough for DNS timeouts on all recipients plus some fudge
+ ** factor. The main thing is that it should not be infinite.
+ */
+
+ if (setjmp(CtxDataTimeout) != 0)
+ {
+ mci->mci_errno = errno;
+ mci->mci_exitstat = EX_TEMPFAIL;
+ mci->mci_state = MCIS_ERROR;
+ syserr("451 timeout writing message to %s", mci->mci_host);
+ smtpquit(m, mci, e);
+ return EX_TEMPFAIL;
+ }
+
+ timeout = e->e_msgsize / 16;
+ if (timeout < (time_t) 60)
+ timeout = (time_t) 60;
+ timeout += e->e_nrcpts * 90;
+ ev = setevent(timeout, datatimeout, 0);
+
+ /* now output the actual message */
+ (*e->e_puthdr)(mci, e);
+ putline("\n", mci);
+ (*e->e_putbody)(mci, e, NULL);
+
+ clrevent(ev);
+
+ if (ferror(mci->mci_out))
+ {
+ /* error during processing -- don't send the dot */
+ mci->mci_errno = EIO;
+ mci->mci_exitstat = EX_IOERR;
+ mci->mci_state = MCIS_ERROR;
+ smtpquit(m, mci, e);
+ return EX_IOERR;
+ }
+
+ /* terminate the message */
+ fprintf(mci->mci_out, ".%s", m->m_eol);
+ if (TrafficLogFile != NULL)
+ fprintf(TrafficLogFile, "%05d >>> .\n", getpid());
+ if (Verbose)
+ nmessage(">>> .");
+
+ /* check for the results of the transaction */
+ SmtpPhase = mci->mci_phase = "client DATA 250";
+ setproctitle("%s %s: %s", e->e_id, CurHostName, mci->mci_phase);
+ r = reply(m, mci, e, TimeOuts.to_datafinal, NULL);
+ if (r < 0)
+ {
+ smtpquit(m, mci, e);
+ return (EX_TEMPFAIL);
+ }
+ mci->mci_state = MCIS_OPEN;
+ e->e_statmsg = newstr(&SmtpReplyBuffer[4]);
+ if (REPLYTYPE(r) == 4)
+ return (EX_TEMPFAIL);
+ else if (r == 250)
+ return (EX_OK);
+ else if (r == 552 || r == 554)
+ return (EX_UNAVAILABLE);
+#ifdef LOG
+ if (LogLevel > 1)
+ {
+ syslog(LOG_CRIT, "%s: SMTP DATA-2 protocol error: %s",
+ e->e_id, SmtpReplyBuffer);
+ }
+#endif
+ return (EX_PROTOCOL);
+}
+
+
+static int
+datatimeout()
+{
+ longjmp(CtxDataTimeout, 1);
+}
+ /*
+** SMTPQUIT -- close the SMTP connection.
+**
+** Parameters:
+** m -- a pointer to the mailer.
+**
+** Returns:
+** none.
+**
+** Side Effects:
+** sends the final protocol and closes the connection.
+*/
+
+smtpquit(m, mci, e)
+ register MAILER *m;
+ register MCI *mci;
+ ENVELOPE *e;
+{
+ bool oldSuprErrs = SuprErrs;
+
+ /*
+ ** Suppress errors here -- we may be processing a different
+ ** job when we do the quit connection, and we don't want the
+ ** new job to be penalized for something that isn't it's
+ ** problem.
+ */
+
+ SuprErrs = TRUE;
+
+ /* send the quit message if we haven't gotten I/O error */
+ if (mci->mci_state != MCIS_ERROR)
+ {
+ SmtpPhase = "client QUIT";
+ smtpmessage("QUIT", m, mci);
+ (void) reply(m, mci, e, TimeOuts.to_quit, NULL);
+ SuprErrs = oldSuprErrs;
+ if (mci->mci_state == MCIS_CLOSED)
+ {
+ SuprErrs = oldSuprErrs;
+ return;
+ }
+ }
+
+ /* now actually close the connection and pick up the zombie */
+ (void) endmailer(mci, e, NULL);
+
+ SuprErrs = oldSuprErrs;
+}
+ /*
+** SMTPRSET -- send a RSET (reset) command
+*/
+
+smtprset(m, mci, e)
+ register MAILER *m;
+ register MCI *mci;
+ ENVELOPE *e;
+{
+ int r;
+
+ SmtpPhase = "client RSET";
+ smtpmessage("RSET", m, mci);
+ r = reply(m, mci, e, TimeOuts.to_rset, NULL);
+ if (r < 0)
+ mci->mci_state = MCIS_ERROR;
+ else if (REPLYTYPE(r) == 2)
+ {
+ mci->mci_state = MCIS_OPEN;
+ return;
+ }
+ smtpquit(m, mci, e);
+}
+ /*
+** SMTPPROBE -- check the connection state
+*/
+
+smtpprobe(mci)
+ register MCI *mci;
+{
+ int r;
+ MAILER *m = mci->mci_mailer;
+ extern ENVELOPE BlankEnvelope;
+ ENVELOPE *e = &BlankEnvelope;
+
+ SmtpPhase = "client probe";
+ smtpmessage("RSET", m, mci);
+ r = reply(m, mci, e, TimeOuts.to_miscshort, NULL);
+ if (r < 0 || REPLYTYPE(r) != 2)
+ smtpquit(m, mci, e);
+ return r;
+}
+ /*
+** REPLY -- read arpanet reply
+**
+** Parameters:
+** m -- the mailer we are reading the reply from.
+** mci -- the mailer connection info structure.
+** e -- the current envelope.
+** timeout -- the timeout for reads.
+** pfunc -- processing function for second and subsequent
+** lines of response -- if null, no special
+** processing is done.
+**
+** Returns:
+** reply code it reads.
+**
+** Side Effects:
+** flushes the mail file.
+*/
+
+reply(m, mci, e, timeout, pfunc)
+ MAILER *m;
+ MCI *mci;
+ ENVELOPE *e;
+ time_t timeout;
+ void (*pfunc)();
+{
+ register char *bufp;
+ register int r;
+ bool firstline = TRUE;
+ char junkbuf[MAXLINE];
+
+ if (mci->mci_out != NULL)
+ (void) fflush(mci->mci_out);
+
+ if (tTd(18, 1))
+ printf("reply\n");
+
+ /*
+ ** Read the input line, being careful not to hang.
+ */
+
+ for (bufp = SmtpReplyBuffer;; bufp = junkbuf)
+ {
+ register char *p;
+ extern time_t curtime();
+
+ /* actually do the read */
+ if (e->e_xfp != NULL)
+ (void) fflush(e->e_xfp); /* for debugging */
+
+ /* if we are in the process of closing just give the code */
+ if (mci->mci_state == MCIS_CLOSED)
+ return (SMTPCLOSING);
+
+ if (mci->mci_out != NULL)
+ fflush(mci->mci_out);
+
+ /* get the line from the other side */
+ p = sfgets(bufp, MAXLINE, mci->mci_in, timeout, SmtpPhase);
+ mci->mci_lastuse = curtime();
+
+ if (p == NULL)
+ {
+ bool oldholderrs;
+ extern char MsgBuf[]; /* err.c */
+
+ /* if the remote end closed early, fake an error */
+ if (errno == 0)
+# ifdef ECONNRESET
+ errno = ECONNRESET;
+# else /* ECONNRESET */
+ errno = EPIPE;
+# endif /* ECONNRESET */
+
+ mci->mci_errno = errno;
+ mci->mci_exitstat = EX_TEMPFAIL;
+ oldholderrs = HoldErrs;
+ HoldErrs = TRUE;
+ usrerr("451 reply: read error from %s", mci->mci_host);
+
+ /* if debugging, pause so we can see state */
+ if (tTd(18, 100))
+ pause();
+ mci->mci_state = MCIS_ERROR;
+ smtpquit(m, mci, e);
+#ifdef XDEBUG
+ {
+ char wbuf[MAXLINE];
+ char *p = wbuf;
+ if (e->e_to != NULL)
+ {
+ sprintf(p, "%s... ", e->e_to);
+ p += strlen(p);
+ }
+ sprintf(p, "reply(%s) during %s",
+ mci->mci_host, SmtpPhase);
+ checkfd012(wbuf);
+ }
+#endif
+ HoldErrs = oldholderrs;
+ return (-1);
+ }
+ fixcrlf(bufp, TRUE);
+
+ /* EHLO failure is not a real error */
+ if (e->e_xfp != NULL && (bufp[0] == '4' ||
+ (bufp[0] == '5' && strncmp(SmtpMsgBuffer, "EHLO", 4) != 0)))
+ {
+ /* serious error -- log the previous command */
+ if (SmtpNeedIntro)
+ {
+ /* inform user who we are chatting with */
+ fprintf(CurEnv->e_xfp,
+ "... while talking to %s:\n",
+ CurHostName);
+ SmtpNeedIntro = FALSE;
+ }
+ if (SmtpMsgBuffer[0] != '\0')
+ fprintf(e->e_xfp, ">>> %s\n", SmtpMsgBuffer);
+ SmtpMsgBuffer[0] = '\0';
+
+ /* now log the message as from the other side */
+ fprintf(e->e_xfp, "<<< %s\n", bufp);
+ }
+
+ /* display the input for verbose mode */
+ if (Verbose)
+ nmessage("050 %s", bufp);
+
+ /* process the line */
+ if (pfunc != NULL && !firstline)
+ (*pfunc)(bufp, m, mci, e);
+
+ firstline = FALSE;
+
+ /* if continuation is required, we can go on */
+ if (bufp[3] == '-')
+ continue;
+
+ /* ignore improperly formated input */
+ if (!(isascii(bufp[0]) && isdigit(bufp[0])))
+ continue;
+
+ /* decode the reply code */
+ r = atoi(bufp);
+
+ /* extra semantics: 0xx codes are "informational" */
+ if (r >= 100)
+ break;
+ }
+
+ /*
+ ** Now look at SmtpReplyBuffer -- only care about the first
+ ** line of the response from here on out.
+ */
+
+ /* save temporary failure messages for posterity */
+ if (SmtpReplyBuffer[0] == '4' && SmtpError[0] == '\0')
+ (void) strcpy(SmtpError, SmtpReplyBuffer);
+
+ /* reply code 421 is "Service Shutting Down" */
+ if (r == SMTPCLOSING && mci->mci_state != MCIS_SSD)
+ {
+ /* send the quit protocol */
+ mci->mci_state = MCIS_SSD;
+ smtpquit(m, mci, e);
+ }
+
+ return (r);
+}
+ /*
+** SMTPMESSAGE -- send message to server
+**
+** Parameters:
+** f -- format
+** m -- the mailer to control formatting.
+** a, b, c -- parameters
+**
+** Returns:
+** none.
+**
+** Side Effects:
+** writes message to mci->mci_out.
+*/
+
+/*VARARGS1*/
+#ifdef __STDC__
+smtpmessage(char *f, MAILER *m, MCI *mci, ...)
+#else
+smtpmessage(f, m, mci, va_alist)
+ char *f;
+ MAILER *m;
+ MCI *mci;
+ va_dcl
+#endif
+{
+ VA_LOCAL_DECL
+
+ VA_START(mci);
+ (void) vsprintf(SmtpMsgBuffer, f, ap);
+ VA_END;
+
+ if (tTd(18, 1) || Verbose)
+ nmessage(">>> %s", SmtpMsgBuffer);
+ if (TrafficLogFile != NULL)
+ fprintf(TrafficLogFile, "%05d >>> %s\n", getpid(), SmtpMsgBuffer);
+ if (mci->mci_out != NULL)
+ {
+ fprintf(mci->mci_out, "%s%s", SmtpMsgBuffer,
+ m == NULL ? "\r\n" : m->m_eol);
+ }
+ else if (tTd(18, 1))
+ {
+ printf("smtpmessage: NULL mci_out\n");
+ }
+}
+
+# endif /* SMTP */
diff --git a/usr.sbin/sendmail/src/util.c b/usr.sbin/sendmail/src/util.c
new file mode 100644
index 0000000..10b3fb4
--- /dev/null
+++ b/usr.sbin/sendmail/src/util.c
@@ -0,0 +1,1467 @@
+/*
+ * Copyright (c) 1983 Eric P. Allman
+ * Copyright (c) 1988, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)util.c 8.39 (Berkeley) 4/14/94";
+#endif /* not lint */
+
+# include "sendmail.h"
+# include <sysexits.h>
+ /*
+** STRIPQUOTES -- Strip quotes & quote bits from a string.
+**
+** Runs through a string and strips off unquoted quote
+** characters and quote bits. This is done in place.
+**
+** Parameters:
+** s -- the string to strip.
+**
+** Returns:
+** none.
+**
+** Side Effects:
+** none.
+**
+** Called By:
+** deliver
+*/
+
+stripquotes(s)
+ char *s;
+{
+ register char *p;
+ register char *q;
+ register char c;
+
+ if (s == NULL)
+ return;
+
+ p = q = s;
+ do
+ {
+ c = *p++;
+ if (c == '\\')
+ c = *p++;
+ else if (c == '"')
+ continue;
+ *q++ = c;
+ } while (c != '\0');
+}
+ /*
+** XALLOC -- Allocate memory and bitch wildly on failure.
+**
+** THIS IS A CLUDGE. This should be made to give a proper
+** error -- but after all, what can we do?
+**
+** Parameters:
+** sz -- size of area to allocate.
+**
+** Returns:
+** pointer to data region.
+**
+** Side Effects:
+** Memory is allocated.
+*/
+
+char *
+xalloc(sz)
+ register int sz;
+{
+ register char *p;
+
+ /* some systems can't handle size zero mallocs */
+ if (sz <= 0)
+ sz = 1;
+
+ p = malloc((unsigned) sz);
+ if (p == NULL)
+ {
+ syserr("Out of memory!!");
+ abort();
+ /* exit(EX_UNAVAILABLE); */
+ }
+ return (p);
+}
+ /*
+** COPYPLIST -- copy list of pointers.
+**
+** This routine is the equivalent of newstr for lists of
+** pointers.
+**
+** Parameters:
+** list -- list of pointers to copy.
+** Must be NULL terminated.
+** copycont -- if TRUE, copy the contents of the vector
+** (which must be a string) also.
+**
+** Returns:
+** a copy of 'list'.
+**
+** Side Effects:
+** none.
+*/
+
+char **
+copyplist(list, copycont)
+ char **list;
+ bool copycont;
+{
+ register char **vp;
+ register char **newvp;
+
+ for (vp = list; *vp != NULL; vp++)
+ continue;
+
+ vp++;
+
+ newvp = (char **) xalloc((int) (vp - list) * sizeof *vp);
+ bcopy((char *) list, (char *) newvp, (int) (vp - list) * sizeof *vp);
+
+ if (copycont)
+ {
+ for (vp = newvp; *vp != NULL; vp++)
+ *vp = newstr(*vp);
+ }
+
+ return (newvp);
+}
+ /*
+** COPYQUEUE -- copy address queue.
+**
+** This routine is the equivalent of newstr for address queues
+** addresses marked with QDONTSEND aren't copied
+**
+** Parameters:
+** addr -- list of address structures to copy.
+**
+** Returns:
+** a copy of 'addr'.
+**
+** Side Effects:
+** none.
+*/
+
+ADDRESS *
+copyqueue(addr)
+ ADDRESS *addr;
+{
+ register ADDRESS *newaddr;
+ ADDRESS *ret;
+ register ADDRESS **tail = &ret;
+
+ while (addr != NULL)
+ {
+ if (!bitset(QDONTSEND, addr->q_flags))
+ {
+ newaddr = (ADDRESS *) xalloc(sizeof(ADDRESS));
+ STRUCTCOPY(*addr, *newaddr);
+ *tail = newaddr;
+ tail = &newaddr->q_next;
+ }
+ addr = addr->q_next;
+ }
+ *tail = NULL;
+
+ return ret;
+}
+ /*
+** PRINTAV -- print argument vector.
+**
+** Parameters:
+** av -- argument vector.
+**
+** Returns:
+** none.
+**
+** Side Effects:
+** prints av.
+*/
+
+printav(av)
+ register char **av;
+{
+ while (*av != NULL)
+ {
+ if (tTd(0, 44))
+ printf("\n\t%08x=", *av);
+ else
+ (void) putchar(' ');
+ xputs(*av++);
+ }
+ (void) putchar('\n');
+}
+ /*
+** LOWER -- turn letter into lower case.
+**
+** Parameters:
+** c -- character to turn into lower case.
+**
+** Returns:
+** c, in lower case.
+**
+** Side Effects:
+** none.
+*/
+
+char
+lower(c)
+ register char c;
+{
+ return((isascii(c) && isupper(c)) ? tolower(c) : c);
+}
+ /*
+** XPUTS -- put string doing control escapes.
+**
+** Parameters:
+** s -- string to put.
+**
+** Returns:
+** none.
+**
+** Side Effects:
+** output to stdout
+*/
+
+xputs(s)
+ register char *s;
+{
+ register int c;
+ register struct metamac *mp;
+ extern struct metamac MetaMacros[];
+
+ if (s == NULL)
+ {
+ printf("<null>");
+ return;
+ }
+ while ((c = (*s++ & 0377)) != '\0')
+ {
+ if (!isascii(c))
+ {
+ if (c == MATCHREPL || c == MACROEXPAND)
+ {
+ putchar('$');
+ continue;
+ }
+ for (mp = MetaMacros; mp->metaname != '\0'; mp++)
+ {
+ if ((mp->metaval & 0377) == c)
+ {
+ printf("$%c", mp->metaname);
+ break;
+ }
+ }
+ if (mp->metaname != '\0')
+ continue;
+ (void) putchar('\\');
+ c &= 0177;
+ }
+ if (isprint(c))
+ {
+ putchar(c);
+ continue;
+ }
+
+ /* wasn't a meta-macro -- find another way to print it */
+ switch (c)
+ {
+ case '\0':
+ continue;
+
+ case '\n':
+ c = 'n';
+ break;
+
+ case '\r':
+ c = 'r';
+ break;
+
+ case '\t':
+ c = 't';
+ break;
+
+ default:
+ (void) putchar('^');
+ (void) putchar(c ^ 0100);
+ continue;
+ }
+ }
+ (void) fflush(stdout);
+}
+ /*
+** MAKELOWER -- Translate a line into lower case
+**
+** Parameters:
+** p -- the string to translate. If NULL, return is
+** immediate.
+**
+** Returns:
+** none.
+**
+** Side Effects:
+** String pointed to by p is translated to lower case.
+**
+** Called By:
+** parse
+*/
+
+makelower(p)
+ register char *p;
+{
+ register char c;
+
+ if (p == NULL)
+ return;
+ for (; (c = *p) != '\0'; p++)
+ if (isascii(c) && isupper(c))
+ *p = tolower(c);
+}
+ /*
+** BUILDFNAME -- build full name from gecos style entry.
+**
+** This routine interprets the strange entry that would appear
+** in the GECOS field of the password file.
+**
+** Parameters:
+** p -- name to build.
+** login -- the login name of this user (for &).
+** buf -- place to put the result.
+**
+** Returns:
+** none.
+**
+** Side Effects:
+** none.
+*/
+
+buildfname(gecos, login, buf)
+ register char *gecos;
+ char *login;
+ char *buf;
+{
+ register char *p;
+ register char *bp = buf;
+ int l;
+
+ if (*gecos == '*')
+ gecos++;
+
+ /* find length of final string */
+ l = 0;
+ for (p = gecos; *p != '\0' && *p != ',' && *p != ';' && *p != '%'; p++)
+ {
+ if (*p == '&')
+ l += strlen(login);
+ else
+ l++;
+ }
+
+ /* now fill in buf */
+ for (p = gecos; *p != '\0' && *p != ',' && *p != ';' && *p != '%'; p++)
+ {
+ if (*p == '&')
+ {
+ (void) strcpy(bp, login);
+ *bp = toupper(*bp);
+ while (*bp != '\0')
+ bp++;
+ }
+ else
+ *bp++ = *p;
+ }
+ *bp = '\0';
+}
+ /*
+** SAFEFILE -- return true if a file exists and is safe for a user.
+**
+** Parameters:
+** fn -- filename to check.
+** uid -- user id to compare against.
+** gid -- group id to compare against.
+** uname -- user name to compare against (used for group
+** sets).
+** flags -- modifiers:
+** SFF_MUSTOWN -- "uid" must own this file.
+** SFF_NOSLINK -- file cannot be a symbolic link.
+** mode -- mode bits that must match.
+**
+** Returns:
+** 0 if fn exists, is owned by uid, and matches mode.
+** An errno otherwise. The actual errno is cleared.
+**
+** Side Effects:
+** none.
+*/
+
+#include <grp.h>
+
+#ifndef S_IXOTH
+# define S_IXOTH (S_IEXEC >> 6)
+#endif
+
+#ifndef S_IXGRP
+# define S_IXGRP (S_IEXEC >> 3)
+#endif
+
+#ifndef S_IXUSR
+# define S_IXUSR (S_IEXEC)
+#endif
+
+int
+safefile(fn, uid, gid, uname, flags, mode)
+ char *fn;
+ uid_t uid;
+ gid_t gid;
+ char *uname;
+ int flags;
+ int mode;
+{
+ register char *p;
+ register struct group *gr = NULL;
+ struct stat stbuf;
+
+ if (tTd(54, 4))
+ printf("safefile(%s, uid=%d, gid=%d, flags=%x, mode=%o):\n",
+ fn, uid, gid, flags, mode);
+ errno = 0;
+
+ for (p = fn; (p = strchr(++p, '/')) != NULL; *p = '/')
+ {
+ *p = '\0';
+ if (stat(fn, &stbuf) < 0)
+ break;
+ if (uid == 0 && !bitset(SFF_ROOTOK, flags))
+ {
+ if (bitset(S_IXOTH, stbuf.st_mode))
+ continue;
+ break;
+ }
+ if (stbuf.st_uid == uid && bitset(S_IXUSR, stbuf.st_mode))
+ continue;
+ if (stbuf.st_gid == gid && bitset(S_IXGRP, stbuf.st_mode))
+ continue;
+#ifndef NO_GROUP_SET
+ if (uname != NULL &&
+ ((gr != NULL && gr->gr_gid == stbuf.st_gid) ||
+ (gr = getgrgid(stbuf.st_gid)) != NULL))
+ {
+ register char **gp;
+
+ for (gp = gr->gr_mem; *gp != NULL; gp++)
+ if (strcmp(*gp, uname) == 0)
+ break;
+ if (*gp != NULL && bitset(S_IXGRP, stbuf.st_mode))
+ continue;
+ }
+#endif
+ if (!bitset(S_IXOTH, stbuf.st_mode))
+ break;
+ }
+ if (p != NULL)
+ {
+ int ret = errno;
+
+ if (ret == 0)
+ ret = EACCES;
+ if (tTd(54, 4))
+ printf("\t[dir %s] %s\n", fn, errstring(ret));
+ *p = '/';
+ return ret;
+ }
+
+#ifdef HASLSTAT
+ if ((bitset(SFF_NOSLINK, flags) ? lstat(fn, &stbuf)
+ : stat(fn, &stbuf)) < 0)
+#else
+ if (stat(fn, &stbuf) < 0)
+#endif
+ {
+ int ret = errno;
+
+ if (tTd(54, 4))
+ printf("\t%s\n", errstring(ret));
+
+ errno = 0;
+ return ret;
+ }
+
+#ifdef S_ISLNK
+ if (bitset(SFF_NOSLINK, flags) && S_ISLNK(stbuf.st_mode))
+ {
+ if (tTd(54, 4))
+ printf("\t[slink mode %o]\tEPERM\n", stbuf.st_mode);
+ return EPERM;
+ }
+#endif
+
+ if (uid == 0 && !bitset(SFF_ROOTOK, flags))
+ mode >>= 6;
+ else if (stbuf.st_uid != uid)
+ {
+ mode >>= 3;
+ if (stbuf.st_gid == gid)
+ ;
+#ifndef NO_GROUP_SET
+ else if (uname != NULL &&
+ ((gr != NULL && gr->gr_gid == stbuf.st_gid) ||
+ (gr = getgrgid(stbuf.st_gid)) != NULL))
+ {
+ register char **gp;
+
+ for (gp = gr->gr_mem; *gp != NULL; gp++)
+ if (strcmp(*gp, uname) == 0)
+ break;
+ if (*gp == NULL)
+ mode >>= 3;
+ }
+#endif
+ else
+ mode >>= 3;
+ }
+ if (tTd(54, 4))
+ printf("\t[uid %d, stat %o, mode %o] ",
+ stbuf.st_uid, stbuf.st_mode, mode);
+ if ((stbuf.st_uid == uid || stbuf.st_uid == 0 ||
+ !bitset(SFF_MUSTOWN, flags)) &&
+ (stbuf.st_mode & mode) == mode)
+ {
+ if (tTd(54, 4))
+ printf("\tOK\n");
+ return 0;
+ }
+ if (tTd(54, 4))
+ printf("\tEACCES\n");
+ return EACCES;
+}
+ /*
+** FIXCRLF -- fix <CR><LF> in line.
+**
+** Looks for the <CR><LF> combination and turns it into the
+** UNIX canonical <NL> character. It only takes one line,
+** i.e., it is assumed that the first <NL> found is the end
+** of the line.
+**
+** Parameters:
+** line -- the line to fix.
+** stripnl -- if true, strip the newline also.
+**
+** Returns:
+** none.
+**
+** Side Effects:
+** line is changed in place.
+*/
+
+fixcrlf(line, stripnl)
+ char *line;
+ bool stripnl;
+{
+ register char *p;
+
+ p = strchr(line, '\n');
+ if (p == NULL)
+ return;
+ if (p > line && p[-1] == '\r')
+ p--;
+ if (!stripnl)
+ *p++ = '\n';
+ *p = '\0';
+}
+ /*
+** DFOPEN -- determined file open
+**
+** This routine has the semantics of fopen, except that it will
+** keep trying a few times to make this happen. The idea is that
+** on very loaded systems, we may run out of resources (inodes,
+** whatever), so this tries to get around it.
+*/
+
+#ifndef O_ACCMODE
+# define O_ACCMODE (O_RDONLY|O_WRONLY|O_RDWR)
+#endif
+
+struct omodes
+{
+ int mask;
+ int mode;
+ char *farg;
+} OpenModes[] =
+{
+ O_ACCMODE, O_RDONLY, "r",
+ O_ACCMODE|O_APPEND, O_WRONLY, "w",
+ O_ACCMODE|O_APPEND, O_WRONLY|O_APPEND, "a",
+ O_TRUNC, 0, "w+",
+ O_APPEND, O_APPEND, "a+",
+ 0, 0, "r+",
+};
+
+FILE *
+dfopen(filename, omode, cmode)
+ char *filename;
+ int omode;
+ int cmode;
+{
+ register int tries;
+ int fd;
+ register struct omodes *om;
+ struct stat st;
+
+ for (om = OpenModes; om->mask != 0; om++)
+ if ((omode & om->mask) == om->mode)
+ break;
+
+ for (tries = 0; tries < 10; tries++)
+ {
+ sleep((unsigned) (10 * tries));
+ errno = 0;
+ fd = open(filename, omode, cmode);
+ if (fd >= 0)
+ break;
+ switch (errno)
+ {
+ case ENFILE: /* system file table full */
+ case EINTR: /* interrupted syscall */
+#ifdef ETXTBSY
+ case ETXTBSY: /* Apollo: net file locked */
+#endif
+ continue;
+ }
+ break;
+ }
+ if (fd >= 0 && fstat(fd, &st) >= 0 && S_ISREG(st.st_mode))
+ {
+ int locktype;
+
+ /* lock the file to avoid accidental conflicts */
+ if ((omode & O_ACCMODE) != O_RDONLY)
+ locktype = LOCK_EX;
+ else
+ locktype = LOCK_SH;
+ (void) lockfile(fd, filename, NULL, locktype);
+ errno = 0;
+ }
+ if (fd < 0)
+ return NULL;
+ else
+ return fdopen(fd, om->farg);
+}
+ /*
+** PUTLINE -- put a line like fputs obeying SMTP conventions
+**
+** This routine always guarantees outputing a newline (or CRLF,
+** as appropriate) at the end of the string.
+**
+** Parameters:
+** l -- line to put.
+** mci -- the mailer connection information.
+**
+** Returns:
+** none
+**
+** Side Effects:
+** output of l to fp.
+*/
+
+putline(l, mci)
+ register char *l;
+ register MCI *mci;
+{
+ register char *p;
+ register char svchar;
+ int slop = 0;
+
+ /* strip out 0200 bits -- these can look like TELNET protocol */
+ if (bitset(MCIF_7BIT, mci->mci_flags))
+ {
+ for (p = l; (svchar = *p) != '\0'; ++p)
+ if (bitset(0200, svchar))
+ *p = svchar &~ 0200;
+ }
+
+ do
+ {
+ /* find the end of the line */
+ p = strchr(l, '\n');
+ if (p == NULL)
+ p = &l[strlen(l)];
+
+ if (TrafficLogFile != NULL)
+ fprintf(TrafficLogFile, "%05d >>> ", getpid());
+
+ /* check for line overflow */
+ while (mci->mci_mailer->m_linelimit > 0 &&
+ (p - l + slop) > mci->mci_mailer->m_linelimit)
+ {
+ register char *q = &l[mci->mci_mailer->m_linelimit - slop - 1];
+
+ svchar = *q;
+ *q = '\0';
+ if (l[0] == '.' && slop == 0 &&
+ bitnset(M_XDOT, mci->mci_mailer->m_flags))
+ {
+ (void) putc('.', mci->mci_out);
+ if (TrafficLogFile != NULL)
+ (void) putc('.', TrafficLogFile);
+ }
+ fputs(l, mci->mci_out);
+ (void) putc('!', mci->mci_out);
+ fputs(mci->mci_mailer->m_eol, mci->mci_out);
+ (void) putc(' ', mci->mci_out);
+ if (TrafficLogFile != NULL)
+ fprintf(TrafficLogFile, "%s!\n%05d >>> ",
+ l, getpid());
+ *q = svchar;
+ l = q;
+ slop = 1;
+ }
+
+ /* output last part */
+ if (l[0] == '.' && slop == 0 &&
+ bitnset(M_XDOT, mci->mci_mailer->m_flags))
+ {
+ (void) putc('.', mci->mci_out);
+ if (TrafficLogFile != NULL)
+ (void) putc('.', TrafficLogFile);
+ }
+ if (TrafficLogFile != NULL)
+ fprintf(TrafficLogFile, "%.*s\n", p - l, l);
+ for ( ; l < p; ++l)
+ (void) putc(*l, mci->mci_out);
+ fputs(mci->mci_mailer->m_eol, mci->mci_out);
+ if (*l == '\n')
+ ++l;
+ } while (l[0] != '\0');
+}
+ /*
+** XUNLINK -- unlink a file, doing logging as appropriate.
+**
+** Parameters:
+** f -- name of file to unlink.
+**
+** Returns:
+** none.
+**
+** Side Effects:
+** f is unlinked.
+*/
+
+xunlink(f)
+ char *f;
+{
+ register int i;
+
+# ifdef LOG
+ if (LogLevel > 98)
+ syslog(LOG_DEBUG, "%s: unlink %s", CurEnv->e_id, f);
+# endif /* LOG */
+
+ i = unlink(f);
+# ifdef LOG
+ if (i < 0 && LogLevel > 97)
+ syslog(LOG_DEBUG, "%s: unlink-fail %d", f, errno);
+# endif /* LOG */
+}
+ /*
+** XFCLOSE -- close a file, doing logging as appropriate.
+**
+** Parameters:
+** fp -- file pointer for the file to close
+** a, b -- miscellaneous crud to print for debugging
+**
+** Returns:
+** none.
+**
+** Side Effects:
+** fp is closed.
+*/
+
+xfclose(fp, a, b)
+ FILE *fp;
+ char *a, *b;
+{
+ if (tTd(53, 99))
+ printf("xfclose(%x) %s %s\n", fp, a, b);
+#ifdef XDEBUG
+ if (fileno(fp) == 1)
+ syserr("xfclose(%s %s): fd = 1", a, b);
+#endif
+ if (fclose(fp) < 0 && tTd(53, 99))
+ printf("xfclose FAILURE: %s\n", errstring(errno));
+}
+ /*
+** SFGETS -- "safe" fgets -- times out and ignores random interrupts.
+**
+** Parameters:
+** buf -- place to put the input line.
+** siz -- size of buf.
+** fp -- file to read from.
+** timeout -- the timeout before error occurs.
+** during -- what we are trying to read (for error messages).
+**
+** Returns:
+** NULL on error (including timeout). This will also leave
+** buf containing a null string.
+** buf otherwise.
+**
+** Side Effects:
+** none.
+*/
+
+static jmp_buf CtxReadTimeout;
+static int readtimeout();
+static EVENT *GlobalTimeout = NULL;
+static bool EnableTimeout = FALSE;
+static int ReadProgress;
+
+char *
+sfgets(buf, siz, fp, timeout, during)
+ char *buf;
+ int siz;
+ FILE *fp;
+ time_t timeout;
+ char *during;
+{
+ register EVENT *ev = NULL;
+ register char *p;
+
+ if (fp == NULL)
+ {
+ buf[0] = '\0';
+ return NULL;
+ }
+
+ /* set the timeout */
+ if (timeout != 0)
+ {
+ if (setjmp(CtxReadTimeout) != 0)
+ {
+# ifdef LOG
+ syslog(LOG_NOTICE,
+ "timeout waiting for input from %s during %s\n",
+ CurHostName? CurHostName: "local", during);
+# endif
+ errno = 0;
+ usrerr("451 timeout waiting for input during %s",
+ during);
+ buf[0] = '\0';
+#ifdef XDEBUG
+ checkfd012(during);
+#endif
+ return (NULL);
+ }
+ if (GlobalTimeout == NULL)
+ ev = setevent(timeout, readtimeout, 0);
+ else
+ EnableTimeout = TRUE;
+ }
+
+ /* try to read */
+ p = NULL;
+ while (!feof(fp) && !ferror(fp))
+ {
+ errno = 0;
+ p = fgets(buf, siz, fp);
+ if (p != NULL || errno != EINTR)
+ break;
+ clearerr(fp);
+ }
+
+ /* clear the event if it has not sprung */
+ if (GlobalTimeout == NULL)
+ clrevent(ev);
+ else
+ EnableTimeout = FALSE;
+
+ /* clean up the books and exit */
+ LineNumber++;
+ if (p == NULL)
+ {
+ buf[0] = '\0';
+ if (TrafficLogFile != NULL)
+ fprintf(TrafficLogFile, "%05d <<< [EOF]\n", getpid());
+ return (NULL);
+ }
+ if (TrafficLogFile != NULL)
+ fprintf(TrafficLogFile, "%05d <<< %s", getpid(), buf);
+ if (SevenBit)
+ for (p = buf; *p != '\0'; p++)
+ *p &= ~0200;
+ return (buf);
+}
+
+void
+sfgetset(timeout)
+ time_t timeout;
+{
+ /* cancel pending timer */
+ if (GlobalTimeout != NULL)
+ {
+ clrevent(GlobalTimeout);
+ GlobalTimeout = NULL;
+ }
+
+ /* schedule fresh one if so requested */
+ if (timeout != 0)
+ {
+ ReadProgress = LineNumber;
+ GlobalTimeout = setevent(timeout, readtimeout, timeout);
+ }
+}
+
+static
+readtimeout(timeout)
+ time_t timeout;
+{
+ /* terminate if ordinary timeout */
+ if (GlobalTimeout == NULL)
+ longjmp(CtxReadTimeout, 1);
+
+ /* terminate if no progress was made -- reset state */
+ if (EnableTimeout && (LineNumber <= ReadProgress))
+ {
+ EnableTimeout = FALSE;
+ GlobalTimeout = NULL;
+ longjmp(CtxReadTimeout, 2);
+ }
+
+ /* schedule a new timeout */
+ GlobalTimeout = NULL;
+ sfgetset(timeout);
+}
+ /*
+** FGETFOLDED -- like fgets, but know about folded lines.
+**
+** Parameters:
+** buf -- place to put result.
+** n -- bytes available.
+** f -- file to read from.
+**
+** Returns:
+** input line(s) on success, NULL on error or EOF.
+** This will normally be buf -- unless the line is too
+** long, when it will be xalloc()ed.
+**
+** Side Effects:
+** buf gets lines from f, with continuation lines (lines
+** with leading white space) appended. CRLF's are mapped
+** into single newlines. Any trailing NL is stripped.
+*/
+
+char *
+fgetfolded(buf, n, f)
+ char *buf;
+ register int n;
+ FILE *f;
+{
+ register char *p = buf;
+ char *bp = buf;
+ register int i;
+
+ n--;
+ while ((i = getc(f)) != EOF)
+ {
+ if (i == '\r')
+ {
+ i = getc(f);
+ if (i != '\n')
+ {
+ if (i != EOF)
+ (void) ungetc(i, f);
+ i = '\r';
+ }
+ }
+ if (--n <= 0)
+ {
+ /* allocate new space */
+ char *nbp;
+ int nn;
+
+ nn = (p - bp);
+ if (nn < MEMCHUNKSIZE)
+ nn *= 2;
+ else
+ nn += MEMCHUNKSIZE;
+ nbp = xalloc(nn);
+ bcopy(bp, nbp, p - bp);
+ p = &nbp[p - bp];
+ if (bp != buf)
+ free(bp);
+ bp = nbp;
+ n = nn - (p - bp);
+ }
+ *p++ = i;
+ if (i == '\n')
+ {
+ LineNumber++;
+ i = getc(f);
+ if (i != EOF)
+ (void) ungetc(i, f);
+ if (i != ' ' && i != '\t')
+ break;
+ }
+ }
+ if (p == bp)
+ return (NULL);
+ *--p = '\0';
+ return (bp);
+}
+ /*
+** CURTIME -- return current time.
+**
+** Parameters:
+** none.
+**
+** Returns:
+** the current time.
+**
+** Side Effects:
+** none.
+*/
+
+time_t
+curtime()
+{
+ auto time_t t;
+
+ (void) time(&t);
+ return (t);
+}
+ /*
+** ATOBOOL -- convert a string representation to boolean.
+**
+** Defaults to "TRUE"
+**
+** Parameters:
+** s -- string to convert. Takes "tTyY" as true,
+** others as false.
+**
+** Returns:
+** A boolean representation of the string.
+**
+** Side Effects:
+** none.
+*/
+
+bool
+atobool(s)
+ register char *s;
+{
+ if (s == NULL || *s == '\0' || strchr("tTyY", *s) != NULL)
+ return (TRUE);
+ return (FALSE);
+}
+ /*
+** ATOOCT -- convert a string representation to octal.
+**
+** Parameters:
+** s -- string to convert.
+**
+** Returns:
+** An integer representing the string interpreted as an
+** octal number.
+**
+** Side Effects:
+** none.
+*/
+
+atooct(s)
+ register char *s;
+{
+ register int i = 0;
+
+ while (*s >= '0' && *s <= '7')
+ i = (i << 3) | (*s++ - '0');
+ return (i);
+}
+ /*
+** WAITFOR -- wait for a particular process id.
+**
+** Parameters:
+** pid -- process id to wait for.
+**
+** Returns:
+** status of pid.
+** -1 if pid never shows up.
+**
+** Side Effects:
+** none.
+*/
+
+int
+waitfor(pid)
+ int pid;
+{
+#ifdef WAITUNION
+ union wait st;
+#else
+ auto int st;
+#endif
+ int i;
+
+ do
+ {
+ errno = 0;
+ i = wait(&st);
+ } while ((i >= 0 || errno == EINTR) && i != pid);
+ if (i < 0)
+ return -1;
+#ifdef WAITUNION
+ return st.w_status;
+#else
+ return st;
+#endif
+}
+ /*
+** BITINTERSECT -- tell if two bitmaps intersect
+**
+** Parameters:
+** a, b -- the bitmaps in question
+**
+** Returns:
+** TRUE if they have a non-null intersection
+** FALSE otherwise
+**
+** Side Effects:
+** none.
+*/
+
+bool
+bitintersect(a, b)
+ BITMAP a;
+ BITMAP b;
+{
+ int i;
+
+ for (i = BITMAPBYTES / sizeof (int); --i >= 0; )
+ if ((a[i] & b[i]) != 0)
+ return (TRUE);
+ return (FALSE);
+}
+ /*
+** BITZEROP -- tell if a bitmap is all zero
+**
+** Parameters:
+** map -- the bit map to check
+**
+** Returns:
+** TRUE if map is all zero.
+** FALSE if there are any bits set in map.
+**
+** Side Effects:
+** none.
+*/
+
+bool
+bitzerop(map)
+ BITMAP map;
+{
+ int i;
+
+ for (i = BITMAPBYTES / sizeof (int); --i >= 0; )
+ if (map[i] != 0)
+ return (FALSE);
+ return (TRUE);
+}
+ /*
+** STRCONTAINEDIN -- tell if one string is contained in another
+**
+** Parameters:
+** a -- possible substring.
+** b -- possible superstring.
+**
+** Returns:
+** TRUE if a is contained in b.
+** FALSE otherwise.
+*/
+
+bool
+strcontainedin(a, b)
+ register char *a;
+ register char *b;
+{
+ int la;
+ int lb;
+ int c;
+
+ la = strlen(a);
+ lb = strlen(b);
+ c = *a;
+ if (isascii(c) && isupper(c))
+ c = tolower(c);
+ for (; lb-- >= la; b++)
+ {
+ if (*b != c && isascii(*b) && isupper(*b) && tolower(*b) != c)
+ continue;
+ if (strncasecmp(a, b, la) == 0)
+ return TRUE;
+ }
+ return FALSE;
+}
+ /*
+** CHECKFD012 -- check low numbered file descriptors
+**
+** File descriptors 0, 1, and 2 should be open at all times.
+** This routine verifies that, and fixes it if not true.
+**
+** Parameters:
+** where -- a tag printed if the assertion failed
+**
+** Returns:
+** none
+*/
+
+checkfd012(where)
+ char *where;
+{
+#ifdef XDEBUG
+ register int i;
+ struct stat stbuf;
+
+ for (i = 0; i < 3; i++)
+ {
+ if (fstat(i, &stbuf) < 0 && errno != EOPNOTSUPP)
+ {
+ /* oops.... */
+ int fd;
+
+ syserr("%s: fd %d not open", where, i);
+ fd = open("/dev/null", i == 0 ? O_RDONLY : O_WRONLY, 0666);
+ if (fd != i)
+ {
+ (void) dup2(fd, i);
+ (void) close(fd);
+ }
+ }
+ }
+#endif /* XDEBUG */
+}
+ /*
+** PRINTOPENFDS -- print the open file descriptors (for debugging)
+**
+** Parameters:
+** logit -- if set, send output to syslog; otherwise
+** print for debugging.
+**
+** Returns:
+** none.
+*/
+
+#include <netdb.h>
+#include <arpa/inet.h>
+
+printopenfds(logit)
+ bool logit;
+{
+ register int fd;
+ extern int DtableSize;
+
+ for (fd = 0; fd < DtableSize; fd++)
+ dumpfd(fd, FALSE, logit);
+}
+ /*
+** DUMPFD -- dump a file descriptor
+**
+** Parameters:
+** fd -- the file descriptor to dump.
+** printclosed -- if set, print a notification even if
+** it is closed; otherwise print nothing.
+** logit -- if set, send output to syslog instead of stdout.
+*/
+
+dumpfd(fd, printclosed, logit)
+ int fd;
+ bool printclosed;
+ bool logit;
+{
+ register struct hostent *hp;
+ register char *p;
+ char *fmtstr;
+ struct sockaddr_in sin;
+ auto int slen;
+ struct stat st;
+ char buf[200];
+
+ p = buf;
+ sprintf(p, "%3d: ", fd);
+ p += strlen(p);
+
+ if (fstat(fd, &st) < 0)
+ {
+ if (printclosed || errno != EBADF)
+ {
+ sprintf(p, "CANNOT STAT (%s)", errstring(errno));
+ goto printit;
+ }
+ return;
+ }
+
+ slen = fcntl(fd, F_GETFL, NULL);
+ if (slen != -1)
+ {
+ sprintf(p, "fl=0x%x, ", slen);
+ p += strlen(p);
+ }
+
+ sprintf(p, "mode=%o: ", st.st_mode);
+ p += strlen(p);
+ switch (st.st_mode & S_IFMT)
+ {
+#ifdef S_IFSOCK
+ case S_IFSOCK:
+ sprintf(p, "SOCK ");
+ p += strlen(p);
+ slen = sizeof sin;
+ if (getsockname(fd, (struct sockaddr *) &sin, &slen) < 0)
+ sprintf(p, "(badsock)");
+ else
+ {
+ hp = gethostbyaddr((char *) &sin.sin_addr, slen, AF_INET);
+ sprintf(p, "%s/%d", hp == NULL ? inet_ntoa(sin.sin_addr)
+ : hp->h_name, ntohs(sin.sin_port));
+ }
+ p += strlen(p);
+ sprintf(p, "->");
+ p += strlen(p);
+ slen = sizeof sin;
+ if (getpeername(fd, (struct sockaddr *) &sin, &slen) < 0)
+ sprintf(p, "(badsock)");
+ else
+ {
+ hp = gethostbyaddr((char *) &sin.sin_addr, slen, AF_INET);
+ sprintf(p, "%s/%d", hp == NULL ? inet_ntoa(sin.sin_addr)
+ : hp->h_name, ntohs(sin.sin_port));
+ }
+ break;
+#endif
+
+ case S_IFCHR:
+ sprintf(p, "CHR: ");
+ p += strlen(p);
+ goto defprint;
+
+ case S_IFBLK:
+ sprintf(p, "BLK: ");
+ p += strlen(p);
+ goto defprint;
+
+#if defined(S_IFIFO) && (!defined(S_IFSOCK) || S_IFIFO != S_IFSOCK)
+ case S_IFIFO:
+ sprintf(p, "FIFO: ");
+ p += strlen(p);
+ goto defprint;
+#endif
+
+#ifdef S_IFDIR
+ case S_IFDIR:
+ sprintf(p, "DIR: ");
+ p += strlen(p);
+ goto defprint;
+#endif
+
+#ifdef S_IFLNK
+ case S_IFLNK:
+ sprintf(p, "LNK: ");
+ p += strlen(p);
+ goto defprint;
+#endif
+
+ default:
+defprint:
+ if (sizeof st.st_size > sizeof (long))
+ fmtstr = "dev=%d/%d, ino=%d, nlink=%d, u/gid=%d/%d, size=%qd";
+ else
+ fmtstr = "dev=%d/%d, ino=%d, nlink=%d, u/gid=%d/%d, size=%ld";
+ sprintf(p, fmtstr,
+ major(st.st_dev), minor(st.st_dev), st.st_ino,
+ st.st_nlink, st.st_uid, st.st_gid, st.st_size);
+ break;
+ }
+
+printit:
+#ifdef LOG
+ if (logit)
+ syslog(LOG_DEBUG, "%s", buf);
+ else
+#endif
+ printf("%s\n", buf);
+}
+ /*
+** SHORTENSTRING -- return short version of a string
+**
+** If the string is already short, just return it. If it is too
+** long, return the head and tail of the string.
+**
+** Parameters:
+** s -- the string to shorten.
+** m -- the max length of the string.
+**
+** Returns:
+** Either s or a short version of s.
+*/
+
+#ifndef MAXSHORTSTR
+# define MAXSHORTSTR 203
+#endif
+
+char *
+shortenstring(s, m)
+ register char *s;
+ int m;
+{
+ int l;
+ static char buf[MAXSHORTSTR + 1];
+
+ l = strlen(s);
+ if (l < m)
+ return s;
+ if (m > MAXSHORTSTR)
+ m = MAXSHORTSTR;
+ else if (m < 10)
+ {
+ if (m < 5)
+ {
+ strncpy(buf, s, m);
+ buf[m] = '\0';
+ return buf;
+ }
+ strncpy(buf, s, m - 3);
+ strcpy(buf + m - 3, "...");
+ return buf;
+ }
+ m = (m - 3) / 2;
+ strncpy(buf, s, m);
+ strcpy(buf + m, "...");
+ strcpy(buf + m + 3, s + l - m);
+ return buf;
+}
diff --git a/usr.sbin/sendmail/src/version.c b/usr.sbin/sendmail/src/version.c
new file mode 100644
index 0000000..fa3c31a
--- /dev/null
+++ b/usr.sbin/sendmail/src/version.c
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 1983 Eric P. Allman
+ * Copyright (c) 1988, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)version.c 8.6.9.1 (Berkeley) 4/18/94";
+#endif /* not lint */
+
+char Version[] = "8.6.9";
OpenPOWER on IntegriCloud